* Moved lcc and q3asm into code/tools

This commit is contained in:
Tim Angus 2005-10-04 15:18:22 +00:00
parent b1cef6352e
commit ad118b9baf
452 changed files with 0 additions and 0 deletions

61
code/tools/lcc/COPYRIGHT Normal file
View file

@ -0,0 +1,61 @@
The authors of this software are Christopher W. Fraser and
David R. Hanson.
Copyright (c) 1991,1992,1993,1994,1995,1996,1997,1998 by AT&T,
Christopher W. Fraser, and David R. Hanson. All Rights Reserved.
Permission to use, copy, modify, and distribute this software for any
purpose, subject to the provisions described below, without fee is
hereby granted, provided that this entire notice is included in all
copies of any software that is or includes a copy or modification of
this software and in all copies of the supporting documentation for
such software.
THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
lcc is not public-domain software, shareware, and it is not protected
by a `copyleft' agreement, like the code from the Free Software
Foundation.
lcc is available free for your personal research and instructional use
under the `fair use' provisions of the copyright law. You may, however,
redistribute lcc in whole or in part provided you acknowledge its
source and include this CPYRIGHT file. You may, for example, include
the distribution in a CDROM of free software, provided you charge only
for the media, or mirror the distribution files at your site.
You may not sell lcc or any product derived from it in which it is a
significant part of the value of the product. Using the lcc front end
to build a C syntax checker is an example of this kind of product.
You may use parts of lcc in products as long as you charge for only
those components that are entirely your own and you acknowledge the use
of lcc clearly in all product documentation and distribution media. You
must state clearly that your product uses or is based on parts of lcc
and that lcc is available free of charge. You must also request that
bug reports on your product be reported to you. Using the lcc front
end to build a C compiler for the Motorola 88000 chip and charging for
and distributing only the 88000 code generator is an example of this
kind of product.
Using parts of lcc in other products is more problematic. For example,
using parts of lcc in a C++ compiler could save substantial time and
effort and therefore contribute significantly to the profitability of
the product. This kind of use, or any use where others stand to make a
profit from what is primarily our work, requires a license agreement
with Addison-Wesley. Per-copy and unlimited use licenses are
available; for more information, contact
J. Carter Shanklin
Addison Wesley Longman, Inc.
2725 Sand Hill Rd.
Menlo Park, CA 94025
650/854-0300 x2478 FAX: 650/614-2930 jcs@awl.com
-----
Chris Fraser / cwfraser@microsoft.com
David Hanson / drh@microsoft.com
$Revision: 145 $ $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $

91
code/tools/lcc/LOG Normal file
View file

@ -0,0 +1,91 @@
From lcc 4.0 to 4.1:
Changes:
See doc/4.html for changes in the code-generation interface.
Warns about constants that are too large, eg, short x = 70000;
Warns about expressions that have no effect.
Unsigned shorts are now used for wide-character constants, and
wchar_t is a typedef for unsigned short.
More assertions in gen.c to confirm that the register allocator is
configured correctly; ie, that the various masks, wildcards,
clobbers, and targets are internally consistent. Full checking
appears impractical, but there's still more than than there was
before.
On the SPARC, lcc now emits .type and .size directives
unconditionally.
On the x86, constants are now emitted into the text segment.
If the environment variable "LCCDIR" is defined, it gives the directory
that contains the preprocessor, the compiler proper, and the
lcc-specific libraries.
Under Windows, lcc searches the directories named in the environment
variable "include" for header files.
Errors fixed:
Erroneously complained about unknown sizes for some const fields, eg,
typedef struct foo ref; struct foo { const ref *q; int a; };
f(ref *p, int i) { return p->q[i].a; }
-A -A erroneously complained about static main's that didn't conform
to the ANSI-mandated "int main(void)" or "int main(int, char **)".
Silently generated incorrect code for a structure copy with a
post-incremented target, eg,
struct { int x; } data = {1}, copy[2], *q = copy;
main() { *q++ = data; }
Generated incorrect values in some expressions with constant pointers.
Silently truncated string literals longer than 4095 characters.
Failed to emit debugging information for uninitialized globals.
Failed to diagnose missing sizes in some multi-dimensioned array
declarators, eg, extern int x[][10]; int x[5][];
Silently emitted incorrect sizes and initalizations for some
incomplete multi-dimensioned arrays involving pointers and whose size
is determined by the number of initializers.
Set only the x.name field for some back-end symbols (eg, wildcards),
and the uninitialized name field crashed some debugging output.
uses() failed to check the register *set* as well as the register
mask. There's no known bug demo, but a wildcard set might be
contrived that would need the test.
Crashed with -b on some conditional expressions involving calls, eg,
int p; void g(void) { p ? f() : 1; }
On the MIPS, sometimes generated an incorrect frame size and thus a
crash when floating-point registers were saved.
On the SPARC, erroneously reused a register variable as a temporary
when the variable is compiler-generated.
On the SPARC with -b, emitted incorrect code for returning structs.
On the x86, conversion from float to int rounded instead of truncated
with the default floating-point mode.
On the x86, eliminate rtargets for kids after the first (see p. 419).
On the x86, substitute reg for freg, in order to use the common reg
rules. Needed only for debugging output, since we're not using any
float regs as regs at this time.
On the x86, "double f(); main(){f();}" wasn't popping the FP register stack.
On the x86, ECX was saved by the callee, when it should have been
saved by the caller.
$Id: LOG 145 2001-10-17 21:53:10Z timo $

21
code/tools/lcc/README Normal file
View file

@ -0,0 +1,21 @@
This hierarchy is the distribution for lcc version 4.1.
lcc version 3.x is described in the book "A Retargetable C Compiler:
Design and Implementation" (Addison-Wesley, 1995, ISBN 0-8053-1670-1).
There are significant differences between 3.x and 4.x, most notably in
the intermediate code. doc/4.html summarizes the differences.
VERSION 4.1 IS INCOMPATIBLE WITH EARLIER VERSIONS OF LCC. DO NOT
UNLOAD THIS DISTRIBUTION ON TOP OF A 3.X DISTRIBUTION.
LOG describes the changes since the last release.
CPYRIGHT describes the conditions under you can use, copy, modify, and
distribute lcc or works derived from lcc.
doc/install.html is an HTML file that gives a complete description of
the distribution and installation instructions.
Chris Fraser / cwfraser@microsoft.com
David Hanson / drh@microsoft.com
$Revision: 145 $ $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $

3
code/tools/lcc/README.id Normal file
View file

@ -0,0 +1,3 @@
2001-10-31 Timothee Besset <ttimo@idsoftware.com>
updated from the $/source/lcc code
modified for portability and use with >= 1.31 mod source release

View file

@ -0,0 +1,92 @@
1 5 8 6 3 7 2 4
1 6 8 3 7 4 2 5
1 7 4 6 8 2 5 3
1 7 5 8 2 4 6 3
2 4 6 8 3 1 7 5
2 5 7 1 3 8 6 4
2 5 7 4 1 8 6 3
2 6 1 7 4 8 3 5
2 6 8 3 1 4 7 5
2 7 3 6 8 5 1 4
2 7 5 8 1 4 6 3
2 8 6 1 3 5 7 4
3 1 7 5 8 2 4 6
3 5 2 8 1 7 4 6
3 5 2 8 6 4 7 1
3 5 7 1 4 2 8 6
3 5 8 4 1 7 2 6
3 6 2 5 8 1 7 4
3 6 2 7 1 4 8 5
3 6 2 7 5 1 8 4
3 6 4 1 8 5 7 2
3 6 4 2 8 5 7 1
3 6 8 1 4 7 5 2
3 6 8 1 5 7 2 4
3 6 8 2 4 1 7 5
3 7 2 8 5 1 4 6
3 7 2 8 6 4 1 5
3 8 4 7 1 6 2 5
4 1 5 8 2 7 3 6
4 1 5 8 6 3 7 2
4 2 5 8 6 1 3 7
4 2 7 3 6 8 1 5
4 2 7 3 6 8 5 1
4 2 7 5 1 8 6 3
4 2 8 5 7 1 3 6
4 2 8 6 1 3 5 7
4 6 1 5 2 8 3 7
4 6 8 2 7 1 3 5
4 6 8 3 1 7 5 2
4 7 1 8 5 2 6 3
4 7 3 8 2 5 1 6
4 7 5 2 6 1 3 8
4 7 5 3 1 6 8 2
4 8 1 3 6 2 7 5
4 8 1 5 7 2 6 3
4 8 5 3 1 7 2 6
5 1 4 6 8 2 7 3
5 1 8 4 2 7 3 6
5 1 8 6 3 7 2 4
5 2 4 6 8 3 1 7
5 2 4 7 3 8 6 1
5 2 6 1 7 4 8 3
5 2 8 1 4 7 3 6
5 3 1 6 8 2 4 7
5 3 1 7 2 8 6 4
5 3 8 4 7 1 6 2
5 7 1 3 8 6 4 2
5 7 1 4 2 8 6 3
5 7 2 4 8 1 3 6
5 7 2 6 3 1 4 8
5 7 2 6 3 1 8 4
5 7 4 1 3 8 6 2
5 8 4 1 3 6 2 7
5 8 4 1 7 2 6 3
6 1 5 2 8 3 7 4
6 2 7 1 3 5 8 4
6 2 7 1 4 8 5 3
6 3 1 7 5 8 2 4
6 3 1 8 4 2 7 5
6 3 1 8 5 2 4 7
6 3 5 7 1 4 2 8
6 3 5 8 1 4 2 7
6 3 7 2 4 8 1 5
6 3 7 2 8 5 1 4
6 3 7 4 1 8 2 5
6 4 1 5 8 2 7 3
6 4 2 8 5 7 1 3
6 4 7 1 3 5 2 8
6 4 7 1 8 2 5 3
6 8 2 4 1 7 5 3
7 1 3 8 6 4 2 5
7 2 4 1 8 5 3 6
7 2 6 3 1 4 8 5
7 3 1 6 8 5 2 4
7 3 8 2 5 1 6 4
7 4 2 5 8 1 3 6
7 4 2 8 6 1 3 5
7 5 3 1 6 8 2 4
8 2 4 1 7 5 3 6
8 2 5 3 1 7 4 6
8 3 1 6 2 5 7 4
8 4 1 3 6 2 7 5

View file

@ -0,0 +1,2 @@
tst/8q.c:30: warning: missing return value
tst/8q.c:39: warning: missing return value

View file

@ -0,0 +1,193 @@
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
.prologue 1
mov $31,$14
L.2:
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
lda $25,1
stl $25,down($27)
stl $25,up($27)
L.3:
lda $14,1($14)
cmplt $14,15,$23
bne $23,L.2
mov $31,$14
L.6:
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
lda $25,1
stl $25,rows($27)
L.7:
lda $14,1($14)
cmplt $14,8,$23
bne $23,L.6
mov $31,$16
jsr $26,queens
ldgp $gp,0($26)
mov $31,$0
L.1:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end main
.globl queens
.text
.ent queens
queens:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4006000,-64
.frame $sp,80,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $26,16($sp)
mov $16,$14
.prologue 1
mov $31,$13
L.11:
sll $13,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,2,$25
ldl $25,rows($25)
cmpeq $25,$31,$23
bne $23,L.15
subl $13,$14,$25
lda $25,7($25)
sll $25,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,2,$25
ldl $25,up($25)
cmpeq $25,$31,$23
bne $23,L.15
addl $13,$14,$25
sll $25,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,2,$25
ldl $25,down($25)
cmpeq $25,$31,$23
bne $23,L.15
addl $13,$14,$25
sll $25,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,2,$25
stl $31,down($25)
subl $13,$14,$25
lda $25,7($25)
sll $25,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,2,$25
stl $31,up($25)
sll $13,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,2,$25
stl $31,rows($25)
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
stl $13,x($27)
cmpeq $14,7,$23
beq $23,L.17
jsr $26,print
ldgp $gp,0($26)
br L.18
L.17:
lda $16,1($14)
jsr $26,queens
ldgp $gp,0($26)
L.18:
lda $27,1
addl $13,$14,$25
sll $25,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,2,$25
stl $27,down($25)
subl $13,$14,$25
lda $25,7($25)
sll $25,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,2,$25
stl $27,up($25)
sll $13,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,2,$25
stl $27,rows($25)
L.15:
L.12:
lda $13,1($13)
cmplt $13,8,$23
bne $23,L.11
mov $31,$0
L.10:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $26,16($sp)
lda $sp,80($sp)
ret
.end queens
.globl print
.text
.ent print
print:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
.prologue 1
mov $31,$14
L.20:
lda $16,L.24
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
ldl $27,x($27)
lda $17,49($27)
jsr $26,printf
ldgp $gp,0($26)
L.21:
lda $14,1($14)
cmplt $14,8,$23
bne $23,L.20
lda $16,L.25
jsr $26,printf
ldgp $gp,0($26)
mov $31,$0
L.19:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end print
.globl x
.comm x,32
.globl rows
.comm rows,32
.globl down
.comm down,60
.globl up
.comm up,60
.rdata
.align 0
L.25:
.byte 10
.byte 0
.align 0
L.24:
.byte 37
.byte 99
.byte 32
.byte 0

View file

@ -0,0 +1,4 @@
0 1 2 3 1000 1001 1002 1003 2000 2001 2002 2003
0 1 2 3 1000 1001 1002 1003 2000 2001 2002 2003
0 1 2 3 1000 1001 1002 1003 2000 2001 2002 2003
0 1 2 3 1000 1001 1002 1003 2000 2001 2002 2003

View file

@ -0,0 +1,2 @@
tst/array.c:33: warning: missing return value
tst/array.c:48: warning: missing return value

View file

@ -0,0 +1,260 @@
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-144($sp)
.mask 0x4007000,-120
.frame $sp,144,$26,48
stq $12,0($sp)
stq $13,8($sp)
stq $14,16($sp)
stq $26,24($sp)
.prologue 1
mov $31,$13
L.2:
mov $31,$14
L.6:
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
sll $13,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,4,$25
lda $25,x($25)
addq $27,$25,$27
lda $25,1000
mull $25,$13,$25
addl $25,$14,$25
stl $25,($27)
L.7:
lda $14,1($14)
cmplt $14,4,$23
bne $23,L.6
sll $13,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,3,$25
sll $27,4,$27
lda $27,x($27)
stq $27,y($25)
L.3:
lda $13,1($13)
cmplt $13,3,$23
bne $23,L.2
jsr $26,f
ldgp $gp,0($26)
mov $31,$13
L.10:
sll $13,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,4,$25
lda $22,-104+144($sp)
addq $25,$22,$25
mov $25,$12
sll $27,3,$27
stq $25,y($27)
mov $31,$14
L.14:
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
addq $27,$12,$25
sll $13,8*(8-4),$22
sra $22,8*(8-4),$22
sll $22,4,$22
lda $22,x($22)
addq $27,$22,$27
ldl $27,($27)
stl $27,($25)
L.15:
lda $14,1($14)
cmplt $14,4,$23
bne $23,L.14
L.11:
lda $13,1($13)
cmplt $13,3,$23
bne $23,L.10
lda $16,-104+144($sp)
lda $17,y
jsr $26,g
ldgp $gp,0($26)
mov $31,$0
L.1:
ldq $12,0($sp)
ldq $13,8($sp)
ldq $14,16($sp)
ldq $26,24($sp)
lda $sp,144($sp)
ret
.end main
.globl f
.text
.ent f
f:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4006000,-64
.frame $sp,80,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $26,16($sp)
.prologue 1
mov $31,$13
L.19:
mov $31,$14
L.23:
lda $16,L.27
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
sll $13,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,4,$25
lda $25,x($25)
addq $27,$25,$27
ldl $17,($27)
jsr $26,printf
ldgp $gp,0($26)
L.24:
lda $14,1($14)
cmplt $14,4,$23
bne $23,L.23
L.20:
lda $13,1($13)
cmplt $13,3,$23
bne $23,L.19
lda $16,L.28
jsr $26,printf
ldgp $gp,0($26)
mov $31,$13
L.29:
mov $31,$14
L.33:
lda $16,L.27
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
sll $13,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,3,$25
ldq $25,y($25)
addq $27,$25,$27
ldl $17,($27)
jsr $26,printf
ldgp $gp,0($26)
L.34:
lda $14,1($14)
cmplt $14,4,$23
bne $23,L.33
L.30:
lda $13,1($13)
cmplt $13,3,$23
bne $23,L.29
lda $16,L.28
jsr $26,printf
ldgp $gp,0($26)
mov $31,$0
L.18:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $26,16($sp)
lda $sp,80($sp)
ret
.end f
.globl g
.text
.ent g
g:
ldgp $gp,0($27)
lda $sp,-96($sp)
.mask 0x4007800,-64
.frame $sp,96,$26,48
stq $11,0($sp)
stq $12,8($sp)
stq $13,16($sp)
stq $14,24($sp)
stq $26,32($sp)
mov $16,$14
mov $17,$13
.prologue 1
mov $31,$11
L.38:
mov $31,$12
L.42:
lda $16,L.27
sll $12,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
sll $11,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,4,$25
addq $25,$14,$25
addq $27,$25,$27
ldl $17,($27)
jsr $26,printf
ldgp $gp,0($26)
L.43:
lda $12,1($12)
cmplt $12,4,$23
bne $23,L.42
L.39:
lda $11,1($11)
cmplt $11,3,$23
bne $23,L.38
lda $16,L.28
jsr $26,printf
ldgp $gp,0($26)
mov $31,$11
L.46:
mov $31,$12
L.50:
lda $16,L.27
sll $12,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
sll $11,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,3,$25
addq $25,$13,$25
ldq $25,($25)
addq $27,$25,$27
ldl $17,($27)
jsr $26,printf
ldgp $gp,0($26)
L.51:
lda $12,1($12)
cmplt $12,4,$23
bne $23,L.50
L.47:
lda $11,1($11)
cmplt $11,3,$23
bne $23,L.46
lda $16,L.28
jsr $26,printf
ldgp $gp,0($26)
mov $31,$0
L.37:
ldq $11,0($sp)
ldq $12,8($sp)
ldq $13,16($sp)
ldq $14,24($sp)
ldq $26,32($sp)
lda $sp,96($sp)
ret
.end g
.globl y
.comm y,24
.globl x
.comm x,48
.rdata
.align 0
L.28:
.byte 10
.byte 0
.align 0
L.27:
.byte 32
.byte 37
.byte 100
.byte 0

View file

@ -0,0 +1,51 @@
char freq
011 8.1
012 6.1
040 11.9
! 0.2
" 1.5
% 0.6
& 0.4
' 0.4
( 2.9
) 2.9
* 0.8
+ 1.3
, 1.3
- 0.4
. 0.6
/ 1.0
0 2.5
1 1.9
2 0.6
3 0.2
7 0.4
8 0.2
; 3.8
< 0.8
= 2.7
> 0.2
[ 1.5
\ 0.8
] 1.5
a 3.1
c 4.4
e 2.3
f 6.0
g 1.3
h 1.0
i 5.0
l 1.0
m 0.2
n 3.3
o 2.1
p 1.0
q 0.4
r 4.2
s 0.6
t 3.8
u 1.2
v 0.6
w 0.2
{ 0.6
} 0.6

View file

View file

@ -0,0 +1,170 @@
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-96($sp)
.fmask 0x200,-96
.mask 0x4007000,-64
.frame $sp,96,$26,48
stt $f9,0($sp)
stq $12,8($sp)
stq $13,16($sp)
stq $14,24($sp)
stq $26,32($sp)
stq $16,48($sp)
stq $17,56($sp)
.prologue 1
ldl $27,-48+96($sp)
cmple $27,1,$23
beq $23,L.2
lds $f9,L.4
br L.3
L.2:
ldq $27,-40+96($sp)
ldq $16,8($27)
jsr $26,atof
ldgp $gp,0($26)
lds $f29,L.5
divs $f0,$f29,$f9
L.3:
mov $31,$14
L.6:
mov $14,$27
lda $14,1($27)
sll $27,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
lds $f30,L.4
sts $f30,f($27)
L.7:
lda $27,127
cmple $14,$27,$23
bne $23,L.6
mov $31,$13
br L.11
L.10:
sll $12,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
lda $27,f($27)
lds $f30,($27)
lds $f29,L.13
adds $f30,$f29,$f30
sts $f30,($27)
lda $13,1($13)
L.11:
jsr $26,getchar
ldgp $gp,0($26)
mov $0,$12
lda $25,-1
cmpeq $0,$25,$23
beq $23,L.10
lda $16,L.14
jsr $26,printf
ldgp $gp,0($26)
mov $31,$14
L.15:
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
lds $f30,f($27)
lds $f29,L.4
cmpteq $f30,$f29,$f1
fbne $f1,L.19
stq $13,-56+96($sp)
ldt $f29,-56+96($sp)
cvtqs $f29,$f29
divs $f30,$f29,$f30
cmptlt $f30,$f9,$f1
fbne $f1,L.19
cmple $14,32,$23
beq $23,L.21
lda $16,L.23
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.22
L.21:
lda $16,L.24
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
L.22:
lda $16,L.25
lds $f30,L.5
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
lds $f29,f($27)
muls $f30,$f29,$f30
stq $13,-56+96($sp)
ldt $f29,-56+96($sp)
cvtqs $f29,$f29
divs $f30,$f29,$f30
cvtst $f30,$f17
jsr $26,printf
ldgp $gp,0($26)
L.19:
L.16:
lda $14,1($14)
lda $27,127
cmple $14,$27,$23
bne $23,L.15
mov $31,$0
L.1:
ldt $f9,0($sp)
ldq $12,8($sp)
ldq $13,16($sp)
ldq $14,24($sp)
ldq $26,32($sp)
lda $sp,96($sp)
ret
.end main
.globl f
.comm f,512
.rdata
.align 0
L.25:
.byte 9
.byte 37
.byte 46
.byte 49
.byte 102
.byte 10
.byte 0
.align 0
L.24:
.byte 37
.byte 99
.byte 0
.align 0
L.23:
.byte 37
.byte 48
.byte 51
.byte 111
.byte 0
.align 0
L.14:
.byte 99
.byte 104
.byte 97
.byte 114
.byte 9
.byte 102
.byte 114
.byte 101
.byte 113
.byte 10
.byte 0
.align 2
L.13:
.long 0x3f800000
.align 2
L.5:
.long 0x42c80000
.align 2
L.4:
.long 0x0

View file

@ -0,0 +1,45 @@
Section s22 returned 0.
s241,er4
Section s241 returned 4.
Section s243 returned 0.
Section s244 returned 0.
Section s25 returned 0.
8 bits in chars.
32 bits in ints.
16 bits in shorts.
64 bits in longs.
32 bits in unsigneds.
32 bits in floats.
64 bits in doubles.
1.192093e-07 is the least number that can be added to 1. (float).
2.220446e-16 is the least number that can be added to 1. (double).
Section s26 returned 0.
Section s4 returned 0.
Section s61 returned 0.
Section s626 returned 0.
Section s71 returned 0.
Section s72 returned 0.
Section s757 returned 0.
Section s7813 returned 0.
Section s714 returned 0.
Section s715 returned 0.
Register count for char is unreliable.
Register count for pointer is unreliable.
Register count for int is unreliable.
Section s81 returned 0.
Section s84 returned 0.
char alignment: 1
short alignment: 2
int alignment: 4
long alignment: 8
unsigned alignment: 4
float alignment: 4
double alignment: 8
Sign extension in fields
Be especially careful with 1-bit fields!
Section s85 returned 0.
Section s86 returned 0.
Section s88 returned 0.
Section s9 returned 0.
Failed.

View file

@ -0,0 +1,4 @@
tst/cq.c:533: warning: missing return value
tst/cq.c:1169: warning: missing return value
tst/cq.c:5294: warning: unreachable code
tst/cq.c:5303: warning: missing return value

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,11 @@
1 1 1 1 1 1 1 1 1.000000 1.000000 1.000000
2 2 2 2 2 2 2 2 2.000000 2.000000 2.000000
3 3 3 3 3 3 3 3 3.000000 3.000000 3.000000
4 4 4 4 4 4 4 4 4.000000 4.000000 4.000000
5 5 5 5 5 5 5 5 5.000000 5.000000 5.000000
6 6 6 6 6 6 6 6 6.000000 6.000000 6.000000
7 7 7 7 7 7 7 7 7.000000 7.000000 7.000000
8 8 8 8 8 8 8 8 8.000000 8.000000 8.000000
9 9 9 9 9 9 9 9 9.000000 9.000000 9.000000
10 10 10 10 10 10 10 10 10.000000 10.000000 10.000000
11 11 11 11 11 11 11 11 11.000000 11.000000 11.000000

View file

@ -0,0 +1,2 @@
tst/cvt.c:32: warning: conversion from `pointer to void function(void)' to `pointer to void' is compiler dependent
tst/cvt.c:33: warning: conversion from `pointer to void' to `pointer to void function(void)' is compiler dependent

View file

@ -0,0 +1,744 @@
.globl print
.text
.text
.ent print
print:
ldgp $gp,0($27)
lda $sp,-112($sp)
.mask 0x4000000,-64
.frame $sp,112,$26,48
stq $26,48($sp)
.prologue 1
lda $16,L.2
lda $27,c
ldb $17,($27)
lda $27,s
ldw $18,($27)
ldl $19,i
ldq $20,l
lda $27,C
ldbu $21,($27)
lda $27,S
ldwu $27,($27)
stq $27,0($sp)
ldl $27,I
zap $27,240,$27
stq $27,8($sp)
ldq $27,L
stq $27,16($sp)
lds $f30,f
cvtst $f30,$f30
stt $f30,24($sp)
ldt $f30,d
stt $f30,32($sp)
ldt $f30,D
stt $f30,40($sp)
jsr $26,printf
ldgp $gp,0($26)
L.1:
ldq $26,48($sp)
lda $sp,112($sp)
ret
.end print
.globl main
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-160($sp)
.mask 0x5007e00,-104
.frame $sp,160,$26,48
stq $9,0($sp)
stq $10,8($sp)
stq $11,16($sp)
stq $12,24($sp)
stq $13,32($sp)
stq $14,40($sp)
stq $24,48($sp)
stq $26,56($sp)
.prologue 1
lda $27,c
lda $25,1
stb $25,c
ldb $27,($27)
mov $27,$25
stw $25,s
stl $27,i
sll $27,8*(8-4),$25
sra $25,8*(8-4),$25
stq $25,l
mov $27,$25
mov $25,$22
stb $22,C
mov $25,$22
stw $22,S
stl $25,I
mov $27,$25
stq $25,L
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqs $f30,$f30
sts $f30,f
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqt $f30,$f30
stt $f30,d
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
lda $27,s
lda $25,2
stw $25,s
ldw $27,($27)
mov $27,$25
stb $25,c
stl $27,i
sll $27,8*(8-4),$25
sra $25,8*(8-4),$25
stq $25,l
mov $27,$25
mov $25,$22
stb $22,C
mov $25,$22
stw $22,S
stl $25,I
mov $27,$25
stq $25,L
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqs $f30,$f30
sts $f30,f
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqt $f30,$f30
stt $f30,d
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
lda $27,3
stl $27,i
ldl $27,i
mov $27,$25
stb $25,c
mov $27,$25
stw $25,s
sll $27,8*(8-4),$25
sra $25,8*(8-4),$25
stq $25,l
mov $27,$25
mov $25,$22
stb $22,C
mov $25,$22
stw $22,S
stl $25,I
mov $27,$25
stq $25,L
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqs $f30,$f30
sts $f30,f
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqt $f30,$f30
stt $f30,d
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
lda $27,4
stq $27,l
ldq $27,l
mov $27,$25
stb $25,c
mov $27,$25
stw $25,s
mov $27,$25
stl $25,i
mov $27,$25
mov $25,$22
stb $22,C
mov $25,$22
stw $22,S
stl $25,I
mov $27,$25
stq $25,L
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqs $f30,$f30
sts $f30,f
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqt $f30,$f30
stt $f30,d
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
lda $27,C
lda $25,5
stb $25,C
ldbu $27,($27)
mov $27,$25
stb $25,c
mov $27,$25
stw $25,s
stl $27,i
sll $27,8*(8-4),$25
sra $25,8*(8-4),$25
stq $25,l
mov $27,$25
mov $25,$22
stw $22,S
stl $25,I
mov $27,$25
stq $25,L
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqs $f30,$f30
sts $f30,f
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqt $f30,$f30
stt $f30,d
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
lda $27,S
lda $25,6
stw $25,S
ldwu $27,($27)
mov $27,$25
stb $25,c
mov $27,$25
stw $25,s
stl $27,i
sll $27,8*(8-4),$25
sra $25,8*(8-4),$25
stq $25,l
mov $27,$25
mov $25,$22
stb $22,C
stl $25,I
mov $27,$25
stq $25,L
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqs $f30,$f30
sts $f30,f
stq $27,-56+160($sp)
ldt $f30,-56+160($sp)
cvtqt $f30,$f30
stt $f30,d
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
lda $27,7
stl $27,I
ldl $27,I
zap $27,240,$27
mov $27,$25
mov $25,$22
stb $22,c
mov $25,$22
stw $22,s
stl $25,i
and $27,(1<<(8*4))-1,$25
stq $25,l
mov $27,$25
stb $25,C
mov $27,$25
stw $25,S
and $27,(1<<(8*4))-1,$25
stq $25,L
ldt $f30,L.4
srl $27,1,$25
stq $25,-56+160($sp)
ldt $f29,-56+160($sp)
cvtqt $f29,$f29
mult $f30,$f29,$f30
and $27,1,$27
stq $27,-56+160($sp)
ldt $f29,-56+160($sp)
cvtqt $f29,$f29
addt $f30,$f29,$f30
cvtts $f30,$f29
sts $f29,f
stt $f30,d
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
lda $27,8
stq $27,L
ldq $27,L
mov $27,$25
mov $25,$22
stb $22,c
mov $25,$22
stw $22,s
stl $25,i
mov $27,$25
stq $25,l
mov $27,$25
stb $25,C
lda $25,S
mov $27,$22
stw $22,S
ldwu $25,($25)
stl $25,I
ldt $f30,L.4
srl $27,1,$25
stq $25,-56+160($sp)
ldt $f29,-56+160($sp)
cvtqt $f29,$f29
mult $f30,$f29,$f30
and $27,1,$27
stq $27,-56+160($sp)
ldt $f29,-56+160($sp)
cvtqt $f29,$f29
addt $f30,$f29,$f30
cvtts $f30,$f29
sts $f29,f
stt $f30,d
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
lds $f30,L.5
sts $f30,f
lds $f30,f
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
mov $27,$25
stb $25,c
mov $27,$25
stw $25,s
stl $27,i
cvttqc $f30,$f1
stt $f1,-56+160($sp)
ldq $27,-56+160($sp)
stq $27,l
lds $f29,L.9
cmptlt $f30,$f29,$f1
fbne $f1,L.7
subs $f30,$f29,$f29
cvttqc $f29,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
addl $27,0x80000000,$14
zap $14,240,$14
br L.8
L.7:
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
mov $27,$14
L.8:
mov $14,$27
stb $27,C
lds $f30,f
lds $f29,L.9
cmptlt $f30,$f29,$f1
fbne $f1,L.11
subs $f30,$f29,$f29
cvttqc $f29,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
addl $27,0x80000000,$13
zap $13,240,$13
br L.12
L.11:
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
mov $27,$13
L.12:
mov $13,$27
stw $27,S
lds $f30,f
lds $f29,L.9
cmptlt $f30,$f29,$f1
fbne $f1,L.14
subs $f30,$f29,$f29
cvttqc $f29,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
addl $27,0x80000000,$12
zap $12,240,$12
br L.15
L.14:
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
mov $27,$12
L.15:
stl $12,I
lds $f30,f
lds $f29,L.19
cmptlt $f30,$f29,$f1
fbne $f1,L.17
subs $f30,$f29,$f29
cvttqc $f29,$f1
stt $f1,-56+160($sp)
ldq $27,-56+160($sp)
lda $11,0x8000000000000000($27)
br L.18
L.17:
cvttqc $f30,$f1
stt $f1,-56+160($sp)
ldq $27,-56+160($sp)
mov $27,$11
L.18:
stq $11,L
lds $f30,f
cvtst $f30,$f30
stt $f30,d
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
ldt $f30,L.20
stt $f30,d
ldt $f30,d
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
mov $27,$25
stb $25,c
mov $27,$25
stw $25,s
stl $27,i
cvttqc $f30,$f1
stt $f1,-56+160($sp)
ldq $27,-56+160($sp)
stq $27,l
ldt $f29,L.24
cmptlt $f30,$f29,$f1
fbne $f1,L.22
subt $f30,$f29,$f29
cvttqc $f29,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
addl $27,0x80000000,$10
zap $10,240,$10
br L.23
L.22:
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
mov $27,$10
L.23:
mov $10,$27
stb $27,C
ldt $f30,d
ldt $f29,L.24
cmptlt $f30,$f29,$f1
fbne $f1,L.26
subt $f30,$f29,$f29
cvttqc $f29,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
addl $27,0x80000000,$9
zap $9,240,$9
br L.27
L.26:
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
mov $27,$9
L.27:
mov $9,$27
stw $27,S
ldt $f30,d
ldt $f29,L.24
cmptlt $f30,$f29,$f1
fbne $f1,L.29
subt $f30,$f29,$f29
cvttqc $f29,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
addl $27,0x80000000,$27
zap $27,240,$27
stl $27,-60+160($sp)
br L.30
L.29:
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
stl $27,-60+160($sp)
L.30:
ldl $27,-60+160($sp)
zap $27,240,$27
stl $27,I
ldt $f30,d
ldt $f29,L.34
cmptlt $f30,$f29,$f1
fbne $f1,L.32
subt $f30,$f29,$f29
cvttqc $f29,$f1
stt $f1,-56+160($sp)
ldq $27,-56+160($sp)
lda $27,0x8000000000000000($27)
stq $27,-72+160($sp)
br L.33
L.32:
cvttqc $f30,$f1
stt $f1,-56+160($sp)
ldq $27,-56+160($sp)
stq $27,-72+160($sp)
L.33:
ldq $27,-72+160($sp)
stq $27,L
ldt $f30,d
cvtts $f30,$f29
sts $f29,f
stt $f30,D
jsr $26,print
ldgp $gp,0($26)
ldt $f30,L.35
stt $f30,D
ldt $f30,D
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
mov $27,$25
stb $25,c
mov $27,$25
stw $25,s
stl $27,i
cvttqc $f30,$f1
stt $f1,-56+160($sp)
ldq $27,-56+160($sp)
stq $27,l
ldt $f29,L.39
cmptlt $f30,$f29,$f1
fbne $f1,L.37
subt $f30,$f29,$f29
cvttqc $f29,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
addl $27,0x80000000,$27
zap $27,240,$27
stl $27,-76+160($sp)
br L.38
L.37:
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
stl $27,-76+160($sp)
L.38:
ldl $27,-76+160($sp)
zap $27,240,$27
stb $27,C
ldt $f30,D
ldt $f29,L.39
cmptlt $f30,$f29,$f1
fbne $f1,L.41
subt $f30,$f29,$f29
cvttqc $f29,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
addl $27,0x80000000,$27
zap $27,240,$27
stl $27,-80+160($sp)
br L.42
L.41:
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
stl $27,-80+160($sp)
L.42:
ldl $27,-80+160($sp)
zap $27,240,$27
stw $27,S
ldt $f30,D
ldt $f29,L.39
cmptlt $f30,$f29,$f1
fbne $f1,L.44
subt $f30,$f29,$f29
cvttqc $f29,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
addl $27,0x80000000,$27
zap $27,240,$27
stl $27,-84+160($sp)
br L.45
L.44:
cvttqc $f30,$f1
cvtql $f1,$f1
sts $f1,-56+160($sp)
ldl $27,-56+160($sp)
stl $27,-84+160($sp)
L.45:
ldl $27,-84+160($sp)
zap $27,240,$27
stl $27,I
ldt $f30,D
ldt $f29,L.49
cmptlt $f30,$f29,$f1
fbne $f1,L.47
subt $f30,$f29,$f29
cvttqc $f29,$f1
stt $f1,-56+160($sp)
ldq $27,-56+160($sp)
lda $27,0x8000000000000000($27)
stq $27,-96+160($sp)
br L.48
L.47:
cvttqc $f30,$f1
stt $f1,-56+160($sp)
ldq $27,-56+160($sp)
stq $27,-96+160($sp)
L.48:
ldq $27,-96+160($sp)
stq $27,L
ldt $f30,D
cvtts $f30,$f29
sts $f29,f
stt $f30,d
jsr $26,print
ldgp $gp,0($26)
stq $31,p
stq $31,p
stq $31,p
stq $31,p
ldq $27,P
stq $27,p
stq $31,P
stq $31,P
stq $31,P
stq $31,P
ldq $27,p
stq $27,P
mov $31,$0
L.3:
ldq $9,0($sp)
ldq $10,8($sp)
ldq $11,16($sp)
ldq $12,24($sp)
ldq $13,32($sp)
ldq $14,40($sp)
ldq $24,48($sp)
ldq $26,56($sp)
lda $sp,160($sp)
ret
.end main
.globl P
.comm P,8
.globl p
.comm p,8
.globl D
.comm D,8
.globl d
.comm d,8
.globl f
.comm f,4
.globl L
.comm L,8
.globl I
.comm I,4
.globl S
.comm S,2
.globl C
.comm C,1
.globl l
.comm l,8
.globl i
.comm i,4
.globl s
.comm s,2
.globl c
.comm c,1
.rdata
.align 3
L.49:
.long 0x0
.long 0x43e00000
.align 3
L.39:
.long 0x0
.long 0x41e00000
.align 3
L.35:
.long 0x0
.long 0x40260000
.align 3
L.34:
.long 0x0
.long 0x43e00000
.align 3
L.24:
.long 0x0
.long 0x41e00000
.align 3
L.20:
.long 0x0
.long 0x40240000
.align 2
L.19:
.long 0x5f000000
.align 2
L.9:
.long 0x4f000000
.align 2
L.5:
.long 0x41100000
.align 3
L.4:
.long 0x0
.long 0x40000000
.align 0
L.2:
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 108
.byte 100
.byte 32
.byte 37
.byte 117
.byte 32
.byte 37
.byte 117
.byte 32
.byte 37
.byte 117
.byte 32
.byte 37
.byte 108
.byte 117
.byte 32
.byte 37
.byte 102
.byte 32
.byte 37
.byte 102
.byte 32
.byte 37
.byte 108
.byte 102
.byte 10
.byte 0

View file

@ -0,0 +1,5 @@
x = 1 2 3 4 -3 6
y = 3 8 9
x = 1 2 3 0 0 6
y = 2 8 16
p->a = 0x3, p->b = 0xf

View file

@ -0,0 +1,4 @@
tst/fields.c:6: warning: initializer exceeds bit-field width
tst/fields.c:8: warning: initializer exceeds bit-field width
tst/fields.c:30: warning: missing return value
tst/fields.c:34: warning: missing return value

View file

@ -0,0 +1,325 @@
.sdata
.globl x
.align 2
x:
.long 0x1
.byte 0x2
.space 3
.byte 0x3
.byte 0x40
.space 2
.byte 0x50
.byte 0x6
.space 2
.globl i
.align 2
i:
.long 0x10
.globl y
.align 2
y:
.byte 0x23
.space 3
.byte 0x9
.byte 0x0
.byte 0x0
.byte 0x0
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4000000,-72
.frame $sp,80,$26,48
stq $26,8($sp)
.prologue 1
lda $16,L.4
ldl $17,x
lda $27,x+4
ldb $18,($27)
ldl $27,x+8
sll $27,20,$27
addl $27,0,$27
sra $27,20,$19
addl $19,0,$19
ldl $27,x+8
sll $27,16,$27
addl $27,0,$27
sra $27,28,$20
addl $20,0,$20
ldl $27,x+12
sll $27,25,$27
addl $27,0,$27
sra $27,29,$21
addl $21,0,$21
lda $27,x+13
ldb $27,($27)
stq $27,0($sp)
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.10
ldl $27,y
zap $27,240,$27
and $27,3,$17
srl $27,2,$27
and $27,15,$18
ldl $19,y+4
zap $19,240,$19
jsr $26,printf
ldgp $gp,0($26)
ldl $27,x+8
and $27,0xffff0fff,$27
ldl $25,i
sll $25,28,$25
addl $25,0,$25
sra $25,28,$25
addl $25,0,$25
sll $25,12,$25
zap $25,240,$25
and $25,0xf000,$25
or $27,$25,$27
stl $27,x+8
ldl $27,x+12
and $27,0xffffff8f,$27
stl $27,x+12
lda $16,L.4
ldl $17,x
lda $27,x+4
ldb $18,($27)
ldl $27,x+8
sll $27,20,$27
addl $27,0,$27
sra $27,20,$19
addl $19,0,$19
ldl $27,x+8
sll $27,16,$27
addl $27,0,$27
sra $27,28,$20
addl $20,0,$20
ldl $27,x+12
sll $27,25,$27
addl $27,0,$27
sra $27,29,$21
addl $21,0,$21
lda $27,x+13
ldb $27,($27)
stq $27,0($sp)
jsr $26,printf
ldgp $gp,0($26)
ldl $27,y
zap $27,240,$27
and $27,0xfffffffc,$27
or $27,2,$27
stl $27,y
ldl $27,i
stl $27,y+4
lda $16,L.10
ldl $27,y
zap $27,240,$27
and $27,3,$17
srl $27,2,$27
and $27,15,$18
ldl $19,y+4
zap $19,240,$19
jsr $26,printf
ldgp $gp,0($26)
lda $16,x
jsr $26,f2
ldgp $gp,0($26)
mov $31,$0
L.3:
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end main
.globl f1
.text
.ent f1
f1:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
mov $16,$14
.prologue 1
ldl $27,($14)
zap $27,240,$27
and $27,0xffffffc3,$27
stl $27,($14)
ldl $27,($14)
zap $27,240,$27
and $27,0xfffffffc,$27
and $31,3,$25
and $25,3,$25
or $27,$25,$27
stl $27,($14)
ldl $27,($14)
zap $27,240,$27
and $27,60,$27
cmpeq $27,$31,$23
bne $23,L.22
lda $16,L.24
jsr $26,printf
ldgp $gp,0($26)
L.22:
ldl $27,($14)
zap $27,240,$27
or $27,3,$27
stl $27,($14)
ldl $27,($14)
zap $27,240,$27
or $27,60,$27
stl $27,($14)
lda $16,L.25
ldl $27,($14)
zap $27,240,$27
and $27,3,$17
srl $27,2,$27
and $27,15,$18
jsr $26,printf
ldgp $gp,0($26)
mov $31,$0
L.21:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end f1
.globl f2
.text
.ent f2
f2:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4006000,-64
.frame $sp,80,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $26,16($sp)
mov $16,$14
.prologue 1
ldl $27,i
cmpeq $27,$31,$23
beq $23,L.28
lda $13,1
br L.29
L.28:
mov $31,$13
L.29:
ldl $27,($14)
zap $27,240,$27
and $27,0xfffffffc,$27
mov $13,$25
and $25,3,$25
and $25,3,$25
or $27,$25,$27
stl $27,($14)
mov $14,$16
jsr $26,f1
ldgp $gp,0($26)
ldl $27,($14)
zap $27,240,$27
and $27,0xffffffc3,$27
mov $31,$25
and $25,15,$25
sll $25,2,$25
zap $25,240,$25
and $25,60,$25
or $27,$25,$27
stl $27,($14)
mov $31,$0
L.26:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $26,16($sp)
lda $sp,80($sp)
ret
.end f2
.rdata
.align 0
L.25:
.byte 112
.byte 45
.byte 62
.byte 97
.byte 32
.byte 61
.byte 32
.byte 48
.byte 120
.byte 37
.byte 120
.byte 44
.byte 32
.byte 112
.byte 45
.byte 62
.byte 98
.byte 32
.byte 61
.byte 32
.byte 48
.byte 120
.byte 37
.byte 120
.byte 10
.byte 0
.align 0
L.24:
.byte 112
.byte 45
.byte 62
.byte 98
.byte 32
.byte 33
.byte 61
.byte 32
.byte 48
.byte 33
.byte 10
.byte 0
.align 0
L.10:
.byte 121
.byte 32
.byte 61
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.4:
.byte 120
.byte 32
.byte 61
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0

View file

@ -0,0 +1,29 @@
tst/front.c:3: warning: missing return value
tst/front.c:10: warning: missing return value
tst/front.c:20: type error in argument 1 to `s'; found `pointer to struct D' expected `pointer to incomplete struct D defined at tst/front.c:14'
tst/front.c:21: warning: missing return value
tst/front.c:32: warning: missing return value
tst/front.c:36: operands of = have illegal types `pointer to int' and `pointer to const int'
tst/front.c:38: warning: missing return value
tst/front.c:62: operands of = have illegal types `pointer to char' and `pointer to const void'
tst/front.c:63: warning: missing return value
tst/front.c:68: warning: missing return value
tst/front.c:69: warning: inconsistent linkage for `yy' previously declared at tst/front.c:68
tst/front.c:69: warning: missing return value
tst/front.c:71: invalid storage class `static' for `int function goo'
tst/front.c:71: warning: declaration of `goo' does not match previous declaration at tst/front.c:70
tst/front.c:71: warning: missing return value
tst/front.c:74: warning: declaration of `xr' does not match previous declaration at tst/front.c:72
tst/front.c:74: warning: missing return value
tst/front.c:81: warning: missing return value
tst/front.c:82: warning: declaration of `ss2' does not match previous declaration at tst/front.c:81
tst/front.c:84: warning: inconsistent linkage for `ss5' previously declared at tst/front.c:80
tst/front.c:92: type error in argument 1 to `gx1'; found `pointer to double' expected `double'
tst/front.c:92: warning: missing return value
tst/front.c:95: redeclaration of `hx1' previously declared at tst/front.c:94
tst/front.c:98: warning: missing return value
tst/front.c:101: conflicting argument declarations for function `gg1'
tst/front.c:101: warning: missing return value
tst/front.c:112: type error in argument 4 to `qsort'; found `pointer to int function(pointer to pointer to char,pointer to pointer to char)' expected `pointer to int function(pointer to const void,pointer to const void)'
tst/front.c:113: warning: missing return value
tst/front.c:120: warning: missing return value

View file

@ -0,0 +1,380 @@
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
.prologue 1
mov $31,$16
jsr $26,exit
ldgp $gp,0($26)
mov $31,$0
L.1:
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end main
.globl nested
.text
.ent nested
nested:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
.prologue 1
cmplt $16,4,$23
beq $23,L.6
lda $27,114
cmpeq $17,$27,$23
bne $23,L.9
L.6:
cmpeq $16,1,$23
beq $23,L.8
lda $27,104
cmpeq $17,$27,$23
bne $23,L.9
lda $27,105
cmpeq $17,$27,$23
bne $23,L.9
L.8:
cmpeq $16,2,$23
beq $23,L.3
lda $27,111
cmpeq $17,$27,$23
bne $23,L.9
lda $27,121
cmpeq $17,$27,$23
beq $23,L.3
L.9:
mov $17,$16
L.3:
mov $31,$0
L.2:
lda $sp,64($sp)
ret
.end nested
.globl s
.text
.ent s
s:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
.prologue 1
L.10:
lda $sp,64($sp)
ret
.end s
.sdata
.globl Dy
.align 2
Dy:
.long 0x0
.space 4
.globl Dz
.align 2
Dz:
.long 0x1
.space 4
.globl Dfunc
.text
.text
.ent Dfunc
Dfunc:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
.prologue 1
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end Dfunc
.globl f
.text
.ent f
f:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end f
.globl f1
.text
.ent f1
f1:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end f1
.globl f2
.text
.ent f2
f2:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
stq $16,16($sp)
stq $17,24($sp)
.prologue 1
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end f2
.globl g
.text
.ent g
g:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
stq $16,16($sp)
.prologue 1
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end g
.globl h
.text
.ent h
h:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
stq $16,16($sp)
.prologue 1
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end h
.globl h1
.text
.ent h1
h1:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
stq $16,16($sp)
stq $17,24($sp)
.prologue 1
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end h1
.globl h2
.text
.ent h2
h2:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end h2
.sdata
.align 2
L.21:
.long 0x1
.globl set1
.text
.text
.ent set1
set1:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end set1
.sdata
.align 2
L.23:
.long 0x2
.globl set2
.text
.text
.ent set2
set2:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end set2
.text
.ent goo
goo:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end goo
.globl sss
.text
.ent sss
sss:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end sss
.lcomm L.27,4
.globl rrr
.text
.text
.ent rrr
rrr:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end rrr
.globl setstatic
.text
.ent setstatic
setstatic:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end setstatic
.globl gx1
.text
.ent gx1
gx1:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
stt $f16,16($sp)
.prologue 1
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end gx1
.globl ff1
.text
.ent ff1
ff1:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end ff1
.globl gg1
.text
.ent gg1
gg1:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end gg1
.globl hh1
.text
.ent hh1
hh1:
ldgp $gp,0($27)
lda $sp,-48($sp)
.frame $sp,48,$26,48
.prologue 1
lda $sp,48($sp)
ret
.end hh1
.globl cmp
.text
.ent cmp
cmp:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
stq $16,16($sp)
stq $17,24($sp)
.prologue 1
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end cmp
.globl sort
.text
.ent sort
sort:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
.prologue 1
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end sort
.globl onearg
.text
.ent onearg
onearg:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
.prologue 1
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end onearg
.extern xr 4
.globl ss4
.comm ss4,4
.lcomm ss2,4
.lcomm ss5,4
.globl ss3
.comm ss3,4
.lcomm ss1,4
.lcomm yy,4
.globl z
.comm z,4
.globl y
.comm y,8
.globl x
.comm x,8
.globl b
.comm b,4
.globl a
.comm a,4

View file

View file

@ -0,0 +1,9 @@
tst/incr.c:1: warning: missing return value
tst/incr.c:6: warning: expression with no effect elided
tst/incr.c:6: warning: expression with no effect elided
tst/incr.c:11: warning: missing return value
tst/incr.c:16: warning: expression with no effect elided
tst/incr.c:16: warning: expression with no effect elided
tst/incr.c:21: warning: missing return value
tst/incr.c:30: warning: missing return value
tst/incr.c:39: warning: missing return value

View file

@ -0,0 +1,151 @@
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
.prologue 1
mov $31,$0
L.1:
lda $sp,64($sp)
ret
.end main
.globl memchar
.text
.ent memchar
memchar:
ldgp $gp,0($27)
lda $sp,-96($sp)
.mask 0x5000000,-88
.frame $sp,96,$26,48
stq $24,0($sp)
stq $26,8($sp)
.prologue 1
ldq $27,-72+96($sp)
lda $25,1($27)
stq $25,-72+96($sp)
ldb $27,($27)
stb $27,-57+96($sp)
ldq $27,-72+96($sp)
lda $27,1($27)
stq $27,-72+96($sp)
ldb $27,($27)
stb $27,-57+96($sp)
ldq $27,-72+96($sp)
lda $25,-1($27)
stq $25,-72+96($sp)
ldb $27,($27)
stb $27,-57+96($sp)
ldq $27,-72+96($sp)
lda $27,-1($27)
stq $27,-72+96($sp)
ldb $27,($27)
stb $27,-57+96($sp)
mov $31,$0
L.2:
ldq $24,0($sp)
ldq $26,8($sp)
lda $sp,96($sp)
ret
.end memchar
.globl memint
.text
.ent memint
memint:
ldgp $gp,0($27)
lda $sp,-80($sp)
.frame $sp,80,$26,48
.prologue 1
ldq $27,-72+80($sp)
lda $25,4($27)
stq $25,-72+80($sp)
ldl $27,($27)
stl $27,-60+80($sp)
ldq $27,-72+80($sp)
lda $27,4($27)
stq $27,-72+80($sp)
ldl $27,($27)
stl $27,-60+80($sp)
ldq $27,-72+80($sp)
lda $25,-4($27)
stq $25,-72+80($sp)
ldl $27,($27)
stl $27,-60+80($sp)
ldq $27,-72+80($sp)
lda $27,-4($27)
stq $27,-72+80($sp)
ldl $27,($27)
stl $27,-60+80($sp)
mov $31,$0
L.3:
lda $sp,80($sp)
ret
.end memint
.globl regchar
.text
.ent regchar
regchar:
ldgp $gp,0($27)
lda $sp,-96($sp)
.mask 0x5006000,-72
.frame $sp,96,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $24,16($sp)
stq $26,24($sp)
.prologue 1
mov $13,$27
lda $13,1($27)
ldb $14,($27)
lda $27,1($13)
mov $27,$13
ldb $14,($27)
mov $13,$27
lda $13,-1($27)
ldb $14,($27)
lda $27,-1($13)
mov $27,$13
ldb $14,($27)
mov $31,$0
L.4:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $24,16($sp)
ldq $26,24($sp)
lda $sp,96($sp)
ret
.end regchar
.globl regint
.text
.ent regint
regint:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4006000,-64
.frame $sp,80,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $26,16($sp)
.prologue 1
mov $13,$27
lda $13,4($27)
ldl $14,($27)
lda $27,4($13)
mov $27,$13
ldl $14,($27)
mov $13,$27
lda $13,-4($27)
ldl $14,($27)
lda $27,-4($13)
mov $27,$13
ldl $14,($27)
mov $31,$0
L.5:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $26,16($sp)
lda $sp,80($sp)
ret
.end regint

View file

@ -0,0 +1,16 @@
1 2 3 4
5 6
7
if
for
else
while
1 2 3 if
4 5 0 for
6 7 8 else
9 10 11 while
1 2 3 if
4 5 0 for
6 7 8 else
9 10 11 while
0 0 0

View file

@ -0,0 +1,3 @@
tst/init.c:36: warning: missing return value
tst/init.c:49: warning: missing return value
tst/init.c:59: warning: missing return value

View file

@ -0,0 +1,333 @@
.sdata
.globl words
.align 2
words:
.long 0x1
.long 0x2
.long 0x3
.byte 105
.byte 102
.byte 0
.space 3
.space 2
.long 0x4
.long 0x5
.space 4
.byte 102
.byte 111
.byte 114
.space 3
.space 2
.long 0x6
.long 0x7
.long 0x8
.byte 101
.byte 108
.byte 115
.byte 101
.byte 0
.space 1
.space 2
.long 0x9
.long 0xa
.long 0xb
.byte 119
.byte 104
.byte 105
.byte 108
.byte 101
.space 1
.space 2
.long 0x0
.space 8
.space 8
.globl wordlist
.align 3
wordlist:
.quad words
.globl x
.align 2
x:
.long 0x1
.long 0x2
.long 0x3
.long 0x4
.long 0x0
.long 0x5
.long 0x6
.space 12
.long 0x7
.space 16
.globl y
.align 3
y:
.quad x
.quad x+20
.quad x+40
.quad 0x0
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4006000,-64
.frame $sp,80,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $26,16($sp)
.prologue 1
mov $31,$13
br L.8
L.5:
mov $31,$14
br L.12
L.9:
lda $16,L.13
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
sll $13,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,3,$25
ldq $25,y($25)
addq $27,$25,$27
ldl $17,($27)
jsr $26,printf
ldgp $gp,0($26)
L.10:
lda $14,1($14)
L.12:
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
sll $13,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,3,$25
ldq $25,y($25)
addq $27,$25,$27
ldl $27,($27)
cmpeq $27,$31,$23
beq $23,L.9
lda $16,L.14
jsr $26,printf
ldgp $gp,0($26)
L.6:
lda $13,1($13)
L.8:
sll $13,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,3,$27
ldq $27,y($27)
cmpeq $27,$31,$23
beq $23,L.5
jsr $26,f
ldgp $gp,0($26)
ldq $16,wordlist
jsr $26,g
ldgp $gp,0($26)
mov $31,$0
L.4:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $26,16($sp)
lda $sp,80($sp)
ret
.end main
.sdata
.align 3
L.16:
.quad L.17
.quad L.18
.quad L.19
.quad L.20
.quad 0x0
.globl f
.text
.text
.ent f
f:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
.prologue 1
lda $14,L.16
br L.24
L.21:
lda $16,L.25
ldq $17,($14)
jsr $26,printf
ldgp $gp,0($26)
L.22:
lda $14,8($14)
L.24:
ldq $27,($14)
cmpeq $27,$31,$23
beq $23,L.21
mov $31,$0
L.15:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end f
.globl g
.text
.ent g
g:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4006000,-64
.frame $sp,80,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $26,16($sp)
mov $16,$14
.prologue 1
br L.30
L.27:
mov $31,$13
br L.34
L.31:
lda $16,L.35
sll $13,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
addq $27,$14,$27
ldl $17,($27)
jsr $26,printf
ldgp $gp,0($26)
L.32:
lda $13,1($13)
L.34:
mov $13,$27
lda $25,3
cmpult $27,$25,$23
bne $23,L.31
lda $16,L.25
lda $17,12($14)
jsr $26,printf
ldgp $gp,0($26)
L.28:
lda $14,20($14)
L.30:
ldl $27,($14)
cmpeq $27,$31,$23
beq $23,L.27
jsr $26,h
ldgp $gp,0($26)
mov $31,$0
L.26:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $26,16($sp)
lda $sp,80($sp)
ret
.end g
.globl h
.text
.ent h
h:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
.prologue 1
mov $31,$14
br L.40
L.37:
lda $16,L.41
lda $27,20
sll $14,8*(8-4),$25
sra $25,8*(8-4),$25
mulq $27,$25,$27
ldl $17,words($27)
ldl $18,words+4($27)
ldl $19,words+8($27)
lda $20,words+12($27)
jsr $26,printf
ldgp $gp,0($26)
L.38:
lda $14,1($14)
L.40:
mov $14,$27
lda $25,5
cmpult $27,$25,$23
bne $23,L.37
mov $31,$0
L.36:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end h
.rdata
.align 0
L.41:
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 115
.byte 10
.byte 0
.align 0
L.35:
.byte 37
.byte 100
.byte 32
.byte 0
.align 0
L.25:
.byte 37
.byte 115
.byte 10
.byte 0
.align 0
L.20:
.byte 119
.byte 104
.byte 105
.byte 108
.byte 101
.byte 0
.align 0
L.19:
.byte 101
.byte 108
.byte 115
.byte 101
.byte 0
.align 0
L.18:
.byte 102
.byte 111
.byte 114
.byte 0
.align 0
L.17:
.byte 105
.byte 102
.byte 0
.align 0
L.14:
.byte 10
.byte 0
.align 0
L.13:
.byte 32
.byte 37
.byte 100
.byte 0

View file

@ -0,0 +1,14 @@
UCHAR_MAX: 000000ff=255
USHRT_MAX: 0000ffff=65535
UINT_MAX: ffffffff=-1
ULONG_MAX: ffffffffffffffff=-1
CHAR_MAX: 0000007f=127
SCHAR_MAX: 0000007f=127
SHRT_MAX: 00007fff=32767
INT_MAX: 7fffffff=2147483647
LONG_MAX: 7fffffffffffffff=9223372036854775807
CHAR_MIN: ffffff80=-128
SCHAR_MIN: ffffff80=-128
SHRT_MIN: ffff8000=-32768
INT_MIN: 80000000=-2147483648
LONG_MIN: 8000000000000000=-9223372036854775808

View file

View file

@ -0,0 +1,405 @@
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
.prologue 1
lda $16,L.2
lda $27,255
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.3
lda $27,65535
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.4
lda $27,0xffffffff
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.5
lda $27,0xffffffffffffffff
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.6
lda $27,127
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.7
lda $27,127
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.8
lda $27,32767
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.9
lda $27,2147483647
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.10
lda $27,9223372036854775807
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.11
lda $27,-128
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.12
lda $27,-128
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.13
lda $27,-32768
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.14
lda $27,-2147483648
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
lda $16,L.15
lda $27,-9223372036854775808
mov $27,$17
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
mov $31,$0
L.1:
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end main
.rdata
.align 0
L.15:
.byte 76
.byte 79
.byte 78
.byte 71
.byte 95
.byte 77
.byte 73
.byte 78
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 108
.byte 120
.byte 61
.byte 37
.byte 108
.byte 100
.byte 10
.byte 0
.align 0
L.14:
.byte 73
.byte 78
.byte 84
.byte 95
.byte 77
.byte 73
.byte 78
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.13:
.byte 83
.byte 72
.byte 82
.byte 84
.byte 95
.byte 77
.byte 73
.byte 78
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.12:
.byte 83
.byte 67
.byte 72
.byte 65
.byte 82
.byte 95
.byte 77
.byte 73
.byte 78
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.11:
.byte 67
.byte 72
.byte 65
.byte 82
.byte 95
.byte 77
.byte 73
.byte 78
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.10:
.byte 76
.byte 79
.byte 78
.byte 71
.byte 95
.byte 77
.byte 65
.byte 88
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 108
.byte 120
.byte 61
.byte 37
.byte 108
.byte 100
.byte 10
.byte 0
.align 0
L.9:
.byte 73
.byte 78
.byte 84
.byte 95
.byte 77
.byte 65
.byte 88
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.8:
.byte 83
.byte 72
.byte 82
.byte 84
.byte 95
.byte 77
.byte 65
.byte 88
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.7:
.byte 83
.byte 67
.byte 72
.byte 65
.byte 82
.byte 95
.byte 77
.byte 65
.byte 88
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.6:
.byte 67
.byte 72
.byte 65
.byte 82
.byte 95
.byte 77
.byte 65
.byte 88
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.5:
.byte 85
.byte 76
.byte 79
.byte 78
.byte 71
.byte 95
.byte 77
.byte 65
.byte 88
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 108
.byte 120
.byte 61
.byte 37
.byte 108
.byte 100
.byte 10
.byte 0
.align 0
L.4:
.byte 85
.byte 73
.byte 78
.byte 84
.byte 95
.byte 77
.byte 65
.byte 88
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.3:
.byte 85
.byte 83
.byte 72
.byte 82
.byte 84
.byte 95
.byte 77
.byte 65
.byte 88
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.2:
.byte 85
.byte 67
.byte 72
.byte 65
.byte 82
.byte 95
.byte 77
.byte 65
.byte 88
.byte 58
.byte 9
.byte 37
.byte 48
.byte 56
.byte 120
.byte 61
.byte 37
.byte 100
.byte 10
.byte 0

View file

@ -0,0 +1,195 @@
Lest this program stop prematurely, i.e. before displaying
`END OF TEST',
try to persuade the computer NOT to terminate execution when an
error like Over/Underflow or Division by Zero occurs, but rather
to persevere with a surrogate value after, perhaps, displaying some
warning. If persuasion avails naught, don't despair but run this
program anyway to see how many milestones it passes, and then
amend it to make further progress.
Answer questions with Y, y, N or n (unless otherwise indicated).
Diagnosis resumes after milestone Number 0 Page: 1
Users are invited to help debug and augment this program so it will
cope with unanticipated and newly uncovered arithmetic pathologies.
Please send suggestions and interesting results to
Richard Karpinski
Computer Center U-76
University of California
San Francisco, CA 94143-0704, USA
In doing so, please include the following information:
Precision: double;
Version: 10 February 1989;
Computer:
Compiler:
Optimization level:
Other relevant compiler options:
Diagnosis resumes after milestone Number 1 Page: 2
Running this program should reveal these characteristics:
Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...
Precision = number of significant digits carried.
U2 = Radix/Radix^Precision = One Ulp
(OneUlpnit in the Last Place) of 1.000xxx .
U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .
Adequacy of guard digits for Mult., Div. and Subt.
Whether arithmetic is chopped, correctly rounded, or something else
for Mult., Div., Add/Subt. and Sqrt.
Whether a Sticky Bit used correctly for rounding.
UnderflowThreshold = an underflow threshold.
E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.
V = an overflow threshold, roughly.
V0 tells, roughly, whether Infinity is represented.
Comparisions are checked for consistency with subtraction
and for contamination with pseudo-zeros.
Sqrt is tested. Y^X is not tested.
Extra-precise subexpressions are revealed but NOT YET tested.
Decimal-Binary conversion is NOT YET tested for accuracy.
Diagnosis resumes after milestone Number 2 Page: 3
The program attempts to discriminate among
FLAWs, like lack of a sticky bit,
Serious DEFECTs, like lack of a guard digit, and
FAILUREs, like 2+2 == 5 .
Failures may confound subsequent diagnoses.
The diagnostic capabilities of this program go beyond an earlier
program called `MACHAR', which can be found at the end of the
book `Software Manual for the Elementary Functions' (1980) by
W. J. Cody and W. Waite. Although both programs try to discover
the Radix, Precision and range (over/underflow thresholds)
of the arithmetic, this program tries to cope with a wider variety
of pathologies, and to say how well the arithmetic is implemented.
The program is based upon a conventional radix representation for
floating-point numbers, but also allows logarithmic encoding
as used by certain early WANG machines.
BASIC version of this program (C) 1983 by Prof. W. M. Kahan;
see source comments for more history.
Diagnosis resumes after milestone Number 3 Page: 4
Program is now RUNNING tests on small integers:
-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.
Searching for Radix and Precision.
Radix = 2.000000 .
Closest relative separation found is U1 = 1.1102230e-16 .
Recalculating radix and precision
confirms closest relative separation U1 .
Radix confirmed.
The number of significant digits of the Radix is 53.000000 .
Diagnosis resumes after milestone Number 30 Page: 5
Subtraction appears to be normalized, as it should be.
Checking for guard digit in *, /, and -.
*, /, and - appear to have guard digits, as they should.
Diagnosis resumes after milestone Number 40 Page: 6
Checking rounding on multiply, divide and add/subtract.
Multiplication appears to round correctly.
Division appears to round correctly.
Addition/Subtraction appears to round correctly.
Checking for sticky bit.
Sticky bit apparently used correctly.
Does Multiplication commute? Testing on 20 random pairs.
No failures found in 20 integer pairs.
Running test of square root(x).
Testing if sqrt(X * X) == X for 20 Integers X.
Test for sqrt monotonicity.
sqrt has passed a test for Monotonicity.
Testing whether sqrt is rounded or chopped.
Square root appears to be correctly rounded.
Diagnosis resumes after milestone Number 90 Page: 7
Testing powers Z^i for small Integers Z and i.
... no discrepancis found.
Seeking Underflow thresholds UfThold and E0.
Smallest strictly positive number found is E0 = 2.22507e-308 .
Since comparison denies Z = 0, evaluating (Z + Z) / Z should be safe.
What the machine gets for (Z + Z) / Z is 2.00000000000000000e+00 .
This is O.K., provided Over/Underflow has NOT just been signaled.
Diagnosis resumes after milestone Number 120 Page: 8
FLAW: X = 3.05947655544740190e-308
is not equal to Z = 2.22507385850720140e-308 .
yet X - Z yields 0.00000000000000000e+00 .
Should this NOT signal Underflow, this is a SERIOUS DEFECT
that causes confusion when innocent statements like
if (X == Z) ... else ... (f(X) - f(Z)) / (X - Z) ...
encounter Division by Zero although actually
X / Z = 1 + 0.375 .
The Underflow threshold is 2.22507385850720140e-308, below which
calculation may suffer larger Relative error than merely roundoff.
Since underflow occurs below the threshold
UfThold = (2.00000000000000000e+00) ^ (-1.02200000000000000e+03)
only underflow should afflict the expression
(2.00000000000000000e+00) ^ (-1.02200000000000000e+03);
actually calculating yields: 0.00000000000000000e+00 .
This computed value is O.K.
Testing X^((X + 1) / (X - 1)) vs. exp(2) = 7.38905609893065220e+00 as X -> 1.
Accuracy seems adequate.
Testing powers Z^Q at four nearly extreme values.
... no discrepancies found.
Diagnosis resumes after milestone Number 160 Page: 9
Searching for Overflow threshold:
This may generate an error.
* * * FLOATING-POINT ERROR * * *
Can `Z = -Y' overflow?
Trying it on Y = -8.98846567431157950e+307 .
Seems O.K.
Overflow threshold is V = 1.79769313486231570e+308 .
There is no saturation value because the system traps on overflow.
No Overflow should be signaled for V * 1 = 1.79769313486231570e+308
nor for V / 1 = 1.79769313486231570e+308 .
Any overflow signal separating this * from the one
above is a DEFECT.
Diagnosis resumes after milestone Number 190 Page: 10
What message and/or values does Division by Zero produce?
Trying to compute 1 / 0 produces ...
* * * FLOATING-POINT ERROR * * *
Trying to compute 0 / 0 produces ...
* * * FLOATING-POINT ERROR * * *
Diagnosis resumes after milestone Number 220 Page: 11
No failures, defects nor flaws have been discovered.
Rounding appears to conform to the proposed IEEE standard P754,
except for possibly Double Rounding during Gradual Underflow.
The arithmetic diagnosed appears to be Excellent!
A total of 3 floating point exceptions were registered.
END OF TEST.

View file

@ -0,0 +1,16 @@
tst/paranoia.c:1867: warning: missing return value
tst/paranoia.c:1874: warning: missing return value
tst/paranoia.c:1884: warning: missing return value
tst/paranoia.c:1924: warning: missing return value
tst/paranoia.c:1939: warning: missing return value
tst/paranoia.c:1956: warning: missing return value
tst/paranoia.c:1975: warning: missing return value
tst/paranoia.c:1988: warning: missing return value
tst/paranoia.c:1995: warning: missing return value
tst/paranoia.c:2055: warning: missing return value
tst/paranoia.c:2062: warning: missing return value
tst/paranoia.c:2070: warning: missing return value
tst/paranoia.c:2087: warning: missing return value
tst/paranoia.c:2115: warning: missing return value
tst/paranoia.c:2144: warning: missing return value
tst/paranoia.c:2173: warning: missing return value

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
exchange(1,9)
exchange(3,7)
exchange(5,6)
exchange(0,5)
exchange(0,3)
exchange(0,0)
exchange(1,2)
exchange(6,6)
exchange(8,9)
exchange(7,8)
-51
-1
0
1
3
10
18
32
567
789

View file

@ -0,0 +1,5 @@
tst/sort.c:23: warning: missing return value
tst/sort.c:30: warning: missing return value
tst/sort.c:37: warning: missing return value
tst/sort.c:41: warning: missing return value
tst/sort.c:65: warning: missing return value

View file

@ -0,0 +1,323 @@
.sdata
.globl in
.align 2
in:
.long 0xa
.long 0x20
.long 0xffffffff
.long 0x237
.long 0x3
.long 0x12
.long 0x1
.long 0xffffffcd
.long 0x315
.long 0x0
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
.prologue 1
lda $16,in
lda $17,10
jsr $26,sort
ldgp $gp,0($26)
mov $31,$14
br L.5
L.2:
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
ldl $16,in($27)
jsr $26,putd
ldgp $gp,0($26)
lda $16,10
jsr $26,putchar
ldgp $gp,0($26)
L.3:
lda $14,1($14)
L.5:
mov $14,$27
lda $25,10
cmpult $27,$25,$23
bne $23,L.2
mov $31,$0
L.1:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end main
.globl putd
.text
.ent putd
putd:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x5004000,-64
.frame $sp,80,$26,48
stq $14,0($sp)
stq $24,8($sp)
stq $26,16($sp)
mov $16,$14
.prologue 1
cmplt $14,$31,$23
beq $23,L.7
lda $16,45
jsr $26,putchar
ldgp $gp,0($26)
negl $14,$14
L.7:
divl $14,10,$27
cmpeq $27,$31,$23
bne $23,L.9
divl $14,10,$16
jsr $26,putd
ldgp $gp,0($26)
L.9:
reml $14,10,$27
lda $16,48($27)
jsr $26,putchar
ldgp $gp,0($26)
mov $31,$0
L.6:
ldq $14,0($sp)
ldq $24,8($sp)
ldq $26,16($sp)
lda $sp,80($sp)
ret
.end putd
.globl sort
.text
.ent sort
sort:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
stq $16,16($sp)
stq $17,24($sp)
.prologue 1
ldq $27,-48+64($sp)
stq $27,xx
mov $27,$16
mov $31,$17
ldl $27,-40+64($sp)
subl $27,1,$27
stl $27,-40+64($sp)
mov $27,$18
jsr $26,quick
ldgp $gp,0($26)
mov $31,$0
L.11:
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end sort
.globl quick
.text
.ent quick
quick:
ldgp $gp,0($27)
lda $sp,-96($sp)
.mask 0x4007800,-64
.frame $sp,96,$26,48
stq $11,0($sp)
stq $12,8($sp)
stq $13,16($sp)
stq $14,24($sp)
stq $26,32($sp)
mov $16,$14
mov $17,$13
mov $18,$12
.prologue 1
cmplt $13,$12,$23
bne $23,L.13
br L.12
L.13:
mov $14,$16
mov $13,$17
mov $12,$18
jsr $26,partition
ldgp $gp,0($26)
mov $0,$11
mov $14,$16
mov $13,$17
subl $11,1,$18
jsr $26,quick
ldgp $gp,0($26)
mov $14,$16
lda $17,1($11)
mov $12,$18
jsr $26,quick
ldgp $gp,0($26)
mov $31,$0
L.12:
ldq $11,0($sp)
ldq $12,8($sp)
ldq $13,16($sp)
ldq $14,24($sp)
ldq $26,32($sp)
lda $sp,96($sp)
ret
.end quick
.globl partition
.text
.ent partition
partition:
ldgp $gp,0($27)
lda $sp,-112($sp)
.mask 0x4007c00,-72
.frame $sp,112,$26,48
stq $10,0($sp)
stq $11,8($sp)
stq $12,16($sp)
stq $13,24($sp)
stq $14,32($sp)
stq $26,40($sp)
mov $16,$14
mov $17,$13
mov $18,$12
.prologue 1
lda $12,1($12)
mov $13,$10
sll $10,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
addq $27,$14,$27
ldl $11,($27)
br L.17
L.16:
lda $13,1($13)
br L.20
L.19:
lda $13,1($13)
L.20:
sll $13,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
addq $27,$14,$27
ldl $27,($27)
cmplt $27,$11,$23
bne $23,L.19
subl $12,1,$12
br L.23
L.22:
subl $12,1,$12
L.23:
sll $12,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
addq $27,$14,$27
ldl $27,($27)
cmple $27,$11,$23
beq $23,L.22
cmplt $13,$12,$23
beq $23,L.25
sll $13,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
addq $27,$14,$16
sll $12,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
addq $27,$14,$17
jsr $26,exchange
ldgp $gp,0($26)
L.25:
L.17:
cmplt $13,$12,$23
bne $23,L.16
sll $10,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
addq $27,$14,$16
sll $12,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,2,$27
addq $27,$14,$17
jsr $26,exchange
ldgp $gp,0($26)
mov $12,$0
L.15:
ldq $10,0($sp)
ldq $11,8($sp)
ldq $12,16($sp)
ldq $13,24($sp)
ldq $14,32($sp)
ldq $26,40($sp)
lda $sp,112($sp)
ret
.end partition
.globl exchange
.text
.ent exchange
exchange:
ldgp $gp,0($27)
lda $sp,-112($sp)
.mask 0x5006000,-88
.frame $sp,112,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $24,16($sp)
stq $26,24($sp)
mov $16,$14
mov $17,$13
.prologue 1
lda $16,L.28
ldq $27,xx
stq $27,-80+112($sp)
mov $14,$25
subq $25,$27,$25
stq $25,-72+112($sp)
divq $25,4,$17
mov $13,$27
ldq $25,-80+112($sp)
subq $27,$25,$27
divq $27,4,$18
jsr $26,printf
ldgp $gp,0($26)
ldl $27,($14)
stl $27,-60+112($sp)
ldl $27,($13)
stl $27,($14)
ldl $27,-60+112($sp)
stl $27,($13)
mov $31,$0
L.27:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $24,16($sp)
ldq $26,24($sp)
lda $sp,112($sp)
ret
.end exchange
.globl xx
.comm xx,8
.rdata
.align 0
L.28:
.byte 101
.byte 120
.byte 99
.byte 104
.byte 97
.byte 110
.byte 103
.byte 101
.byte 40
.byte 37
.byte 100
.byte 44
.byte 37
.byte 100
.byte 41
.byte 10
.byte 0

View file

View file

@ -0,0 +1,6 @@
tst/spill.c:1: warning: missing return value
tst/spill.c:3: warning: missing return value
tst/spill.c:5: warning: missing return value
tst/spill.c:7: warning: missing return value
tst/spill.c:9: warning: missing return value
tst/spill.c:17: warning: missing return value

View file

@ -0,0 +1,272 @@
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
.prologue 1
mov $31,$0
L.1:
lda $sp,64($sp)
ret
.end main
.globl f
.text
.ent f
f:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4000000,-80
.frame $sp,80,$26,48
stq $26,0($sp)
stq $16,32($sp)
.prologue 1
jsr $26,f
ldgp $gp,0($26)
mov $0,$27
stl $27,-60+80($sp)
jsr $26,f
ldgp $gp,0($26)
ldl $25,-60+80($sp)
addl $25,$0,$27
stl $27,-48+80($sp)
mov $31,$0
L.2:
ldq $26,0($sp)
lda $sp,80($sp)
ret
.end f
.globl f2
.text
.ent f2
f2:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
stq $16,32($sp)
.prologue 1
jsr $26,f
ldgp $gp,0($26)
mov $0,$27
stl $27,-60+80($sp)
ldl $25,-48+80($sp)
cmpeq $25,$31,$23
bne $23,L.5
jsr $26,f
ldgp $gp,0($26)
mov $0,$27
mov $27,$14
br L.6
L.5:
lda $14,1
L.6:
ldl $27,-60+80($sp)
addl $27,$14,$27
stl $27,-48+80($sp)
mov $31,$0
L.3:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end f2
.globl f3
.text
.ent f3
f3:
ldgp $gp,0($27)
lda $sp,-144($sp)
.mask 0x4007e00,-96
.frame $sp,144,$26,48
stq $9,0($sp)
stq $10,8($sp)
stq $11,16($sp)
stq $12,24($sp)
stq $13,32($sp)
stq $14,40($sp)
stq $26,48($sp)
stq $16,96($sp)
stq $17,104($sp)
.prologue 1
mov $31,$14
mov $31,$13
mov $31,$12
mov $31,$11
mov $31,$10
mov $31,$9
stl $31,-60+144($sp)
stl $31,-64+144($sp)
stl $31,-68+144($sp)
stl $31,-72+144($sp)
ldq $27,-40+144($sp)
stq $27,-88+144($sp)
lda $25,4($27)
stq $25,-40+144($sp)
ldl $25,-48+144($sp)
cmpeq $25,$31,$23
bne $23,L.9
jsr $26,f
ldgp $gp,0($26)
mov $0,$27
stl $27,-76+144($sp)
br L.10
L.9:
stl $31,-76+144($sp)
L.10:
ldl $27,-76+144($sp)
ldq $25,-88+144($sp)
stl $27,($25)
mov $31,$0
L.7:
ldq $9,0($sp)
ldq $10,8($sp)
ldq $11,16($sp)
ldq $12,24($sp)
ldq $13,32($sp)
ldq $14,40($sp)
ldq $26,48($sp)
lda $sp,144($sp)
ret
.end f3
.globl f4
.text
.ent f4
f4:
ldgp $gp,0($27)
lda $sp,-128($sp)
.mask 0x4007e00,-80
.frame $sp,128,$26,48
stq $9,0($sp)
stq $10,8($sp)
stq $11,16($sp)
stq $12,24($sp)
stq $13,32($sp)
stq $14,40($sp)
stq $26,48($sp)
.prologue 1
mov $31,$14
mov $31,$13
mov $31,$12
mov $31,$11
mov $31,$10
mov $31,$9
ldl $27,i
sll $27,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,3,$25
ldt $f30,a($25)
ldt $f29,b($25)
ldt $f28,L.15
addt $f30,$f29,$f27
cmpteq $f27,$f28,$f1
fbne $f1,L.13
cmpeq $27,$31,$23
bne $23,L.13
subt $f30,$f29,$f30
cmpteq $f30,$f28,$f1
fbne $f1,L.13
lda $27,1
stl $27,-60+128($sp)
br L.14
L.13:
stl $31,-60+128($sp)
L.14:
ldl $27,-60+128($sp)
stl $27,i
mov $31,$0
L.11:
ldq $9,0($sp)
ldq $10,8($sp)
ldq $11,16($sp)
ldq $12,24($sp)
ldq $13,32($sp)
ldq $14,40($sp)
ldq $26,48($sp)
lda $sp,128($sp)
ret
.end f4
.globl f5
.text
.ent f5
f5:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
.prologue 1
ldl $27,k
ldl $25,m
ldq $22,A
mull $27,$25,$8
sll $8,8*(8-4),$8
sra $8,8*(8-4),$8
sll $8,3,$8
addq $8,$22,$8
ldl $7,j
mull $7,$25,$25
sll $25,8*(8-4),$25
sra $25,8*(8-4),$25
sll $25,3,$25
addq $25,$22,$25
ldl $22,n
ldq $6,B
mull $27,$22,$27
sll $27,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,3,$27
addq $27,$6,$27
mull $7,$22,$22
sll $22,8*(8-4),$22
sra $22,8*(8-4),$22
sll $22,3,$22
addq $22,$6,$22
ldt $f30,($8)
ldt $f29,($25)
mult $f30,$f29,$f30
ldt $f29,($27)
ldt $f28,($22)
mult $f29,$f28,$f29
addt $f30,$f29,$f30
stt $f30,x
ldt $f30,($8)
ldt $f29,($22)
mult $f30,$f29,$f30
ldt $f29,($27)
ldt $f28,($25)
mult $f29,$f28,$f29
subt $f30,$f29,$f30
stt $f30,x
mov $31,$0
L.16:
lda $sp,64($sp)
ret
.end f5
.globl x
.comm x,8
.globl B
.comm B,8
.globl A
.comm A,8
.globl n
.comm n,4
.globl m
.comm m,4
.globl k
.comm k,4
.globl j
.comm j,4
.globl i
.comm i,4
.globl b
.comm b,80
.globl a
.comm a,80
.rdata
.align 3
L.15:
.long 0x0
.long 0x0

View file

@ -0,0 +1,6 @@
test 1
test 2
test 3
test 4
test 5.000000
{1 2 3 4} {1 2 3 4} {1 2 3 4} {1 2 3 4} {1 2 3 4} {1 2 3 4}

View file

@ -0,0 +1 @@
tst/stdarg.c:51: warning: missing return value

View file

@ -0,0 +1,430 @@
.sdata
.globl x
.align 2
x:
.long 0x1
.long 0x2
.long 0x3
.long 0x4
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-128($sp)
.mask 0x4000000,-72
.frame $sp,128,$26,48
stq $26,56($sp)
.prologue 1
lda $16,L.3
jsr $26,print
ldgp $gp,0($26)
lda $16,L.4
lda $17,L.5
jsr $26,print
ldgp $gp,0($26)
lda $16,L.6
lda $17,3
lda $18,10
jsr $26,print
ldgp $gp,0($26)
lda $16,L.7
lda $17,L.8
lda $18,L.9
lda $19,4
lda $20,10
jsr $26,print
ldgp $gp,0($26)
lda $16,L.10
lda $17,L.8
lda $18,L.9
ldt $f19,L.11
lda $20,10
jsr $26,print
ldgp $gp,0($26)
lda $16,L.12
lda $27,x
mov $27,$1
uldq $17,0($1)
uldq $18,8($1)
mov $27,$1
uldq $19,0($1)
uldq $20,8($1)
mov $27,$1
uldq $21,0($1)
ldl $4,8($1)
ldl $2,12($1)
stl $4,0($30)
stl $2,4($30)
mov $27,$1
ldl $4,0($1)
ldl $2,4($1)
stl $4,8($30)
stl $2,12($30)
ldl $4,8($1)
ldl $2,12($1)
stl $4,16($30)
stl $2,20($30)
mov $27,$1
ldl $4,0($1)
ldl $2,4($1)
stl $4,24($30)
stl $2,28($30)
ldl $4,8($1)
ldl $2,12($1)
stl $4,32($30)
stl $2,36($30)
mov $27,$1
ldl $4,0($1)
ldl $2,4($1)
stl $4,40($30)
stl $2,44($30)
ldl $4,8($1)
ldl $2,12($1)
stl $4,48($30)
stl $2,52($30)
jsr $26,print
ldgp $gp,0($26)
mov $31,$0
L.2:
ldq $26,56($sp)
lda $sp,128($sp)
ret
.end main
.globl print
.text
.ent print
print:
ldgp $gp,0($27)
lda $sp,-160($sp)
.mask 0x4006000,-144
.frame $sp,160,$26,96
stq $13,0($sp)
stq $14,8($sp)
stq $26,16($sp)
stq $16,112($sp)
stq $17,120($sp)
stt $f17,72($sp)
stq $18,128($sp)
stt $f18,80($sp)
stq $19,136($sp)
stt $f19,88($sp)
stq $20,144($sp)
stt $f20,96($sp)
stq $21,152($sp)
stt $f21,104($sp)
.prologue 1
lda $27,-48+160($sp)
stq $27,-120+160($sp)
lda $27,-40+160($sp)
ldq $25,-120+160($sp)
subq $27,$25,$27
stl $27,-112+160($sp)
br L.21
L.18:
ldq $27,-48+160($sp)
ldb $27,($27)
cmpeq $27,37,$23
beq $23,L.22
ldq $27,-48+160($sp)
lda $27,1($27)
stq $27,-48+160($sp)
ldb $14,($27)
lda $27,115
cmpeq $14,$27,$23
bne $23,L.74
cmple $14,$27,$23
beq $23,L.100
L.99:
lda $27,98
cmplt $14,$27,$23
bne $23,L.24
lda $27,102
cmple $14,$27,$23
beq $23,L.24
subl $14,98,$27
sll $27,3,$27
ldq $27,L.101($27)
jmp ($27)
.rdata
.align 3
L.101:
.quad L.27
.quad L.41
.quad L.52
.quad L.24
.quad L.85
.text
L.100:
lda $27,119
cmpeq $14,$27,$23
bne $23,L.63
br L.24
L.27:
ldl $27,-112+160($sp)
lda $27,16($27)
stl $27,-112+160($sp)
lda $27,-136+160($sp)
ldl $25,-112+160($sp)
ldq $22,-120+160($sp)
addq $25,$22,$25
lda $1,-16($25)
ldl $4,0($1)
ldl $2,4($1)
stl $4,0($27)
stl $2,4($27)
ldl $4,8($1)
ldl $2,12($1)
stl $4,8($27)
stl $2,12($27)
lda $16,L.37
ldl $17,-136+160($sp)
ldl $18,-132+160($sp)
ldl $19,-128+160($sp)
ldl $20,-124+160($sp)
jsr $26,printf
ldgp $gp,0($26)
br L.23
L.41:
lda $16,L.42
ldl $27,-112+160($sp)
lda $27,8($27)
stl $27,-112+160($sp)
ldl $27,-112+160($sp)
ldq $25,-120+160($sp)
addq $27,$25,$27
lda $27,-8($27)
ldb $17,($27)
jsr $26,printf
ldgp $gp,0($26)
br L.23
L.52:
lda $16,L.53
ldl $27,-112+160($sp)
lda $27,8($27)
stl $27,-112+160($sp)
ldl $27,-112+160($sp)
ldq $25,-120+160($sp)
addq $27,$25,$27
ldl $17,-8($27)
jsr $26,printf
ldgp $gp,0($26)
br L.23
L.63:
lda $16,L.64
ldl $27,-112+160($sp)
lda $27,8($27)
stl $27,-112+160($sp)
ldl $27,-112+160($sp)
ldq $25,-120+160($sp)
addq $27,$25,$27
lda $27,-8($27)
ldw $17,($27)
jsr $26,printf
ldgp $gp,0($26)
br L.23
L.74:
lda $16,L.75
ldl $27,-112+160($sp)
lda $27,8($27)
stl $27,-112+160($sp)
ldl $27,-112+160($sp)
ldq $25,-120+160($sp)
addq $27,$25,$27
ldq $17,-8($27)
jsr $26,printf
ldgp $gp,0($26)
br L.23
L.85:
lda $16,L.86
ldl $27,-112+160($sp)
lda $27,8($27)
stl $27,-112+160($sp)
ldl $27,-112+160($sp)
cmple $27,48,$23
beq $23,L.97
ldl $27,-112+160($sp)
ldq $25,-120+160($sp)
addq $27,$25,$27
lda $13,-56($27)
br L.98
L.97:
ldl $27,-112+160($sp)
ldq $25,-120+160($sp)
addq $27,$25,$27
lda $13,-8($27)
L.98:
ldt $f17,($13)
jsr $26,printf
ldgp $gp,0($26)
br L.23
L.24:
lda $16,L.42
ldq $27,-48+160($sp)
ldb $17,($27)
jsr $26,printf
ldgp $gp,0($26)
br L.23
L.22:
lda $16,L.42
ldq $27,-48+160($sp)
ldb $17,($27)
jsr $26,printf
ldgp $gp,0($26)
L.23:
L.19:
ldq $27,-48+160($sp)
lda $27,1($27)
stq $27,-48+160($sp)
L.21:
ldq $27,-48+160($sp)
ldb $27,($27)
cmpeq $27,$31,$23
beq $23,L.18
mov $31,$0
L.13:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $26,16($sp)
lda $sp,160($sp)
ret
.end print
.rdata
.align 0
L.86:
.byte 37
.byte 102
.byte 0
.align 0
L.75:
.byte 37
.byte 115
.byte 0
.align 0
L.64:
.byte 37
.byte 120
.byte 0
.align 0
L.53:
.byte 37
.byte 100
.byte 0
.align 0
L.42:
.byte 37
.byte 99
.byte 0
.align 0
L.37:
.byte 123
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 32
.byte 37
.byte 100
.byte 125
.byte 0
.align 0
L.12:
.byte 37
.byte 98
.byte 32
.byte 37
.byte 98
.byte 32
.byte 37
.byte 98
.byte 32
.byte 37
.byte 98
.byte 32
.byte 37
.byte 98
.byte 32
.byte 37
.byte 98
.byte 10
.byte 0
.align 3
L.11:
.long 0x0
.long 0x40140000
.align 0
L.10:
.byte 37
.byte 115
.byte 37
.byte 115
.byte 32
.byte 37
.byte 102
.byte 37
.byte 99
.byte 0
.align 0
L.9:
.byte 115
.byte 116
.byte 0
.align 0
L.8:
.byte 116
.byte 101
.byte 0
.align 0
L.7:
.byte 37
.byte 115
.byte 37
.byte 115
.byte 32
.byte 37
.byte 119
.byte 37
.byte 99
.byte 0
.align 0
L.6:
.byte 116
.byte 101
.byte 115
.byte 116
.byte 32
.byte 37
.byte 100
.byte 37
.byte 99
.byte 0
.align 0
L.5:
.byte 50
.byte 0
.align 0
L.4:
.byte 116
.byte 101
.byte 115
.byte 116
.byte 32
.byte 37
.byte 115
.byte 10
.byte 0
.align 0
L.3:
.byte 116
.byte 101
.byte 115
.byte 116
.byte 32
.byte 49
.byte 10
.byte 0

View file

@ -0,0 +1,5 @@
(-1,-1) is not within [10,10; 310,310]
(1,1) is not within [10,10; 310,310]
(20,300) is within [10,10; 310,310]
(500,400) is not within [10,10; 310,310]
ab

View file

@ -0,0 +1,2 @@
tst/struct.c:49: warning: missing return value
tst/struct.c:68: warning: missing return value

View file

@ -0,0 +1,443 @@
.globl addpoint
.text
.text
.ent addpoint
addpoint:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
stq $17,24($sp)
stq $18,32($sp)
.prologue 1
ldl $27,-40+64($sp)
ldl $25,-32+64($sp)
addl $27,$25,$27
stl $27,-40+64($sp)
ldl $27,-36+64($sp)
ldl $25,-28+64($sp)
addl $27,$25,$27
stl $27,-36+64($sp)
lda $1,-40+64($sp)
ldl $4,0($1)
ldl $2,4($1)
stl $4,0($16)
stl $2,4($16)
L.1:
lda $sp,64($sp)
ret
.end addpoint
.globl canonrect
.text
.ent canonrect
canonrect:
ldgp $gp,0($27)
lda $sp,-112($sp)
.mask 0x4007800,-80
.frame $sp,112,$26,48
stq $11,0($sp)
stq $12,8($sp)
stq $13,16($sp)
stq $14,24($sp)
stq $26,32($sp)
stq $17,72($sp)
stq $18,80($sp)
.prologue 1
ldl $27,-40+112($sp)
ldl $25,-32+112($sp)
cmplt $27,$25,$23
beq $23,L.10
ldl $14,-40+112($sp)
br L.11
L.10:
ldl $14,-32+112($sp)
L.11:
stl $14,-72+112($sp)
ldl $27,-36+112($sp)
ldl $25,-28+112($sp)
cmplt $27,$25,$23
beq $23,L.20
ldl $13,-36+112($sp)
br L.21
L.20:
ldl $13,-28+112($sp)
L.21:
stl $13,-68+112($sp)
ldl $27,-40+112($sp)
ldl $25,-32+112($sp)
cmple $27,$25,$23
bne $23,L.26
ldl $12,-40+112($sp)
br L.27
L.26:
ldl $12,-32+112($sp)
L.27:
stl $12,-64+112($sp)
ldl $27,-36+112($sp)
ldl $25,-28+112($sp)
cmple $27,$25,$23
bne $23,L.37
ldl $11,-36+112($sp)
br L.38
L.37:
ldl $11,-28+112($sp)
L.38:
stl $11,-60+112($sp)
lda $1,-72+112($sp)
ldl $4,0($1)
ldl $2,4($1)
stl $4,0($16)
stl $2,4($16)
ldl $4,8($1)
ldl $2,12($1)
stl $4,8($16)
stl $2,12($16)
L.5:
ldq $11,0($sp)
ldq $12,8($sp)
ldq $13,16($sp)
ldq $14,24($sp)
ldq $26,32($sp)
lda $sp,112($sp)
ret
.end canonrect
.globl makepoint
.text
.ent makepoint
makepoint:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
.prologue 1
stl $17,-64+64($sp)
stl $18,-60+64($sp)
lda $1,-64+64($sp)
ldl $4,0($1)
ldl $2,4($1)
stl $4,0($16)
stl $2,4($16)
L.39:
lda $sp,64($sp)
ret
.end makepoint
.globl makerect
.text
.ent makerect
makerect:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4000000,-80
.frame $sp,80,$26,48
stq $26,0($sp)
stq $16,32($sp)
stq $17,40($sp)
stq $18,48($sp)
.prologue 1
lda $27,-72+80($sp)
lda $1,-40+80($sp)
ldl $4,0($1)
ldl $2,4($1)
stl $4,0($27)
stl $2,4($27)
lda $27,-64+80($sp)
lda $1,-32+80($sp)
ldl $4,0($1)
ldl $2,4($1)
stl $4,0($27)
stl $2,4($27)
ldq $16,-48+80($sp)
lda $1,-72+80($sp)
uldq $17,0($1)
uldq $18,8($1)
jsr $26,canonrect
ldgp $gp,0($26)
L.42:
ldq $26,0($sp)
lda $sp,80($sp)
ret
.end makerect
.globl ptinrect
.text
.ent ptinrect
ptinrect:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
stq $16,32($sp)
stq $17,40($sp)
stq $18,48($sp)
.prologue 1
ldl $27,-48+80($sp)
ldl $25,-40+80($sp)
cmplt $27,$25,$23
bne $23,L.53
ldl $25,-32+80($sp)
cmplt $27,$25,$23
beq $23,L.53
ldl $27,-44+80($sp)
ldl $25,-36+80($sp)
cmplt $27,$25,$23
bne $23,L.53
ldl $27,-44+80($sp)
ldl $25,-28+80($sp)
cmplt $27,$25,$23
beq $23,L.53
lda $14,1
br L.54
L.53:
mov $31,$14
L.54:
mov $14,$0
L.45:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end ptinrect
.sdata
.globl y
.align 0
y:
.byte 97
.byte 98
.byte 0
.globl odd
.text
.text
.ent odd
odd:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4000000,-80
.frame $sp,80,$26,48
stq $26,0($sp)
stq $16,32($sp)
.prologue 1
lda $27,-59+80($sp)
lda $1,-48+80($sp)
ldb $4,0($1)
ldb $2,1($1)
stb $4,0($27)
stb $2,1($27)
ldb $4,2($1)
stb $4,2($27)
lda $16,L.56
lda $17,-59+80($sp)
jsr $26,printf
ldgp $gp,0($26)
mov $31,$0
L.55:
ldq $26,0($sp)
lda $sp,80($sp)
ret
.end odd
.rdata
.align 2
L.58:
.long 0x0
.long 0x0
.align 2
L.59:
.long 0x140
.long 0x140
.align 2
L.60:
.long 0xffffffff
.long 0xffffffff
.long 0x1
.long 0x1
.long 0x14
.long 0x12c
.long 0x1f4
.long 0x190
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-176($sp)
.mask 0x4004000,-168
.frame $sp,176,$26,48
stq $14,0($sp)
stq $26,8($sp)
.prologue 1
lda $27,-120+176($sp)
lda $1,L.58
ldl $4,0($1)
ldl $2,4($1)
stl $4,0($27)
stl $2,4($27)
lda $27,-128+176($sp)
lda $1,L.59
ldl $4,0($1)
ldl $2,4($1)
stl $4,0($27)
stl $2,4($27)
lda $27,-88+176($sp)
lda $1,L.60
addq $1,32,$1
addq $27,32,$3
L.76:
addq $1,-8,$1
addq $3,-8,$3
ldl $4,0($1)
ldl $2,4($1)
stl $4,0($3)
stl $2,4($3)
cmpult $27,$3,$23
bne $23,L.76
lda $16,-136+176($sp)
lda $27,-10
mov $27,$17
mov $27,$18
jsr $26,makepoint
ldgp $gp,0($26)
lda $16,-144+176($sp)
lda $1,-128+176($sp)
uldq $17,0($1)
lda $1,-136+176($sp)
uldq $18,0($1)
jsr $26,addpoint
ldgp $gp,0($26)
lda $16,-152+176($sp)
lda $27,10
mov $27,$17
mov $27,$18
jsr $26,makepoint
ldgp $gp,0($26)
lda $16,-160+176($sp)
lda $1,-120+176($sp)
uldq $17,0($1)
lda $1,-152+176($sp)
uldq $18,0($1)
jsr $26,addpoint
ldgp $gp,0($26)
lda $16,-104+176($sp)
lda $1,-144+176($sp)
uldq $17,0($1)
lda $1,-160+176($sp)
uldq $18,0($1)
jsr $26,makerect
ldgp $gp,0($26)
mov $31,$14
br L.64
L.61:
lda $16,-112+176($sp)
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,3,$27
lda $25,-88+176($sp)
addq $27,$25,$25
ldl $17,($25)
lda $25,-84+176($sp)
addq $27,$25,$27
ldl $18,($27)
jsr $26,makepoint
ldgp $gp,0($26)
lda $16,L.65
sll $14,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,3,$27
lda $25,-88+176($sp)
addq $27,$25,$27
ldl $17,($27)
ldl $18,-108+176($sp)
jsr $26,printf
ldgp $gp,0($26)
lda $1,-112+176($sp)
uldq $16,0($1)
lda $1,-104+176($sp)
uldq $17,0($1)
uldq $18,8($1)
jsr $26,ptinrect
ldgp $gp,0($26)
cmpeq $0,$31,$23
beq $23,L.68
lda $16,L.70
jsr $26,printf
ldgp $gp,0($26)
L.68:
lda $16,L.71
ldl $17,-104+176($sp)
ldl $18,-100+176($sp)
ldl $19,-96+176($sp)
ldl $20,-92+176($sp)
jsr $26,printf
ldgp $gp,0($26)
L.62:
lda $14,1($14)
L.64:
mov $14,$27
lda $25,4
cmpult $27,$25,$23
bne $23,L.61
lda $1,y
uldq $16,0($1)
jsr $26,odd
ldgp $gp,0($26)
mov $31,$16
jsr $26,exit
ldgp $gp,0($26)
mov $31,$0
L.57:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,176($sp)
ret
.end main
.rdata
.align 0
L.71:
.byte 119
.byte 105
.byte 116
.byte 104
.byte 105
.byte 110
.byte 32
.byte 91
.byte 37
.byte 100
.byte 44
.byte 37
.byte 100
.byte 59
.byte 32
.byte 37
.byte 100
.byte 44
.byte 37
.byte 100
.byte 93
.byte 10
.byte 0
.align 0
L.70:
.byte 110
.byte 111
.byte 116
.byte 32
.byte 0
.align 0
L.65:
.byte 40
.byte 37
.byte 100
.byte 44
.byte 37
.byte 100
.byte 41
.byte 32
.byte 105
.byte 115
.byte 32
.byte 0
.align 0
L.56:
.byte 37
.byte 115
.byte 10
.byte 0

View file

@ -0,0 +1,76 @@
b = 0x8
f = 0xc
n = 0xa
r = 0xd
t = 0x9
v = 0xb
x = 0x78
f:
x = 0
x = 1
x = 2
x = 2
x = 2
x = 2
x = 2
x = 7
x = 8
x = 9
x = 9
x = 9
x = 9
x = 9
x = 9
x = 9
x = 16
x = 17
x = 18
x = 19
x = 20
g:
1 1
1 2
2 3
2 4
2 5
3 6
d 6
3 7
d 7
3 8
d 8
d 9
d 10
h:
i = 8
i = 16
i = 120
i = 128
i = 248
i = 264
i = 272
i = 280
i = 288
i = 296
i = 304
i = 312
488 defaults
x = 0x1000000
x = 0x2000000
x = 0x3000000
x = 0x4000000
x = 0x5000000
x = 0x6000000 (default)
x = 0x7000000 (default)
0
1
2
3
4
5
0
1
2
3
4
5

View file

@ -0,0 +1,7 @@
tst/switch.c:55: warning: missing return value
tst/switch.c:73: warning: missing return value
tst/switch.c:97: warning: missing return value
tst/switch.c:101: warning: overflow in converting constant expression from `int' to `unsigned int'
tst/switch.c:102: warning: overflow in converting constant expression from `int' to `unsigned int'
tst/switch.c:112: warning: missing return value
tst/switch.c:137: warning: missing return value

View file

@ -0,0 +1,903 @@
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4006000,-64
.frame $sp,80,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $26,16($sp)
.prologue 1
lda $14,L.6
br L.5
L.2:
ldb $16,($14)
jsr $26,backslash
ldgp $gp,0($26)
mov $0,$27
lda $16,L.7
ldb $17,($14)
mov $27,$18
jsr $26,printf
ldgp $gp,0($26)
L.3:
lda $14,1($14)
L.5:
ldb $27,($14)
cmpeq $27,$31,$23
beq $23,L.2
jsr $26,f
ldgp $gp,0($26)
jsr $26,g
ldgp $gp,0($26)
jsr $26,h
ldgp $gp,0($26)
lda $13,16777216
br L.11
L.8:
mov $13,$16
jsr $26,big
ldgp $gp,0($26)
L.9:
lda $13,16777216($13)
L.11:
and $13,117440512,$27
addl $27,0,$27
cmpeq $27,$31,$23
beq $23,L.8
jsr $26,limit
ldgp $gp,0($26)
mov $31,$0
L.1:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $26,16($sp)
lda $sp,80($sp)
ret
.end main
.globl backslash
.text
.ent backslash
backslash:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
.prologue 1
lda $27,102
cmpeq $16,$27,$23
bne $23,L.16
cmple $16,$27,$23
beq $23,L.22
L.21:
lda $27,98
cmpeq $16,$27,$23
bne $23,L.15
br L.13
L.22:
lda $27,110
cmpeq $16,$27,$23
bne $23,L.17
cmplt $16,$27,$23
bne $23,L.13
L.23:
lda $27,114
cmpeq $16,$27,$23
bne $23,L.18
lda $27,116
cmpeq $16,$27,$23
bne $23,L.19
lda $27,118
cmpeq $16,$27,$23
bne $23,L.20
br L.13
L.15:
lda $0,8
br L.12
L.16:
lda $0,12
br L.12
L.17:
lda $0,10
br L.12
L.18:
lda $0,13
br L.12
L.19:
lda $0,9
br L.12
L.20:
lda $0,11
br L.12
L.13:
mov $16,$0
L.12:
lda $sp,64($sp)
ret
.end backslash
.globl f
.text
.ent f
f:
ldgp $gp,0($27)
lda $sp,-96($sp)
.mask 0x4007000,-72
.frame $sp,96,$26,48
stq $12,0($sp)
stq $13,8($sp)
stq $14,16($sp)
stq $26,24($sp)
.prologue 1
mov $31,$13
lda $16,L.25
jsr $26,printf
ldgp $gp,0($26)
mov $31,$14
L.26:
mov $14,$12
cmplt $14,1,$23
bne $23,L.30
cmple $14,20,$23
beq $23,L.30
subl $14,1,$27
sll $27,3,$27
ldq $27,L.42($27)
jmp ($27)
.rdata
.align 3
L.42:
.quad L.32
.quad L.33
.quad L.30
.quad L.30
.quad L.30
.quad L.30
.quad L.34
.quad L.35
.quad L.36
.quad L.30
.quad L.30
.quad L.30
.quad L.30
.quad L.30
.quad L.30
.quad L.37
.quad L.38
.quad L.39
.quad L.40
.quad L.41
.text
L.32:
mov $14,$13
br L.31
L.33:
mov $14,$13
br L.31
L.34:
mov $14,$13
br L.31
L.35:
mov $14,$13
br L.31
L.36:
mov $14,$13
br L.31
L.37:
mov $14,$13
br L.31
L.38:
mov $14,$13
br L.31
L.39:
mov $14,$13
br L.31
L.40:
mov $14,$13
br L.31
L.41:
mov $14,$13
L.30:
L.31:
lda $16,L.43
mov $13,$17
jsr $26,printf
ldgp $gp,0($26)
L.27:
lda $14,1($14)
cmple $14,20,$23
bne $23,L.26
mov $31,$0
L.24:
ldq $12,0($sp)
ldq $13,8($sp)
ldq $14,16($sp)
ldq $26,24($sp)
lda $sp,96($sp)
ret
.end f
.globl g
.text
.ent g
g:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
.prologue 1
lda $16,L.45
jsr $26,printf
ldgp $gp,0($26)
lda $14,1
L.46:
lda $27,1001
cmplt $14,$27,$23
bne $23,L.63
lda $27,1004
cmple $14,$27,$23
beq $23,L.64
subl $14,1001,$27
sll $27,3,$27
ldq $27,L.65($27)
jmp ($27)
.rdata
.align 3
L.65:
.quad L.59
.quad L.59
.quad L.59
.quad L.59
.text
L.63:
cmplt $14,1,$23
bne $23,L.50
cmple $14,8,$23
beq $23,L.50
subl $14,1,$27
sll $27,3,$27
ldq $27,L.66($27)
jmp ($27)
.rdata
.align 3
L.66:
.quad L.52
.quad L.52
.quad L.54
.quad L.54
.quad L.54
.quad L.56
.quad L.56
.quad L.56
.text
L.64:
lda $27,3001
cmplt $14,$27,$23
bne $23,L.50
lda $27,3004
cmple $14,$27,$23
beq $23,L.50
subl $14,3001,$27
sll $27,3,$27
ldq $27,L.67($27)
jmp ($27)
.rdata
.align 3
L.67:
.quad L.61
.quad L.61
.quad L.61
.quad L.61
.text
L.52:
lda $16,L.53
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.51
L.54:
lda $16,L.55
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.51
L.56:
lda $16,L.57
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
L.50:
lda $16,L.58
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.51
L.59:
lda $16,L.60
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.51
L.61:
lda $16,L.62
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
L.51:
L.47:
lda $14,1($14)
cmple $14,10,$23
bne $23,L.46
mov $31,$0
L.44:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end g
.globl h
.text
.ent h
h:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4006000,-64
.frame $sp,80,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $26,16($sp)
.prologue 1
mov $31,$13
lda $16,L.69
jsr $26,printf
ldgp $gp,0($26)
lda $14,1
L.70:
lda $27,264
cmpeq $14,$27,$23
bne $23,L.82
cmple $14,$27,$23
beq $23,L.90
L.89:
lda $27,120
cmpeq $14,$27,$23
bne $23,L.80
cmple $14,$27,$23
beq $23,L.92
L.91:
cmpeq $14,8,$23
bne $23,L.79
cmplt $14,8,$23
bne $23,L.74
L.93:
cmpeq $14,16,$23
bne $23,L.78
br L.74
L.92:
lda $27,128
cmpeq $14,$27,$23
bne $23,L.76
cmplt $14,$27,$23
bne $23,L.74
L.94:
lda $27,248
cmpeq $14,$27,$23
bne $23,L.83
br L.74
L.90:
lda $27,288
cmpeq $14,$27,$23
bne $23,L.87
cmple $14,$27,$23
beq $23,L.96
L.95:
lda $27,272
cmpeq $14,$27,$23
bne $23,L.84
cmplt $14,$27,$23
bne $23,L.74
L.97:
lda $27,280
cmpeq $14,$27,$23
bne $23,L.81
br L.74
L.96:
lda $27,304
cmpeq $14,$27,$23
bne $23,L.85
cmple $14,$27,$23
beq $23,L.99
L.98:
lda $27,296
cmpeq $14,$27,$23
bne $23,L.86
br L.74
L.99:
lda $27,312
cmpeq $14,$27,$23
bne $23,L.88
br L.74
L.74:
lda $13,1($13)
br L.71
L.76:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.78:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.79:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.80:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.81:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.82:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.83:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.84:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.85:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.86:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.87:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
br L.75
L.88:
lda $16,L.77
mov $14,$17
jsr $26,printf
ldgp $gp,0($26)
L.75:
L.71:
lda $14,1($14)
lda $27,500
cmple $14,$27,$23
bne $23,L.70
lda $16,L.100
mov $13,$17
jsr $26,printf
ldgp $gp,0($26)
mov $31,$0
L.68:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $26,16($sp)
lda $sp,80($sp)
ret
.end h
.globl big
.text
.ent big
big:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
stq $16,32($sp)
.prologue 1
ldl $27,-48+80($sp)
zap $27,240,$27
and $27,0x6000000,$14
lda $25,33554432
cmpeq $14,$25,$23
bne $23,L.107
cmple $14,$25,$23
beq $23,L.111
L.110:
lda $25,-2
cmpeq $14,$25,$23
bne $23,L.105
lda $25,-1
cmpeq $14,$25,$23
bne $23,L.105
cmpeq $14,$31,$23
bne $23,L.105
br L.102
L.111:
mov $14,$27
lda $25,67108864
cmpeq $27,$25,$23
bne $23,L.108
br L.102
L.105:
lda $16,L.106
ldl $17,-48+80($sp)
zap $17,240,$17
jsr $26,printf
ldgp $gp,0($26)
br L.103
L.107:
lda $16,L.106
ldl $17,-48+80($sp)
zap $17,240,$17
jsr $26,printf
ldgp $gp,0($26)
br L.103
L.108:
lda $16,L.106
ldl $17,-48+80($sp)
zap $17,240,$17
jsr $26,printf
ldgp $gp,0($26)
br L.103
L.102:
lda $16,L.109
ldl $17,-48+80($sp)
zap $17,240,$17
jsr $26,printf
ldgp $gp,0($26)
L.103:
mov $31,$0
L.101:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end big
.globl limit
.text
.ent limit
limit:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
.prologue 1
lda $14,-2147483648
L.113:
lda $27,-2147483648
cmplt $14,$27,$23
bne $23,L.117
lda $27,-2147483644
cmple $14,$27,$23
beq $23,L.117
subl $14,-2147483648,$27
sll $27,3,$27
ldq $27,L.130($27)
jmp ($27)
.rdata
.align 3
L.130:
.quad L.119
.quad L.121
.quad L.123
.quad L.125
.quad L.127
.text
L.119:
lda $16,L.120
jsr $26,printf
ldgp $gp,0($26)
br L.118
L.121:
lda $16,L.122
jsr $26,printf
ldgp $gp,0($26)
br L.118
L.123:
lda $16,L.124
jsr $26,printf
ldgp $gp,0($26)
br L.118
L.125:
lda $16,L.126
jsr $26,printf
ldgp $gp,0($26)
br L.118
L.127:
lda $16,L.128
jsr $26,printf
ldgp $gp,0($26)
br L.118
L.117:
lda $16,L.129
jsr $26,printf
ldgp $gp,0($26)
L.118:
L.114:
lda $14,1($14)
lda $27,-2147483643
cmple $14,$27,$23
bne $23,L.113
lda $14,2147483647
L.131:
lda $27,2147483643
cmplt $14,$27,$23
bne $23,L.135
lda $27,2147483647
cmple $14,$27,$23
beq $23,L.135
subl $14,2147483643,$27
sll $27,3,$27
ldq $27,L.142($27)
jmp ($27)
.rdata
.align 3
L.142:
.quad L.141
.quad L.140
.quad L.139
.quad L.138
.quad L.137
.text
L.137:
lda $16,L.120
jsr $26,printf
ldgp $gp,0($26)
br L.136
L.138:
lda $16,L.122
jsr $26,printf
ldgp $gp,0($26)
br L.136
L.139:
lda $16,L.124
jsr $26,printf
ldgp $gp,0($26)
br L.136
L.140:
lda $16,L.126
jsr $26,printf
ldgp $gp,0($26)
br L.136
L.141:
lda $16,L.128
jsr $26,printf
ldgp $gp,0($26)
br L.136
L.135:
lda $16,L.129
jsr $26,printf
ldgp $gp,0($26)
L.136:
L.132:
subl $14,1,$14
lda $27,2147483642
cmplt $14,$27,$23
beq $23,L.131
mov $31,$0
L.112:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end limit
.rdata
.align 0
L.129:
.byte 53
.byte 10
.byte 0
.align 0
L.128:
.byte 52
.byte 10
.byte 0
.align 0
L.126:
.byte 51
.byte 10
.byte 0
.align 0
L.124:
.byte 50
.byte 10
.byte 0
.align 0
L.122:
.byte 49
.byte 10
.byte 0
.align 0
L.120:
.byte 48
.byte 10
.byte 0
.align 0
L.109:
.byte 120
.byte 32
.byte 61
.byte 32
.byte 48
.byte 120
.byte 37
.byte 120
.byte 32
.byte 40
.byte 100
.byte 101
.byte 102
.byte 97
.byte 117
.byte 108
.byte 116
.byte 41
.byte 10
.byte 0
.align 0
L.106:
.byte 120
.byte 32
.byte 61
.byte 32
.byte 48
.byte 120
.byte 37
.byte 120
.byte 10
.byte 0
.align 0
L.100:
.byte 37
.byte 100
.byte 32
.byte 100
.byte 101
.byte 102
.byte 97
.byte 117
.byte 108
.byte 116
.byte 115
.byte 10
.byte 0
.align 0
L.77:
.byte 105
.byte 32
.byte 61
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.69:
.byte 104
.byte 58
.byte 10
.byte 0
.align 0
L.62:
.byte 54
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.60:
.byte 53
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.58:
.byte 100
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.57:
.byte 51
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.55:
.byte 50
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.53:
.byte 49
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.45:
.byte 103
.byte 58
.byte 10
.byte 0
.align 0
L.43:
.byte 120
.byte 32
.byte 61
.byte 32
.byte 37
.byte 100
.byte 10
.byte 0
.align 0
L.25:
.byte 102
.byte 58
.byte 10
.byte 0
.align 0
L.7:
.byte 37
.byte 99
.byte 32
.byte 61
.byte 32
.byte 48
.byte 120
.byte 37
.byte 120
.byte 10
.byte 0
.align 0
L.6:
.byte 98
.byte 102
.byte 110
.byte 114
.byte 116
.byte 118
.byte 120
.byte 0

View file

@ -0,0 +1,74 @@
5 a
2 and
5 buf
16 c
8 char
1 compare
4 cond
5 count
1 d
1 die
3 else
1 entry
1 eof
4 err
1 error
1 exit
1 folded
1 for
1 free
1 frequencies
1 frequency
1 get
2 getchar
3 getword
14 if
2 in
1 index
1 input
1 install
8 int
1 into
1 is
4 isletter
1 it
1 itself
5 left
1 letter
7 lookup
1 main
2 malloc
1 message
2 n
1 necessary
12 next
9 node
4 of
1 on
1 or
1 otherwise
2 out
8 p
3 print
2 printf
16 return
5 right
4 root
25 s
2 storage
3 strcmp
1 strcpy
1 strlen
8 struct
1 structures
2 subtree
1 t
5 tprint
9 tree
1 uses
1 version
1 wf
3 while
21 word
9 words
2 z

View file

@ -0,0 +1,2 @@
tst/wf1.c:29: warning: missing return value
tst/wf1.c:87: warning: missing return value

View file

@ -0,0 +1,400 @@
.globl main
.text
.text
.ent main
main:
ldgp $gp,0($27)
lda $sp,-96($sp)
.mask 0x4000000,-96
.frame $sp,96,$26,48
stq $26,0($sp)
.prologue 1
stq $31,-88+96($sp)
stl $31,next
br L.3
L.2:
lda $16,-76+96($sp)
lda $17,-88+96($sp)
jsr $26,lookup
ldgp $gp,0($26)
ldl $25,($0)
lda $25,1($25)
stl $25,($0)
L.3:
lda $16,-76+96($sp)
jsr $26,getword
ldgp $gp,0($26)
cmpeq $0,$31,$23
beq $23,L.2
ldq $16,-88+96($sp)
jsr $26,tprint
ldgp $gp,0($26)
mov $31,$0
L.1:
ldq $26,0($sp)
lda $sp,96($sp)
ret
.end main
.globl err
.text
.ent err
err:
ldgp $gp,0($27)
lda $sp,-64($sp)
.mask 0x4000000,-64
.frame $sp,64,$26,48
stq $26,0($sp)
stq $16,16($sp)
.prologue 1
lda $16,L.6
ldq $17,-48+64($sp)
jsr $26,printf
ldgp $gp,0($26)
lda $16,1
jsr $26,exit
ldgp $gp,0($26)
mov $31,$0
L.5:
ldq $26,0($sp)
lda $sp,64($sp)
ret
.end err
.globl getword
.text
.ent getword
getword:
ldgp $gp,0($27)
lda $sp,-96($sp)
.mask 0x5006000,-72
.frame $sp,96,$26,48
stq $13,0($sp)
stq $14,8($sp)
stq $24,16($sp)
stq $26,24($sp)
stq $16,48($sp)
.prologue 1
L.8:
L.9:
jsr $26,getchar
ldgp $gp,0($26)
mov $0,$27
mov $27,$14
lda $25,-1
cmpeq $27,$25,$23
bne $23,L.11
mov $14,$16
jsr $26,isletter
ldgp $gp,0($26)
cmpeq $0,$31,$23
bne $23,L.8
L.11:
ldq $13,-48+96($sp)
br L.15
L.12:
mov $13,$27
lda $13,1($27)
mov $14,$25
stb $25,($27)
L.13:
jsr $26,getchar
ldgp $gp,0($26)
mov $0,$14
L.15:
mov $14,$16
jsr $26,isletter
ldgp $gp,0($26)
mov $0,$14
cmpeq $0,$31,$23
beq $23,L.12
stb $31,($13)
mov $13,$27
ldq $25,-48+96($sp)
cmpule $27,$25,$23
bne $23,L.16
lda $0,1
br L.7
L.16:
mov $31,$0
L.7:
ldq $13,0($sp)
ldq $14,8($sp)
ldq $24,16($sp)
ldq $26,24($sp)
lda $sp,96($sp)
ret
.end getword
.globl isletter
.text
.ent isletter
isletter:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
.prologue 1
lda $27,65
cmplt $16,$27,$23
bne $23,L.19
lda $27,90
cmple $16,$27,$23
beq $23,L.19
lda $16,32($16)
L.19:
lda $27,97
cmplt $16,$27,$23
bne $23,L.21
lda $27,122
cmple $16,$27,$23
beq $23,L.21
mov $16,$0
br L.18
L.21:
mov $31,$0
L.18:
lda $sp,64($sp)
ret
.end isletter
.globl lookup
.text
.ent lookup
lookup:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
stq $16,32($sp)
mov $17,$14
.prologue 1
ldq $27,($14)
cmpeq $27,$31,$23
bne $23,L.24
ldq $16,-48+80($sp)
ldq $27,($14)
ldq $17,24($27)
jsr $26,strcmp
ldgp $gp,0($26)
stl $0,-60+80($sp)
ldl $27,-60+80($sp)
cmplt $27,$31,$23
beq $23,L.26
ldq $16,-48+80($sp)
ldq $27,($14)
lda $17,8($27)
jsr $26,lookup
ldgp $gp,0($26)
mov $0,$27
br L.23
L.26:
ldl $27,-60+80($sp)
cmple $27,$31,$23
bne $23,L.28
ldq $16,-48+80($sp)
ldq $27,($14)
lda $17,16($27)
jsr $26,lookup
ldgp $gp,0($26)
mov $0,$27
br L.23
L.28:
ldq $0,($14)
br L.23
L.24:
ldl $27,next
lda $25,2000
cmplt $27,$25,$23
bne $23,L.30
lda $16,L.32
jsr $26,err
ldgp $gp,0($26)
L.30:
ldl $27,next
sll $27,5,$27
stl $31,words($27)
ldl $27,next
sll $27,5,$27
stq $31,words+16($27)
stq $31,words+8($27)
ldq $16,-48+80($sp)
jsr $26,strlen
ldgp $gp,0($26)
mov $0,$27
lda $16,1($27)
jsr $26,malloc
ldgp $gp,0($26)
ldl $25,next
sll $25,5,$25
stq $0,words+24($25)
ldl $27,next
sll $27,5,$27
ldq $27,words+24($27)
cmpeq $27,$31,$23
beq $23,L.36
lda $16,L.39
jsr $26,err
ldgp $gp,0($26)
L.36:
ldl $27,next
sll $27,5,$27
ldq $16,words+24($27)
ldq $17,-48+80($sp)
jsr $26,strcpy
ldgp $gp,0($26)
ldl $27,next
lda $25,1($27)
stl $25,next
sll $27,8*(8-4),$27
sra $27,8*(8-4),$27
sll $27,5,$27
lda $27,words($27)
stq $27,($14)
mov $27,$0
L.23:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end lookup
.globl tprint
.text
.ent tprint
tprint:
ldgp $gp,0($27)
lda $sp,-80($sp)
.mask 0x4004000,-72
.frame $sp,80,$26,48
stq $14,0($sp)
stq $26,8($sp)
mov $16,$14
.prologue 1
mov $14,$27
cmpeq $27,$31,$23
bne $23,L.42
ldq $16,8($14)
jsr $26,tprint
ldgp $gp,0($26)
lda $16,L.44
ldl $17,($14)
ldq $18,24($14)
jsr $26,printf
ldgp $gp,0($26)
ldq $16,16($14)
jsr $26,tprint
ldgp $gp,0($26)
L.42:
mov $31,$0
L.41:
ldq $14,0($sp)
ldq $26,8($sp)
lda $sp,80($sp)
ret
.end tprint
.globl strcmp
.text
.ent strcmp
strcmp:
ldgp $gp,0($27)
lda $sp,-64($sp)
.frame $sp,64,$26,48
.prologue 1
br L.47
L.46:
mov $16,$27
lda $16,1($27)
ldb $27,($27)
cmpeq $27,$31,$23
beq $23,L.49
mov $31,$0
br L.45
L.49:
lda $17,1($17)
L.47:
ldb $27,($16)
ldb $25,($17)
cmpeq $27,$25,$23
bne $23,L.46
ldb $27,($16)
cmpeq $27,$31,$23
beq $23,L.51
lda $0,-1
br L.45
L.51:
ldb $27,($17)
cmpeq $27,$31,$23
beq $23,L.53
lda $0,1
br L.45
L.53:
ldb $27,($16)
ldb $25,($17)
subl $27,$25,$0
L.45:
lda $sp,64($sp)
ret
.end strcmp
.globl next
.comm next,4
.globl words
.comm words,64000
.rdata
.align 0
L.44:
.byte 37
.byte 100
.byte 9
.byte 37
.byte 115
.byte 10
.byte 0
.align 0
L.39:
.byte 111
.byte 117
.byte 116
.byte 32
.byte 111
.byte 102
.byte 32
.byte 119
.byte 111
.byte 114
.byte 100
.byte 32
.byte 115
.byte 116
.byte 111
.byte 114
.byte 97
.byte 103
.byte 101
.byte 0
.align 0
L.32:
.byte 111
.byte 117
.byte 116
.byte 32
.byte 111
.byte 102
.byte 32
.byte 110
.byte 111
.byte 100
.byte 101
.byte 32
.byte 115
.byte 116
.byte 111
.byte 114
.byte 97
.byte 103
.byte 101
.byte 0
.align 0
L.6:
.byte 63
.byte 32
.byte 37
.byte 115
.byte 10
.byte 0

View file

@ -0,0 +1,10 @@
a
b
load
negate
push 5
c
load
multiply
add
store

View file

@ -0,0 +1,3 @@
tst/yacc.c:345: warning: missing return value
tst/yacc.c:349: warning: missing return value
tst/yacc.c:359: warning: missing return value

File diff suppressed because it is too large Load diff

BIN
code/tools/lcc/bin/lcc.exe Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,3 @@
call vcvars32
set BUILDDIR=bin
nmake -f makefile.nt all

View file

@ -0,0 +1,4 @@
#!/bin/sh
export BUILDDIR=.\\out
mkdir out
nmake -f makefile.nt all

322
code/tools/lcc/cpp/cpp.c Normal file
View file

@ -0,0 +1,322 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include "cpp.h"
char rcsid[] = "cpp.c - faked rcsid";
#define OUTS 16384
char outbuf[OUTS];
char *outp = outbuf;
Source *cursource;
int nerrs;
struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" };
char *curtime;
int incdepth;
int ifdepth;
int ifsatisfied[NIF];
int skipping;
int
main(int argc, char **argv)
{
Tokenrow tr;
time_t t;
char ebuf[BUFSIZ];
setbuf(stderr, ebuf);
t = time(NULL);
curtime = ctime(&t);
maketokenrow(3, &tr);
expandlex();
setup(argc, argv);
fixlex();
iniths();
genline();
process(&tr);
flushout();
fflush(stderr);
exit(nerrs > 0);
return 0;
}
void
process(Tokenrow *trp)
{
int anymacros = 0;
for (;;) {
if (trp->tp >= trp->lp) {
trp->tp = trp->lp = trp->bp;
outp = outbuf;
anymacros |= gettokens(trp, 1);
trp->tp = trp->bp;
}
if (trp->tp->type == END) {
if (--incdepth>=0) {
if (cursource->ifdepth)
error(ERROR,
"Unterminated conditional in #include");
unsetsource();
cursource->line += cursource->lineinc;
trp->tp = trp->lp;
genline();
continue;
}
if (ifdepth)
error(ERROR, "Unterminated #if/#ifdef/#ifndef");
break;
}
if (trp->tp->type==SHARP) {
trp->tp += 1;
control(trp);
} else if (!skipping && anymacros)
expandrow(trp, NULL);
if (skipping)
setempty(trp);
puttokens(trp);
anymacros = 0;
cursource->line += cursource->lineinc;
if (cursource->lineinc>1) {
genline();
}
}
}
void
control(Tokenrow *trp)
{
Nlist *np;
Token *tp;
tp = trp->tp;
if (tp->type!=NAME) {
if (tp->type==NUMBER)
goto kline;
if (tp->type != NL)
error(ERROR, "Unidentifiable control line");
return; /* else empty line */
}
if ((np = lookup(tp, 0))==NULL || ((np->flag&ISKW)==0 && !skipping)) {
error(WARNING, "Unknown preprocessor control %t", tp);
return;
}
if (skipping) {
switch (np->val) {
case KENDIF:
if (--ifdepth<skipping)
skipping = 0;
--cursource->ifdepth;
setempty(trp);
return;
case KIFDEF:
case KIFNDEF:
case KIF:
if (++ifdepth >= NIF)
error(FATAL, "#if too deeply nested");
++cursource->ifdepth;
return;
case KELIF:
case KELSE:
if (ifdepth<=skipping)
break;
return;
default:
return;
}
}
switch (np->val) {
case KDEFINE:
dodefine(trp);
break;
case KUNDEF:
tp += 1;
if (tp->type!=NAME || trp->lp - trp->bp != 4) {
error(ERROR, "Syntax error in #undef");
break;
}
if ((np = lookup(tp, 0)) != NULL)
np->flag &= ~ISDEFINED;
break;
case KPRAGMA:
return;
case KIFDEF:
case KIFNDEF:
case KIF:
if (++ifdepth >= NIF)
error(FATAL, "#if too deeply nested");
++cursource->ifdepth;
ifsatisfied[ifdepth] = 0;
if (eval(trp, np->val))
ifsatisfied[ifdepth] = 1;
else
skipping = ifdepth;
break;
case KELIF:
if (ifdepth==0) {
error(ERROR, "#elif with no #if");
return;
}
if (ifsatisfied[ifdepth]==2)
error(ERROR, "#elif after #else");
if (eval(trp, np->val)) {
if (ifsatisfied[ifdepth])
skipping = ifdepth;
else {
skipping = 0;
ifsatisfied[ifdepth] = 1;
}
} else
skipping = ifdepth;
break;
case KELSE:
if (ifdepth==0 || cursource->ifdepth==0) {
error(ERROR, "#else with no #if");
return;
}
if (ifsatisfied[ifdepth]==2)
error(ERROR, "#else after #else");
if (trp->lp - trp->bp != 3)
error(ERROR, "Syntax error in #else");
skipping = ifsatisfied[ifdepth]? ifdepth: 0;
ifsatisfied[ifdepth] = 2;
break;
case KENDIF:
if (ifdepth==0 || cursource->ifdepth==0) {
error(ERROR, "#endif with no #if");
return;
}
--ifdepth;
--cursource->ifdepth;
if (trp->lp - trp->bp != 3)
error(WARNING, "Syntax error in #endif");
break;
case KERROR:
trp->tp = tp+1;
error(WARNING, "#error directive: %r", trp);
break;
case KLINE:
trp->tp = tp+1;
expandrow(trp, "<line>");
tp = trp->bp+2;
kline:
if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
|| ((tp+3==trp->lp && ((tp+1)->type!=STRING))||*(tp+1)->t=='L')){
error(ERROR, "Syntax error in #line");
return;
}
cursource->line = atol((char*)tp->t)-1;
if (cursource->line<0 || cursource->line>=32768)
error(WARNING, "#line specifies number out of range");
tp = tp+1;
if (tp+1<trp->lp)
cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
return;
case KDEFINED:
error(ERROR, "Bad syntax for control line");
break;
case KINCLUDE:
doinclude(trp);
trp->lp = trp->bp;
return;
case KEVAL:
eval(trp, np->val);
break;
default:
error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
break;
}
setempty(trp);
return;
}
void *
domalloc(int size)
{
void *p = malloc(size);
if (p==NULL)
error(FATAL, "Out of memory from malloc");
return p;
}
void
dofree(void *p)
{
free(p);
}
void
error(enum errtype type, char *string, ...)
{
va_list ap;
char *cp, *ep;
Token *tp;
Tokenrow *trp;
Source *s;
int i;
fprintf(stderr, "cpp: ");
for (s=cursource; s; s=s->next)
if (*s->filename)
fprintf(stderr, "%s:%d ", s->filename, s->line);
va_start(ap, string);
for (ep=string; *ep; ep++) {
if (*ep=='%') {
switch (*++ep) {
case 's':
cp = va_arg(ap, char *);
fprintf(stderr, "%s", cp);
break;
case 'd':
i = va_arg(ap, int);
fprintf(stderr, "%d", i);
break;
case 't':
tp = va_arg(ap, Token *);
fprintf(stderr, "%.*s", tp->len, tp->t);
break;
case 'r':
trp = va_arg(ap, Tokenrow *);
for (tp=trp->tp; tp<trp->lp&&tp->type!=NL; tp++) {
if (tp>trp->tp && tp->wslen)
fputc(' ', stderr);
fprintf(stderr, "%.*s", tp->len, tp->t);
}
break;
default:
fputc(*ep, stderr);
break;
}
} else
fputc(*ep, stderr);
}
va_end(ap);
fputc('\n', stderr);
if (type==FATAL)
exit(1);
if (type!=WARNING)
nerrs = 1;
fflush(stderr);
}

163
code/tools/lcc/cpp/cpp.h Normal file
View file

@ -0,0 +1,163 @@
#define INS 32768 /* input buffer */
#define OBS 4096 /* outbut buffer */
#define NARG 32 /* Max number arguments to a macro */
#define NINCLUDE 32 /* Max number of include directories (-I) */
#define NIF 32 /* depth of nesting of #if */
#ifndef EOF
#define EOF (-1)
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef __alpha
typedef unsigned char uchar;
#endif
enum toktype { END, UNCLASS, NAME, NUMBER, STRING, CCON, NL, WS, DSHARP,
EQ, NEQ, LEQ, GEQ, LSH, RSH, LAND, LOR, PPLUS, MMINUS,
ARROW, SBRA, SKET, LP, RP, DOT, AND, STAR, PLUS, MINUS,
TILDE, NOT, SLASH, PCT, LT, GT, CIRC, OR, QUEST,
COLON, ASGN, COMMA, SHARP, SEMIC, CBRA, CKET,
ASPLUS, ASMINUS, ASSTAR, ASSLASH, ASPCT, ASCIRC, ASLSH,
ASRSH, ASOR, ASAND, ELLIPS,
DSHARP1, NAME1, DEFINED, UMINUS };
enum kwtype { KIF, KIFDEF, KIFNDEF, KELIF, KELSE, KENDIF, KINCLUDE, KDEFINE,
KUNDEF, KLINE, KERROR, KPRAGMA, KDEFINED,
KLINENO, KFILE, KDATE, KTIME, KSTDC, KEVAL };
#define ISDEFINED 01 /* has #defined value */
#define ISKW 02 /* is PP keyword */
#define ISUNCHANGE 04 /* can't be #defined in PP */
#define ISMAC 010 /* builtin macro, e.g. __LINE__ */
#define EOB 0xFE /* sentinel for end of input buffer */
#define EOFC 0xFD /* sentinel for end of input file */
#define XPWS 1 /* token flag: white space to assure token sep. */
typedef struct token {
unsigned char type;
unsigned char flag;
unsigned short hideset;
unsigned int wslen;
unsigned int len;
uchar *t;
} Token;
typedef struct tokenrow {
Token *tp; /* current one to scan */
Token *bp; /* base (allocated value) */
Token *lp; /* last+1 token used */
int max; /* number allocated */
} Tokenrow;
typedef struct source {
char *filename; /* name of file of the source */
int line; /* current line number */
int lineinc; /* adjustment for \\n lines */
uchar *inb; /* input buffer */
uchar *inp; /* input pointer */
uchar *inl; /* end of input */
int fd; /* input source */
int ifdepth; /* conditional nesting in include */
struct source *next; /* stack for #include */
} Source;
typedef struct nlist {
struct nlist *next;
uchar *name;
int len;
Tokenrow *vp; /* value as macro */
Tokenrow *ap; /* list of argument names, if any */
char val; /* value as preprocessor name */
char flag; /* is defined, is pp name */
} Nlist;
typedef struct includelist {
char deleted;
char always;
char *file;
} Includelist;
#define new(t) (t *)domalloc(sizeof(t))
#define quicklook(a,b) (namebit[(a)&077] & (1<<((b)&037)))
#define quickset(a,b) namebit[(a)&077] |= (1<<((b)&037))
extern unsigned long namebit[077+1];
enum errtype { WARNING, ERROR, FATAL };
void expandlex(void);
void fixlex(void);
void setup(int, char **);
int gettokens(Tokenrow *, int);
int comparetokens(Tokenrow *, Tokenrow *);
Source *setsource(char *, int, char *);
void unsetsource(void);
void puttokens(Tokenrow *);
void process(Tokenrow *);
void *domalloc(int);
void dofree(void *);
void error(enum errtype, char *, ...);
void flushout(void);
int fillbuf(Source *);
int trigraph(Source *);
int foldline(Source *);
Nlist *lookup(Token *, int);
void control(Tokenrow *);
void dodefine(Tokenrow *);
void doadefine(Tokenrow *, int);
void doinclude(Tokenrow *);
void doif(Tokenrow *, enum kwtype);
void expand(Tokenrow *, Nlist *);
void builtin(Tokenrow *, int);
int gatherargs(Tokenrow *, Tokenrow **, int *);
void substargs(Nlist *, Tokenrow *, Tokenrow **);
void expandrow(Tokenrow *, char *);
void maketokenrow(int, Tokenrow *);
Tokenrow *copytokenrow(Tokenrow *, Tokenrow *);
Token *growtokenrow(Tokenrow *);
Tokenrow *normtokenrow(Tokenrow *);
void adjustrow(Tokenrow *, int);
void movetokenrow(Tokenrow *, Tokenrow *);
void insertrow(Tokenrow *, int, Tokenrow *);
void peektokens(Tokenrow *, char *);
void doconcat(Tokenrow *);
Tokenrow *stringify(Tokenrow *);
int lookuparg(Nlist *, Token *);
long eval(Tokenrow *, int);
void genline(void);
void setempty(Tokenrow *);
void makespace(Tokenrow *);
char *outnum(char *, int);
int digit(int);
uchar *newstring(uchar *, int, int);
int checkhideset(int, Nlist *);
void prhideset(int);
int newhideset(int, Nlist *);
int unionhideset(int, int);
void iniths(void);
void setobjname(char *);
#define rowlen(tokrow) ((tokrow)->lp - (tokrow)->bp)
extern char *outp;
extern Token nltoken;
extern Source *cursource;
extern char *curtime;
extern int incdepth;
extern int ifdepth;
extern int ifsatisfied[NIF];
extern int Mflag;
extern int skipping;
extern int verbose;
extern int Cplusplus;
extern Nlist *kwdefined;
extern Includelist includelist[NINCLUDE];
extern char wd[];
extern int creat(char *, int);
extern int open(char *, int);
extern int close(int);
extern int dup2(int, int);
extern int write(int, char *, size_t);
extern int read(int, char *, size_t);

520
code/tools/lcc/cpp/eval.c Normal file
View file

@ -0,0 +1,520 @@
#include <stdlib.h>
#include <string.h>
#include "cpp.h"
#define NSTAK 32
#define SGN 0
#define UNS 1
#define UND 2
#define UNSMARK 0x1000
struct value {
long val;
int type;
};
/* conversion types */
#define RELAT 1
#define ARITH 2
#define LOGIC 3
#define SPCL 4
#define SHIFT 5
#define UNARY 6
/* operator priority, arity, and conversion type, indexed by tokentype */
struct pri {
char pri;
char arity;
char ctype;
} priority[] = {
{ 0, 0, 0 }, /* END */
{ 0, 0, 0 }, /* UNCLASS */
{ 0, 0, 0 }, /* NAME */
{ 0, 0, 0 }, /* NUMBER */
{ 0, 0, 0 }, /* STRING */
{ 0, 0, 0 }, /* CCON */
{ 0, 0, 0 }, /* NL */
{ 0, 0, 0 }, /* WS */
{ 0, 0, 0 }, /* DSHARP */
{ 11, 2, RELAT }, /* EQ */
{ 11, 2, RELAT }, /* NEQ */
{ 12, 2, RELAT }, /* LEQ */
{ 12, 2, RELAT }, /* GEQ */
{ 13, 2, SHIFT }, /* LSH */
{ 13, 2, SHIFT }, /* RSH */
{ 7, 2, LOGIC }, /* LAND */
{ 6, 2, LOGIC }, /* LOR */
{ 0, 0, 0 }, /* PPLUS */
{ 0, 0, 0 }, /* MMINUS */
{ 0, 0, 0 }, /* ARROW */
{ 0, 0, 0 }, /* SBRA */
{ 0, 0, 0 }, /* SKET */
{ 3, 0, 0 }, /* LP */
{ 3, 0, 0 }, /* RP */
{ 0, 0, 0 }, /* DOT */
{ 10, 2, ARITH }, /* AND */
{ 15, 2, ARITH }, /* STAR */
{ 14, 2, ARITH }, /* PLUS */
{ 14, 2, ARITH }, /* MINUS */
{ 16, 1, UNARY }, /* TILDE */
{ 16, 1, UNARY }, /* NOT */
{ 15, 2, ARITH }, /* SLASH */
{ 15, 2, ARITH }, /* PCT */
{ 12, 2, RELAT }, /* LT */
{ 12, 2, RELAT }, /* GT */
{ 9, 2, ARITH }, /* CIRC */
{ 8, 2, ARITH }, /* OR */
{ 5, 2, SPCL }, /* QUEST */
{ 5, 2, SPCL }, /* COLON */
{ 0, 0, 0 }, /* ASGN */
{ 4, 2, 0 }, /* COMMA */
{ 0, 0, 0 }, /* SHARP */
{ 0, 0, 0 }, /* SEMIC */
{ 0, 0, 0 }, /* CBRA */
{ 0, 0, 0 }, /* CKET */
{ 0, 0, 0 }, /* ASPLUS */
{ 0, 0, 0 }, /* ASMINUS */
{ 0, 0, 0 }, /* ASSTAR */
{ 0, 0, 0 }, /* ASSLASH */
{ 0, 0, 0 }, /* ASPCT */
{ 0, 0, 0 }, /* ASCIRC */
{ 0, 0, 0 }, /* ASLSH */
{ 0, 0, 0 }, /* ASRSH */
{ 0, 0, 0 }, /* ASOR */
{ 0, 0, 0 }, /* ASAND */
{ 0, 0, 0 }, /* ELLIPS */
{ 0, 0, 0 }, /* DSHARP1 */
{ 0, 0, 0 }, /* NAME1 */
{ 16, 1, UNARY }, /* DEFINED */
{ 16, 0, UNARY }, /* UMINUS */
};
int evalop(struct pri);
struct value tokval(Token *);
struct value vals[NSTAK], *vp;
enum toktype ops[NSTAK], *op;
/*
* Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword.
*/
long
eval(Tokenrow *trp, int kw)
{
Token *tp;
Nlist *np;
int ntok, rand;
trp->tp++;
if (kw==KIFDEF || kw==KIFNDEF) {
if (trp->lp - trp->bp != 4 || trp->tp->type!=NAME) {
error(ERROR, "Syntax error in #ifdef/#ifndef");
return 0;
}
np = lookup(trp->tp, 0);
return (kw==KIFDEF) == (np && np->flag&(ISDEFINED|ISMAC));
}
ntok = trp->tp - trp->bp;
kwdefined->val = KDEFINED; /* activate special meaning of defined */
expandrow(trp, "<if>");
kwdefined->val = NAME;
vp = vals;
op = ops;
*op++ = END;
for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) {
switch(tp->type) {
case WS:
case NL:
continue;
/* nilary */
case NAME:
case NAME1:
case NUMBER:
case CCON:
case STRING:
if (rand)
goto syntax;
*vp++ = tokval(tp);
rand = 1;
continue;
/* unary */
case DEFINED:
case TILDE:
case NOT:
if (rand)
goto syntax;
*op++ = tp->type;
continue;
/* unary-binary */
case PLUS: case MINUS: case STAR: case AND:
if (rand==0) {
if (tp->type==MINUS)
*op++ = UMINUS;
if (tp->type==STAR || tp->type==AND) {
error(ERROR, "Illegal operator * or & in #if/#elsif");
return 0;
}
continue;
}
/* flow through */
/* plain binary */
case EQ: case NEQ: case LEQ: case GEQ: case LSH: case RSH:
case LAND: case LOR: case SLASH: case PCT:
case LT: case GT: case CIRC: case OR: case QUEST:
case COLON: case COMMA:
if (rand==0)
goto syntax;
if (evalop(priority[tp->type])!=0)
return 0;
*op++ = tp->type;
rand = 0;
continue;
case LP:
if (rand)
goto syntax;
*op++ = LP;
continue;
case RP:
if (!rand)
goto syntax;
if (evalop(priority[RP])!=0)
return 0;
if (op<=ops || op[-1]!=LP) {
goto syntax;
}
op--;
continue;
default:
error(ERROR,"Bad operator (%t) in #if/#elsif", tp);
return 0;
}
}
if (rand==0)
goto syntax;
if (evalop(priority[END])!=0)
return 0;
if (op!=&ops[1] || vp!=&vals[1]) {
error(ERROR, "Botch in #if/#elsif");
return 0;
}
if (vals[0].type==UND)
error(ERROR, "Undefined expression value");
return vals[0].val;
syntax:
error(ERROR, "Syntax error in #if/#elsif");
return 0;
}
int
evalop(struct pri pri)
{
struct value v1, v2;
long rv1, rv2;
int rtype, oper;
rv2=0;
rtype=0;
while (pri.pri < priority[op[-1]].pri) {
oper = *--op;
if (priority[oper].arity==2) {
v2 = *--vp;
rv2 = v2.val;
}
v1 = *--vp;
rv1 = v1.val;
/*lint -e574 -e644 */
switch (priority[oper].ctype) {
case 0:
default:
error(WARNING, "Syntax error in #if/#endif");
return 1;
case ARITH:
case RELAT:
if (v1.type==UNS || v2.type==UNS)
rtype = UNS;
else
rtype = SGN;
if (v1.type==UND || v2.type==UND)
rtype = UND;
if (priority[oper].ctype==RELAT && rtype==UNS) {
oper |= UNSMARK;
rtype = SGN;
}
break;
case SHIFT:
if (v1.type==UND || v2.type==UND)
rtype = UND;
else
rtype = v1.type;
if (rtype==UNS)
oper |= UNSMARK;
break;
case UNARY:
rtype = v1.type;
break;
case LOGIC:
case SPCL:
break;
}
switch (oper) {
case EQ: case EQ|UNSMARK:
rv1 = rv1==rv2; break;
case NEQ: case NEQ|UNSMARK:
rv1 = rv1!=rv2; break;
case LEQ:
rv1 = rv1<=rv2; break;
case GEQ:
rv1 = rv1>=rv2; break;
case LT:
rv1 = rv1<rv2; break;
case GT:
rv1 = rv1>rv2; break;
case LEQ|UNSMARK:
rv1 = (unsigned long)rv1<=rv2; break;
case GEQ|UNSMARK:
rv1 = (unsigned long)rv1>=rv2; break;
case LT|UNSMARK:
rv1 = (unsigned long)rv1<rv2; break;
case GT|UNSMARK:
rv1 = (unsigned long)rv1>rv2; break;
case LSH:
rv1 <<= rv2; break;
case LSH|UNSMARK:
rv1 = (unsigned long)rv1<<rv2; break;
case RSH:
rv1 >>= rv2; break;
case RSH|UNSMARK:
rv1 = (unsigned long)rv1>>rv2; break;
case LAND:
rtype = UND;
if (v1.type==UND)
break;
if (rv1!=0) {
if (v2.type==UND)
break;
rv1 = rv2!=0;
} else
rv1 = 0;
rtype = SGN;
break;
case LOR:
rtype = UND;
if (v1.type==UND)
break;
if (rv1==0) {
if (v2.type==UND)
break;
rv1 = rv2!=0;
} else
rv1 = 1;
rtype = SGN;
break;
case AND:
rv1 &= rv2; break;
case STAR:
rv1 *= rv2; break;
case PLUS:
rv1 += rv2; break;
case MINUS:
rv1 -= rv2; break;
case UMINUS:
if (v1.type==UND)
rtype = UND;
rv1 = -rv1; break;
case OR:
rv1 |= rv2; break;
case CIRC:
rv1 ^= rv2; break;
case TILDE:
rv1 = ~rv1; break;
case NOT:
rv1 = !rv1; if (rtype!=UND) rtype = SGN; break;
case SLASH:
if (rv2==0) {
rtype = UND;
break;
}
if (rtype==UNS)
rv1 /= (unsigned long)rv2;
else
rv1 /= rv2;
break;
case PCT:
if (rv2==0) {
rtype = UND;
break;
}
if (rtype==UNS)
rv1 %= (unsigned long)rv2;
else
rv1 %= rv2;
break;
case COLON:
if (op[-1] != QUEST)
error(ERROR, "Bad ?: in #if/endif");
else {
op--;
if ((--vp)->val==0)
v1 = v2;
rtype = v1.type;
rv1 = v1.val;
}
break;
case DEFINED:
break;
default:
error(ERROR, "Eval botch (unknown operator)");
return 1;
}
/*lint +e574 +e644 */
v1.val = rv1;
v1.type = rtype;
*vp++ = v1;
}
return 0;
}
struct value
tokval(Token *tp)
{
struct value v;
Nlist *np;
int i, base, c;
unsigned long n;
uchar *p;
v.type = SGN;
v.val = 0;
switch (tp->type) {
case NAME:
v.val = 0;
break;
case NAME1:
if ((np = lookup(tp, 0)) != NULL && np->flag&(ISDEFINED|ISMAC))
v.val = 1;
break;
case NUMBER:
n = 0;
base = 10;
p = tp->t;
c = p[tp->len];
p[tp->len] = '\0';
if (*p=='0') {
base = 8;
if (p[1]=='x' || p[1]=='X') {
base = 16;
p++;
}
p++;
}
for (;; p++) {
if ((i = digit(*p)) < 0)
break;
if (i>=base)
error(WARNING,
"Bad digit in number %t", tp);
n *= base;
n += i;
}
if (n>=0x80000000 && base!=10)
v.type = UNS;
for (; *p; p++) {
if (*p=='u' || *p=='U')
v.type = UNS;
else if (*p=='l' || *p=='L')
;
else {
error(ERROR,
"Bad number %t in #if/#elsif", tp);
break;
}
}
v.val = n;
tp->t[tp->len] = c;
break;
case CCON:
n = 0;
p = tp->t;
if (*p=='L') {
p += 1;
error(WARNING, "Wide char constant value undefined");
}
p += 1;
if (*p=='\\') {
p += 1;
if ((i = digit(*p))>=0 && i<=7) {
n = i;
p += 1;
if ((i = digit(*p))>=0 && i<=7) {
p += 1;
n <<= 3;
n += i;
if ((i = digit(*p))>=0 && i<=7) {
p += 1;
n <<= 3;
n += i;
}
}
} else if (*p=='x') {
p += 1;
while ((i = digit(*p))>=0 && i<=15) {
p += 1;
n <<= 4;
n += i;
}
} else {
static char cvcon[]
= "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
for (i=0; i<sizeof(cvcon); i+=2) {
if (*p == cvcon[i]) {
n = cvcon[i+1];
break;
}
}
p += 1;
if (i>=sizeof(cvcon))
error(WARNING,
"Undefined escape in character constant");
}
} else if (*p=='\'')
error(ERROR, "Empty character constant");
else
n = *p++;
if (*p!='\'')
error(WARNING, "Multibyte character constant undefined");
else if (n>127)
error(WARNING, "Character constant taken as not signed");
v.val = n;
break;
case STRING:
error(ERROR, "String in #if/#elsif");
break;
}
return v;
}
int
digit(int i)
{
if ('0'<=i && i<='9')
i -= '0';
else if ('a'<=i && i<='f')
i -= 'a'-10;
else if ('A'<=i && i<='F')
i -= 'A'-10;
else
i = -1;
return i;
}

View file

@ -0,0 +1,53 @@
#include <stdio.h>
#include <string.h>
#define EPR fprintf(stderr,
#define ERR(str, chr) if(opterr){EPR "%s%c\n", str, chr);}
int opterr = 1;
int optind = 1;
int optopt;
char *optarg;
int
getopt (int argc, char *const argv[], const char *opts)
{
static int sp = 1;
int c;
char *cp;
if (sp == 1) {
if (optind >= argc ||
argv[optind][0] != '-' || argv[optind][1] == '\0')
return -1;
else if (strcmp(argv[optind], "--") == 0) {
optind++;
return -1;
}
}
optopt = c = argv[optind][sp];
if (c == ':' || (cp=strchr(opts, c)) == 0) {
ERR (": illegal option -- ", c);
if (argv[optind][++sp] == '\0') {
optind++;
sp = 1;
}
return '?';
}
if (*++cp == ':') {
if (argv[optind][sp+1] != '\0')
optarg = &argv[optind++][sp+1];
else if (++optind >= argc) {
ERR (": option requires an argument -- ", c);
sp = 1;
return '?';
} else
optarg = argv[optind++];
sp = 1;
} else {
if (argv[optind][++sp] == '\0') {
sp = 1;
optind++;
}
optarg = 0;
}
return c;
}

View file

@ -0,0 +1,112 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpp.h"
/*
* A hideset is a null-terminated array of Nlist pointers.
* They are referred to by indices in the hidesets array.
* Hideset 0 is empty.
*/
#define HSSIZ 32
typedef Nlist **Hideset;
Hideset *hidesets;
int nhidesets = 0;
int maxhidesets = 3;
int inserths(Hideset, Hideset, Nlist *);
/*
* Test for membership in a hideset
*/
int
checkhideset(int hs, Nlist *np)
{
Hideset hsp;
if (hs>=nhidesets)
abort();
for (hsp = hidesets[hs]; *hsp; hsp++) {
if (*hsp == np)
return 1;
}
return 0;
}
/*
* Return the (possibly new) hideset obtained by adding np to hs.
*/
int
newhideset(int hs, Nlist *np)
{
int i, len;
Nlist *nhs[HSSIZ+3];
Hideset hs1, hs2;
len = inserths(nhs, hidesets[hs], np);
for (i=0; i<nhidesets; i++) {
for (hs1=nhs, hs2=hidesets[i]; *hs1==*hs2; hs1++, hs2++)
if (*hs1 == NULL)
return i;
}
if (len>=HSSIZ)
return hs;
if (nhidesets >= maxhidesets) {
maxhidesets = 3*maxhidesets/2+1;
hidesets = (Hideset *)realloc(hidesets, (sizeof (Hideset *))*maxhidesets);
if (hidesets == NULL)
error(FATAL, "Out of memory from realloc");
}
hs1 = (Hideset)domalloc(len*sizeof(Hideset));
memmove(hs1, nhs, len*sizeof(Hideset));
hidesets[nhidesets] = hs1;
return nhidesets++;
}
int
inserths(Hideset dhs, Hideset shs, Nlist *np)
{
Hideset odhs = dhs;
while (*shs && *shs < np)
*dhs++ = *shs++;
if (*shs != np)
*dhs++ = np;
do {
*dhs++ = *shs;
} while (*shs++);
return dhs - odhs;
}
/*
* Hideset union
*/
int
unionhideset(int hs1, int hs2)
{
Hideset hp;
for (hp = hidesets[hs2]; *hp; hp++)
hs1 = newhideset(hs1, *hp);
return hs1;
}
void
iniths(void)
{
hidesets = (Hideset *)domalloc(maxhidesets*sizeof(Hideset *));
hidesets[0] = (Hideset)domalloc(sizeof(Hideset));
*hidesets[0] = NULL;
nhidesets++;
}
void
prhideset(int hs)
{
Hideset np;
for (np = hidesets[hs]; *np; np++) {
fprintf(stderr, (char*)(*np)->name, (*np)->len);
fprintf(stderr, " ");
}
}

View file

@ -0,0 +1,122 @@
#include <stdlib.h>
#include <string.h>
#include "cpp.h"
Includelist includelist[NINCLUDE];
extern char *objname;
void
doinclude(Tokenrow *trp)
{
char fname[256], iname[256];
Includelist *ip;
int angled, len, fd, i;
trp->tp += 1;
if (trp->tp>=trp->lp)
goto syntax;
if (trp->tp->type!=STRING && trp->tp->type!=LT) {
len = trp->tp - trp->bp;
expandrow(trp, "<include>");
trp->tp = trp->bp+len;
}
if (trp->tp->type==STRING) {
len = trp->tp->len-2;
if (len > sizeof(fname) - 1)
len = sizeof(fname) - 1;
strncpy(fname, (char*)trp->tp->t+1, len);
angled = 0;
} else if (trp->tp->type==LT) {
len = 0;
trp->tp++;
while (trp->tp->type!=GT) {
if (trp->tp>trp->lp || len+trp->tp->len+2 >= sizeof(fname))
goto syntax;
strncpy(fname+len, (char*)trp->tp->t, trp->tp->len);
len += trp->tp->len;
trp->tp++;
}
angled = 1;
} else
goto syntax;
trp->tp += 2;
if (trp->tp < trp->lp || len==0)
goto syntax;
fname[len] = '\0';
if (fname[0]=='/') {
fd = open(fname, 0);
strcpy(iname, fname);
} else for (fd = -1,i=NINCLUDE-1; i>=0; i--) {
ip = &includelist[i];
if (ip->file==NULL || ip->deleted || (angled && ip->always==0))
continue;
if (strlen(fname)+strlen(ip->file)+2 > sizeof(iname))
continue;
strcpy(iname, ip->file);
strcat(iname, "/");
strcat(iname, fname);
if ((fd = open(iname, 0)) >= 0)
break;
}
if ( Mflag>1 || (!angled&&Mflag==1) ) {
write(1,objname,strlen(objname));
write(1,iname,strlen(iname));
write(1,"\n",1);
}
if (fd >= 0) {
if (++incdepth > 10)
error(FATAL, "#include too deeply nested");
setsource((char*)newstring((uchar*)iname, strlen(iname), 0), fd, NULL);
genline();
} else {
trp->tp = trp->bp+2;
error(ERROR, "Could not find include file %r", trp);
}
return;
syntax:
error(ERROR, "Syntax error in #include");
return;
}
/*
* Generate a line directive for cursource
*/
void
genline(void)
{
static Token ta = { UNCLASS };
static Tokenrow tr = { &ta, &ta, &ta+1, 1 };
uchar *p;
ta.t = p = (uchar*)outp;
strcpy((char*)p, "#line ");
p += sizeof("#line ")-1;
p = (uchar*)outnum((char*)p, cursource->line);
*p++ = ' '; *p++ = '"';
if (cursource->filename[0]!='/' && wd[0]) {
strcpy((char*)p, wd);
p += strlen(wd);
*p++ = '/';
}
strcpy((char*)p, cursource->filename);
p += strlen((char*)p);
*p++ = '"'; *p++ = '\n';
ta.len = (char*)p-outp;
outp = (char*)p;
tr.tp = tr.bp;
puttokens(&tr);
}
void
setobjname(char *f)
{
int n = strlen(f);
objname = (char*)domalloc(n+5);
strcpy(objname,f);
if(objname[n-2]=='.'){
strcpy(objname+n-1,"$O: ");
}else{
strcpy(objname+n,"$O: ");
}
}

580
code/tools/lcc/cpp/lex.c Normal file
View file

@ -0,0 +1,580 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpp.h"
/*
* lexical FSM encoding
* when in state state, and one of the characters
* in ch arrives, enter nextstate.
* States >= S_SELF are either final, or at least require special action.
* In 'fsm' there is a line for each state X charset X nextstate.
* List chars that overwrite previous entries later (e.g. C_ALPH
* can be overridden by '_' by a later entry; and C_XX is the
* the universal set, and should always be first.
* States above S_SELF are represented in the big table as negative values.
* S_SELF and S_SELFB encode the resulting token type in the upper bits.
* These actions differ in that S_SELF doesn't have a lookahead char,
* S_SELFB does.
*
* The encoding is blown out into a big table for time-efficiency.
* Entries have
* nextstate: 6 bits; ?\ marker: 1 bit; tokentype: 9 bits.
*/
#define MAXSTATE 32
#define ACT(tok,act) ((tok<<7)+act)
#define QBSBIT 0100
#define GETACT(st) (st>>7)&0x1ff
/* character classes */
#define C_WS 1
#define C_ALPH 2
#define C_NUM 3
#define C_EOF 4
#define C_XX 5
enum state {
START=0, NUM1, NUM2, NUM3, ID1, ST1, ST2, ST3, COM1, COM2, COM3, COM4,
CC1, CC2, WS1, PLUS1, MINUS1, STAR1, SLASH1, PCT1, SHARP1,
CIRC1, GT1, GT2, LT1, LT2, OR1, AND1, ASG1, NOT1, DOTS1,
S_SELF=MAXSTATE, S_SELFB, S_EOF, S_NL, S_EOFSTR,
S_STNL, S_COMNL, S_EOFCOM, S_COMMENT, S_EOB, S_WS, S_NAME
};
int tottok;
int tokkind[256];
struct fsm {
int state; /* if in this state */
uchar ch[4]; /* and see one of these characters */
int nextstate; /* enter this state if +ve */
};
/*const*/ struct fsm fsm[] = {
/* start state */
{START, { C_XX }, ACT(UNCLASS,S_SELF)},
{START, { ' ', '\t', '\v' }, WS1},
{START, { C_NUM }, NUM1},
{START, { '.' }, NUM3},
{START, { C_ALPH }, ID1},
{START, { 'L' }, ST1},
{START, { '"' }, ST2},
{START, { '\'' }, CC1},
{START, { '/' }, COM1},
{START, { EOFC }, S_EOF},
{START, { '\n' }, S_NL},
{START, { '-' }, MINUS1},
{START, { '+' }, PLUS1},
{START, { '<' }, LT1},
{START, { '>' }, GT1},
{START, { '=' }, ASG1},
{START, { '!' }, NOT1},
{START, { '&' }, AND1},
{START, { '|' }, OR1},
{START, { '#' }, SHARP1},
{START, { '%' }, PCT1},
{START, { '[' }, ACT(SBRA,S_SELF)},
{START, { ']' }, ACT(SKET,S_SELF)},
{START, { '(' }, ACT(LP,S_SELF)},
{START, { ')' }, ACT(RP,S_SELF)},
{START, { '*' }, STAR1},
{START, { ',' }, ACT(COMMA,S_SELF)},
{START, { '?' }, ACT(QUEST,S_SELF)},
{START, { ':' }, ACT(COLON,S_SELF)},
{START, { ';' }, ACT(SEMIC,S_SELF)},
{START, { '{' }, ACT(CBRA,S_SELF)},
{START, { '}' }, ACT(CKET,S_SELF)},
{START, { '~' }, ACT(TILDE,S_SELF)},
{START, { '^' }, CIRC1},
/* saw a digit */
{NUM1, { C_XX }, ACT(NUMBER,S_SELFB)},
{NUM1, { C_NUM, C_ALPH, '.' }, NUM1},
{NUM1, { 'E', 'e' }, NUM2},
{NUM1, { '_' }, ACT(NUMBER,S_SELFB)},
/* saw possible start of exponent, digits-e */
{NUM2, { C_XX }, ACT(NUMBER,S_SELFB)},
{NUM2, { '+', '-' }, NUM1},
{NUM2, { C_NUM, C_ALPH }, NUM1},
{NUM2, { '_' }, ACT(NUMBER,S_SELFB)},
/* saw a '.', which could be a number or an operator */
{NUM3, { C_XX }, ACT(DOT,S_SELFB)},
{NUM3, { '.' }, DOTS1},
{NUM3, { C_NUM }, NUM1},
{DOTS1, { C_XX }, ACT(UNCLASS, S_SELFB)},
{DOTS1, { C_NUM }, NUM1},
{DOTS1, { '.' }, ACT(ELLIPS, S_SELF)},
/* saw a letter or _ */
{ID1, { C_XX }, ACT(NAME,S_NAME)},
{ID1, { C_ALPH, C_NUM }, ID1},
/* saw L (start of wide string?) */
{ST1, { C_XX }, ACT(NAME,S_NAME)},
{ST1, { C_ALPH, C_NUM }, ID1},
{ST1, { '"' }, ST2},
{ST1, { '\'' }, CC1},
/* saw " beginning string */
{ST2, { C_XX }, ST2},
{ST2, { '"' }, ACT(STRING, S_SELF)},
{ST2, { '\\' }, ST3},
{ST2, { '\n' }, S_STNL},
{ST2, { EOFC }, S_EOFSTR},
/* saw \ in string */
{ST3, { C_XX }, ST2},
{ST3, { '\n' }, S_STNL},
{ST3, { EOFC }, S_EOFSTR},
/* saw ' beginning character const */
{CC1, { C_XX }, CC1},
{CC1, { '\'' }, ACT(CCON, S_SELF)},
{CC1, { '\\' }, CC2},
{CC1, { '\n' }, S_STNL},
{CC1, { EOFC }, S_EOFSTR},
/* saw \ in ccon */
{CC2, { C_XX }, CC1},
{CC2, { '\n' }, S_STNL},
{CC2, { EOFC }, S_EOFSTR},
/* saw /, perhaps start of comment */
{COM1, { C_XX }, ACT(SLASH, S_SELFB)},
{COM1, { '=' }, ACT(ASSLASH, S_SELF)},
{COM1, { '*' }, COM2},
{COM1, { '/' }, COM4},
/* saw / then *, start of comment */
{COM2, { C_XX }, COM2},
{COM2, { '\n' }, S_COMNL},
{COM2, { '*' }, COM3},
{COM2, { EOFC }, S_EOFCOM},
/* saw the * possibly ending a comment */
{COM3, { C_XX }, COM2},
{COM3, { '\n' }, S_COMNL},
{COM3, { '*' }, COM3},
{COM3, { '/' }, S_COMMENT},
/* // comment */
{COM4, { C_XX }, COM4},
{COM4, { '\n' }, S_NL},
{COM4, { EOFC }, S_EOFCOM},
/* saw white space, eat it up */
{WS1, { C_XX }, S_WS},
{WS1, { ' ', '\t', '\v' }, WS1},
/* saw -, check --, -=, -> */
{MINUS1, { C_XX }, ACT(MINUS, S_SELFB)},
{MINUS1, { '-' }, ACT(MMINUS, S_SELF)},
{MINUS1, { '=' }, ACT(ASMINUS,S_SELF)},
{MINUS1, { '>' }, ACT(ARROW,S_SELF)},
/* saw +, check ++, += */
{PLUS1, { C_XX }, ACT(PLUS, S_SELFB)},
{PLUS1, { '+' }, ACT(PPLUS, S_SELF)},
{PLUS1, { '=' }, ACT(ASPLUS, S_SELF)},
/* saw <, check <<, <<=, <= */
{LT1, { C_XX }, ACT(LT, S_SELFB)},
{LT1, { '<' }, LT2},
{LT1, { '=' }, ACT(LEQ, S_SELF)},
{LT2, { C_XX }, ACT(LSH, S_SELFB)},
{LT2, { '=' }, ACT(ASLSH, S_SELF)},
/* saw >, check >>, >>=, >= */
{GT1, { C_XX }, ACT(GT, S_SELFB)},
{GT1, { '>' }, GT2},
{GT1, { '=' }, ACT(GEQ, S_SELF)},
{GT2, { C_XX }, ACT(RSH, S_SELFB)},
{GT2, { '=' }, ACT(ASRSH, S_SELF)},
/* = */
{ASG1, { C_XX }, ACT(ASGN, S_SELFB)},
{ASG1, { '=' }, ACT(EQ, S_SELF)},
/* ! */
{NOT1, { C_XX }, ACT(NOT, S_SELFB)},
{NOT1, { '=' }, ACT(NEQ, S_SELF)},
/* & */
{AND1, { C_XX }, ACT(AND, S_SELFB)},
{AND1, { '&' }, ACT(LAND, S_SELF)},
{AND1, { '=' }, ACT(ASAND, S_SELF)},
/* | */
{OR1, { C_XX }, ACT(OR, S_SELFB)},
{OR1, { '|' }, ACT(LOR, S_SELF)},
{OR1, { '=' }, ACT(ASOR, S_SELF)},
/* # */
{SHARP1, { C_XX }, ACT(SHARP, S_SELFB)},
{SHARP1, { '#' }, ACT(DSHARP, S_SELF)},
/* % */
{PCT1, { C_XX }, ACT(PCT, S_SELFB)},
{PCT1, { '=' }, ACT(ASPCT, S_SELF)},
/* * */
{STAR1, { C_XX }, ACT(STAR, S_SELFB)},
{STAR1, { '=' }, ACT(ASSTAR, S_SELF)},
/* ^ */
{CIRC1, { C_XX }, ACT(CIRC, S_SELFB)},
{CIRC1, { '=' }, ACT(ASCIRC, S_SELF)},
{-1}
};
/* first index is char, second is state */
/* increase #states to power of 2 to encourage use of shift */
short bigfsm[256][MAXSTATE];
void
expandlex(void)
{
/*const*/ struct fsm *fp;
int i, j, nstate;
for (fp = fsm; fp->state>=0; fp++) {
for (i=0; fp->ch[i]; i++) {
nstate = fp->nextstate;
if (nstate >= S_SELF)
nstate = ~nstate;
switch (fp->ch[i]) {
case C_XX: /* random characters */
for (j=0; j<256; j++)
bigfsm[j][fp->state] = nstate;
continue;
case C_ALPH:
for (j=0; j<=256; j++)
if (('a'<=j&&j<='z') || ('A'<=j&&j<='Z')
|| j=='_')
bigfsm[j][fp->state] = nstate;
continue;
case C_NUM:
for (j='0'; j<='9'; j++)
bigfsm[j][fp->state] = nstate;
continue;
default:
bigfsm[fp->ch[i]][fp->state] = nstate;
}
}
}
/* install special cases for ? (trigraphs), \ (splicing), runes, and EOB */
for (i=0; i<MAXSTATE; i++) {
for (j=0; j<0xFF; j++)
if (j=='?' || j=='\\') {
if (bigfsm[j][i]>0)
bigfsm[j][i] = ~bigfsm[j][i];
bigfsm[j][i] &= ~QBSBIT;
}
bigfsm[EOB][i] = ~S_EOB;
if (bigfsm[EOFC][i]>=0)
bigfsm[EOFC][i] = ~S_EOF;
}
}
void
fixlex(void)
{
/* do C++ comments? */
if (Cplusplus==0)
bigfsm['/'][COM1] = bigfsm['x'][COM1];
}
/*
* fill in a row of tokens from input, terminated by NL or END
* First token is put at trp->lp.
* Reset is non-zero when the input buffer can be "rewound."
* The value is a flag indicating that possible macros have
* been seen in the row.
*/
int
gettokens(Tokenrow *trp, int reset)
{
register int c, state, oldstate;
register uchar *ip;
register Token *tp, *maxp;
int runelen;
Source *s = cursource;
int nmac = 0;
tp = trp->lp;
ip = s->inp;
if (reset) {
s->lineinc = 0;
if (ip>=s->inl) { /* nothing in buffer */
s->inl = s->inb;
fillbuf(s);
ip = s->inp = s->inb;
} else if (ip >= s->inb+(3*INS/4)) {
memmove(s->inb, ip, 4+s->inl-ip);
s->inl = s->inb+(s->inl-ip);
ip = s->inp = s->inb;
}
}
maxp = &trp->bp[trp->max];
runelen = 1;
for (;;) {
continue2:
if (tp>=maxp) {
trp->lp = tp;
tp = growtokenrow(trp);
maxp = &trp->bp[trp->max];
}
tp->type = UNCLASS;
tp->hideset = 0;
tp->t = ip;
tp->wslen = 0;
tp->flag = 0;
state = START;
for (;;) {
oldstate = state;
c = *ip;
if ((state = bigfsm[c][state]) >= 0) {
ip += runelen;
runelen = 1;
continue;
}
state = ~state;
reswitch:
switch (state&0177) {
case S_SELF:
ip += runelen;
runelen = 1;
case S_SELFB:
tp->type = GETACT(state);
tp->len = ip - tp->t;
tp++;
goto continue2;
case S_NAME: /* like S_SELFB but with nmac check */
tp->type = NAME;
tp->len = ip - tp->t;
nmac |= quicklook(tp->t[0], tp->len>1?tp->t[1]:0);
tp++;
goto continue2;
case S_WS:
tp->wslen = ip - tp->t;
tp->t = ip;
state = START;
continue;
default:
if ((state&QBSBIT)==0) {
ip += runelen;
runelen = 1;
continue;
}
state &= ~QBSBIT;
s->inp = ip;
if (c=='?') { /* check trigraph */
if (trigraph(s)) {
state = oldstate;
continue;
}
goto reswitch;
}
if (c=='\\') { /* line-folding */
if (foldline(s)) {
s->lineinc++;
state = oldstate;
continue;
}
goto reswitch;
}
error(WARNING, "Lexical botch in cpp");
ip += runelen;
runelen = 1;
continue;
case S_EOB:
s->inp = ip;
fillbuf(cursource);
state = oldstate;
continue;
case S_EOF:
tp->type = END;
tp->len = 0;
s->inp = ip;
if (tp!=trp->bp && (tp-1)->type!=NL && cursource->fd!=-1)
error(WARNING,"No newline at end of file");
trp->lp = tp+1;
return nmac;
case S_STNL:
error(ERROR, "Unterminated string or char const");
case S_NL:
tp->t = ip;
tp->type = NL;
tp->len = 1;
tp->wslen = 0;
s->lineinc++;
s->inp = ip+1;
trp->lp = tp+1;
return nmac;
case S_EOFSTR:
error(FATAL, "EOF in string or char constant");
break;
case S_COMNL:
s->lineinc++;
state = COM2;
ip += runelen;
runelen = 1;
if (ip >= s->inb+(7*INS/8)) { /* very long comment */
memmove(tp->t, ip, 4+s->inl-ip);
s->inl -= ip-tp->t;
ip = tp->t+1;
}
continue;
case S_EOFCOM:
error(WARNING, "EOF inside comment");
--ip;
case S_COMMENT:
++ip;
tp->t = ip;
tp->t[-1] = ' ';
tp->wslen = 1;
state = START;
continue;
}
break;
}
ip += runelen;
runelen = 1;
tp->len = ip - tp->t;
tp++;
}
}
/* have seen ?; handle the trigraph it starts (if any) else 0 */
int
trigraph(Source *s)
{
int c;
while (s->inp+2 >= s->inl && fillbuf(s)!=EOF)
;
if (s->inp[1]!='?')
return 0;
c = 0;
switch(s->inp[2]) {
case '=':
c = '#'; break;
case '(':
c = '['; break;
case '/':
c = '\\'; break;
case ')':
c = ']'; break;
case '\'':
c = '^'; break;
case '<':
c = '{'; break;
case '!':
c = '|'; break;
case '>':
c = '}'; break;
case '-':
c = '~'; break;
}
if (c) {
*s->inp = c;
memmove(s->inp+1, s->inp+3, s->inl-s->inp+2);
s->inl -= 2;
}
return c;
}
int
foldline(Source *s)
{
while (s->inp+1 >= s->inl && fillbuf(s)!=EOF)
;
if (s->inp[1] == '\n') {
memmove(s->inp, s->inp+2, s->inl-s->inp+3);
s->inl -= 2;
return 1;
}
return 0;
}
int
fillbuf(Source *s)
{
int n, nr;
nr = INS/8;
if ((char *)s->inl+nr > (char *)s->inb+INS)
error(FATAL, "Input buffer overflow");
if (s->fd<0 || (n=read(s->fd, (char *)s->inl, INS/8)) <= 0)
n = 0;
if ((*s->inp&0xff) == EOB) /* sentinel character appears in input */
*s->inp = EOFC;
s->inl += n;
s->inl[0] = s->inl[1]= s->inl[2]= s->inl[3] = EOB;
if (n==0) {
s->inl[0] = s->inl[1]= s->inl[2]= s->inl[3] = EOFC;
return EOF;
}
return 0;
}
/*
* Push down to new source of characters.
* If fd>0 and str==NULL, then from a file `name';
* if fd==-1 and str, then from the string.
*/
Source *
setsource(char *name, int fd, char *str)
{
Source *s = new(Source);
int len;
s->line = 1;
s->lineinc = 0;
s->fd = fd;
s->filename = name;
s->next = cursource;
s->ifdepth = 0;
cursource = s;
/* slop at right for EOB */
if (str) {
len = strlen(str);
s->inb = domalloc(len+4);
s->inp = s->inb;
strncpy((char *)s->inp, str, len);
} else {
s->inb = domalloc(INS+4);
s->inp = s->inb;
len = 0;
}
s->inl = s->inp+len;
s->inl[0] = s->inl[1] = EOB;
return s;
}
void
unsetsource(void)
{
Source *s = cursource;
if (s->fd>=0) {
close(s->fd);
dofree(s->inb);
}
cursource = s->next;
dofree(s);
}

515
code/tools/lcc/cpp/macro.c Normal file
View file

@ -0,0 +1,515 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpp.h"
/*
* do a macro definition. tp points to the name being defined in the line
*/
void
dodefine(Tokenrow *trp)
{
Token *tp;
Nlist *np;
Tokenrow *def, *args;
tp = trp->tp+1;
if (tp>=trp->lp || tp->type!=NAME) {
error(ERROR, "#defined token is not a name");
return;
}
np = lookup(tp, 1);
if (np->flag&ISUNCHANGE) {
error(ERROR, "#defined token %t can't be redefined", tp);
return;
}
/* collect arguments */
tp += 1;
args = NULL;
if (tp<trp->lp && tp->type==LP && tp->wslen==0) {
/* macro with args */
int narg = 0;
tp += 1;
args = new(Tokenrow);
maketokenrow(2, args);
if (tp->type!=RP) {
int err = 0;
for (;;) {
Token *atp;
if (tp->type!=NAME) {
err++;
break;
}
if (narg>=args->max)
growtokenrow(args);
for (atp=args->bp; atp<args->lp; atp++)
if (atp->len==tp->len
&& strncmp((char*)atp->t, (char*)tp->t, tp->len)==0)
error(ERROR, "Duplicate macro argument");
*args->lp++ = *tp;
narg++;
tp += 1;
if (tp->type==RP)
break;
if (tp->type!=COMMA) {
err++;
break;
}
tp += 1;
}
if (err) {
error(ERROR, "Syntax error in macro parameters");
return;
}
}
tp += 1;
}
trp->tp = tp;
if (((trp->lp)-1)->type==NL)
trp->lp -= 1;
def = normtokenrow(trp);
if (np->flag&ISDEFINED) {
if (comparetokens(def, np->vp)
|| (np->ap==NULL) != (args==NULL)
|| (np->ap && comparetokens(args, np->ap)))
error(ERROR, "Macro redefinition of %t", trp->bp+2);
}
if (args) {
Tokenrow *tap;
tap = normtokenrow(args);
dofree(args->bp);
args = tap;
}
np->ap = args;
np->vp = def;
np->flag |= ISDEFINED;
}
/*
* Definition received via -D or -U
*/
void
doadefine(Tokenrow *trp, int type)
{
Nlist *np;
static Token onetoken[1] = {{ NUMBER, 0, 0, 0, 1, (uchar*)"1" }};
static Tokenrow onetr = { onetoken, onetoken, onetoken+1, 1 };
trp->tp = trp->bp;
if (type=='U') {
if (trp->lp-trp->tp != 2 || trp->tp->type!=NAME)
goto syntax;
if ((np = lookup(trp->tp, 0)) == NULL)
return;
np->flag &= ~ISDEFINED;
return;
}
if (trp->tp >= trp->lp || trp->tp->type!=NAME)
goto syntax;
np = lookup(trp->tp, 1);
np->flag |= ISDEFINED;
trp->tp += 1;
if (trp->tp >= trp->lp || trp->tp->type==END) {
np->vp = &onetr;
return;
}
if (trp->tp->type!=ASGN)
goto syntax;
trp->tp += 1;
if ((trp->lp-1)->type == END)
trp->lp -= 1;
np->vp = normtokenrow(trp);
return;
syntax:
error(FATAL, "Illegal -D or -U argument %r", trp);
}
/*
* Do macro expansion in a row of tokens.
* Flag is NULL if more input can be gathered.
*/
void
expandrow(Tokenrow *trp, char *flag)
{
Token *tp;
Nlist *np;
if (flag)
setsource(flag, -1, "");
for (tp = trp->tp; tp<trp->lp; ) {
if (tp->type!=NAME
|| quicklook(tp->t[0], tp->len>1?tp->t[1]:0)==0
|| (np = lookup(tp, 0))==NULL
|| (np->flag&(ISDEFINED|ISMAC))==0
|| (tp->hideset && checkhideset(tp->hideset, np))) {
tp++;
continue;
}
trp->tp = tp;
if (np->val==KDEFINED) {
tp->type = DEFINED;
if ((tp+1)<trp->lp && (tp+1)->type==NAME)
(tp+1)->type = NAME1;
else if ((tp+3)<trp->lp && (tp+1)->type==LP
&& (tp+2)->type==NAME && (tp+3)->type==RP)
(tp+2)->type = NAME1;
else
error(ERROR, "Incorrect syntax for `defined'");
tp++;
continue;
}
if (np->flag&ISMAC)
builtin(trp, np->val);
else {
expand(trp, np);
}
tp = trp->tp;
}
if (flag)
unsetsource();
}
/*
* Expand the macro whose name is np, at token trp->tp, in the tokenrow.
* Return trp->tp at the first token next to be expanded
* (ordinarily the beginning of the expansion)
*/
void
expand(Tokenrow *trp, Nlist *np)
{
Tokenrow ntr;
int ntokc, narg, i;
Token *tp;
Tokenrow *atr[NARG+1];
int hs;
copytokenrow(&ntr, np->vp); /* copy macro value */
if (np->ap==NULL) /* parameterless */
ntokc = 1;
else {
ntokc = gatherargs(trp, atr, &narg);
if (narg<0) { /* not actually a call (no '(') */
trp->tp++;
return;
}
if (narg != rowlen(np->ap)) {
error(ERROR, "Disagreement in number of macro arguments");
trp->tp->hideset = newhideset(trp->tp->hideset, np);
trp->tp += ntokc;
return;
}
substargs(np, &ntr, atr); /* put args into replacement */
for (i=0; i<narg; i++) {
dofree(atr[i]->bp);
dofree(atr[i]);
}
}
doconcat(&ntr); /* execute ## operators */
hs = newhideset(trp->tp->hideset, np);
for (tp=ntr.bp; tp<ntr.lp; tp++) { /* distribute hidesets */
if (tp->type==NAME) {
if (tp->hideset==0)
tp->hideset = hs;
else
tp->hideset = unionhideset(tp->hideset, hs);
}
}
ntr.tp = ntr.bp;
insertrow(trp, ntokc, &ntr);
trp->tp -= rowlen(&ntr);
dofree(ntr.bp);
return;
}
/*
* Gather an arglist, starting in trp with tp pointing at the macro name.
* Return total number of tokens passed, stash number of args found.
* trp->tp is not changed relative to the tokenrow.
*/
int
gatherargs(Tokenrow *trp, Tokenrow **atr, int *narg)
{
int parens = 1;
int ntok = 0;
Token *bp, *lp;
Tokenrow ttr;
int ntokp;
int needspace;
*narg = -1; /* means that there is no macro call */
/* look for the ( */
for (;;) {
trp->tp++;
ntok++;
if (trp->tp >= trp->lp) {
gettokens(trp, 0);
if ((trp->lp-1)->type==END) {
trp->lp -= 1;
trp->tp -= ntok;
return ntok;
}
}
if (trp->tp->type==LP)
break;
if (trp->tp->type!=NL)
return ntok;
}
*narg = 0;
ntok++;
ntokp = ntok;
trp->tp++;
/* search for the terminating ), possibly extending the row */
needspace = 0;
while (parens>0) {
if (trp->tp >= trp->lp)
gettokens(trp, 0);
if (needspace) {
needspace = 0;
makespace(trp);
}
if (trp->tp->type==END) {
trp->lp -= 1;
trp->tp -= ntok;
error(ERROR, "EOF in macro arglist");
return ntok;
}
if (trp->tp->type==NL) {
trp->tp += 1;
adjustrow(trp, -1);
trp->tp -= 1;
makespace(trp);
needspace = 1;
continue;
}
if (trp->tp->type==LP)
parens++;
else if (trp->tp->type==RP)
parens--;
trp->tp++;
ntok++;
}
trp->tp -= ntok;
/* Now trp->tp won't move underneath us */
lp = bp = trp->tp+ntokp;
for (; parens>=0; lp++) {
if (lp->type == LP) {
parens++;
continue;
}
if (lp->type==RP)
parens--;
if (lp->type==DSHARP)
lp->type = DSHARP1; /* ## not special in arg */
if ((lp->type==COMMA && parens==0) || (parens<0 && (lp-1)->type!=LP)) {
if (*narg>=NARG-1)
error(FATAL, "Sorry, too many macro arguments");
ttr.bp = ttr.tp = bp;
ttr.lp = lp;
atr[(*narg)++] = normtokenrow(&ttr);
bp = lp+1;
}
}
return ntok;
}
/*
* substitute the argument list into the replacement string
* This would be simple except for ## and #
*/
void
substargs(Nlist *np, Tokenrow *rtr, Tokenrow **atr)
{
Tokenrow tatr;
Token *tp;
int ntok, argno;
for (rtr->tp=rtr->bp; rtr->tp<rtr->lp; ) {
if (rtr->tp->type==SHARP) { /* string operator */
tp = rtr->tp;
rtr->tp += 1;
if ((argno = lookuparg(np, rtr->tp))<0) {
error(ERROR, "# not followed by macro parameter");
continue;
}
ntok = 1 + (rtr->tp - tp);
rtr->tp = tp;
insertrow(rtr, ntok, stringify(atr[argno]));
continue;
}
if (rtr->tp->type==NAME
&& (argno = lookuparg(np, rtr->tp)) >= 0) {
if ((rtr->tp+1)->type==DSHARP
|| (rtr->tp!=rtr->bp && (rtr->tp-1)->type==DSHARP))
insertrow(rtr, 1, atr[argno]);
else {
copytokenrow(&tatr, atr[argno]);
expandrow(&tatr, "<macro>");
insertrow(rtr, 1, &tatr);
dofree(tatr.bp);
}
continue;
}
rtr->tp++;
}
}
/*
* Evaluate the ## operators in a tokenrow
*/
void
doconcat(Tokenrow *trp)
{
Token *ltp, *ntp;
Tokenrow ntr;
int len;
for (trp->tp=trp->bp; trp->tp<trp->lp; trp->tp++) {
if (trp->tp->type==DSHARP1)
trp->tp->type = DSHARP;
else if (trp->tp->type==DSHARP) {
char tt[128];
ltp = trp->tp-1;
ntp = trp->tp+1;
if (ltp<trp->bp || ntp>=trp->lp) {
error(ERROR, "## occurs at border of replacement");
continue;
}
len = ltp->len + ntp->len;
strncpy((char*)tt, (char*)ltp->t, ltp->len);
strncpy((char*)tt+ltp->len, (char*)ntp->t, ntp->len);
tt[len] = '\0';
setsource("<##>", -1, tt);
maketokenrow(3, &ntr);
gettokens(&ntr, 1);
unsetsource();
if (ntr.lp-ntr.bp!=2 || ntr.bp->type==UNCLASS)
error(WARNING, "Bad token %r produced by ##", &ntr);
ntr.lp = ntr.bp+1;
trp->tp = ltp;
makespace(&ntr);
insertrow(trp, (ntp-ltp)+1, &ntr);
dofree(ntr.bp);
trp->tp--;
}
}
}
/*
* tp is a potential parameter name of macro mac;
* look it up in mac's arglist, and if found, return the
* corresponding index in the argname array. Return -1 if not found.
*/
int
lookuparg(Nlist *mac, Token *tp)
{
Token *ap;
if (tp->type!=NAME || mac->ap==NULL)
return -1;
for (ap=mac->ap->bp; ap<mac->ap->lp; ap++) {
if (ap->len==tp->len && strncmp((char*)ap->t,(char*)tp->t,ap->len)==0)
return ap - mac->ap->bp;
}
return -1;
}
/*
* Return a quoted version of the tokenrow (from # arg)
*/
#define STRLEN 512
Tokenrow *
stringify(Tokenrow *vp)
{
static Token t = { STRING };
static Tokenrow tr = { &t, &t, &t+1, 1 };
Token *tp;
uchar s[STRLEN];
uchar *sp = s, *cp;
int i, instring;
*sp++ = '"';
for (tp = vp->bp; tp < vp->lp; tp++) {
instring = tp->type==STRING || tp->type==CCON;
if (sp+2*tp->len >= &s[STRLEN-10]) {
error(ERROR, "Stringified macro arg is too long");
break;
}
if (tp->wslen && (tp->flag&XPWS)==0)
*sp++ = ' ';
for (i=0, cp=tp->t; i<tp->len; i++) {
if (instring && (*cp=='"' || *cp=='\\'))
*sp++ = '\\';
*sp++ = *cp++;
}
}
*sp++ = '"';
*sp = '\0';
sp = s;
t.len = strlen((char*)sp);
t.t = newstring(sp, t.len, 0);
return &tr;
}
/*
* expand a builtin name
*/
void
builtin(Tokenrow *trp, int biname)
{
char *op;
Token *tp;
Source *s;
tp = trp->tp;
trp->tp++;
/* need to find the real source */
s = cursource;
while (s && s->fd==-1)
s = s->next;
if (s==NULL)
s = cursource;
/* most are strings */
tp->type = STRING;
if (tp->wslen) {
*outp++ = ' ';
tp->wslen = 1;
}
op = outp;
*op++ = '"';
switch (biname) {
case KLINENO:
tp->type = NUMBER;
op = outnum(op-1, s->line);
break;
case KFILE: {
char *src = s->filename;
while ((*op++ = *src++) != 0)
if (src[-1] == '\\')
*op++ = '\\';
op--;
break;
}
case KDATE:
strncpy(op, curtime+4, 7);
strncpy(op+7, curtime+20, 4);
op += 11;
break;
case KTIME:
strncpy(op, curtime+11, 8);
op += 8;
break;
default:
error(ERROR, "cpp botch: unknown internal macro");
return;
}
if (tp->type==STRING)
*op++ = '"';
tp->t = (uchar*)outp;
tp->len = op - outp;
outp = op;
}

104
code/tools/lcc/cpp/nlist.c Normal file
View file

@ -0,0 +1,104 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpp.h"
extern int getopt(int, char *const *, const char *);
extern char *optarg;
extern int optind;
extern int verbose;
extern int Cplusplus;
Nlist *kwdefined;
char wd[128];
#define NLSIZE 128
static Nlist *nlist[NLSIZE];
struct kwtab {
char *kw;
int val;
int flag;
} kwtab[] = {
{"if", KIF, ISKW},
{"ifdef", KIFDEF, ISKW},
{"ifndef", KIFNDEF, ISKW},
{"elif", KELIF, ISKW},
{"else", KELSE, ISKW},
{"endif", KENDIF, ISKW},
{"include", KINCLUDE, ISKW},
{"define", KDEFINE, ISKW},
{"undef", KUNDEF, ISKW},
{"line", KLINE, ISKW},
{"error", KERROR, ISKW},
{"pragma", KPRAGMA, ISKW},
{"eval", KEVAL, ISKW},
{"defined", KDEFINED, ISDEFINED+ISUNCHANGE},
{"__LINE__", KLINENO, ISMAC+ISUNCHANGE},
{"__FILE__", KFILE, ISMAC+ISUNCHANGE},
{"__DATE__", KDATE, ISMAC+ISUNCHANGE},
{"__TIME__", KTIME, ISMAC+ISUNCHANGE},
{"__STDC__", KSTDC, ISUNCHANGE},
{NULL}
};
unsigned long namebit[077+1];
Nlist *np;
void
setup_kwtab(void)
{
struct kwtab *kp;
Nlist *np;
Token t;
static Token deftoken[1] = {{ NAME, 0, 0, 0, 7, (uchar*)"defined" }};
static Tokenrow deftr = { deftoken, deftoken, deftoken+1, 1 };
for (kp=kwtab; kp->kw; kp++) {
t.t = (uchar*)kp->kw;
t.len = strlen(kp->kw);
np = lookup(&t, 1);
np->flag = kp->flag;
np->val = kp->val;
if (np->val == KDEFINED) {
kwdefined = np;
np->val = NAME;
np->vp = &deftr;
np->ap = 0;
}
}
}
Nlist *
lookup(Token *tp, int install)
{
unsigned int h;
Nlist *np;
uchar *cp, *cpe;
h = 0;
for (cp=tp->t, cpe=cp+tp->len; cp<cpe; )
h += *cp++;
h %= NLSIZE;
np = nlist[h];
while (np) {
if (*tp->t==*np->name && tp->len==np->len
&& strncmp((char*)tp->t, (char*)np->name, tp->len)==0)
return np;
np = np->next;
}
if (install) {
np = new(Nlist);
np->vp = NULL;
np->ap = NULL;
np->flag = 0;
np->val = 0;
np->len = tp->len;
np->name = newstring(tp->t, tp->len, 0);
np->next = nlist[h];
nlist[h] = np;
quickset(tp->t[0], tp->len>1? tp->t[1]:0);
return np;
}
return NULL;
}

370
code/tools/lcc/cpp/tokens.c Normal file
View file

@ -0,0 +1,370 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpp.h"
static char wbuf[2*OBS];
static char *wbp = wbuf;
/*
* 1 for tokens that don't need whitespace when they get inserted
* by macro expansion
*/
static const char wstab[] = {
0, /* END */
0, /* UNCLASS */
0, /* NAME */
0, /* NUMBER */
0, /* STRING */
0, /* CCON */
1, /* NL */
0, /* WS */
0, /* DSHARP */
0, /* EQ */
0, /* NEQ */
0, /* LEQ */
0, /* GEQ */
0, /* LSH */
0, /* RSH */
0, /* LAND */
0, /* LOR */
0, /* PPLUS */
0, /* MMINUS */
0, /* ARROW */
1, /* SBRA */
1, /* SKET */
1, /* LP */
1, /* RP */
0, /* DOT */
0, /* AND */
0, /* STAR */
0, /* PLUS */
0, /* MINUS */
0, /* TILDE */
0, /* NOT */
0, /* SLASH */
0, /* PCT */
0, /* LT */
0, /* GT */
0, /* CIRC */
0, /* OR */
0, /* QUEST */
0, /* COLON */
0, /* ASGN */
1, /* COMMA */
0, /* SHARP */
1, /* SEMIC */
1, /* CBRA */
1, /* CKET */
0, /* ASPLUS */
0, /* ASMINUS */
0, /* ASSTAR */
0, /* ASSLASH */
0, /* ASPCT */
0, /* ASCIRC */
0, /* ASLSH */
0, /* ASRSH */
0, /* ASOR */
0, /* ASAND */
0, /* ELLIPS */
0, /* DSHARP1 */
0, /* NAME1 */
0, /* DEFINED */
0, /* UMINUS */
};
void
maketokenrow(int size, Tokenrow *trp)
{
trp->max = size;
if (size>0)
trp->bp = (Token *)domalloc(size*sizeof(Token));
else
trp->bp = NULL;
trp->tp = trp->bp;
trp->lp = trp->bp;
}
Token *
growtokenrow(Tokenrow *trp)
{
int ncur = trp->tp - trp->bp;
int nlast = trp->lp - trp->bp;
trp->max = 3*trp->max/2 + 1;
trp->bp = (Token *)realloc(trp->bp, trp->max*sizeof(Token));
if (trp->bp == NULL)
error(FATAL, "Out of memory from realloc");
trp->lp = &trp->bp[nlast];
trp->tp = &trp->bp[ncur];
return trp->lp;
}
/*
* Compare a row of tokens, ignoring the content of WS; return !=0 if different
*/
int
comparetokens(Tokenrow *tr1, Tokenrow *tr2)
{
Token *tp1, *tp2;
tp1 = tr1->tp;
tp2 = tr2->tp;
if (tr1->lp-tp1 != tr2->lp-tp2)
return 1;
for (; tp1<tr1->lp ; tp1++, tp2++) {
if (tp1->type != tp2->type
|| (tp1->wslen==0) != (tp2->wslen==0)
|| tp1->len != tp2->len
|| strncmp((char*)tp1->t, (char*)tp2->t, tp1->len)!=0)
return 1;
}
return 0;
}
/*
* replace ntok tokens starting at dtr->tp with the contents of str.
* tp ends up pointing just beyond the replacement.
* Canonical whitespace is assured on each side.
*/
void
insertrow(Tokenrow *dtr, int ntok, Tokenrow *str)
{
int nrtok = rowlen(str);
dtr->tp += ntok;
adjustrow(dtr, nrtok-ntok);
dtr->tp -= ntok;
movetokenrow(dtr, str);
makespace(dtr);
dtr->tp += nrtok;
makespace(dtr);
}
/*
* make sure there is WS before trp->tp, if tokens might merge in the output
*/
void
makespace(Tokenrow *trp)
{
uchar *tt;
Token *tp = trp->tp;
if (tp >= trp->lp)
return;
if (tp->wslen) {
if (tp->flag&XPWS
&& (wstab[tp->type] || (trp->tp>trp->bp && wstab[(tp-1)->type]))) {
tp->wslen = 0;
return;
}
tp->t[-1] = ' ';
return;
}
if (wstab[tp->type] || (trp->tp>trp->bp && wstab[(tp-1)->type]))
return;
tt = newstring(tp->t, tp->len, 1);
*tt++ = ' ';
tp->t = tt;
tp->wslen = 1;
tp->flag |= XPWS;
}
/*
* Copy an entire tokenrow into another, at tp.
* It is assumed that there is enough space.
* Not strictly conforming.
*/
void
movetokenrow(Tokenrow *dtr, Tokenrow *str)
{
int nby;
/* nby = sizeof(Token) * (str->lp - str->bp); */
nby = (char *)str->lp - (char *)str->bp;
memmove(dtr->tp, str->bp, nby);
}
/*
* Move the tokens in a row, starting at tr->tp, rightward by nt tokens;
* nt may be negative (left move).
* The row may need to be grown.
* Non-strictly conforming because of the (char *), but easily fixed
*/
void
adjustrow(Tokenrow *trp, int nt)
{
int nby, size;
if (nt==0)
return;
size = (trp->lp - trp->bp) + nt;
while (size > trp->max)
growtokenrow(trp);
/* nby = sizeof(Token) * (trp->lp - trp->tp); */
nby = (char *)trp->lp - (char *)trp->tp;
if (nby)
memmove(trp->tp+nt, trp->tp, nby);
trp->lp += nt;
}
/*
* Copy a row of tokens into the destination holder, allocating
* the space for the contents. Return the destination.
*/
Tokenrow *
copytokenrow(Tokenrow *dtr, Tokenrow *str)
{
int len = rowlen(str);
maketokenrow(len, dtr);
movetokenrow(dtr, str);
dtr->lp += len;
return dtr;
}
/*
* Produce a copy of a row of tokens. Start at trp->tp.
* The value strings are copied as well. The first token
* has WS available.
*/
Tokenrow *
normtokenrow(Tokenrow *trp)
{
Token *tp;
Tokenrow *ntrp = new(Tokenrow);
int len;
len = trp->lp - trp->tp;
if (len<=0)
len = 1;
maketokenrow(len, ntrp);
for (tp=trp->tp; tp < trp->lp; tp++) {
*ntrp->lp = *tp;
if (tp->len) {
ntrp->lp->t = newstring(tp->t, tp->len, 1);
*ntrp->lp->t++ = ' ';
if (tp->wslen)
ntrp->lp->wslen = 1;
}
ntrp->lp++;
}
if (ntrp->lp > ntrp->bp)
ntrp->bp->wslen = 0;
return ntrp;
}
/*
* Debugging
*/
void
peektokens(Tokenrow *trp, char *str)
{
Token *tp;
tp = trp->tp;
flushout();
if (str)
fprintf(stderr, "%s ", str);
if (tp<trp->bp || tp>trp->lp)
fprintf(stderr, "(tp offset %d) ", tp-trp->bp);
for (tp=trp->bp; tp<trp->lp && tp<trp->bp+32; tp++) {
if (tp->type!=NL) {
int c = tp->t[tp->len];
tp->t[tp->len] = 0;
fprintf(stderr, "%s", tp->t);
tp->t[tp->len] = c;
}
if (tp->type==NAME) {
fprintf(stderr, tp==trp->tp?"{*":"{");
prhideset(tp->hideset);
fprintf(stderr, "} ");
} else
fprintf(stderr, tp==trp->tp?"{%x*} ":"{%x} ", tp->type);
}
fprintf(stderr, "\n");
fflush(stderr);
}
void
puttokens(Tokenrow *trp)
{
Token *tp;
int len;
uchar *p;
if (verbose)
peektokens(trp, "");
tp = trp->bp;
for (; tp<trp->lp; tp++) {
len = tp->len+tp->wslen;
p = tp->t-tp->wslen;
while (tp<trp->lp-1 && p+len == (tp+1)->t - (tp+1)->wslen) {
tp++;
len += tp->wslen+tp->len;
}
if (len>OBS/2) { /* handle giant token */
if (wbp > wbuf)
write(1, wbuf, wbp-wbuf);
write(1, (char *)p, len);
wbp = wbuf;
} else {
memcpy(wbp, p, len);
wbp += len;
}
if (wbp >= &wbuf[OBS]) {
write(1, wbuf, OBS);
if (wbp > &wbuf[OBS])
memcpy(wbuf, wbuf+OBS, wbp - &wbuf[OBS]);
wbp -= OBS;
}
}
trp->tp = tp;
if (cursource->fd==0)
flushout();
}
void
flushout(void)
{
if (wbp>wbuf) {
write(1, wbuf, wbp-wbuf);
wbp = wbuf;
}
}
/*
* turn a row into just a newline
*/
void
setempty(Tokenrow *trp)
{
trp->tp = trp->bp;
trp->lp = trp->bp+1;
*trp->bp = nltoken;
}
/*
* generate a number
*/
char *
outnum(char *p, int n)
{
if (n>=10)
p = outnum(p, n/10);
*p++ = n%10 + '0';
return p;
}
/*
* allocate and initialize a new string from s, of length l, at offset o
* Null terminated.
*/
uchar *
newstring(uchar *s, int l, int o)
{
uchar *ns = (uchar *)domalloc(l+o+1);
ns[l+o] = '\0';
return (uchar*)strncpy((char*)ns+o, (char*)s, l) - o;
}

116
code/tools/lcc/cpp/unix.c Normal file
View file

@ -0,0 +1,116 @@
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "cpp.h"
extern int getopt(int, char *const *, const char *);
extern char *optarg, rcsid[];
extern int optind;
int verbose;
int Mflag; /* only print active include files */
char *objname; /* "src.$O: " */
int Cplusplus = 1;
void
setup(int argc, char **argv)
{
int c, fd, i;
char *fp, *dp;
Tokenrow tr;
extern void setup_kwtab(void);
setup_kwtab();
while ((c = getopt(argc, argv, "MNOVv+I:D:U:F:lg")) != -1)
switch (c) {
case 'N':
for (i=0; i<NINCLUDE; i++)
if (includelist[i].always==1)
includelist[i].deleted = 1;
break;
case 'I':
for (i=NINCLUDE-2; i>=0; i--) {
if (includelist[i].file==NULL) {
includelist[i].always = 1;
includelist[i].file = optarg;
break;
}
}
if (i<0)
error(FATAL, "Too many -I directives");
break;
case 'D':
case 'U':
setsource("<cmdarg>", -1, optarg);
maketokenrow(3, &tr);
gettokens(&tr, 1);
doadefine(&tr, c);
unsetsource();
break;
case 'M':
Mflag++;
break;
case 'v':
fprintf(stderr, "%s %s\n", argv[0], rcsid);
break;
case 'V':
verbose++;
break;
case '+':
Cplusplus++;
break;
default:
break;
}
dp = ".";
fp = "<stdin>";
fd = 0;
if (optind<argc) {
if ((fp = strrchr(argv[optind], '/')) != NULL) {
int len = fp - argv[optind];
dp = (char*)newstring((uchar*)argv[optind], len+1, 0);
dp[len] = '\0';
}
fp = (char*)newstring((uchar*)argv[optind], strlen(argv[optind]), 0);
if ((fd = open(fp, 0)) <= 0)
error(FATAL, "Can't open input file %s", fp);
}
if (optind+1<argc) {
int fdo = creat(argv[optind+1], 0666);
if (fdo<0)
error(FATAL, "Can't open output file %s", argv[optind+1]);
dup2(fdo, 1);
}
if(Mflag)
setobjname(fp);
includelist[NINCLUDE-1].always = 0;
includelist[NINCLUDE-1].file = dp;
setsource(fp, fd, NULL);
}
/* memmove is defined here because some vendors don't provide it at
all and others do a terrible job (like calling malloc) */
void *
memmove(void *dp, const void *sp, size_t n)
{
unsigned char *cdp, *csp;
if (n<=0)
return 0;
cdp = dp;
csp = (unsigned char *)sp;
if (cdp < csp) {
do {
*cdp++ = *csp++;
} while (--n);
} else {
cdp += n;
csp += n;
do {
*--cdp = *--csp;
} while (--n);
}
return 0;
}

754
code/tools/lcc/doc/4.html Normal file
View file

@ -0,0 +1,754 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<link HREF="mailto:drh@microsoft.com" REV="made" TITLE="David R. Hanson">
<title>The lcc 4.1 Code-Generation Interface</title>
</head>
<body>
<h1>The lcc 4.1 Code-Generation Interface</h1>
<p ALIGN="LEFT"><strong><a HREF="http://www.research.microsoft.com/~cwfraser/">Christopher
W. Fraser</a> and <a HREF="http://www.research.microsoft.com/~drh/">David R. Hanson</a>, <a
HREF="http://www.research.microsoft.com/">Microsoft Research</a></strong></p>
<h2>Contents</h2>
<dir>
<li><a HREF="#intro">Introduction</a> </li>
<li><a HREF="#metrics">5.1 Type Metrics</a></li>
<li><a HREF="#symbols">5.3 Symbols</a> </li>
<li><a HREF="#operators">5.5 Dag Operators</a></li>
<li><a HREF="#flags">5.6 Interface Flags</a></li>
<li><a HREF="#definitions">5.8 Definitions</a></li>
<li><a HREF="#constants">5.9 Constants</a></li>
<li><a HREF="#upcalls">5.12 Upcalls</a></li>
</dir>
<h2><a NAME="intro">Introduction</a></h2>
<p>Version 4.1 is the latest release of <a
HREF="http://www.cs.princeton.edu/software/lcc/">lcc</a>, the ANSI C compiler described in
our book <cite>A Retargetable C Compiler: Design and Implementation</cite>
(Addison-Wesley, 1995, ISBN 0-8053-1670-1). This document summarizes the differences
between the 4.1 code-generation interface and the 3.x interface described in Chap. 5 of <cite>A
Retargetable C Compiler</cite>.</p>
<p>Previous versions of lcc supported only three sizes of integers, two sizes of floats,
and insisted that pointers fit in unsigned integers (see Sec. 5.1 of <cite>A Retargetable
C Compiler</cite>). These assumptions simplified the compiler, and were suitable for
32-bit architectures. But on 64-bit architectures, such as the DEC ALPHA, it's natural to
have four sizes of integers and perhaps three sizes of floats, and on 16-bit
architectures, 32-bit pointers don't fit in unsigned integers. Also, the 3.x constaints
limited the use of lcc's back ends for other languages, such as Java.</p>
<p>Version 4.x removes all of these restrictions: It supports any number of sizes for
integers and floats, and the size of pointers need not be related to the size of any of
the integer types. The major changes in the code-generation interface are:
<ul>
<li>The number of type suffixes has been reduced to 6.</li>
<li>Dag operators are composed of a generic operator, a type suffix, and a size.</li>
<li>Unsigned variants of several operators have been added.</li>
<li>Several interface functions have new signatures.</li>
</ul>
<p>In addition, version 4.x is written in ANSI C and uses the standard I/O library and
other standard C functions.</p>
<p>The sections below parallel the subsections of Chap. 5 of <cite>A Retargetable C
Compiler</cite> and summarize the differences between the 3.x and 4.x code-generation
interface. Unaffected subsections are omitted. Page citations refer to pages in <cite>A
Retargetable C Compiler</cite>.</p>
<h2><a NAME="metrics">5.1 Type Metrics</a></h2>
<p>There are now 10 metrics in an interface record:</p>
<pre>Metrics charmetric;
Metrics shortmetric;
Metrics intmetric;
Metrics longmetric;
Metrics longlongmetric;
Metrics floatmetric;
Metrics doublemetric;
Metrics longdoublemetric;
Metrics ptrmetric;
Metrics structmetric;</pre>
<p>Each of these specifies the size and alignment of the corresponding type. <code>ptrmetric</code>
describes all pointers.</p>
<h2><a NAME="symbols">5.3 Symbols</a></h2>
<p>The actual value of a constant is stored in the <code>u.c.v</code> field of a symbol,
which holds a <code>Value</code>:</p>
<pre>typedef union value {
long i;
unsigned long u;
long double d;
void *p;
void (*g)(void);
} Value;</pre>
<p>The value is stored in the appropriate field according to its type, which is given by
the symbol's <code>type</code> field.</p>
<h2><a NAME="operators">5.5 Dag Operators</a></h2>
<p>The <code>op</code> field a of <code>node</code> structure holds a dag operator, which
consists of a generic operator, a type suffix, and a size indicator. The type suffixes
are:</p>
<pre>enum {
F=FLOAT,
I=INT,
U=UNSIGNED,
P=POINTER,
V=VOID,
B=STRUCT
};
#define sizeop(n) ((n)&lt;&lt;10)</pre>
<p>Given a generic operator <code>o</code>, a type suffix <code>t</code>, and a size <code>s</code>,
a type- and size-specific operator is formed by <code>o+t+sizeop(s)</code>. For example, <code>ADD+F+sizeop(4)</code>
forms the operator <code>ADDF4</code>, which denotes the sum of two 4-byte floats.
Similarly, <code>ADD+F+sizeop(8)</code> forms <code>ADDF8</code>, which denotes 8-byte
floating addition. In the 3.x code-generation interface, <code>ADDF</code> and <code>ADDD</code>
denoted these operations. There was no size indicator in the 3.x operators because the
type suffix supplied both a type and a size.</p>
<p>Table 5.1 lists each generic operator, its valid type suffixes, and the number of <code>kids</code>
and <code>syms</code> that it uses; multiple values for <code>kids</code> indicate
type-specific variants. The notations in the <strong>syms</strong> column give the number
of <code>syms</code> values and a one-letter code that suggests their uses: 1V indicates
that <code>syms[0]</code> points to a symbol for a variable, 1C indicates that <code>syms[0]</code>
is a constant, and 1L indicates that <code>syms[0]</code> is a label. For 1S, <code>syms[0]</code>
is a constant whose value is a size in bytes; 2S adds <code>syms[1]</code>, which is a
constant whose value is an alignment. For most operators, the type suffix and size
indicator denote the type and size of operation to perform and the type and size of the
result.</p>
<table WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0">
<tr>
<td COLSPAN="6" ALIGN="CENTER"><strong>Table 5.1<img SRC="/~drh/resources/dot_clear.gif"
ALT="|" WIDTH="18" HEIGHT="1">Node Operators.</strong></td>
</tr>
<tr>
<td><strong>syms</strong></td>
<td><strong>kids</strong></td>
<td><strong>Operator</strong></td>
<td><strong>Type Suffixes</strong></td>
<td><strong>Sizes</strong></td>
<td><strong>Operation</strong></td>
</tr>
<tr>
<td>1V</td>
<td>0</td>
<td><code>ADDRF</code></td>
<td><code>...P..</code></td>
<td>p</td>
<td>address of a parameter</td>
</tr>
<tr>
<td>1V</td>
<td>0</td>
<td><code>ADDRG</code></td>
<td><code>...P..</code></td>
<td>p</td>
<td>address of a global</td>
</tr>
<tr>
<td>1V</td>
<td>0</td>
<td><code>ADDRL</code></td>
<td><code>...P..</code></td>
<td>p</td>
<td>address of a local</td>
</tr>
<tr>
<td>1C</td>
<td>0</td>
<td><code>CNST</code></td>
<td><code>FIUP..</code></td>
<td>fdx csilh p</td>
<td>constant</td>
</tr>
<tr ALIGN="LEFT" VALIGN="TOP">
<td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>1</td>
<td><code>BCOM</code></td>
<td><code>.IU...</code></td>
<td>ilh</td>
<td>bitwise complement</td>
</tr>
<tr>
<td>1S</td>
<td>1</td>
<td><code>CVF</code></td>
<td><code>FI....</code></td>
<td>fdx ilh</td>
<td>convert from float</td>
</tr>
<tr>
<td>1S</td>
<td>1</td>
<td><code>CVI</code></td>
<td><code>FIU...</code></td>
<td>fdx csilh csilhp</td>
<td>convert from signed integer</td>
</tr>
<tr>
<td>1S</td>
<td>1</td>
<td><code>CVP</code></td>
<td><code>..U..</code></td>
<td>p</td>
<td>convert from pointer</td>
</tr>
<tr>
<td>1S</td>
<td>1</td>
<td><code>CVU</code></td>
<td><code>.IUP..</code></td>
<td>csilh p</td>
<td>convert from unsigned integer</td>
</tr>
<tr>
<td></td>
<td>1</td>
<td><code>INDIR</code></td>
<td><code>FIUP.B</code></td>
<td>fdx csilh p</td>
<td>fetch</td>
</tr>
<tr>
<td></td>
<td>1</td>
<td><code>NEG</code></td>
<td><code>FI....</code></td>
<td>fdx ilh</td>
<td>negation</td>
</tr>
<tr>
<td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>ADD</code></td>
<td><code>FIUP..</code></td>
<td>fdx ilh ilhp p</td>
<td>addition</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>BAND</code></td>
<td><code>.IU...</code></td>
<td>ilh</td>
<td>bitwise AND</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>BOR</code></td>
<td><code>.IU...</code></td>
<td>ilh</td>
<td>bitwise inclusive OR</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>BXOR</code></td>
<td><code>.IU...</code></td>
<td>ilh</td>
<td>bitwise exclusive OR</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>DIV</code></td>
<td><code>FIU...</code></td>
<td>fdx ilh</td>
<td>division</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>LSH</code></td>
<td><code>.IU...</code></td>
<td>ilh</td>
<td>left shift</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>MOD</code></td>
<td><code>.IU...</code></td>
<td>ilh</td>
<td>modulus</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>MUL</code></td>
<td><code>FIU...</code></td>
<td>fdx ilh</td>
<td>multiplication</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>RSH</code></td>
<td><code>.IU...</code></td>
<td>ilh</td>
<td>right shift</td>
</tr>
<tr>
<td></td>
<td>2</td>
<td><code>SUB</code></td>
<td><code>FIUP..</code></td>
<td>fdx ilh ilhp p</td>
<td>subtraction</td>
</tr>
<tr>
<td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>2S</td>
<td>2</td>
<td><code>ASGN</code></td>
<td><code>FIUP.B</code></td>
<td>fdx csilh p</td>
<td>assignment</td>
</tr>
<tr>
<td>1L</td>
<td>2</td>
<td><code>EQ</code></td>
<td><code>FIU...</code></td>
<td>fdx ilh ilhp</td>
<td>jump if equal</td>
</tr>
<tr>
<td>1L</td>
<td>2</td>
<td><code>GE</code></td>
<td><code>FIU...</code></td>
<td>fdx ilh ilhp</td>
<td>jump if greater than or equal</td>
</tr>
<tr>
<td>1L</td>
<td>2</td>
<td><code>GT</code></td>
<td><code>FIU...</code></td>
<td>fdx ilh ilhp</td>
<td>jump if greater than</td>
</tr>
<tr>
<td>1L</td>
<td>2</td>
<td><code>LE</code></td>
<td><code>FIU...</code></td>
<td>fdx ilh ilhp</td>
<td>jump if less than or equal</td>
</tr>
<tr>
<td>1L</td>
<td>2</td>
<td><code>LT</code></td>
<td><code>FIU...</code></td>
<td>fdx ilh ilhp</td>
<td>jump if less than</td>
</tr>
<tr>
<td>1L</td>
<td>2</td>
<td><code>NE</code></td>
<td><code>FIU...</code></td>
<td>fdx ilh ilhp</td>
<td>jump if not equal</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>2S</td>
<td>1</td>
<td><code>ARG</code></td>
<td><code>FIUP.B</code></td>
<td>fdx ilh p</td>
<td>argument</td>
</tr>
<tr>
<td>1</td>
<td>1 or 2</td>
<td><code>CALL</code></td>
<td><code>FIUPVB</code></td>
<td>fdx ilh p</td>
<td>function call</td>
</tr>
<tr>
<td></td>
<td>1</td>
<td><code>RET</code></td>
<td><code>FIUPV.</code></td>
<td>fdx ilh p</td>
<td>return from function</td>
</tr>
<tr>
<td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="1" HEIGHT="12"></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>1</td>
<td><code>JUMP</code></td>
<td><code>....V.</code></td>
<td></td>
<td>unconditional jump</td>
</tr>
<tr>
<td>1L</td>
<td>0</td>
<td><code>LABEL</code></td>
<td><code>....V.</code></td>
<td></td>
<td>label definition</td>
</tr>
</table>
<p>The entries in the <strong>Sizes</strong> column indicate sizes of the operators that
back ends must implement. Letters denote the size of float (f), double (d), long double
(x), character (c), short integer (s), integer (i), long integer (l), &quot;long
long&quot; integer (h) , and pointer (p). These sizes are separated into sets for each
type suffix, except that a single set is used for both I and U when the set for I is
identical to the set for U.</p>
<p>The actual values for the size indicators, fdxcsilhp, depend on the target. A
specification like <code>ADDF</code>f denotes the operator <code>ADD+F+sizeop(</code>f<code>)</code>,
where &quot;f&quot; is replaced by a target-dependent value, e.g., <code>ADDF4</code> and <code>ADDF8</code>.
For example, back ends must implement the following <code>CVI</code> and <code>MUL</code>
operators.</p>
<blockquote>
<p><code>CVIF</code>f <code>CVIF</code>d <code>CVIF</code>x<br>
<code>CVII</code>c <code>CVII</code>s <code>CVII</code>i <code>CVII</code>l <code>CVII</code>h<br>
<code>CVIU</code>c <code>CVIU</code>s <code>CVIU</code>i <code>CVIU</code>l <code>CVIU</code>h
<code>CVIU</code>p<br>
<br>
<code>MULF</code>f <code>MULF</code>d <code>MULF</code>x<br>
<code>MULI</code>i <code>MULI</code>l <code>MULI</code>h<br>
<code>MULU</code>i <code>MULU</code>l <code>MULU</code>h</p>
</blockquote>
<p>On most platforms, there are fewer than three sizes of floats and six sizes of
integers, and pointers are usually the same size as one of the integers. And lcc doesn't
support the &quot;long long&quot; type, so h is not currently used. So the set of
platform-specific operators is usually smaller than the list above suggests. For example,
the X86, SPARC, and MIPS back ends implement the following <code>CVI</code> and <code>MUL</code>
operators.</p>
<blockquote>
<p><code>CVIF</code>4 <code>CVIF</code>8<br>
<code>CVII</code>1 <code>CVII</code>2 <code>CVII</code>4<br>
<code>CVIU</code>1 <code>CVIU</code>2 <code>CVIU</code>4 <br>
<br>
<code>MULF</code>4 <code>MULF</code>8<br>
<code>MULI</code>4<br>
<code>MULU</code>4</p>
</blockquote>
<p>The set of operators is thus target-dependent; for example, <code>ADDI8</code> appears
only if the target supports an 8-byte integer type. <a
HREF="ftp://ftp.cs.princeton.edu/pub/packages/lcc/contrib/ops.c"><code>ops.c</code></a> is
a program that, given a set of sizes, prints the required operators and their values,
e.g.,</p>
<blockquote>
<pre>% <em>ops c=1 s=2 i=4 l=4 h=4 f=4 d=8 x=8 p=4</em>
...
CVIF4=4225 CVIF8=8321
CVII1=1157 CVII2=2181 CVII4=4229
CVIU1=1158 CVIU2=2182 CVIU4=4230
...
MULF4=4561 MULF8=8657
MULI4=4565
MULU4=4566
...
131 operators</pre>
</blockquote>
<p>The type suffix for a conversion operator denotes the type of the result and the size
indicator gives the size of the result. For example, <code>CVUI4</code> converts an
unsigned (<code>U</code>) to a 4-byte signed integer (<code>I4</code>). The <code>syms[0]</code>
field points to a symbol-table entry for a integer constant that gives the size of the
source operand. For example, if <code>syms[0]</code> in a <code>CVUI4</code> points to a
symbol-table entry for 2, the conversion widens a 2-byte unsigned integer to a 4-byte
signed integer. Conversions that widen unsigned integers zero-extend; those that widen
signed integers sign-extend.</p>
<p>The front end composes conversions between types <em>T</em><sub>1</sub> and <em>T</em><sub>2</sub>
by widening <em>T</em><sub>1</sub> to it's &quot;supertype&quot;, if necessary, converting
that result to <em>T</em><sub>2</sub>'s supertype, then narrowing the result to <em>T</em><sub>2</sub>,
if necessary. The following table lists the supertypes; omitted entries are their own
supertypes.</p>
<blockquote>
<table BORDER="0" CELLPADDING="0" CELLSPACING="0">
<tr>
<td><strong>Type</strong></td>
<td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td>
<td><strong>Supertype</strong></td>
</tr>
<tr>
<td>signed char</td>
<td></td>
<td>int</td>
</tr>
<tr>
<td>signed short</td>
<td></td>
<td>int</td>
</tr>
<tr ALIGN="LEFT" VALIGN="TOP">
<td>unsigned char</td>
<td></td>
<td>int, if sizeof (char) &lt; sizeof (int)<br>
unsigned, otherwise</td>
</tr>
<tr ALIGN="LEFT" VALIGN="TOP">
<td>unsigned short</td>
<td></td>
<td>int, if sizeof (short) &lt; sizeof (int)<br>
unsigned, otherwise</td>
</tr>
<tr ALIGN="LEFT" VALIGN="TOP">
<td>void *</td>
<td></td>
<td>an unsigned type as large as a pointer</td>
</tr>
</table>
</blockquote>
<p>Pointers are converted to an unsigned type of the same size, even when that type is not
one of the integer types.</p>
<p>For example, the front end converts a signed short to a float by first converting it to
an int and then to a float. It converts an unsigned short to an int with a single <code>CVUI</code>i
conversion, when shorts are smaller than ints.</p>
<p>There are now signed and unsigned variants of <code>ASGN</code>, <code>INDIR</code>, <code>BCOM</code>,
<code>BOR</code>, <code>BXOR</code>, <code>BAND</code>, <code>ARG</code>, <code>CALL</code>,
and <code>RET</code> to simplify code generation on platforms that use different
instructions or register set for signed and unsigned operations. Likewise there are now
pointer variants of <code>ASGN</code>, <code>INDIR</code>, <code>ARG</code>, <code>CALL</code>,
and <code>RET</code>.</p>
<h2><a NAME="flags">5.6 Interface Flags</a></h2>
<pre>unsigned unsigned_char:1;</pre>
<p>tells the front end whether plain characters are signed or unsigned. If it's zero, char
is a signed type; otherwise, char is an unsigned type.</p>
<p>All the interface flags can be set by command-line options, e.g., <code>-Wf-unsigned_char=1</code>
causes plain characters to be unsigned.</p>
<h2><a NAME="definitions">5.8 Definitions</a></h2>
<p>The front end announces local variables by calling</p>
<pre>void (*local)(Symbol);</pre>
<p>It announces temporaries likewise; these have the symbol's <code>temporary</code> flag
set, which indicates that the symbol will be used only in the next call to <code>gen</code>.
If a temporary's <code>u.t.cse</code> field is nonnull, it points to the node that
computes the value assigned to the temporary; see page 346.</p>
<p>The front end calls</p>
<pre>void (*address)(Symbol p, Symbol q, long n);</pre>
<p>to initialize <code>q</code> to a symbol that represents an address of the form <em>x</em>+<code>n</code>,
where <em>x</em> is the address represented by <code>p</code> and the long integer <code>n</code>
is positive or negative.</p>
<h2><a NAME="constants">5.9 Constants</a></h2>
<p>The interface function</p>
<pre>void (*defconst)(int suffix, int size, Value v);</pre>
<p>initializes constants. defconst emits directives to define a cell and initialize it to
a constant value. v is the constant value, suffix identifies the type of the value, and
size is the size of the value in bytes. The value of suffix indicates which field of v
holds the value, as shown in the following table.</p>
<blockquote>
<table BORDER="0" CELLPADDING="1" CELLSPACING="1">
<tr>
<td><strong>suffix</strong></td>
<td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td>
<td><strong>v Field</strong></td>
<td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td>
<td><strong>size</strong></td>
</tr>
<tr>
<td><code>F</code></td>
<td></td>
<td><code>v.d</code></td>
<td></td>
<td>float, double, long double</td>
</tr>
<tr>
<td><code>I</code></td>
<td></td>
<td><code>v.i</code></td>
<td></td>
<td>signed char, signed short, signed int, signed long</td>
</tr>
<tr>
<td><code>U</code></td>
<td></td>
<td><code>v.u</code></td>
<td></td>
<td>unsigned char, unsigned short, unsigned int, unsigned long</td>
</tr>
<tr>
<td><code>P</code></td>
<td></td>
<td><code>v.p</code></td>
<td></td>
<td>void *</td>
</tr>
</table>
</blockquote>
<p><code>defconst</code> must narrow <code>v.</code>x when <code>size</code> is less than <code>sizeof</code>
<code>v.</code>x; e.g., to emit an unsigned char, <code>defconst</code> should emit <code>(unsigned
char)v.i</code>.</p>
<h2><a NAME="upcalls">5.12 Upcalls</a></h2>
<p>lcc 4.x uses standard I/O and its I/O functions have been changed accordingly. lcc
reads input from the standard input, emits code to the standard output, and writes
diagnostics to the standard error output. It uses <code>freopen</code> to redirect these
streams to explicit files, when necessary.</p>
<p><code>bp</code>, <code>outflush</code>, and <code>outs</code> have been eliminated.</p>
<pre>extern void fprint(FILE *f, const char *fmt, ...);
extern void print(const char *fmt, ...);</pre>
<p>print formatted data to file <code>f</code> (<code>fprint</code>) or the standard
output (<code>print</code>). These functions are like standard C's <code>printf</code> and
<code>fprintf</code>, but support only some of the standard conversion specifiers and do
not support flags, precision, and field-width specifications. They support the following
new conversion specifiers in addition to those described on page 99.</p>
<blockquote>
<table BORDER="0" CELLPADDING="0" CELLSPACING="0">
<tr>
<td><strong>Specifiers</strong></td>
<td><img SRC="/~drh/resources/dot_clear.gif" ALT="|" WIDTH="24" HEIGHT="1"></td>
<td><strong>Corresponding printf Specifiers</strong></td>
</tr>
<tr>
<td><code>%c</code></td>
<td></td>
<td><code>%c</code></td>
</tr>
<tr>
<td><code>%d %D</code></td>
<td></td>
<td><code>%d %ld</code></td>
</tr>
<tr>
<td><code>%u %U</code></td>
<td></td>
<td><code>%u %lu</code></td>
</tr>
<tr>
<td><code>%x %X</code></td>
<td></td>
<td><code>%x %lx</code></td>
</tr>
<tr>
<td><code>%f %e %g</code></td>
<td></td>
<td><code>%e %f %g</code></td>
</tr>
<tr ALIGN="LEFT" VALIGN="TOP">
<td><code>%p</code></td>
<td></td>
<td>Converts the corresponding void * argument to unsigned long and prints it with the <code>printf</code>
<code>%#x</code> specifier or just <code>%x</code> when the argument is null.</td>
</tr>
<tr ALIGN="LEFT" VALIGN="TOP">
<td><code>%I</code></td>
<td></td>
<td>Prints the number of spaces given by the corresponding argument.</td>
</tr>
</table>
</blockquote>
<pre>#define generic(op) ((op)&amp;0x3F0)
#define specific(op) ((op)&amp;0x3FF)</pre>
<p><code>generic(op)</code> returns the generic variant of <code>op</code>; that is,
without its type suffix and size indicator. <code>specific(op)</code> returns the
type-specific variant of <code>op</code>; that is, without its size indicator.</p>
<p><code>newconst</code> has been replaced by</p>
<pre>extern Symbol intconst(int n);</pre>
<p>which installs the integer constant <code>n</code> in the symbol table, if necessary,
and returns a pointer to the symbol-table entry.</p>
<hr>
<address>
<a HREF="http://www.research.microsoft.com/~cwfraser/">Chris Fraser</a> / <a
HREF="mailto:cwfraser@microsoft.com">cwfraser@microsoft.com</a><br>
<a HREF="http://www.research.microsoft.com/~drh/">David Hanson</a> / <a
HREF="mailto:drh@microsoft.com">drh@microsoft.com</a><br>
$Revision: 145 $ $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $
</address>
</body>
</html>

View file

@ -0,0 +1,83 @@
.\" $Id: bprint.1 145 2001-10-17 21:53:10Z timo $
.TH BPRINT 1 "local \- $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $"
.SH NAME
bprint \- expression profiler
.SH SYNOPSIS
.B bprint
[
.I option ...
]
[
.I file ...
]
.SH DESCRIPTION
.I bprint
produces on the standard output a listing of the programs compiled by
.I lcc
with the
.B \-b
option.
Executing an
.B a.out
so compiled appends profiling data to
.BR prof.out .
The first token of each expression in the listing is preceded
by the number of times it was executed
enclosed in angle brackets as determined from the data in
.BR prof.out .
.I bprint
interprets the following options.
.TP
.B \-c
Compress the
.B prof.out
file, which otherwise grows with every execution of
.BR a.out .
.TP
.B \-b
Print an annotated listing as described above.
.TP
.B \-n
Include line numbers in the listing.
.TP
.B \-f
Print only the number of invocations of each function.
A second
.B \-f
summarizes call sites instead of callers.
.TP
.BI \-I \*Sdir
specifies additional directories in which to seek
files given in
.B prof.out
that do not begin with `/'.
.PP
If any file names are given, only the requested data for those files are printed
in the order presented.
If no options are given,
.B \-b
is assumed.
.SH FILES
.PP
.ta \w'$LCCDIR/liblcc.{a,lib}XX'u
.nf
prof.out profiling data
$LCCDIR/liblcc.{a,lib} \fIlcc\fP-specific library
.SH "SEE ALSO"
.IR lcc (1),
.IR prof (1)
.SH BUGS
Macros and comments can confuse
.I bprint
because it uses post-expansion source coordinates
to annotate pre-expansion source files.
If
.I bprint
sees that it's about to print a statement count
.I inside
a number or identifier, it moves the count to just
.I before
the token.
.PP
Can't cope with an ill-formed
.BR prof.out .

Binary file not shown.

View file

@ -0,0 +1,796 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<link HREF="mailto:drh@cs.princeton.edu" REV="made" TITLE="David R. Hanson">
<title>Installing lcc</title>
</head>
<body>
<h1>Installing lcc</h1>
<p ALIGN="LEFT"><strong><a HREF="http://www.research.microsoft.com/~cwfraser/">Christopher
W. Fraser</a> and <a HREF="http://www.research.microsoft.com/~drh/">David R. Hanson</a>, <a
HREF="http://www.research.microsoft.com/">Microsoft Research</a></strong></p>
<h2>Contents</h2>
<dir>
<li><a HREF="#intro">Introduction</a></li>
<li><a HREF="#unix">Installation on UNIX</a></li>
<li><a HREF="#driver">Building the Driver</a></li>
<li><a HREF="#rcc">Building the Compiler and Accessories</a></li>
<li><a HREF="#win32">Installation on Windows NT 4.0 and Windows 95/98</a></li>
<li><a HREF="#bugs">Reporting Bugs</a></li>
<li><a HREF="#mailinglist">Keeping in Touch</a></li>
</dir>
<h2><a NAME="intro">Introduction</a></h2>
<p><a HREF="http://www.cs.princeton.edu/software/lcc/">lcc</a> is the ANSI C compiler
described in our book <cite>A Retargetable C Compiler: Design and Implementation</cite>
(Addison-Wesley, 1995, ISBN 0-8053-1670-1).</p>
<p>If you're installing lcc on a UNIX system, read the remainder of this section and
continue with the next section. If you're installing lcc on a Windows NT 4.0 or Windows
95/98 system, and you intend only to <u>use</u> lcc, you can run the <a
href="ftp://ftp.cs.princeton.edu/pub/packages/lcc/lcc41.exe">InstallShield executable</a>,
which installs the binaries and the documentation. If you want to <u>modify</u> lcc or <u>rebuild</u>
it from the source files, you need the <a
href="ftp://ftp.cs.princeton.edu/packages/lcc/lcc41.zip">complete distribution</a>, and
you should read the rest of the section, the following three sections, and the <a
HREF="#win32">Windows NT/95/98</a> section.</p>
<p>Extract the distribution into its own directory. All non-absolute paths below are
relative to this directory. The distribution holds the following subdirectories.</p>
<blockquote>
<table BORDER="0" CELLPADDING="1" CELLSPACING="1" WIDTH="80%">
<tr>
<td><a HREF="../src"><code>src</code></a></td>
<td></td>
<td>source code</td>
</tr>
<tr>
<td><a HREF="../etc"><code>etc</code></a></td>
<td></td>
<td>driver, accessories</td>
</tr>
<tr>
<td><a HREF="../lib"><code>lib</code></a></td>
<td></td>
<td>runtime library source code</td>
</tr>
<tr>
<td><a HREF="../cpp"><code>cpp</code></a></td>
<td></td>
<td>preprocessor source code</td>
</tr>
<tr>
<td><a HREF="../lburg"><code>lburg</code></a></td>
<td></td>
<td>code-generator generator source code</td>
</tr>
<tr>
<td><a HREF="../doc"><code>doc</code></a></td>
<td></td>
<td>this document, man pages</td>
</tr>
<tr>
<td><code><a HREF="../include">include</a>/*/*</code></td>
<td></td>
<td>include files</td>
</tr>
<tr>
<td><a HREF="../tst"><code>tst</code></a></td>
<td></td>
<td>test suite</td>
</tr>
<tr>
<td><code><a HREF="../alpha">alpha</a>/*/tst</code></td>
<td></td>
<td>ALPHA test outputs</td>
</tr>
<tr>
<td><code><a HREF="../mips">mips</a>/*/tst</code></td>
<td></td>
<td>MIPS test outputs</td>
</tr>
<tr>
<td><code><a HREF="../sparc">sparc</a>/*/tst</code></td>
<td></td>
<td>SPARC test outputs</td>
</tr>
<tr>
<td><code><a HREF="../x86">x86</a>/*/tst</code></td>
<td></td>
<td>X86 test outputs</td>
</tr>
</table>
</blockquote>
<p><code>doc/install.html</code> is the HTML file for this document. <a HREF="4.html"><code>doc/4.html</code></a>
describes the internal differences between lcc 3.x and 4.1.</p>
<p>The installation makefile is designed so that lcc can be installed from a read-only
file system or directory, which is common in networked environments, so the distribution
can be unloaded on a central file server. <strong>You will need an existing ANSI/ISO C
compiler to build and install lcc.</strong></p>
<h2><a NAME="unix">Installation on UNIX</a></h2>
<p>The compilation components (the preprocessor, include files, and compiler proper, etc.)
are installed in a single <em>build directory</em>. On multi-platform systems supported by
a central file server, it's common to store the build directory in a location specific to
the platform and to the version of lcc, and to point a symbolic link to this location. For
example,</p>
<blockquote>
<pre>% ln -s /usr/local/lib/lcc-4.1/sparc-solaris /usr/local/lib/lcc</pre>
</blockquote>
<p>points <code>/usr/local/lib/lcc</code> to a build directory for lcc version 4.1 on the
SPARC under Solaris. Links into <code>/usr/local/lib</code> are created for the programs <code>lcc</code>
and <code>bprint</code>. Thus, a new distribution can be installed by building it in its
own build directory and changing one symbolic link to point to that directory. If these
conventions or their equivalents are followed, the host-specific parts of the driver
program, <code>lcc</code>, can be used unmodified.</p>
<p>Installation on a UNIX system involves the following steps. Below, the build directory
is referred to as <code>BUILDDIR</code>.
<ol>
<li>Create the build directory, using a version- and platform-specific naming convention as
suggested above, and record the name of this directory in the <code>BUILDDIR</code>
environment variable:<blockquote>
<pre>% setenv BUILDDIR /usr/local/lib/lcc-4.1/sparc-solaris
% mkdir -p $BUILDDIR</pre>
</blockquote>
<p>Here and below, commands assume the C shell. Also, you'll need a version of <code>mkdir</code>
that supports the <code>-p</code> option, which creates intermediate directories as
necessary.</p>
</li>
<li>Copy the man pages to the repository for local man pages, e.g.,<blockquote>
<pre>% cp doc/*.1 /usr/local/man/man1</pre>
</blockquote>
<p>Some users copy the man pages to the build directory and create the appropriate
symbolic links, e.g., </p>
<blockquote>
<pre>% cp doc/*.1 $BUILDDIR
% ln -s $BUILDDIR/*.1 /usr/local/man/man1</pre>
</blockquote>
</li>
<li>Platform-specific include files are in directories named <code>include/</code><em>target</em><code>/</code><em>os</em>.
Create the include directory in the build directory, and copy the include hierarchy for
your platform to this directory, e.g.,<blockquote>
<pre>% mkdir $BUILDDIR/include
% cp -p -R include/sparc/solaris/* $BUILDDIR/include</pre>
</blockquote>
<p>Again, some users create a symbolic link to the appropriate directory in the
distribution instead of copying the include files. For example, at Princeton, the
distributions are stored under <code>/proj/pkg/lcc</code>, so the included files are
&quot;installed&quot; by creating one symbolic link: </p>
<blockquote>
<pre>% ln -s /proj/pkg/lcc/4.1/include/sparc/solaris $BUILDDIR/include</pre>
</blockquote>
<p>If you're installing lcc on Linux, you <em>must</em> also plant a symbolic link named <code>gcc</code>
to gcc's library directory, because lcc uses gcc's C preprocessor and most of gcc's header
files:</p>
<blockquote>
<pre>% ln -s /usr/lib/gcc-lib/i486-linux/2.7.2.2 $BUILDDIR/gcc</pre>
</blockquote>
<p>The library directory shown above may be different on your Linux machine; to determine
the correct directory, browse <code>/usr/lib/gcc-lib</code>, or execute</p>
<blockquote>
<pre>% cc -v tst/8q.c</pre>
</blockquote>
<p>and examine the diagnostic output. Make sure that <code>$BUILDDIR/gcc/cpp</code> and <code>$BUILDDIR/gcc/include</code>
point to, respectively, gcc's C preprocessor and header files. On Linux, lcc looks for
include files in <code>$BUILDDIR/include</code>, <code>$BUILDDIR/gcc/include</code>, and <code>/usr/include</code>,
in that order; see <a HREF="#driver"><em>Building the Driver</em></a> and <a
href="../etc/linux.c"><code>etc/linux.c</code></a> for details.</p>
</li>
<li>The <a HREF="../makefile"><code>makefile</code></a> includes the file named by the <code>CUSTOM</code>
macro; the default is <code>custom.mk</code>, and an empty <code>custom.mk</code> is
included in the distribution. If desired, prepare a site-specification customization file
and define <code>CUSTOM</code> to the path of that file when invoking make in steps 5 and
6, e.g.,<blockquote>
<pre>make CUSTOM=/users/drh/solaris.mk</pre>
</blockquote>
<p>You can, for example, use customization files to record site-specific values for macros
instead of using environment variables, and to record targets for the steps in this list.</p>
</li>
<li>Build the host-specific driver, creating a custom host-specific part, if necessary. See <a
HREF="#driver"><em>Building the Driver</em></a>.</li>
<li>Build the preprocessor, compiler proper, library, and other accessories. See <a
HREF="#rcc"><em>Building the Compiler</em></a>.</li>
<li>Plant symbolic links to the build directory and to the installed programs, e.g.,<blockquote>
<pre>% ln -s $BUILDDIR /usr/local/lib/lcc
% ln -s /usr/local/lib/{lcc,bprint} /usr/local/bin</pre>
</blockquote>
<p>Some users copy <code>bprint</code> and <code>lcc</code> into <code>/usr/local/bin</code>
instead of creating symbolic links. The advantange of creating the links for <code>lcc</code>
and <code>bprint</code> as shown is that, once established, they point indirectly to
whatever <code>/usr/local/lib/lcc</code> points to; installing a new version of lcc, say,
4.2, can be done by changing <code>/usr/local/lib/lcc</code> to point to the 4.2 build
directory.</p>
</li>
</ol>
<h2><a NAME="driver">Building the Driver</a></h2>
<p>The preprocessor, compiler, assembler, and loader are invoked by a driver program, <code>lcc</code>,
which is similar to <code>cc</code> on most systems. It's described in the man page <code>doc/lcc.1</code>.
The driver is built by combining the host-independent part, <a href="../etc/lcc.c"><code>etc/lcc.c</code></a>,
with a small host-specific part. Distributed host-specific parts are named <code>etc/</code><em>os</em><code>.c</code>,
where <em>os</em> is the name of the operating system for the host on which <code>lcc</code>
is being installed. If you're following the installations conventions described above, you
can probably use one of the host-specific parts unmodified; otherwise, pick one that is
closely related to your platform, copy it to <em>whatever</em><code>.c</code>, and edit it
as described below. You should not have to edit <code>etc/lcc.c</code>.</p>
<p>We'll use <a HREF="../etc/solaris.c"><code>etc/solaris.c</code></a> as an example in
describing how the host-specific part works. This example illustrates all the important
features. Make sure you have the environment variable <code>BUILDDIR</code> set correctly,
and build the driver with a <code>make</code> command, e.g.,</p>
<blockquote>
<pre>% make HOSTFILE=etc/solaris.c lcc
cc -g -c -DTEMPDIR=\&quot;/tmp\&quot; -o /usr/local/lib/lcc-4.1/sparc-solaris/lcc.o etc/lcc.c
cc -g -c -o /usr/local/lib/lcc-4.1/sparc-solaris/host.o etc/solaris.c
cc -g -o /usr/local/lib/lcc-4.1/sparc-solaris/lcc /usr/local/lib/lcc-4.1/sparc-solaris/lcc.o /usr/local/lib/lcc-4.1/sparc-solaris/host.o</pre>
</blockquote>
<p>The symbolic name <code>HOSTFILE</code> specifies the path to the host-specific part,
either one in the distribution or <em>whatever</em><code>.c</code>. Some versions of make
may require the <code>-e</code> option in order to read the environment.</p>
<p>Here's <code>etc/solaris.c</code>:</p>
<blockquote>
<pre>/* Sparcs running Solaris 2.5.1 at CS Dept., Princeton University */
#include &lt;string.h&gt;
static char rcsid[] = &quot;$ Id: solaris.c,v 1.10 1998/09/14 20:36:33 drh Exp $&quot;;
#ifndef LCCDIR
#define LCCDIR &quot;/usr/local/lib/lcc/&quot;
#endif
#ifndef SUNDIR
#define SUNDIR &quot;/opt/SUNWspro/SC4.2/lib/&quot;
#endif
char *suffixes[] = { &quot;.c&quot;, &quot;.i&quot;, &quot;.s&quot;, &quot;.o&quot;, &quot;.out&quot;, 0 };
char inputs[256] = &quot;&quot;;
char *cpp[] = { LCCDIR &quot;cpp&quot;,
&quot;-D__STDC__=1&quot;, &quot;-Dsparc&quot;, &quot;-D__sparc__&quot;, &quot;-Dsun&quot;, &quot;-D__sun__&quot;, &quot;-Dunix&quot;,
&quot;$1&quot;, &quot;$2&quot;, &quot;$3&quot;, 0 };
char *include[] = { &quot;-I&quot; LCCDIR &quot;include&quot;, &quot;-I/usr/local/include&quot;,
&quot;-I/usr/include&quot;, 0 };
char *com[] = { LCCDIR &quot;rcc&quot;, &quot;-target=sparc/solaris&quot;,
&quot;$1&quot;, &quot;$2&quot;, &quot;$3&quot;, 0 };
char *as[] = { &quot;/usr/ccs/bin/as&quot;, &quot;-Qy&quot;, &quot;-s&quot;, &quot;-o&quot;, &quot;$3&quot;, &quot;$1&quot;, &quot;$2&quot;, 0 };
char *ld[] = { &quot;/usr/ccs/bin/ld&quot;, &quot;-o&quot;, &quot;$3&quot;, &quot;$1&quot;,
SUNDIR &quot;crti.o&quot;, SUNDIR &quot;crt1.o&quot;,
SUNDIR &quot;values-xa.o&quot;, &quot;$2&quot;, &quot;&quot;,
&quot;-Y&quot;, &quot;P,&quot; SUNDIR &quot;:/usr/ccs/lib:/usr/lib&quot;, &quot;-Qy&quot;,
&quot;-L&quot; LCCDIR, &quot;-llcc&quot;, &quot;-lm&quot;, &quot;-lc&quot;, SUNDIR &quot;crtn.o&quot;, 0 };
extern char *concat(char *, char *);
int option(char *arg) {
if (strncmp(arg, &quot;-lccdir=&quot;, 8) == 0) {
cpp[0] = concat(&amp;arg[8], &quot;/cpp&quot;);
include[0] = concat(&quot;-I&quot;, concat(&amp;arg[8], &quot;/include&quot;));
ld[12] = concat(&quot;-L&quot;, &amp;arg[8]);
com[0] = concat(&amp;arg[8], &quot;/rcc&quot;);
} else if (strcmp(arg, &quot;-p&quot;) == 0) {
ld[5] = SUNDIR &quot;mcrt1.o&quot;;
ld[10] = &quot;P,&quot; SUNDIR &quot;libp:/usr/ccs/lib/libp:/usr/lib/libp:&quot;
SUNDIR &quot;:/usr/ccs/lib:/usr/lib&quot;;
} else if (strcmp(arg, &quot;-b&quot;) == 0)
;
else if (strncmp(arg, &quot;-ld=&quot;, 4) == 0)
ld[0] = &amp;arg[4];
else
return 0;
return 1;
}</pre>
</blockquote>
<p><code>LCCDIR</code> defaults to <code>&quot;/usr/local/lib/lcc/&quot;</code> unless
it's defined by a <code>-D</code> option as part of <code>CFLAGS</code> in the make
command, e.g.,</p>
<blockquote>
<pre>% make HOSTFILE=etc/solaris.c CFLAGS='-DLCCDIR=\&quot;/v/lib/lcc/\&quot;' lcc</pre>
</blockquote>
<p>Note the trailing slash; <code>SUNDIR</code> is provided so you can use <code>etc/solaris.c</code>
even if you have a different version of the Sun Pro compiler suite. If you're using the
gcc compiler tools instead of the Sun Pro tools, see <a HREF="../etc/gcc-solaris.c"><code>etc/gcc-solaris.c</code></a>.</p>
<p>Most of the host-specific code is platform-specific data and templates for the commands
that invoke the preprocessor, compiler, assembler, and loader. The <code>suffixes</code>
array lists the file name suffixes for C source files, preprocessed source files, assembly
language source files, object files, and executable files. <code>suffixes</code> must be
terminated with a null pointer, as shown above. The initialization of <code>suffixes</code>
in <code><a HREF="../etc/solaris.c">etc/solaris.c</a></code> are the typical ones for UNIX
systems. Each element of <code>suffixes</code> is actually a list of suffixes, separated
by semicolons; <code><a HREF="../etc/win32.c">etc/win32.c</a></code> holds an example:</p>
<blockquote>
<pre>char *suffixes[] = { &quot;.c;.C&quot;, &quot;.i;.I&quot;, &quot;.asm;.ASM;.s;.S&quot;, &quot;.obj;.OBJ&quot;, &quot;.exe&quot;, 0 };</pre>
</blockquote>
<p>When a list is given, the first suffix is used whenever lcc needs to generate a file
name. For example, with <code><a HREF="../etc/win32.c">etc/win32.c</a></code>, lcc emits
the generated assembly code into <code>.asm</code> files.</p>
<p>The <code>inputs</code> array holds a null-terminated string of directories separated
by colons or semicolons. These are used as the default value of <code>LCCINPUTS</code>, if
the environment variable <code>LCCINPUTS</code> is not set; see the <a HREF="lcc.pdf">man
page</a>.</p>
<p>Each command template is an array of pointers to strings terminated with a null
pointer; the strings are full path names of commands, arguments, or argument placeholders,
which are described below. Commands are executed in a child process, and templates can
contain multiple commands by separating commands with newlines. The driver runs each
command in a new process.</p>
<p>The <code>cpp</code> array gives the command for running lcc's preprocessor, <code>cpp</code>.
Literal arguments specified in templates, e.g., <code>&quot;-Dsparc&quot;</code> in the <code>cpp</code>
command above, are passed to the command as given.</p>
<p>The strings <code>&quot;$1&quot;</code>, <code>&quot;$2&quot;</code>, and <code>&quot;$3&quot;</code>
in templates are placeholders for <em>lists</em> of arguments that are substituted in a
copy of the template before the command is executed. <code>$1</code> is replaced by the <em>options</em>
specified by the user; for the preprocessor, this list always contains at least <code>-D__LCC__</code>.
<code>$2</code> is replaced by the <em>input</em> files, and <code>$3</code> is replaced
by the <em>output</em> file.</p>
<p>Zero-length arguments after replacement are removed from the argument list before the
command is invoked. So, for example, if the preprocessor is invoked without an output
file, <code>&quot;$3&quot;</code> becomes <code>&quot;&quot;</code>, which is removed from
the final argument list.</p>
<p>The <code>include</code> array is a list of <code>-I</code> options that specify which
directives should be searched to satisfy include directives. These directories are
searched in the order given. The first directory should be the one to which the ANSI
header files were copied as described in <a HREF="#unix">UNIX</a> or <a HREF="#win32">Windows</a>
installation instructions. The driver adds these options to <code>cpp</code>'s arguments
when it invokes the preprocessor, except when <code>-N</code> is specified.</p>
<p><code>com</code> gives the command for invoking the compiler. This template can appear
as shown above in a custom host-specific part, but the option <code>-target=sparc/solaris</code>
should be edited to the <em>target</em><code>/</code><em>os</em> for your platform. If <code>com[1]</code>
includes the string &quot;<code>win32</code>&quot;, the driver assumes it's running on
Windows. lcc can generate code for <em>all</em> of the <em>target</em><code>/</code><em>os</em>
combinations listed in the file <code>src/bind.c</code>. The <code>-target</code> option
specifies the default combination. The driver's <code>-Wf</code> option can be used to
specify other combinations; the <a HREF="lcc.pdf">man page</a> elaborates.</p>
<p><code>as</code> gives the command for invoking the assembler. On Linux, you must be
running at least version 2.8.1 of the GNU assembler; earlier versions mis-assemble some
instructions emitted by lcc.</p>
<p><code>ld</code> gives the command for invoking the loader. For the other commands, the
list <code>$2</code> contains a single file; for <code>ld</code>, <code>$2</code> contains
all &quot;.o&quot; files and libraries, and <code>$3</code> is <code>a.out</code>, unless
the <code>-o</code> option is specified. As suggested in the code above, <code>ld</code>
must also specify the appropriate startup code and default libraries, including the lcc
library, <code>liblcc.a</code>.</p>
<p>The <code>option</code> function is described below; the minimal <code>option</code>
function just returns 0.</p>
<p>You can test <code>lcc</code> with the options <code>-v -v</code> to display the
commands that would be executed, e.g.,</p>
<blockquote>
<pre>% $BUILDDIR/lcc -v -v foo.c baz.c mylib.a -lX11
/usr/local/lib/lcc-4.1/lcc $ Id: solaris.c,v 1.10 1998/09/14 20:36:33 drh Exp $
foo.c:
/usr/local/lib/lcc/cpp -D__STDC__=1 -Dsparc -D__sparc__ -Dsun -D__sun__ -Dunix -D__LCC__ -I/usr/local/lib/lcc/include -I/usr/local/include -I/usr/include foo.c /tmp/lcc266290.i
/usr/local/lib/lcc/rcc -target=sparc/solaris -v /tmp/lcc266290.i /tmp/lcc266291.
s
/usr/ccs/bin/as -Qy -s -o /tmp/lcc266292.o /tmp/lcc266291.s
baz.c:
/usr/local/lib/lcc/cpp -D__STDC__=1 -Dsparc -D__sparc__ -Dsun -D__sun__ -Dunix -D__LCC__ -I/usr/local/lib/lcc/include -I/usr/local/include -I/usr/include baz.c /tmp/lcc266290.i
/usr/local/lib/lcc/rcc -target=sparc/solaris -v /tmp/lcc266290.i /tmp/lcc266291.s
/usr/ccs/bin/as -Qy -s -o /tmp/lcc266293.o /tmp/lcc266291.s
/usr/ccs/bin/ld -o a.out /opt/SUNWspro/SC4.2/lib/crti.o /opt/SUNWspro/SC4.2/lib/crt1.o /opt/SUNWspro/SC4.2/lib/values-xa.o /tmp/lcc266292.o /tmp/lcc266293.o mylib.a -lX11 -Y P,/opt/SUNWspro/SC4.2/lib/:/usr/ccs/lib:/usr/lib -Qy -L/usr/local/lib/lcc/ -llcc -lm -lc /opt/SUNWspro/SC4.2/lib/crtn.o
rm /tmp/lcc266293.o /tmp/lcc266290.i /tmp/lcc266291.s /tmp/lcc266292.o</pre>
</blockquote>
<p>As the output shows, <code>lcc</code> places temporary files in <code>/tmp</code>; if
any of the environment variables <code>TMP</code>, <code>TEMP</code>, and <code>TMPDIR</code>
are set, they override this default (in the order shown) as does the <code>-tempdir=</code><em>dir</em>
option. The default can be changed by defining <code>TEMPDIR</code> in <code>CFLAGS</code>
when building the driver.</p>
<p>The <code>option</code> function is called for the options <code>-Wo</code>, <code>-g</code>,
<code>-p</code>, <code>-pg</code>, and <code>-b</code> because these compiler options
might also affect the loader's arguments. For these options, the driver calls <code>option(arg)</code>
to give the host-specific code an opportunity to edit the <code>ld</code> command, if
necessary. <code>option</code> can change <code>ld</code>, if necessary, and return 1 to
announce its acceptance of the option. If the option is unsupported, <code>option</code>
should return 0.</p>
<p>For example, in response to <code>-g</code>, the <code>option</code> function shown
above accepts the option but does nothing else, because the <code>ld</code> and <code>as</code>
commands don't need to be modified on the SPARC. <code>-g</code> will also be added to the
compiler's options by the host-independent part of the driver. The <code>-p</code> causes <code>option</code>
to change the name of the startup code and changed the list of libraries. The <code>-b</code>
option turns on <code>lcc</code>'s per-expression profiling, the code for which is in <code>liblcc.a</code>,
so <code>option</code> need no nothing.</p>
<p>On SPARCs, the driver also recognizes <code>-Bstatic</code> and <code>-Bdynamic</code>
as linker options. The driver recognizes but ignores &quot;<code>-target</code> <em>name</em>&quot;
option.</p>
<p>The option <code>-Wo</code><em>arg</em> causes the driver to pass <em>arg</em> to <code>option</code>.
Such options have no other effect; this mechanism is provided to support system-specific
options that affect the commands executed by the driver. As illustrated above,
host-specific parts should support the <code>-Wo-lccdir=</code><em>dir</em> option, which
causes lcc's compilation components to be found in <em>dir</em>, because this option is
used by the test scripts, and because the driver simulates a <code>-Wo-lccdir</code>
option with the value of the environment variable <code>LCCDIR</code>, if it's defined.
The code above rebuilds the paths to the include files, preprocessor, compiler, and
library by calling <code>concat</code>, which is defined in <code>etc/lcc.c</code>.</p>
<h2><a NAME="rcc">Building the Compiler and Accessories</a></h2>
<p>To build the rest of compilation components make sure <code>BUILDDIR</code> is set
appropriately and type &quot;<code>make all</code>&quot;. This command builds <code>librcc.a</code>
(the compiler's private library), <code>rcc</code> (the compiler proper), <code>lburg</code>
(the code-generator generator), <code>cpp</code> (the preprocessor), <code>liblcc.a</code>
(the runtime library), and <code>bprint</code> (the profile printer), all in <code>BUILDDIR</code>.
There may be warnings, but there should be no errors. If you're using an ANSI/ISO compiler
other than <code>cc</code>, specify its name with the <code>CC=</code> option, e.g.,
&quot;<code>make CC=gcc all</code>&quot;. If you're running on a DEC ALPHA, use &quot;<code>make
CC='cc -std1' all</code>&quot;; the <code>-std1</code> option is essential on the ALPHA.
If you're on a DEC 5000 running Ultrix 4.3, use &quot;<code>make CC=c89 all</code>&quot;.</p>
<p>Once <code>rcc</code> is built with the host C compiler, run the test suite to verify
that <code>rcc</code> is working correctly. If any of the steps below fail, contact us
(see <a HREF="#bugs"><em>Reporting Bugs</em></a>). The commands in the makefile run the
shell script <code>src/run.sh</code> on each C program in the test suite, <code>tst/*.c</code>.
It uses the driver, <code>$BUILDDIR/lcc</code>, so you must have the driver in the build
directory before testing <code>rcc</code>. The <em>target</em><code>/</code><em>os</em>
combination is read from the variable <code>TARGET</code>, which must be specified when
invoking <code>make</code>:</p>
<blockquote>
<pre>% make TARGET=sparc/solaris test
mkdir -p /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/8q.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/array.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/cf.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/cq.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/cvt.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/fields.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/front.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/incr.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/init.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/limits.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/paranoia.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/sort.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/spill.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/stdarg.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/struct.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/switch.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/wf1.s:
/usr/local/lib/lcc-4.1/sparc-solaris/rcc -target=sparc/solaris /usr/local/lib/lcc-4.1/sparc-solaris/sparc/solaris/tst/yacc.s:</pre>
</blockquote>
<p>Each line in the output above is of the form</p>
<blockquote>
<p><code>$BUILDDIR/rcc -target=</code><em>target</em><code>/</code><em>os</em><code>$BUILDDIR/</code><em>target</em><code>/</code><em>os</em><code>/</code><em>X</em><code>.s:</code></p>
</blockquote>
<p>where <em>X</em> is the base name of the C program <em>X</em><code>.c</code> in the
test suite. This output identifies the compiler and the target, e.g., &quot;<code>$BUILDDIR/rcc</code>
is generating code for a <code>sparc</code> running the <code>solaris</code> operating
system.&quot;</p>
<p>For each program in the test suite, <code>src/run.sh</code> compiles the program, drops
the generated assembly language code in <code>BUILDDIR</code>/<em>target</em><code>/</code><em>os</em>,
and uses <code>diff</code> to compare the generated assembly code with the expected code
(the code expected for <code>tst/8q.c</code> on the SPARC under Solaris is in <code>sparc/solaris/tst/8q.sbk</code>,
etc.). If there are differences, the script executes the generated code with the input
given in <code>tst</code> (the input for <code>tst/8q.c</code> is in <code>tst/8q.0</code>,
etc.) and compares the output with the expected output (the expected output from <code>tst/8q.c</code>
on the SPARC under Solaris is in <code>sparc/solaris/tst/8q.1bk</code>, etc.). The script
also compares the diagnostics from the compiler with the expected diagnostics.</p>
<p>On some systems, there may be a few differences between the generated code and the
expected code. These differences occur because the expected code is generated by cross
compilation and the least significant bits of some floating-point constants differ from
those bits in constants generated on your system. On Linux, there may be differences
because of differences in the header files between our system and yours. There should be
no differences in the output from executing the test programs.</p>
<p>Next, run the &quot;triple test&quot;, which builds <code>rcc</code> using itself:</p>
<blockquote>
<pre>% make triple
/usr/local/lib/lcc-4.1/sparc-solaris/lcc -o /usr/local/lib/lcc-4.1/sparc-solaris/1rcc -d0.6 -Wo-lccdir=/usr/local/lib/lcc-4.1/sparc-solaris -B/usr/local/lib/lcc-4.1/sparc-solaris/ -Isrc src/*.c
src/alloc.c:
...
src/x86.c:
/usr/local/lib/lcc-4.1/sparc-solaris/lcc -o /usr/local/lib/lcc-4.1/sparc-solaris/1rcc -d0.6 -Wo-lccdir=/usr/local/lib/lcc-4.1/sparc-solaris -B/usr/local/lib/lcc-4.1/sparc-solaris/ -Isrc src/*.c
src/alloc.c:
...
src/x86.c:
strip /usr/local/lib/lcc-4.1/sparc-solaris/[12]rcc
dd if=/usr/local/lib/lcc-4.1/sparc-solaris/1rcc of=/usr/local/lib/lcc-4.1/sparc-solaris/rcc1 bs=512 skip=1
769+1 records in
769+1 records out
dd if=/usr/local/lib/lcc-4.1/sparc-solaris/2rcc of=/usr/local/lib/lcc-4.1/sparc-solaris/rcc2 bs=512 skip=1
769+1 records in
769+1 records out
if cmp /usr/local/lib/lcc-4.1/sparc-solaris/rcc[12]; then \
mv /usr/local/lib/lcc-4.1/sparc-solaris/2rcc /usr/local/lib/lcc-4.1/sparc-solaris/rcc; \
rm -f /usr/local/lib/lcc-4.1/sparc-solaris/1rcc /usr/local/lib/lcc-4.1/sparc-solaris/rcc[12]; fi</pre>
</blockquote>
<p>This command builds <code>rcc</code> twice; once using the <code>rcc</code> built by <code>cc</code>
and again using the <code>rcc</code> built by <code>lcc</code>. The resulting binaries are
compared. They should be identical, as shown at the end of the output above. If they
aren't, our compiler is generating incorrect code; <a HREF="#bugs">contact</a> us.</p>
<p>The final version of <code>rcc</code> should also pass the test suite; that is, the
output from</p>
<blockquote>
<pre>% make TARGET=sparc/solaris test</pre>
</blockquote>
<p>should be identical to that from the previous <code>make test</code>.</p>
<p>The command &quot;<code>make clean</code>&quot; cleans up, but does not remove <code>rcc</code>,
etc., and &quot;<code>make clobber</code>&quot; cleans up and removes <code>lcc</code>, <code>rcc</code>,
and the other accessories. Test directories under <code>BUILDDIR</code> are <em>not</em>
removed; you'll need to remove these by hand, e.g.,</p>
<blockquote>
<pre>% rm -fr $BUILDDIR/sparc</pre>
</blockquote>
<p>The code generators for the other targets can be tested by specifying the desired <em>target</em><code>/</code><em>os</em>
and setting an environment variable that controls what <code>src/run.sh</code> does. For
example, to test the MIPS code generator, type</p>
<blockquote>
<pre>% setenv REMOTEHOST noexecute
% make TARGET=mips/irix test</pre>
</blockquote>
<p>As above, <code>src/run.sh</code> compares the MIPS code generated with what's
expected. There should be no differences. Setting <code>REMOTEHOST</code> to <code>noexecute</code>
suppresses the assembly and execution of the generated code. If you set <code>REMOTEHOST</code>
to the name of a MIPS machine to which you can <code>rlogin</code>, <code>src/run.sh</code>
will <code>rcp</code> the generated code to that machine and execute it there, if
necessary. See <code>src/run.sh</code> for the details.</p>
<p>You can use lcc as a cross compiler. The options <code>-S</code> and <code>-Wf-target=</code><em>target/os</em>
generate assembly code for the specified target, which is any of those listed in the file <code>src/bind.c</code>.
For example, </p>
<blockquote>
<pre>% lcc -Wf-target=mips/irix -S tst/8q.c</pre>
</blockquote>
<p>generates MIPS code for <code>tst/8q.c</code> in <code>8q.s</code>.</p>
<p>lcc can also generate code for a &quot;symbolic&quot; target. This target is used
routinely in front-end development, and its output is a printable representation of the
input program, e.g., the dags constructed by the front end are printed, and other
interface functions print their arguments. You can specify this target with the option <code>-Wf-target=symbolic</code>.
For example,</p>
<blockquote>
<pre>% lcc -Wf-target=symbolic -S tst/8q.c</pre>
</blockquote>
<p>generates symbolic output for <code>tst/8q.c</code> in <code>8q.s</code>. Adding <code>-Wf-html</code>
causes the symbolic target to emit HTML instead of plain text. Finally, the option <code>-Wf-target=null</code>
specifies the &quot;null&quot; target for which lcc emits nothing and thus only checks the
syntax and semantics of its input files.</p>
<h2><a NAME="win32">Installation on Windows NT 4.0 or Windows 95/98</a></h2>
<p>On Windows NT 4.0 and Windows 95/98, lcc is designed to work with Microsoft's Visual
C++ 5.0 (VC) and Microsoft's Assembler, MASM 6.11d. It uses the VC header files,
libraries, and command-line tools, and it uses MASM to assemble the code it generates. If
you have MASM 6.11, make sure you <a
HREF="http://support.microsoft.com/support/kb/articles/Q138/9/83.asp">upgrade to 6.11d</a>,
because earlier 6.11 releases do not generate correct COFF object files.</p>
<p>Building the distribution components from the ground up requires Microsoft's Visual
C/C++ 5.0 compiler, Microsoft's make, <code>nmake</code>, and the standard Windows command
interpreter. <a HREF="../makefile.nt"><code>makefile.nt</code></a> is written to use only <code>nmake</code>.
As on UNIX systems, the compilation components are installed in a single <em>build
directory</em>, and the top-level programs, <code>lcc.exe</code> and <code>bprint.exe</code>,
are installed in a directory on the PATH. If the conventions used below are followed, the
Windows-specific parts of the driver program, <code>lcc.exe</code>, can be used
unmodified.</p>
<p>Building from the source distribution on a Windows system involves the following steps.
Below, the build directory is referred to as <code>BUILDDIR</code>, and the distribution
is in <code>\dist\lcc\4.1</code>.
<ol>
<li>Create the build directory, perhaps using a version- and platform-specific naming
convention as suggested in <a HREF="#unix"><em>Installation on UNIX</em></a>, and record
the name of this directory in the <code>BUILDDIR</code> environment variable:<blockquote>
<pre>C:\dist\lcc\4.1&gt;set BUILDDIR=\progra~1\lcc\4.1\bin
C:\dist\lcc\4.1&gt;mkdir %BUILDDIR%</pre>
</blockquote>
<p>The default build, or installation, directory is <code>\Program Files\lcc\4.1\bin</code>,
but the <code>nmake</code> commands require that you use the corresponding 8.3 file name, <code>progra~1</code>,
instead of <code>Program Files</code>.</p>
</li>
<li><a HREF="../etc/win32.c"><code>etc\win32.c</code></a> is the Windows-specific part of
the driver. It assumes that environment variable <code>include</code> gives the locations
of the VC header files and that the linker (<code>link.exe</code>) and the assembler (<code>ml.exe</code>)
are on the PATH. It also assumes that the macro <code>LCCDIR</code> gives the build
directory. If necessary, revise a copy of <a HREF="../etc/win32.c"><code>etc\win32.c</code></a>
to reflect the conventions on your computer (see <a HREF="#driver"><em>Building the Driver</em></a>),
then build the driver, specifying the default temporary directory, if necessary:<blockquote>
<pre>C:\dist\lcc\4.1&gt;nmake -f makefile.nt TEMPDIR=\\temp HOSTFILE=etc/win32.c lcc
...
cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -c -DTEMPDIR=\&quot;\\temp\&quot; -Fo\progra~1\lcc\4.1\bin\lcc.obj etc/lcc.c
lcc.c
cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -c -Fo\progra~1\lcc\4.1\bin\host.obj etc/win32.c
win32.c
cl -nologo -Zi -MLd -Fd\progra~1\lcc\4.1\bin\ -Fe\progra~1\lcc\4.1\bin\lcc.exe \progra~1\lcc\4.1\bin\lcc.obj \progra~1\lcc\4.1\bin\host.obj</pre>
</blockquote>
<p>If you make a copy of <code>etc\win32.c</code>, specify the path of the copy as the
value of <code>HOSTFILE</code>. For example, if you copy <code>etc\win32.c</code> to <code>BUILDDIR</code>
and edit it, use the command</p>
<blockquote>
<pre>C:\dist\lcc\4.1&gt;nmake -f makefile.nt TEMPDIR=\\temp HOSTFILE=%BUILDDIR%\win32.c lcc</pre>
</blockquote>
</li>
<li>Build the preprocessor, compiler proper, library, and other accessories (see <a
HREF="#rcc"><em>Building the Compiler</em></a>):<blockquote>
<pre>C:\dist\lcc\4.1&gt;nmake -f makefile.nt all</pre>
</blockquote>
<p>This command uses the VC command-line tools <code>cl</code> and <code>lib</code> to
build <code>bprint.exe</code>, <code>cpp.exe</code>, <code>lburg.exe</code>, <code>liblcc.lib</code>,
<code>librcc.lib</code>, and <code>rcc.exe</code>, all in <code>BUILDDIR</code>. There may
be some warnings, but there should be no warnings.</p>
</li>
<li>Create a test directory and run the test suite:<blockquote>
<pre>C:\dist\lcc\4.1&gt;mkdir %BUILDDIR%\x86\win32\tst
C:\dist\lcc\4.1&gt;nmake -f makefile.nt test</pre>
</blockquote>
<p>This command compiles each program in <a HREF="../tst">tst</a>, compares the generated
assembly code and diagnostics with the expected assembly code and diagnostics, executes
the program, and compares the output with the expected output (using <code>fc</code>). For
example, when the nmake command compiles <a HREF="../tst/8q.c"><code>tst\8q.c</code></a>,
it leaves the generated assembly code and diagnostic output in <code>%BUILDDIR%\x86\win32\tst\8q.s</code>
and <code>%BUILDDIR%\x86\win32\tst\8q.2</code>, and it compares them with the expected
results in <code>x86\win32\tst\8q.sbk</code>. It builds the executable program in <code>%BUILDDIR%\x86\win32\tst\8q.exe</code>,
runs it, and redirects the output to <code>%BUILDDIR%\x86\win32\tst\8q.1</code>, which it
compares with <code>x86\win32\tst\8q.1bk</code>. The output from this step is voluminous,
but there should be no differences and no errors.</p>
</li>
<li>Run the &quot;triple&quot; test, which compiles <code>rcc</code> with itself and
verifies the results:<blockquote>
<pre>C:\dist\lcc\4.1&gt;nmake -f makefile.nt triple
...
\progra~1\lcc\4.1\bin\x86.c:
Assembling: C:/TEMP/lcc2001.asm
fc /b \progra~1\lcc\4.1\bin\1rcc.exe \progra~1\lcc\4.1\bin\2rcc.exe
Comparing files \progra~1\lcc\4.1\bin\1rcc.exe and \progra~1\lcc\4.1\bin\2RCC.EXE
00000088: B4 D5</pre>
</blockquote>
<p>This command builds <code>rcc</code> twice; once using the <code>rcc</code> built by VC
and again using the <code>rcc</code> built by <code>lcc</code>. The resulting binaries are
compared using <code>fc</code>. They should be identical, except for one or two bytes of
timestamp data, as shown at the end of the output above. If they aren't, our compiler is
generating incorrect code; <a HREF="#bugs">contact</a> us.</p>
</li>
<li>Copy <code>lcc.exe</code> and <code>bprint.exe</code> to a directory on your PATH, e.g.,<blockquote>
<pre>C:\dist\lcc\4.1&gt;copy %BUILDDIR%\lcc.exe \bin
1 file(s) copied.
C:\dist\lcc\4.1&gt;copy %BUILDDIR%\bprint.exe \bin
1 file(s) copied.</pre>
</blockquote>
</li>
<li>Finally, clean up:<blockquote>
<pre>C:\dist\lcc\4.1&gt;nmake -f makefile.nt clean</pre>
</blockquote>
<p>This command removes the derived files in <code>BUILDDIR</code>, but does not remove <code>rcc.exe</code>,
etc.; &quot;<code>nmake -f makefile.nt clobber</code>&quot; cleans up and removes all
executables and libraries. Test directories under <code>BUILDDIR</code> are <em>not</em>
removed; you'll need to remove these by hand, e.g.,</p>
<blockquote>
<pre>C:\dist\lcc\4.1&gt;rmdir %BUILDDIR%\x86 /s
\progra~1\lcc\4.1\bin\x86, Are you sure (Y/N)? y</pre>
</blockquote>
</li>
</ol>
<h2><a NAME="bugs">Reporting Bugs</a></h2>
<p>lcc is a large, complex program. We find and repair errors routinely. If you think that
you've found a error, follow the steps below, which are adapted from the instructions in
Chapter 1 of <cite>A Retargetable C Compiler: Design and Implementation</cite>.
<ol>
<li>If you don't have a source file that displays the error, create one. Most errors are
exposed when programmers try to compile a program they think is valid, so you probably
have a demonstration program already.</li>
<li>Preprocess the source file and capture the preprocessor output. Discard the original
code.</li>
<li>Prune your source code until it can be pruned no more without sending the error into
hiding. We prune most error demonstrations to fewer than five lines.</li>
<li>Confirm that the source file displays the error with the <em>distributed</em> version of
lcc. If you've changed lcc and the error appears only in your version, then you'll have to
chase the error yourself, even if it turns out to be our fault, because we can't work on
your code.</li>
<li>Annotate your code with comments that explain why you think that lcc is wrong. If lcc
dies with an assertion failure, please tell us where it died. If lcc crashes, please
report the last part of the call chain if you can. If lcc is rejecting a program you think
is valid, please tell us why you think it's valid, and include supporting page numbers in
the ANSI Standard, Appendix A in <cite>The C Programming Language</cite>, or the
appropriate section in <cite>C: A Reference Manual</cite>, 4th edition by S. B. Harbison
and G. L. Steele, Jr. (Prentice Hall, 1995). If lcc silently generates incorrect code for
some construct, please include the corrupt assembly code in the comments and flag the
incorrect instructions if you can.</li>
<li>Confirm that your error hasn't been fixed already. The latest version of lcc is always
available for anonymous <code>ftp</code> from <code>ftp.cs.princeton.edu</code> in <a
HREF="ftp://ftp.cs.princeton.edu/pub/lcc"><code>pub/lcc</code></a>. A <a
HREF="ftp://ftp.cs.princeton.edu/pub/lcc/README"><code>README</code></a> file there gives
acquistion details, and the <a HREF="../LOG"><code>LOG</code></a> file reports what errors
were fixed and when they were fixed. If you report a error that's been fixed, you might
get a canned reply.</li>
<li>Send your program by electronic mail to <code>lcc-bugs@cs.princeton.edu</code>. Please
send only valid C programs; put all remarks in C comments so that we can process reports
semiautomatically.</li>
</ol>
<h2><a NAME="mailinglist">Keeping in Touch</a></h2>
<p>There is an lcc mailing list for general information about lcc. To be added to the
list, send a message with the 1-line body</p>
<blockquote>
<pre>subscribe lcc</pre>
</blockquote>
<p>to <code>majordomo@cs.princeton.edu</code>. This line must appear in the message body;
&quot;Subject:&quot; lines are ignored. To learn more about mailing lists served by <code>majordomo</code>,
send a message with the 1-word body &quot;<code>help</code>&quot; to <code>majordomo@cs.princeton.edu</code>.
Mail sent to <code>lcc@cs.princeton.edu</code> is forwarded to everyone on the mailing
list.</p>
<p>There is also an <code>lcc-bugs</code> mailing list for reporting bugs; subscribe to it
by sending a message with the 1-line body </p>
<blockquote>
<pre>subscribe lcc-bugs</pre>
</blockquote>
<p>to <code>majordomo@cs.princeton.edu</code>. Mail addressed to <var>lcc-bugs@cs.princeton.edu</var>
is forwarded to everyone on this list.</p>
<hr>
<address>
<a HREF="http://www.research.microsoft.com/~cwfraser/">Chris Fraser</a> / <a
HREF="mailto:cwfraser@microsoft.com">cwfraser@microsoft.com</a><br>
<a HREF="http://www.research.microsoft.com/~drh/">David Hanson</a> / <a
HREF="mailto:drh@microsoft.com">drh@microsoft.com</a><br>
$Revision: 145 $ $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $
</address>
</body>
</html>

605
code/tools/lcc/doc/lcc.1 Normal file
View file

@ -0,0 +1,605 @@
.\" $Id: lcc.1 145 2001-10-17 21:53:10Z timo $
.TH LCC 1 "local \- $Date: 2001-10-17 16:53:10 -0500 (Wed, 17 Oct 2001) $"
.SH NAME
lcc \- ANSI C compiler
.SH SYNOPSIS
.B lcc
[
.I option
|
.I file
]...
.br
.SH DESCRIPTION
.PP
.I lcc
is an ANSI C compiler for a variety of platforms.
.PP
Arguments whose names end with `.c' (plus `.C' under Windows) are taken to be
C source programs; they are preprocessed, compiled, and
each object program is left on the file
whose name is that of the source with `.o' (UNIX) or `.obj' (Windows)
substituted for the extension.
Arguments whose names end with `.i' are treated similarly,
except they are not preprocessed.
In the same way,
arguments ending with `.s' (plus `.S', `.asm', and `.ASM', under Windows)
are taken to be assembly source programs
and are assembled, producing an object file.
If there are no arguments,
.I lcc
summarizes its options on the standard error.
.PP
.I lcc
deletes an object file if and only if exactly one
source file is mentioned and no other file
(source, object, library) or
.B \-l
option is mentioned.
.PP
If the environment variable
.B LCCINPUTS
is set,
.I lcc
assumes it gives a semicolon- or colon-separated list of directories in which to
look for source and object files whose names do not begin with `/'.
These directories are also added to the list of directories
searched for libraries.
If
.B LCCINPUTS
is defined, it must contain `.' in order for the current directory
to be searched for input files.
.PP
.I lcc
uses ANSI standard header files (see `FILES' below).
Include files not found in the ANSI header files
are taken from the normal default include areas,
which usually includes
.BR /usr/include .
Under Windows, if the environment variable
.B include
is defined, it gives a semicolon-separated list of directories in which to search for
header files.
.PP
.I lcc
interprets the following options; unrecognized options are
taken as loader options (see
.IR ld (1))
unless
.BR \-c ,
.BR \-S ,
or
.B \-E
precedes them.
Except for
.BR \-l ,
all options are processed before any of the files
and apply to all of the files.
Applicable options are passed to each compilation phase in the order given.
.TP
.B \-c
Suppress the loading phase of the compilation, and force
an object file to be produced even if only one program is compiled.
.TP
.B \-g
Produce additional symbol table information for the local debuggers.
.I lcc
warns when
.B \-g
is unsupported.
.TP
.BI \-Wf\-g n , x
Set the debugging level to
.I n
and emit source code as comments into the generated assembly code;
.I x
must be the assembly language comment character.
If
.I n
is omitted, it defaults to 1, which is similar to
.BR \-g .
Omitting
.BI , x
just sets the debugging level to
.IR n .
.TP
.B \-w
Suppress warning diagnostics, such as those
announcing unreferenced statics, locals, and parameters.
The line
.I
#pragma ref id
simulates a reference to the variable
.IR id .
.TP
.BI \-d n
Generate jump tables for switches whose density is at least
.IR n ,
a floating point constant between zero and one.
The default is 0.5.
.TP
.B \-A
Warns about
declarations and casts of function types without prototypes,
assignments between pointers to ints and pointers to enums, and
conversions from pointers to smaller integral types.
A second
.B \-A
warns about
unrecognized control lines,
nonANSI language extensions and source characters in literals,
unreferenced variables and static functions,
declaring arrays of incomplete types,
and exceeding
.I some
ANSI environmental limits, like more than 257 cases in switches.
It also arranges for duplicate global definitions in separately compiled
files to cause loader errors.
.TP
.B \-P
Writes declarations for all defined globals on standard error.
Function declarations include prototypes;
editing this output can simplify conversion to ANSI C.
This output may not correspond to the input when
there are several typedefs for the same type.
.TP
.B \-n
Arrange for the compiler to produce code
that tests for dereferencing zero pointers.
The code reports the offending file and line number and calls
.IR abort (3).
.TP
.B \-O
is ignored.
.TP
.B \-S
Compile the named C programs, and leave the
assembler-language output on corresponding files suffixed `.s' or `.asm'.
.TP
.B \-E
Run only the preprocessor on the named C programs
and unsuffixed file arguments,
and send the result to the standard output.
.TP
.BI \-o " output"
Name the output file
.IR output .
If
.B \-c
or
.B \-S
is specified and there is exactly one source file,
this option names the object or assembly file, respectively.
Otherwise, this option names the final executable
file generated by the loader, and `a.out' (UNIX) or `a.exe' (Windows) is left undisturbed.
.I lcc
warns if
.B \-o
and
.B \-c
or
.B \-S
are given with more than one source file and ignores the
.B \-o
option.
.TP
.BI \-D name=def
Define the
.I name
to the preprocessor, as if by `#define'.
If
.I =def
is omitted, the name is defined as "1".
.TP
.BI \-U name
Remove any initial definition of
.IR name .
.TP
.BI \-I dir
`#include' files
whose names do not begin with `/' are always
sought first in the directory of the
.I file
arguments, then in directories named in
.B \-I
options, then in directories on a standard list.
.TP
.B \-N
Do not search
.I any
of the standard directories for `#include' files.
Only those directories specified by subsequent explicit
.B \-I
options will be searched, in the order given.
.TP
.BI \-B str
Use the compiler
.BI "" str rcc
instead of the default version.
Note that
.I str
often requires a trailing slash.
On Sparcs only,
.B \-Bstatic
and
.BI \-Bdynamic
are passed to the loader; see
.IR ld (1).
.TP
.BI \-Wo\-lccdir= dir
Find the preprocessor, compiler proper, and include directory
in the directory
.I dir/
or
.I
dir\\.
If the environment variable
.B LCCDIR
is defined, it gives this directory.
.I lcc
warns when this option is unsupported.
.TP
.B \-Wf-unsigned_char=1
.br
.ns
.TP
.B \-Wf-unsigned_char=0
makes plain
.B char
an unsigned (1) or signed (0) type; by default,
.B char
is signed.
.TP
.B \-Wf\-wchar_t=unsigned_char
.br
.ns
.TP
.B \-Wf\-wchar_t=unsigned_short
.br
.ns
.TP
.B \-Wf\-wchar_t=unsigned_int
Makes wide characters the type indicated; by default,
wide characters are unsigned short ints, and
.B wchar_t
is a typedef for unsigned short defined in stddef.h.
The definition for
.B wchar_t
in stddef.h must correspond to the type specified.
.TP
.B \-v
Print commands as they are executed; some of the executed
programs are directed to print their version numbers.
More than one occurrence of
.B \-v
causes the commands to be printed, but
.I not
executed.
.TP
.BR \-help " or " \-?
Print a message on the standard error summarizing
.IR lcc 's
options and giving the values of the environment variables
.B LCCINPUTS
and
.BR LCCDIR ,
if they are defined.
Under Windows, the values of
.B include
and
.B lib
are also given, if they are defined.
.TP
.B \-b
Produce code that counts the number of times each expression is executed.
If loading takes place, arrange for a
.B prof.out
file to be written when the object program terminates.
A listing annotated with execution counts can then be generated with
.IR bprint (1).
.I lcc
warns when
.B \-b
is unsupported.
.B \-Wf\-C
is similar, but counts only the number of function calls.
.TP
.B \-p
Produce code that counts the number of times each function is called.
If loading takes place, replace the standard startup
function by one that automatically calls
.IR monitor (3)
at the start and arranges to write a
.B mon.out
file when the object program terminates normally.
An execution profile can then be generated with
.IR prof (1).
.I lcc
warns when
.B \-p
is unsupported.
.TP
.B \-pg
Causes the compiler to produce counting code like
.BR \-p ,
but invokes a run-time recording mechanism that keeps more
extensive statistics and produces a
.B gmon.out
file at normal termination.
Also, a profiling library is searched, in lieu of the standard C library.
An execution profile can then be generated with
.IR gprof (1).
.I lcc
warns when
.B \-pg
is unsupported.
.TP
.BI \-t name
.br
.ns
.TP
.BI \-t
Produce code to print the name of the function, an activation number,
and the name and value of each argument at function entry.
At function exit, produce code to print
the name of the function, the activation number, and the return value.
By default,
.I printf
does the printing; if
.I name
appears, it does.
For null
.I char*
values, "(null)" is printed.
.BI \-target
.I name
is accepted, but ignored.
.TP
.BI \-tempdir= dir
Store temporary files in the directory
.I dir/
or
.I
dir\\.
The default is usually
.BR /tmp .
.TP
.BI \-W xarg
pass argument
.I arg
to the program indicated by
.IR x ;
.I x
can be one of
.BR p ,
.BR f ,
.BR a ,
or
.BR l ,
which refer, respectively, to the preprocessor, the compiler proper,
the assembler, and the loader.
.I arg
is passed as given; if a
.B \-
is expected, it must be given explicitly.
.BI \-Wo arg
specifies a system-specific option,
.IR arg .
.PP
Other arguments
are taken to be either loader option arguments, or C-compatible
object programs, typically produced by an earlier
.I lcc
run, or perhaps libraries of C-compatible routines.
Duplicate object files are ignored.
These programs, together with the results of any
compilations specified, are loaded (in the order
given) to produce an executable program with name
.BR a.out
(UNIX) or
.BR a.exe
(Windows).
.PP
.I lcc
assigns the most frequently referenced scalar parameters and
locals to registers whenever possible.
For each block,
explicit register declarations are obeyed first;
remaining registers are assigned to automatic locals if they
are `referenced' at least 3 times.
Each top-level occurrence of an identifier
counts as 1 reference. Occurrences in a loop,
either of the then/else arms of an if statement, or a case
in a switch statement each count, respectively, as 10, 1/2, or 1/10 references.
These values are adjusted accordingly for nested control structures.
.B \-Wf\-a
causes
.I lcc
to read a
.B prof.out
file from a previous execution and to use the data therein
to compute reference counts (see
.BR \-b ).
.PP
.I lcc
is a cross compiler;
.BI \-Wf\-target= target/os
causes
.I lcc
to generate code for
.I target
running the operating system denoted by
.IR os .
The supported
.I target/os
combinations may include
.PP
.RS
.ta \w'sparc/solarisxx'u
.nf
alpha/osf ALPHA, OSF 3.2
mips/irix big-endian MIPS, IRIX 5.2
mips/ultrix little-endian MIPS, ULTRIX 4.3
sparc/solaris SPARC, Solaris 2.3
x86/win32 x86, Windows NT 4.0/Windows 95/98
x86/linux x86, Linux
symbolic text rendition of the generated code
null no output
.fi
.RE
.PP
For
.BR \-Wf\-target=symbolic ,
the option
.B \-Wf-html
causes the text rendition to be emitted as HTML.
.B
.SH LIMITATIONS
.PP
.I lcc
accepts the C programming language
as described in the ANSI standard.
If
.I lcc
is used with the GNU C preprocessor, the
.B \-Wp\-trigraphs
option is required to enable trigraph sequences.
.PP
Plain int bit fields are signed.
Bit fields are aligned like unsigned integers but are otherwise laid out
as by most standard C compilers.
Some compilers, such as the GNU C compiler,
may choose other, incompatible layouts.
.PP
Likewise, calling conventions are intended to be compatible with
the host C compiler,
except possibly for passing and returning structures.
Specifically,
.I lcc
passes and returns structures like host ANSI C compilers
on most targets, but some older host C compilers use different conventions.
Consequently, calls to/from such functions compiled with
older C compilers may not work.
Calling a function that returns
a structure without declaring it as such violates
the ANSI standard and may cause a fault.
.SH FILES
.PP
The file names listed below are
.IR typical ,
but vary among installations; installation-dependent variants
can be displayed by running
.I lcc
with the
.B \-v
option.
.PP
.RS
.ta \w'$LCCDIR/liblcc.{a,lib}XX'u
.nf
file.{c,C} input file
file.{s,asm} assembly-language file
file.{o,obj} object file
a.{out,exe} loaded output
/tmp/lcc* temporary files
$LCCDIR/cpp preprocessor
$LCCDIR/rcc compiler
$LCCDIR/liblcc.{a,lib} \fIlcc\fP-specific library
/lib/crt0.o runtime startup (UNIX)
/lib/[gm]crt0.o startups for profiling (UNIX)
/lib/libc.a standard library (UNIX)
$LCCDIR/include ANSI standard headers
/usr/local/include local headers
/usr/include traditional headers
prof.out file produced for \fIbprint\fR(1)
mon.out file produced for \fIprof\fR(1)
gmon.out file produced for \fIgprof\fR(1)
.fi
.RE
.PP
.I lcc
predefines the macro
.B __LCC__
on all systems.
It may also predefine some installation-dependent symbols; option
.B \-v
exposes them.
.SH "SEE ALSO"
.PP
C. W. Fraser and D. R. Hanson,
.I A Retargetable C Compiler: Design and Implementation,
Addison-Wesley, 1995. ISBN 0-8053-1670-1.
.PP
The World-Wide Web page at http://www.cs.princeton.edu/software/lcc/.
.PP
S. P. Harbison and G. L. Steele, Jr.,
.I C: A Reference Manual,
4th ed., Prentice-Hall, 1995.
.PP
B. W. Kernighan and D. M. Ritchie,
.I The C Programming Language,
2nd ed., Prentice-Hall, 1988.
.PP
American National Standards Inst.,
.I American National Standard for Information Systems\(emProgramming
.IR Language\(emC ,
ANSI X3.159-1989, New York, 1990.
.br
.SH BUGS
Mail bug reports along with the shortest preprocessed program
that exposes them and the details reported by
.IR lcc 's
.B \-v
option to lcc-bugs@princeton.edu. The WWW page at
URL http://www.cs.princeton.edu/software/lcc/
includes detailed instructions for reporting bugs.
.PP
The ANSI standard headers conform to the specifications in
the Standard, which may be too restrictive for some applications,
but necessary for portability.
Functions given in the ANSI headers may be missing from
some local C libraries (e.g., wide-character functions)
or may not correspond exactly to the local versions;
for example, the ANSI standard
stdio.h
specifies that
.IR printf ,
.IR fprintf ,
and
.I sprintf
return the number of characters written to the file or array,
but some existing libraries don't implement this convention.
.PP
On the MIPS and SPARC, old-style variadic functions must use
varargs.h
from MIPS or Sun. New-style is recommended.
.PP
With
.BR \-b ,
files compiled
.I without
.B \-b
may cause
.I bprint
to print erroneous call graphs.
For example, if
.B f
calls
.B g
calls
.B h
and
.B f
and
.B h
are compiled with
.BR \-b ,
but
.B g
is not,
.B bprint
will report that
.B f
called
.BR h .
The total number of calls is correct, however.

BIN
code/tools/lcc/doc/lcc.pdf Normal file

Binary file not shown.

475
code/tools/lcc/etc/bprint.c Normal file
View file

@ -0,0 +1,475 @@
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* bprint [ -c | -Idir... | -f | -b | -n ] [ file... ]
* annotate listings of files with prof.out data
*/
#define NDIRS (sizeof dirs/sizeof dirs[0] - 1)
#define NEW(p,a) ((p) = alloc(sizeof *(p)))
#define newarray(m,n,a) alloc((m)*(n))
#define NELEMS(a) ((int)(sizeof (a)/sizeof ((a)[0])))
#define MAXTOKEN 64
struct count { /* count data: */
int x, y; /* source coordinate */
int count; /* associated execution count */
};
char *progname;
int number;
char *dirs[20];
int fcount;
struct file { /* per-file prof.out data: */
struct file *link; /* link to next file */
char *name; /* file name */
int size; /* size of counts[] */
int count; /* counts[0..count-1] hold valid data */
struct count *counts; /* count data */
struct func { /* function data: */
struct func *link; /* link to next function */
char *name; /* function name */
struct count count; /* total number of calls */
struct caller { /* caller data: */
struct caller *link; /* link to next caller */
char *name; /* caller's name */
char *file; /* call site: file, x, y */
int x, y;
int count; /* number of calls from this site */
} *callers;
} *funcs; /* list of functions */
} *filelist;
FILE *fp;
extern int process(char *);
extern int findfunc(char *, char *);
extern int findcount(char *, int, int);
void *alloc(unsigned);
char *string(char *);
int process(char *);
void emitdata(char *);
void printfile(struct file *, int);
void printfuncs(struct file *, int);
/* alloc - allocate n bytes or die */
void *alloc(unsigned n) {
void *new = malloc(n);
assert(new);
return new;
}
/* emitdata - write prof.out data to file */
void emitdata(char *file) {
FILE *fp;
if ((fp = fopen(file, "w"))) {
struct file *p;
for (p = filelist; p; p = p->link) {
int i;
struct func *q;
struct caller *r;
fprintf(fp, "1\n%s\n", p->name);
for (i = 0, q = p->funcs; q; i++, q = q->link)
if ((r = q->callers))
for (i--; r; r = r->link)
i++;
fprintf(fp, "%d\n", i);
for (q = p->funcs; q; q = q->link)
if (q->count.count == 0 || !q->callers)
fprintf(fp, "%s 1 %d %d %d ? ? 0 0\n", q->name, q->count.x,
q->count.y, q->count.count);
else
for (r = q->callers; r; r = r->link)
fprintf(fp, "%s 1 %d %d %d %s %s %d %d\n", q->name, q->count.x,
q->count.y, r->count, r->name, r->file, r->x, r->y);
fprintf(fp, "%d\n", p->count);
for (i = 0; i < p->count; i++)
fprintf(fp, "1 %d %d %d\n", p->counts[i].x,
p->counts[i].y, p->counts[i].count);
}
fclose(fp);
} else
fprintf(stderr, "%s: can't create `%s'\n", progname, file);
}
/* openfile - open name for reading, searching -I directories */
FILE *openfile(char *name) {
int i;
FILE *fp;
if (*name != '/')
for (i = 0; dirs[i]; i++) {
char buf[200];
sprintf(buf, "%s/%s", dirs[i], name);
if ((fp = fopen(buf, "r")))
return fp;
}
return fopen(name, "r");
}
/* printfile - print annotated listing for p */
void printfile(struct file *p, int nf) {
int lineno;
FILE *fp;
char *s, buf[512];
struct count *u = p->counts, *r, *uend;
if (u == 0 || p->count <= 0)
return;
uend = &p->counts[p->count];
if ((fp = openfile(p->name)) == NULL) {
fprintf(stderr, "%s: can't open `%s'\n", progname, p->name);
return;
}
if (nf)
printf("%s%s:\n\n", nf == 1 ? "" : "\f", p->name);
for (lineno = 1; fgets(buf, sizeof buf, fp); lineno++) {
if (number)
printf("%d\t", lineno);
while (u < uend && u->y < lineno)
u++;
for (s = buf; *s; ) {
char *t = s + 1;
while (u < uend && u->y == lineno && u->x < s - buf)
u++;
if (isalnum(*s) || *s == '_')
while (isalnum(*t) || *t == '_')
t++;
while (u < uend && u->y == lineno && u->x < t - buf) {
printf("<%d>", u->count);
for (r = u++; u < uend && u->x == r->x && u->y == r->y && u->count == r->count; u++)
;
}
while (s < t)
putchar(*s++);
}
if (*s)
printf("%s", s);
}
fclose(fp);
}
/* printfuncs - summarize data for functions in p */
void printfuncs(struct file *p, int nf) {
struct func *q;
if (nf)
printf("%s:\n", p->name);
for (q = p->funcs; q; q = q->link)
if (fcount <= 1 || q->count.count == 0 || !q->callers)
printf("%d\t%s\n", q->count.count, q->name);
else {
struct caller *r;
for (r = q->callers; r; r = r->link)
printf("%d\t%s\tfrom %s\tin %s:%d.%d\n", r->count, q->name, r->name,
r->file, r->y, r->x + 1);
}
}
/* string - save a copy of str, if necessary */
char *string(char *str) {
static struct string { struct string *link; char str[1]; } *list;
struct string *p;
for (p = list; p; p = p->link)
if (strcmp(p->str, str) == 0)
return p->str;
p = (struct string *)alloc(strlen(str) + sizeof *p);
strcpy(p->str, str);
p->link = list;
list = p;
return p->str;
}
/* acaller - add caller and site (file,x,y) to callee's callers list */
static void acaller(char *caller, char *file, int x, int y, int count, struct func *callee) {
struct caller *q;
assert(callee);
for (q = callee->callers; q && (caller != q->name
|| file != q->file || x != q->x || y != q->y); q = q->link)
;
if (!q) {
struct caller **r;
NEW(q, PERM);
q->name = caller;
q->file = file;
q->x = x;
q->y = y;
q->count = 0;
for (r = &callee->callers; *r && (strcmp(q->name, (*r)->name) > 0
|| strcmp(q->file, (*r)->file) > 0 || q->y > (*r)->y || q->y > (*r)->y); r = &(*r)->link)
;
q->link = *r;
*r = q;
}
q->count += count;
}
/* compare - return <0, 0, >0 if a<b, a==b, a>b, resp. */
static int compare(struct count *a, struct count *b) {
if (a->y == b->y)
return a->x - b->x;
return a->y - b->y;
}
/* findfile - return file name's file list entry, or 0 */
static struct file *findfile(char *name) {
struct file *p;
for (p = filelist; p; p = p->link)
if (p->name == name)
return p;
return 0;
}
/* afunction - add function name and its data to file's function list */
static struct func *afunction(char *name, char *file, int x, int y, int count) {
struct file *p = findfile(file);
struct func *q;
assert(p);
for (q = p->funcs; q && name != q->name; q = q->link)
;
if (!q) {
struct func **r;
NEW(q, PERM);
q->name = name;
q->count.x = x;
q->count.y = y;
q->count.count = 0;
q->callers = 0;
for (r = &p->funcs; *r && compare(&q->count, &(*r)->count) > 0; r = &(*r)->link)
;
q->link = *r;
*r = q;
}
q->count.count += count;
return q;
}
/* apoint - append execution point i to file's data */
static void apoint(int i, char *file, int x, int y, int count) {
struct file *p = findfile(file);
assert(p);
if (i >= p->size) {
int j;
if (p->size == 0) {
p->size = i >= 200 ? 2*i : 200;
p->counts = newarray(p->size, sizeof *p->counts, PERM);
} else {
struct count *new;
p->size = 2*i;
new = newarray(p->size, sizeof *new, PERM);
for (j = 0; j < p->count; j++)
new[j] = p->counts[j];
p->counts = new;
}
for (j = p->count; j < p->size; j++) {
static struct count z;
p->counts[j] = z;
}
}
p->counts[i].x = x;
p->counts[i].y = y;
p->counts[i].count += count;
if (i >= p->count)
p->count = i + 1;
}
/* findcount - return count associated with (file,x,y) or -1 */
int findcount(char *file, int x, int y) {
static struct file *cursor;
if (cursor == 0 || cursor->name != file)
cursor = findfile(file);
if (cursor) {
int l, u;
struct count *c = cursor->counts;
for (l = 0, u = cursor->count - 1; l <= u; ) {
int k = (l + u)/2;
if (c[k].y > y || (c[k].y == y && c[k].x > x))
u = k - 1;
else if (c[k].y < y || (c[k].y == y && c[k].x < x))
l = k + 1;
else
return c[k].count;
}
}
return -1;
}
/* findfunc - return count associated with function name in file or -1 */
int findfunc(char *name, char *file) {
static struct file *cursor;
if (cursor == 0 || cursor->name != file)
cursor = findfile(file);
if (cursor) {
struct func *p;
for (p = cursor->funcs; p; p = p->link)
if (p->name == name)
return p->count.count;
}
return -1;
}
/* getd - read a nonnegative number */
static int getd(void) {
int c, n = 0;
while ((c = getc(fp)) != EOF && (c == ' ' || c == '\n' || c == '\t'))
;
if (c >= '0' && c <= '9') {
do
n = 10*n + (c - '0');
while ((c = getc(fp)) >= '0' && c <= '9');
return n;
}
return -1;
}
/* getstr - read a string */
static char *getstr(void) {
int c;
char buf[MAXTOKEN], *s = buf;
while ((c = getc(fp)) != EOF && c != ' ' && c != '\n' && c != '\t')
if (s - buf < (int)sizeof buf - 2)
*s++ = c;
*s = 0;
return s == buf ? (char *)0 : string(buf);
}
/* gather - read prof.out data from fd */
static int gather(void) {
int i, nfiles, nfuncs, npoints;
char *files[64];
if ((nfiles = getd()) < 0)
return 0;
assert(nfiles < NELEMS(files));
for (i = 0; i < nfiles; i++) {
if ((files[i] = getstr()) == 0)
return -1;
if (!findfile(files[i])) {
struct file *new;
NEW(new, PERM);
new->name = files[i];
new->size = new->count = 0;
new->counts = 0;
new->funcs = 0;
new->link = filelist;
filelist = new;
}
}
if ((nfuncs = getd()) < 0)
return -1;
for (i = 0; i < nfuncs; i++) {
struct func *q;
char *name, *file;
int f, x, y, count;
if ((name = getstr()) == 0 || (f = getd()) <= 0
|| (x = getd()) < 0 || (y = getd()) < 0 || (count = getd()) < 0)
return -1;
q = afunction(name, files[f-1], x, y, count);
if ((name = getstr()) == 0 || (file = getstr()) == 0
|| (x = getd()) < 0 || (y = getd()) < 0)
return -1;
if (*name != '?')
acaller(name, file, x, y, count, q);
}
if ((npoints = getd()) < 0)
return -1;
for (i = 0; i < npoints; i++) {
int f, x, y, count;
if ((f = getd()) < 0 || (x = getd()) < 0 || (y = getd()) < 0
|| (count = getd()) < 0)
return -1;
if (f)
apoint(i, files[f-1], x, y, count);
}
return 1;
}
/* process - read prof.out data from file */
int process(char *file) {
int more;
if ((fp = fopen(file, "r")) != NULL) {
struct file *p;
while ((more = gather()) > 0)
;
fclose(fp);
if (more < 0)
return more;
for (p = filelist; p; p = p->link)
qsort(p->counts, p->count, sizeof *p->counts,
(int (*)(const void *, const void *))
compare);
return 1;
}
return 0;
}
int main(int argc, char *argv[]) {
int i;
struct file *p;
void (*f)(struct file *, int) = printfile;
progname = argv[0];
if ((i = process("prof.out")) <= 0) {
fprintf(stderr, "%s: can't %s `%s'\n", progname,
i == 0 ? "open" : "interpret", "prof.out");
exit(1);
}
for (i = 1; i < argc && *argv[i] == '-'; i++)
if (strcmp(argv[i], "-c") == 0) {
emitdata("prof.out");
exit(0);
} else if (strcmp(argv[i], "-b") == 0)
f = printfile;
else if (strcmp(argv[i], "-f") == 0) {
fcount++;
f = printfuncs;
} else if (strcmp(argv[i], "-n") == 0)
number++;
else if (strncmp(argv[i], "-I", 2) == 0) {
int j;
for (j = 0; j < NDIRS && dirs[j]; j++)
;
if (j < NDIRS)
dirs[j] = &argv[i][2];
else
fprintf(stderr, "%s: too many -I options\n", progname);
} else {
fprintf(stderr, "usage: %s [ -c | -b | -n | -f | -Idir... ] [ file... ]\n", progname);
exit(1);
}
for (p = filelist; p; p = p->link)
qsort(p->counts, p->count, sizeof *p->counts,
(int (*)(const void *, const void *))compare);
if (i < argc) {
int nf = i < argc - 1 ? 1 : 0;
for ( ; i < argc; i++, nf ? nf++ : 0)
if ((p = findfile(string(argv[i]))))
(*f)(p, nf);
else
fprintf(stderr, "%s: no data for `%s'\n", progname, argv[i]);
} else {
int nf = filelist && filelist->link ? 1 : 0;
for (p = filelist; p; p = p->link, nf ? nf++ : 0)
(*f)(p, nf);
}
return 0;
}

View file

@ -0,0 +1,50 @@
/* SPARCs running Solaris 2.5.1 w/GCC tools
at CS Dept., Princeton University */
#include <string.h>
#ifndef LCCDIR
#define LCCDIR "/usr/local/lib/lcc/"
#endif
#ifndef GCCDIR
#define GCCDIR "/usr/local/gnu/bin/"
#endif
#ifndef GCCLIB
#define GCCLIB "/usr/local/gnu/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/"
#endif
char *suffixes[] = { ".c", ".i", ".s", ".o", ".out", 0 };
char inputs[256] = "";
char *cpp[] = { LCCDIR "cpp",
"-D__STDC__=1", "-Dsparc", "-D__sparc__", "-Dsun", "-D__sun__", "-Dunix",
"$1", "$2", "$3", 0 };
char *include[] = { "-I" LCCDIR "include", "-I/usr/local/include",
"-I" GCCLIB "include", "-I/usr/include", 0 };
char *com[] = { LCCDIR "rcc", "-target=sparc/solaris",
"$1", "$2", "$3", 0 };
char *as[] = { GCCDIR "as", "-f", "-o", "$3", "$1", "$2", 0 };
char *ld[] = { GCCDIR "ld", "-o", "$3", "$1",
GCCLIB "crti.o", GCCLIB "crt1.o",
GCCLIB "crtbegin.o", "$2", "", "", "-L" LCCDIR, "-llcc",
"-L" GCCLIB, "-lgcc", "-lm", "-lc", "",
GCCLIB "crtend.o", GCCLIB "crtn.o", 0 };
extern char *concat(char *, char *);
int option(char *arg) {
if (strncmp(arg, "-lccdir=", 8) == 0) {
cpp[0] = concat(&arg[8], "/cpp");
include[0] = concat("-I", concat(&arg[8], "/include"));
ld[10] = concat("-L", &arg[8]);
com[0] = concat(&arg[8], "/rcc");
} else if (strcmp(arg, "-g") == 0)
;
else if (strcmp(arg, "-pg") == 0) {
ld[8] = GCCLIB "gmon.o";
} else if (strcmp(arg, "-b") == 0)
;
else
return 0;
return 1;
}

64
code/tools/lcc/etc/irix.c Normal file
View file

@ -0,0 +1,64 @@
/* SGI big endian MIPSes running IRIX 5.2 at CS Dept., Princeton University */
#include <string.h>
#ifndef LCCDIR
#define LCCDIR "/usr/local/lib/lcc/"
#endif
char *suffixes[] = { ".c", ".i", ".s", ".o", ".out", 0 };
char inputs[256] = "";
char *cpp[] = { LCCDIR "cpp", "-D__STDC__=1",
"-DLANGUAGE_C",
"-DMIPSEB",
"-DSYSTYPE_SVR4",
"-D_CFE",
"-D_LANGUAGE_C",
"-D_MIPSEB",
"-D_MIPS_FPSET=16",
"-D_MIPS_ISA=_MIPS_ISA_MIPS1",
"-D_MIPS_SIM=_MIPS_SIM_ABI32",
"-D_MIPS_SZINT=32",
"-D_MIPS_SZLONG=32",
"-D_MIPS_SZPTR=32",
"-D_SGI_SOURCE",
"-D_SVR4_SOURCE",
"-D_SYSTYPE_SVR4",
"-D__host_mips",
"-D__mips=1",
"-D__sgi",
"-D__unix",
"-Dhost_mips",
"-Dmips",
"-Dsgi",
"-Dunix",
"$1", "$2", "$3", 0 };
char *com[] = { LCCDIR "rcc", "-target=mips/irix", "$1", "$2", "$3", "", 0 };
char *include[] = { "-I" LCCDIR "include", "-I/usr/local/include",
"-I/usr/include", 0 };
char *as[] = { "/usr/bin/as", "-o", "$3", "$1", "-nocpp", "-KPIC", "$2", 0 };
char *ld[] = { "/usr/bin/ld", "-require_dynamic_link", "_rld_new_interface",
"-elf", "-_SYSTYPE_SVR4", "-Wx,-G", "0", "-g0", "-KPIC", "-dont_warn_unused",
"-o", "$3", "/usr/lib/crt1.o", "-L/usr/local/lib",
"$1", "$2", "", "-L" LCCDIR, "-llcc", "-lc", "-lm", "/usr/lib/crtn.o", 0
};
extern char *concat(char *, char *);
int option(char *arg) {
if (strncmp(arg, "-lccdir=", 8) == 0) {
cpp[0] = concat(&arg[8], "/cpp");
include[0] = concat("-I", concat(&arg[8], "/include"));
com[0] = concat(&arg[8], "/rcc");
ld[17] = concat("-L", &arg[8]);
} else if (strcmp(arg, "-g") == 0)
;
else if (strcmp(arg, "-p") == 0)
ld[12] = "/usr/lib/mcrt1.o";
else if (strcmp(arg, "-b") == 0)
;
else
return 0;
return 1;
}

799
code/tools/lcc/etc/lcc.c Normal file
View file

@ -0,0 +1,799 @@
/*
* lcc [ option ]... [ file | -llib ]...
* front end for the ANSI C compiler
*/
static char rcsid[] = "Id: dummy rcsid";
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <signal.h>
#include <unistd.h>
#ifndef TEMPDIR
#define TEMPDIR "/tmp"
#endif
typedef struct list *List;
struct list { /* circular list nodes: */
char *str; /* option or file name */
List link; /* next list element */
};
static void *alloc(int);
static List append(char *,List);
extern char *basepath(char *);
static int callsys(char *[]);
extern char *concat(char *, char *);
static int compile(char *, char *);
static void compose(char *[], List, List, List);
static void error(char *, char *);
static char *exists(char *);
static char *first(char *);
static int filename(char *, char *);
static List find(char *, List);
static void help(void);
static void initinputs(void);
static void interrupt(int);
static void opt(char *);
static List path2list(const char *);
extern int main(int, char *[]);
extern char *replace(const char *, int, int);
static void rm(List);
extern char *strsave(const char *);
extern char *stringf(const char *, ...);
extern int suffix(char *, char *[], int);
extern char *tempname(char *);
extern int getpid(void);
extern char *cpp[], *include[], *com[], *as[],*ld[], inputs[], *suffixes[];
extern int option(char *);
static int errcnt; /* number of errors */
static int Eflag; /* -E specified */
static int Sflag; /* -S specified */
static int cflag; /* -c specified */
static int verbose; /* incremented for each -v */
static List llist[2]; /* loader files, flags */
static List alist; /* assembler flags */
static List clist; /* compiler flags */
static List plist; /* preprocessor flags */
static List ilist; /* list of additional includes from LCCINPUTS */
static List rmlist; /* list of files to remove */
static char *outfile; /* ld output file or -[cS] object file */
static int ac; /* argument count */
static char **av; /* argument vector */
char *tempdir = TEMPDIR; /* directory for temporary files */
static char *progname;
static List lccinputs; /* list of input directories */
int main(int argc, char *argv[]) {
int i, j, nf;
progname = argv[0];
ac = argc + 50;
av = alloc(ac*sizeof(char *));
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, interrupt);
if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
signal(SIGTERM, interrupt);
#ifdef SIGHUP
if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
signal(SIGHUP, interrupt);
#endif
if (getenv("TMP"))
tempdir = getenv("TMP");
else if (getenv("TEMP"))
tempdir = getenv("TEMP");
else if (getenv("TMPDIR"))
tempdir = getenv("TMPDIR");
assert(tempdir);
i = strlen(tempdir);
for (; (i > 0 && tempdir[i-1] == '/') || tempdir[i-1] == '\\'; i--)
tempdir[i-1] = '\0';
if (argc <= 1) {
help();
exit(0);
}
plist = append("-D__LCC__", 0);
initinputs();
if (getenv("LCCDIR"))
option(stringf("-lccdir=%s", getenv("LCCDIR")));
for (nf = 0, i = j = 1; i < argc; i++) {
if (strcmp(argv[i], "-o") == 0) {
if (++i < argc) {
if (suffix(argv[i], suffixes, 2) >= 0) {
error("-o would overwrite %s", argv[i]);
exit(8);
}
outfile = argv[i];
continue;
} else {
error("unrecognized option `%s'", argv[i-1]);
exit(8);
}
} else if (strcmp(argv[i], "-target") == 0) {
if (argv[i+1] && *argv[i+1] != '-')
i++;
continue;
} else if (*argv[i] == '-' && argv[i][1] != 'l') {
opt(argv[i]);
continue;
} else if (*argv[i] != '-' && suffix(argv[i], suffixes, 3) >= 0)
nf++;
argv[j++] = argv[i];
}
if ((cflag || Sflag) && outfile && nf != 1) {
fprintf(stderr, "%s: -o %s ignored\n", progname, outfile);
outfile = 0;
}
argv[j] = 0;
for (i = 0; include[i]; i++)
plist = append(include[i], plist);
if (ilist) {
List b = ilist;
do {
b = b->link;
plist = append(b->str, plist);
} while (b != ilist);
}
ilist = 0;
for (i = 1; argv[i]; i++)
if (*argv[i] == '-')
opt(argv[i]);
else {
char *name = exists(argv[i]);
if (name) {
if (strcmp(name, argv[i]) != 0
|| (nf > 1 && suffix(name, suffixes, 3) >= 0))
fprintf(stderr, "%s:\n", name);
filename(name, 0);
} else
error("can't find `%s'", argv[i]);
}
if (errcnt == 0 && !Eflag && !Sflag && !cflag && llist[1]) {
compose(ld, llist[0], llist[1],
append(outfile ? outfile : concat("a", first(suffixes[4])), 0));
if (callsys(av))
errcnt++;
}
rm(rmlist);
return errcnt ? EXIT_FAILURE : EXIT_SUCCESS;
}
/* alloc - allocate n bytes or die */
static void *alloc(int n) {
static char *avail, *limit;
n = (n + sizeof(char *) - 1)&~(sizeof(char *) - 1);
if (n >= limit - avail) {
avail = malloc(n + 4*1024);
assert(avail);
limit = avail + n + 4*1024;
}
avail += n;
return avail - n;
}
/* append - append a node with string str onto list, return new list */
static List append(char *str, List list) {
List p = alloc(sizeof *p);
p->str = str;
if (list) {
p->link = list->link;
list->link = p;
} else
p->link = p;
return p;
}
/* basepath - return base name for name, e.g. /usr/drh/foo.c => foo */
char *basepath(char *name) {
char *s, *b, *t = 0;
for (b = s = name; *s; s++)
if (*s == '/' || *s == '\\') {
b = s + 1;
t = 0;
} else if (*s == '.')
t = s;
s = strsave(b);
if (t)
s[t-b] = 0;
return s;
}
#ifdef WIN32
#include <process.h>
#else
#define _P_WAIT 0
extern int fork(void);
extern int wait(int *);
static int _spawnvp(int mode, const char *cmdname, char *argv[]) {
int pid, n, status;
switch (pid = fork()) {
case -1:
fprintf(stderr, "%s: no more processes\n", progname);
return 100;
case 0:
// TTimo removing hardcoded paths, searching in $PATH
execvp(cmdname, argv);
fprintf(stderr, "%s: ", progname);
perror(cmdname);
fflush(stdout);
exit(100);
}
while ((n = wait(&status)) != pid && n != -1)
;
if (n == -1)
status = -1;
if (status&0377) {
fprintf(stderr, "%s: fatal error in %s\n", progname, cmdname);
status |= 0400;
}
return (status>>8)&0377;
}
#endif
/* callsys - execute the command described by av[0...], return status */
static int callsys(char **av) {
int i, status = 0;
static char **argv;
static int argc;
for (i = 0; av[i] != NULL; i++)
;
if (i + 1 > argc) {
argc = i + 1;
if (argv == NULL)
argv = malloc(argc*sizeof *argv);
else
argv = realloc(argv, argc*sizeof *argv);
assert(argv);
}
for (i = 0; status == 0 && av[i] != NULL; ) {
int j = 0;
char *s = NULL;
for ( ; av[i] != NULL && (s = strchr(av[i], '\n')) == NULL; i++)
argv[j++] = av[i];
if (s != NULL) {
if (s > av[i])
argv[j++] = stringf("%.*s", s - av[i], av[i]);
if (s[1] != '\0')
av[i] = s + 1;
else
i++;
}
argv[j] = NULL;
if (verbose > 0) {
int k;
fprintf(stderr, "%s", argv[0]);
for (k = 1; argv[k] != NULL; k++)
fprintf(stderr, " %s", argv[k]);
fprintf(stderr, "\n");
}
if (verbose < 2)
#ifndef WIN32
status = _spawnvp(_P_WAIT, argv[0], argv);
#else
status = _spawnvp(_P_WAIT, argv[0], (const char* const*)argv);
#endif
if (status == -1) {
fprintf(stderr, "%s: ", progname);
perror(argv[0]);
}
}
return status;
}
/* concat - return concatenation of strings s1 and s2 */
char *concat(char *s1, char *s2) {
int n = strlen(s1);
char *s = alloc(n + strlen(s2) + 1);
strcpy(s, s1);
strcpy(s + n, s2);
return s;
}
/* compile - compile src into dst, return status */
static int compile(char *src, char *dst) {
compose(com, clist, append(src, 0), append(dst, 0));
return callsys(av);
}
/* compose - compose cmd into av substituting a, b, c for $1, $2, $3, resp. */
static void compose(char *cmd[], List a, List b, List c) {
int i, j;
List lists[3];
lists[0] = a;
lists[1] = b;
lists[2] = c;
for (i = j = 0; cmd[i]; i++) {
char *s = strchr(cmd[i], '$');
if (s && isdigit(s[1])) {
int k = s[1] - '0';
assert(k >=1 && k <= 3);
if ((b = lists[k-1])) {
b = b->link;
av[j] = alloc(strlen(cmd[i]) + strlen(b->str) - 1);
strncpy(av[j], cmd[i], s - cmd[i]);
av[j][s-cmd[i]] = '\0';
strcat(av[j], b->str);
strcat(av[j++], s + 2);
while (b != lists[k-1]) {
b = b->link;
assert(j < ac);
av[j++] = b->str;
};
}
} else if (*cmd[i]) {
assert(j < ac);
av[j++] = cmd[i];
}
}
av[j] = NULL;
}
/* error - issue error msg according to fmt, bump error count */
static void error(char *fmt, char *msg) {
fprintf(stderr, "%s: ", progname);
fprintf(stderr, fmt, msg);
fprintf(stderr, "\n");
errcnt++;
}
/* exists - if `name' readable return its path name or return null */
static char *exists(char *name) {
List b;
if ( (name[0] == '/' || name[0] == '\\' || name[2] == ':')
&& access(name, 4) == 0)
return name;
if (!(name[0] == '/' || name[0] == '\\' || name[2] == ':')
&& (b = lccinputs))
do {
b = b->link;
if (b->str[0]) {
char buf[1024];
sprintf(buf, "%s/%s", b->str, name);
if (access(buf, 4) == 0)
return strsave(buf);
} else if (access(name, 4) == 0)
return name;
} while (b != lccinputs);
if (verbose > 1)
return name;
return 0;
}
/* first - return first component in semicolon separated list */
static char *first(char *list) {
char *s = strchr(list, ';');
if (s) {
char buf[1024];
strncpy(buf, list, s-list);
buf[s-list] = '\0';
return strsave(buf);
} else
return list;
}
/* filename - process file name argument `name', return status */
static int filename(char *name, char *base) {
int status = 0;
static char *stemp, *itemp;
if (base == 0)
base = basepath(name);
switch (suffix(name, suffixes, 4)) {
case 0: /* C source files */
compose(cpp, plist, append(name, 0), 0);
if (Eflag) {
status = callsys(av);
break;
}
if (itemp == NULL)
itemp = tempname(first(suffixes[1]));
compose(cpp, plist, append(name, 0), append(itemp, 0));
status = callsys(av);
if (status == 0)
return filename(itemp, base);
break;
case 1: /* preprocessed source files */
if (Eflag)
break;
if (Sflag)
status = compile(name, outfile ? outfile : concat(base, first(suffixes[2])));
else if ((status = compile(name, stemp?stemp:(stemp=tempname(first(suffixes[2]))))) == 0)
return filename(stemp, base);
break;
case 2: /* assembly language files */
if (Eflag)
break;
if (!Sflag) {
char *ofile;
if (cflag && outfile)
ofile = outfile;
else if (cflag)
ofile = concat(base, first(suffixes[3]));
else
ofile = tempname(first(suffixes[3]));
compose(as, alist, append(name, 0), append(ofile, 0));
status = callsys(av);
if (!find(ofile, llist[1]))
llist[1] = append(ofile, llist[1]);
}
break;
case 3: /* object files */
if (!find(name, llist[1]))
llist[1] = append(name, llist[1]);
break;
default:
if (Eflag) {
compose(cpp, plist, append(name, 0), 0);
status = callsys(av);
}
llist[1] = append(name, llist[1]);
break;
}
if (status)
errcnt++;
return status;
}
/* find - find 1st occurrence of str in list, return list node or 0 */
static List find(char *str, List list) {
List b;
if ((b = list))
do {
if (strcmp(str, b->str) == 0)
return b;
} while ((b = b->link) != list);
return 0;
}
/* help - print help message */
static void help(void) {
static char *msgs[] = {
"", " [ option | file ]...\n",
" except for -l, options are processed left-to-right before files\n",
" unrecognized options are taken to be linker options\n",
"-A warn about nonANSI usage; 2nd -A warns more\n",
"-b emit expression-level profiling code; see bprint(1)\n",
#ifdef sparc
"-Bstatic -Bdynamic specify static or dynamic libraries\n",
#endif
"-Bdir/ use the compiler named `dir/rcc'\n",
"-c compile only\n",
"-dn set switch statement density to `n'\n",
"-Dname -Dname=def define the preprocessor symbol `name'\n",
"-E run only the preprocessor on the named C programs and unsuffixed files\n",
"-g produce symbol table information for debuggers\n",
"-help or -? print this message\n",
"-Idir add `dir' to the beginning of the list of #include directories\n",
"-lx search library `x'\n",
"-N do not search the standard directories for #include files\n",
"-n emit code to check for dereferencing zero pointers\n",
"-O is ignored\n",
"-o file leave the output in `file'\n",
"-P print ANSI-style declarations for globals\n",
"-p -pg emit profiling code; see prof(1) and gprof(1)\n",
"-S compile to assembly language\n",
#ifdef linux
"-static specify static libraries (default is dynamic)\n",
#endif
"-t -tname emit function tracing calls to printf or to `name'\n",
"-target name is ignored\n",
"-tempdir=dir place temporary files in `dir/'", "\n"
"-Uname undefine the preprocessor symbol `name'\n",
"-v show commands as they are executed; 2nd -v suppresses execution\n",
"-w suppress warnings\n",
"-Woarg specify system-specific `arg'\n",
"-W[pfal]arg pass `arg' to the preprocessor, compiler, assembler, or linker\n",
0 };
int i;
char *s;
msgs[0] = progname;
for (i = 0; msgs[i]; i++) {
fprintf(stderr, "%s", msgs[i]);
if (strncmp("-tempdir", msgs[i], 8) == 0 && tempdir)
fprintf(stderr, "; default=%s", tempdir);
}
#define xx(v) if ((s = getenv(#v))) fprintf(stderr, #v "=%s\n", s)
xx(LCCINPUTS);
xx(LCCDIR);
#ifdef WIN32
xx(include);
xx(lib);
#endif
#undef xx
}
/* initinputs - if LCCINPUTS or include is defined, use them to initialize various lists */
static void initinputs(void) {
char *s = getenv("LCCINPUTS");
List b;
#ifdef WIN32
List list;
#endif
if (s == 0 || (s = inputs)[0] == 0)
s = ".";
if (s) {
lccinputs = path2list(s);
if ((b = lccinputs))
do {
b = b->link;
if (strcmp(b->str, ".") != 0) {
ilist = append(concat("-I", b->str), ilist);
if (strstr(com[1], "win32") == NULL)
llist[0] = append(concat("-L", b->str), llist[0]);
} else
b->str = "";
} while (b != lccinputs);
}
#ifdef WIN32
if ((list = b = path2list(getenv("include"))))
do {
b = b->link;
ilist = append(stringf("-I\"%s\"", b->str), ilist);
} while (b != list);
#endif
}
/* interrupt - catch interrupt signals */
static void interrupt(int n) {
rm(rmlist);
exit(n = 100);
}
/* opt - process option in arg */
static void opt(char *arg) {
switch (arg[1]) { /* multi-character options */
case 'W': /* -Wxarg */
if (arg[2] && arg[3])
switch (arg[2]) {
case 'o':
if (option(&arg[3]))
return;
break;
case 'p':
plist = append(&arg[3], plist);
return;
case 'f':
if (strcmp(&arg[3], "-C") || option("-b")) {
clist = append(&arg[3], clist);
return;
}
break; /* and fall thru */
case 'a':
alist = append(&arg[3], alist);
return;
case 'l':
llist[0] = append(&arg[3], llist[0]);
return;
}
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'd': /* -dn */
arg[1] = 's';
clist = append(arg, clist);
return;
case 't': /* -t -tname -tempdir=dir */
if (strncmp(arg, "-tempdir=", 9) == 0)
tempdir = arg + 9;
else
clist = append(arg, clist);
return;
case 'p': /* -p -pg */
if (option(arg))
clist = append(arg, clist);
else
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'D': /* -Dname -Dname=def */
case 'U': /* -Uname */
case 'I': /* -Idir */
plist = append(arg, plist);
return;
case 'B': /* -Bdir -Bstatic -Bdynamic */
#ifdef sparc
if (strcmp(arg, "-Bstatic") == 0 || strcmp(arg, "-Bdynamic") == 0)
llist[1] = append(arg, llist[1]);
else
#endif
{
static char *path;
if (path)
error("-B overwrites earlier option", 0);
path = arg + 2;
if (strstr(com[1], "win32") != NULL)
com[0] = concat(replace(path, '/', '\\'), concat("rcc", first(suffixes[4])));
else
com[0] = concat(path, "rcc");
if (path[0] == 0)
error("missing directory in -B option", 0);
}
return;
case 'h':
if (strcmp(arg, "-help") == 0) {
static int printed = 0;
case '?':
if (!printed)
help();
printed = 1;
return;
}
#ifdef linux
case 's':
if (strcmp(arg,"-static") == 0) {
if (!option(arg))
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
}
#endif
}
if (arg[2] == 0)
switch (arg[1]) { /* single-character options */
case 'S':
Sflag++;
return;
case 'O':
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'A': case 'n': case 'w': case 'P':
clist = append(arg, clist);
return;
case 'g': case 'b':
if (option(arg))
clist = append(arg[1] == 'g' ? "-g2" : arg, clist);
else
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'G':
if (option(arg)) {
clist = append("-g3", clist);
llist[0] = append("-N", llist[0]);
} else
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'E':
Eflag++;
return;
case 'c':
cflag++;
return;
case 'N':
if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0)
plist = append("-nostdinc", plist);
include[0] = 0;
ilist = 0;
return;
case 'v':
if (verbose++ == 0) {
if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0)
plist = append(arg, plist);
clist = append(arg, clist);
fprintf(stderr, "%s %s\n", progname, rcsid);
}
return;
}
if (cflag || Sflag || Eflag)
fprintf(stderr, "%s: %s ignored\n", progname, arg);
else
llist[1] = append(arg, llist[1]);
}
/* path2list - convert a colon- or semicolon-separated list to a list */
static List path2list(const char *path) {
List list = NULL;
char sep = ':';
if (path == NULL)
return NULL;
if (strchr(path, ';'))
sep = ';';
while (*path) {
char *p, buf[512];
if ((p = strchr(path, sep))) {
assert(p - path < sizeof buf);
strncpy(buf, path, p - path);
buf[p-path] = '\0';
} else {
assert(strlen(path) < sizeof buf);
strcpy(buf, path);
}
if (!find(buf, list))
list = append(strsave(buf), list);
if (p == 0)
break;
path = p + 1;
}
return list;
}
/* replace - copy str, then replace occurrences of from with to, return the copy */
char *replace(const char *str, int from, int to) {
char *s = strsave(str), *p = s;
for ( ; (p = strchr(p, from)) != NULL; p++)
*p = to;
return s;
}
/* rm - remove files in list */
static void rm(List list) {
if (list) {
List b = list;
if (verbose)
fprintf(stderr, "rm");
do {
if (verbose)
fprintf(stderr, " %s", b->str);
if (verbose < 2)
remove(b->str);
} while ((b = b->link) != list);
if (verbose)
fprintf(stderr, "\n");
}
}
/* strsave - return a saved copy of string str */
char *strsave(const char *str) {
return strcpy(alloc(strlen(str)+1), str);
}
/* stringf - format and return a string */
char *stringf(const char *fmt, ...) {
char buf[1024];
va_list ap;
int n;
va_start(ap, fmt);
n = vsprintf(buf, fmt, ap);
va_end(ap);
return strsave(buf);
}
/* suffix - if one of tails[0..n-1] holds a proper suffix of name, return its index */
int suffix(char *name, char *tails[], int n) {
int i, len = strlen(name);
for (i = 0; i < n; i++) {
char *s = tails[i], *t;
for ( ; (t = strchr(s, ';')); s = t + 1) {
int m = t - s;
if (len > m && strncmp(&name[len-m], s, m) == 0)
return i;
}
if (*s) {
int m = strlen(s);
if (len > m && strncmp(&name[len-m], s, m) == 0)
return i;
}
}
return -1;
}
/* tempname - generate a temporary file name in tempdir with given suffix */
char *tempname(char *suffix) {
static int n;
char *name = stringf("%s/lcc%d%d%s", tempdir, getpid(), n++, suffix);
if (strstr(com[1], "win32") != NULL)
name = replace(name, '/', '\\');
rmlist = append(name, rmlist);
return name;
}

View file

@ -0,0 +1,72 @@
/* x86s running Linux */
#include <string.h>
/*
TTimo - 10-18-2001
our binaries are named q3lcc q3rcc and q3cpp
removed hardcoded paths
removed __linux__ preprocessor define (confuses the preprocessor, we are doing bytecode!)
*/
#ifndef LCCDIR
#define LCCDIR ""
//#define LCCDIR "/usr/local/lib/lcc/"
#endif
char *suffixes[] = { ".c", ".i", ".asm", ".o", ".out", 0 };
char inputs[256] = "";
// TTimo experimental: do not compile with the __linux__ define, we are doing bytecode!
char *cpp[] = { LCCDIR "q3cpp",
"-U__GNUC__", "-D_POSIX_SOURCE", "-D__STDC__=1", "-D__STRICT_ANSI__",
"-Dunix", "-Di386", "-Dlinux",
"-D__unix__", "-D__i386__", "-D__signed__=signed",
"$1", "$2", "$3", 0 };
char *include[] = {"-I" LCCDIR "include", "-I" LCCDIR "gcc/include", "-I/usr/include",
"-I" SYSTEM "include", 0 };
char *com[] = {LCCDIR "q3rcc", "-target=bytecode", "$1", "$2", "$3", 0 };
char *as[] = { "/usr/bin/as", "-o", "$3", "$1", "$2", 0 };
// NOTE TTimo I don't think we have any use with the native linkage
// our target is always bytecode..
char *ld[] = {
/* 0 */ "/usr/bin/ld", "-m", "elf_i386", "-dynamic-linker",
/* 4 */ "/lib/ld-linux.so.2", "-o", "$3",
/* 7 */ "/usr/lib/crt1.o", "/usr/lib/crti.o",
/* 9 */ SYSTEM "crtbegin.o",
"$1", "$2",
/* 12 */ "-L" LCCDIR,
/* 13 */ "-llcc",
/* 14 */ "-L" LCCDIR "/gcc", "-lgcc", "-lc", "-lm",
/* 18 */ "",
/* 19 */ SYSTEM "crtend.o", "/usr/lib/crtn.o",
/* 20 */ "-L" SYSTEM,
0 };
extern char *concat(char *, char *);
int option(char *arg) {
if (strncmp(arg, "-lccdir=", 8) == 0) {
cpp[0] = concat(&arg[8], "/gcc/cpp");
include[0] = concat("-I", concat(&arg[8], "/include"));
include[1] = concat("-I", concat(&arg[8], "/gcc/include"));
ld[9] = concat(&arg[8], "/gcc/crtbegin.o");
ld[12] = concat("-L", &arg[8]);
ld[14] = concat("-L", concat(&arg[8], "/gcc"));
ld[19] = concat(&arg[8], "/gcc/crtend.o");
com[0] = concat(&arg[8], "/rcc");
} else if (strcmp(arg, "-p") == 0 || strcmp(arg, "-pg") == 0) {
ld[7] = "/usr/lib/gcrt1.o";
ld[18] = "-lgmon";
} else if (strcmp(arg, "-b") == 0)
;
else if (strcmp(arg, "-g") == 0)
;
else if (strncmp(arg, "-ld=", 4) == 0)
ld[0] = &arg[4];
else if (strcmp(arg, "-static") == 0) {
ld[3] = "-static";
ld[4] = "";
} else
return 0;
return 1;
}

190
code/tools/lcc/etc/ops.c Normal file
View file

@ -0,0 +1,190 @@
#include "c.h"
/* ops [ {csilhfdxp}=n ]...
* prints lcc dag operator set for a given set of type sizes.
*/
static char list[] = { 'c', 's', 'i', 'l', 'h', 'f', 'd', 'x', 'p', 0 };
static int sizes[] = { 1, 2, 4, 4, 8, 4, 8, 16, 8 };
static int doop(int op, int type, const char *sz, const char *opname) {
int count = 0;
static int last;
if (op == LOAD)
return 0;
if (last != 0 && last != op)
printf("\n");
last = op;
if (type == B || type == V) {
printf(" %s=%d", opname, op + type);
count++;
} else {
int i, done = 0;
const char *s;
for (i = 0; sz[i] != '\0' && (s = strchr(list, sz[i])) != NULL; i++) {
int n = sizes[s-list];
if ((done&(1<<n)) == 0) {
printf(" %s%d=%d", opname, n, op + type + sizeop(n));
count++;
}
done |= 1<<n;
}
}
printf("\n");
return count;
}
int main(int argc, char *argv[]) {
int i, count = 0;
for (i = 1; i < argc; i++) {
char c, *s;
int n;
if (sscanf(argv[i], "%c=%d", &c, &n) == 2
&& n > 0 && (s = strchr(list, c)) != NULL)
sizes[s-list] = n;
else {
fprintf(stderr, "usage: %s [ {csilhfdxp}=n ]...\n", argv[0]);
exit(EXIT_FAILURE);
}
}
#define gop(x,n)
#define op(x,t,s) count += doop(x,t,#s,#x #t);
gop(CNST,1)
op(CNST,F,fdx)
op(CNST,I,csilh)
op(CNST,P,p)
op(CNST,U,csilh)
gop(ARG,2)
op(ARG,B,-)
op(ARG,F,fdx)
op(ARG,I,ilh)
op(ARG,P,p)
op(ARG,U,ilh)
gop(ASGN,3)
op(ASGN,B,-)
op(ASGN,F,fdx)
op(ASGN,I,csilh)
op(ASGN,P,p)
op(ASGN,U,csilh)
gop(INDIR,4)
op(INDIR,B,-)
op(INDIR,F,fdx)
op(INDIR,I,csilh)
op(INDIR,P,p)
op(INDIR,U,csilh)
gop(CVF,7)
op(CVF,F,fdx)
op(CVF,I,ilh)
gop(CVI,8)
op(CVI,F,fdx)
op(CVI,I,csilh)
op(CVI,U,csilhp)
gop(CVP,9)
op(CVP,U,p)
gop(CVU,11)
op(CVU,I,csilh)
op(CVU,P,p)
op(CVU,U,csilh)
gop(NEG,12)
op(NEG,F,fdx)
op(NEG,I,ilh)
gop(CALL,13)
op(CALL,B,-)
op(CALL,F,fdx)
op(CALL,I,ilh)
op(CALL,P,p)
op(CALL,U,ilh)
op(CALL,V,-)
gop(RET,15)
op(RET,F,fdx)
op(RET,I,ilh)
op(RET,P,p)
op(RET,U,ilh)
op(RET,V,-)
gop(ADDRG,16)
op(ADDRG,P,p)
gop(ADDRF,17)
op(ADDRF,P,p)
gop(ADDRL,18)
op(ADDRL,P,p)
gop(ADD,19)
op(ADD,F,fdx)
op(ADD,I,ilh)
op(ADD,P,p)
op(ADD,U,ilhp)
gop(SUB,20)
op(SUB,F,fdx)
op(SUB,I,ilh)
op(SUB,P,p)
op(SUB,U,ilhp)
gop(LSH,21)
op(LSH,I,ilh)
op(LSH,U,ilh)
gop(MOD,22)
op(MOD,I,ilh)
op(MOD,U,ilh)
gop(RSH,23)
op(RSH,I,ilh)
op(RSH,U,ilh)
gop(BAND,24)
op(BAND,I,ilh)
op(BAND,U,ilh)
gop(BCOM,25)
op(BCOM,I,ilh)
op(BCOM,U,ilh)
gop(BOR,26)
op(BOR,I,ilh)
op(BOR,U,ilh)
gop(BXOR,27)
op(BXOR,I,ilh)
op(BXOR,U,ilh)
gop(DIV,28)
op(DIV,F,fdx)
op(DIV,I,ilh)
op(DIV,U,ilh)
gop(MUL,29)
op(MUL,F,fdx)
op(MUL,I,ilh)
op(MUL,U,ilh)
gop(EQ,30)
op(EQ,F,fdx)
op(EQ,I,ilh)
op(EQ,U,ilhp)
gop(GE,31)
op(GE,F,fdx)
op(GE,I,ilh)
op(GE,U,ilhp)
gop(GT,32)
op(GT,F,fdx)
op(GT,I,ilh)
op(GT,U,ilhp)
gop(LE,33)
op(LE,F,fdx)
op(LE,I,ilh)
op(LE,U,ilhp)
gop(LT,34)
op(LT,F,fdx)
op(LT,I,ilh)
op(LT,U,ilhp)
gop(NE,35)
op(NE,F,fdx)
op(NE,I,ilh)
op(NE,U,ilhp)
gop(JUMP,36)
op(JUMP,V,-)
gop(LABEL,37)
op(LABEL,V,-)
gop(LOAD,14)
op(LOAD,B,-)
op(LOAD,F,fdx)
op(LOAD,I,csilh)
op(LOAD,P,p)
op(LOAD,U,csilhp)
#undef gop
#undef op
fprintf(stderr, "%d operators\n", count);
return EXIT_SUCCESS;
}

53
code/tools/lcc/etc/osf.c Normal file
View file

@ -0,0 +1,53 @@
/* DEC ALPHAs running OSF/1 V3.2A (Rev. 17) at Princeton University */
#include <string.h>
#ifndef LCCDIR
#define LCCDIR "/usr/local/lib/lcc/"
#endif
char *suffixes[] = { ".c", ".i", ".s", ".o", ".out", 0 };
char inputs[256] = "";
char *cpp[] = {
LCCDIR "cpp", "-D__STDC__=1",
"-DLANGUAGE_C", "-D__LANGUAGE_C__",
"-D_unix", "-D__unix__", "-D_osf", "-D__osf__", "-Dunix",
"-Dalpha", "-D_alpha", "-D__alpha",
"-D__SYSTYPE_BSD", "-D_SYSTYPE_BSD",
"$1", "$2", "$3", 0 };
char *com[] = { LCCDIR "rcc", "-target=alpha/osf", "$1", "$2", "$3", "", 0 };
char *include[] = { "-I" LCCDIR "include", "-I/usr/local/include",
"-I/usr/include", 0 };
char *as[] = { "/bin/as", "-o", "$3", "", "$1", "-nocpp", "$2", 0 };
char *ld[] = { "/usr/bin/ld", "-o", "$3", "/usr/lib/cmplrs/cc/crt0.o",
"$1", "$2", "", "", "-L" LCCDIR, "-llcc", "-lm", "-lc", 0 };
extern char *concat(char *, char *);
extern int access(const char *, int);
int option(char *arg) {
if (strncmp(arg, "-lccdir=", 8) == 0) {
cpp[0] = concat(&arg[8], "/cpp");
include[0] = concat("-I", concat(&arg[8], "/include"));
com[0] = concat(&arg[8], "/rcc");
ld[8] = concat("-L", &arg[8]);
} else if (strcmp(arg, "-g4") == 0
&& access("/u/drh/lib/alpha/rcc", 4) == 0
&& access("/u/drh/book/cdb/alpha/osf/cdbld", 4) == 0) {
com[0] = "/u/drh/lib/alpha/rcc";
com[5] = "-g4";
ld[0] = "/u/drh/book/cdb/alpha/osf/cdbld";
ld[1] = "-o";
ld[2] = "$3";
ld[3] = "$1";
ld[4] = "$2";
ld[5] = 0;
} else if (strcmp(arg, "-g") == 0)
return 1;
else if (strcmp(arg, "-b") == 0)
;
else
return 0;
return 1;
}

View file

@ -0,0 +1,50 @@
/* SPARCs running Solaris 2.5.1 at CS Dept., Princeton University */
#include <string.h>
#ifndef LCCDIR
#define LCCDIR "/usr/local/lib/lcc/"
#endif
#ifndef SUNDIR
#define SUNDIR "/opt/SUNWspro/SC4.2/lib/"
#endif
char *suffixes[] = { ".c", ".i", ".s", ".o", ".out", 0 };
char inputs[256] = "";
char *cpp[] = { LCCDIR "cpp",
"-D__STDC__=1", "-Dsparc", "-D__sparc__", "-Dsun", "-D__sun__", "-Dunix",
"$1", "$2", "$3", 0 };
char *include[] = { "-I" LCCDIR "include", "-I/usr/local/include",
"-I/usr/include", 0 };
char *com[] = { LCCDIR "rcc", "-target=sparc/solaris",
"$1", "$2", "$3", 0 };
char *as[] = { "/usr/ccs/bin/as", "-Qy", "-s", "-o", "$3", "$1", "$2", 0 };
char *ld[] = { "/usr/ccs/bin/ld", "-o", "$3", "$1",
SUNDIR "crti.o", SUNDIR "crt1.o",
SUNDIR "values-xa.o", "$2", "",
"-Y", "P," SUNDIR ":/usr/ccs/lib:/usr/lib", "-Qy",
"-L" LCCDIR, "-llcc", "-lm", "-lc", SUNDIR "crtn.o", 0 };
extern char *concat(char *, char *);
int option(char *arg) {
if (strncmp(arg, "-lccdir=", 8) == 0) {
cpp[0] = concat(&arg[8], "/cpp");
include[0] = concat("-I", concat(&arg[8], "/include"));
ld[12] = concat("-L", &arg[8]);
com[0] = concat(&arg[8], "/rcc");
} else if (strcmp(arg, "-g") == 0)
;
else if (strcmp(arg, "-p") == 0) {
ld[5] = SUNDIR "mcrt1.o";
ld[10] = "P," SUNDIR "libp:/usr/ccs/lib/libp:/usr/lib/libp:"
SUNDIR ":/usr/ccs/lib:/usr/lib";
} else if (strcmp(arg, "-b") == 0)
;
else if (strncmp(arg, "-ld=", 4) == 0)
ld[0] = &arg[4];
else
return 0;
return 1;
}

View file

@ -0,0 +1,43 @@
/* x86s running MS Windows NT 4.0 */
#include <string.h>
#ifndef LCCDIR
// JDC #define LCCDIR "\\progra~1\\lcc\\4.1\\bin\\"
//#define LCCDIR "\\quake3\\source\\lcc\\bin\\" // JDC
// TTimo: q3cpp q3rcc & no hardcoded paths
#define LCCDIR ""
#endif
char *suffixes[] = { ".c;.C", ".i;.I", ".asm;.ASM;.s;.S", ".obj;.OBJ", ".exe", 0 };
char inputs[256] = "";
char *cpp[] = { LCCDIR "q3cpp", "-D__STDC__=1", "-Dwin32", "-D_WIN32", "-D_M_IX86",
"$1", "$2", "$3", 0 };
char *include[] = { "-I" LCCDIR "include", 0 };
char *com[] = { LCCDIR "q3rcc", "-target=x86/win32", "$1", "$2", "$3", 0 };
char *as[] = { "ml", "-nologo", "-c", "-Cp", "-coff", "-Fo$3", "$1", "$2", 0 };
char *ld[] = { "link", "-nologo",
"-align:0x1000", "-subsystem:console", "-entry:mainCRTStartup",
"$2", "-OUT:$3", "$1", LCCDIR "liblcc.lib", "libc.lib", "kernel32.lib", 0 };
extern char *concat(char *, char *);
extern char *replace(const char *, int, int);
int option(char *arg) {
if (strncmp(arg, "-lccdir=", 8) == 0) {
arg = replace(arg + 8, '/', '\\');
if (arg[strlen(arg)-1] == '\\')
arg[strlen(arg)-1] = '\0';
cpp[0] = concat(arg, "\\cpp.exe");
include[0] = concat("-I", concat(arg, "\\include"));
com[0] = concat(arg, "\\rcc.exe");
ld[8] = concat(arg, "\\liblcc.lib");
} else if (strcmp(arg, "-b") == 0)
;
else if (strncmp(arg, "-ld=", 4) == 0)
ld[0] = &arg[4];
else
return 0;
return 1;
}

View file

@ -0,0 +1,14 @@
#ifndef __ASSERT
#define __ASSERT
void assert(int);
#endif /* __ASSERT */
#undef assert
#ifdef NDEBUG
#define assert(ignore) ((void)0)
#else
extern void __assert(char *, char *, unsigned);
#define assert(e) ((void)((e)||(__assert(#e, __FILE__, __LINE__),0)))
#endif /* NDEBUG */

View file

@ -0,0 +1,25 @@
#ifndef __CTYPE
#define __CTYPE
extern int isalnum(int);
extern int isalpha(int);
extern int iscntrl(int);
extern int isdigit(int);
extern int isgraph(int);
extern int islower(int);
extern int isprint(int);
extern int ispunct(int);
extern int isspace(int);
extern int isupper(int);
extern int isxdigit(int);
extern int tolower(int);
extern int toupper(int);
#define __U 01
#define __L 02
#define __N 04
#define __S 010
#define __P 020
#define __C 040
#endif /* __CTYPE */

View file

@ -0,0 +1,8 @@
#ifndef __ERRNO
#define __ERRNO
#define EDOM 33
#define ERANGE 34
extern int errno;
#endif /* __ERRNO */

View file

@ -0,0 +1,37 @@
#ifndef __FLOAT
#define __FLOAT
#define FLT_ROUNDS 1
#define FLT_RADIX 2
#define FLT_DIG 6
#define FLT_EPSILON 1.19209289550781250000e-07
#define FLT_MANT_DIG 24
#define FLT_MAX 3.40282346638528860000e+38
#define FLT_MAX_10_EXP 38
#define FLT_MAX_EXP 128
#define FLT_MIN 1.17549435082228750000e-38
#define FLT_MIN_10_EXP -37
#define FLT_MIN_EXP -125
#define DBL_DIG 15
#define DBL_EPSILON 2.22044604925031310000e-16
#define DBL_MANT_DIG 53
#define DBL_MAX 1.79769313486231570000e+308
#define DBL_MAX_10_EXP 308
#define DBL_MAX_EXP 1024
#define DBL_MIN 2.22507385850720140000e-308
#define DBL_MIN_10_EXP -307
#define DBL_MIN_EXP -1021
#define LDBL_MANT_DIG DBL_MANT_DIG
#define LDBL_EPSILON DBL_EPSILON
#define LDBL_DIG DBL_DIG
#define LDBL_MIN_EXP DBL_MIN_EXP
#define LDBL_MIN DBL_MIN
#define LDBL_MIN_10_EXP DBL_MIN_10_EXP
#define LDBL_MAX_EXP DBL_MAX_EXP
#define LDBL_MAX DBL_MAX
#define LDBL_MAX_10_EXP DBL_MAX_10_EXP
#endif /* __FLOAT */

View file

@ -0,0 +1,24 @@
#ifndef __LIMITS
#define __LIMITS
#define CHAR_BIT 8
#define MB_LEN_MAX 1
#define UCHAR_MAX 0xff
#define USHRT_MAX 0xffff
#define UINT_MAX (~0U)
#define ULONG_MAX (~0UL)
#define CHAR_MAX SCHAR_MAX
#define SCHAR_MAX 0x7f
#define SHRT_MAX 0x7fff
#define INT_MAX 0x7fffffff
#define LONG_MAX 0x7fffffffffffffffL
#define CHAR_MIN SCHAR_MIN
#define SCHAR_MIN (-SCHAR_MAX-1)
#define SHRT_MIN (-SHRT_MAX-1)
#define INT_MIN (-INT_MAX-1)
#define LONG_MIN (-LONG_MAX-1)
#endif /* __LIMITS */

View file

@ -0,0 +1,36 @@
#ifndef __LOCALE
#define __LOCALE
#define LC_ALL 0
#define LC_COLLATE 1
#define LC_CTYPE 2
#define LC_MONETARY 3
#define LC_NUMERIC 4
#define LC_TIME 5
#define NULL 0
struct lconv {
char *decimal_point;
char *thousands_sep;
char *grouping;
char *int_curr_symbol;
char *currency_symbol;
char *mon_decimal_point;
char *mon_thousands_sep;
char *mon_grouping;
char *positive_sign;
char *negative_sign;
char int_frac_digits;
char frac_digits;
char p_cs_precedes;
char p_sep_by_space;
char n_cs_precedes;
char n_sep_by_space;
char p_sign_posn;
char n_sign_posn;
};
char *setlocale(int, const char *);
struct lconv *localeconv(void);
#endif /* __LOCALE */

View file

@ -0,0 +1,29 @@
#ifndef __MATH
#define __MATH
#define HUGE_VAL 1.79769313486231570000e+308
extern double acos(double);
extern double asin(double);
extern double atan(double);
extern double atan2(double, double);
extern double cos(double);
extern double sin(double);
extern double tan(double);
extern double cosh(double);
extern double sinh(double);
extern double tanh(double);
extern double exp(double);
extern double frexp(double, int *);
extern double ldexp(double, int);
extern double log(double);
extern double log10(double);
extern double modf(double, double *);
extern double pow(double, double);
extern double sqrt(double);
extern double ceil(double);
extern double fabs(double);
extern double floor(double);
extern double fmod(double, double);
#endif /* __MATH */

View file

@ -0,0 +1,10 @@
#ifndef __SETJMP
#define __SETJMP
typedef int jmp_buf[35+1+48];
int setjmp(jmp_buf);
void longjmp(jmp_buf, int);
#endif /* __SETJMP */

View file

@ -0,0 +1,20 @@
#ifndef __SIGNAL
#define __SIGNAL
typedef int sig_atomic_t;
#define SIG_DFL ((void (*)(int))0)
#define SIG_ERR ((void (*)(int))-1)
#define SIG_IGN ((void (*)(int))1)
#define SIGABRT 6
#define SIGFPE 8
#define SIGILL 4
#define SIGINT 2
#define SIGSEGV 11
#define SIGTERM 15
void (*signal(int, void (*)(int)))(int);
int raise(int);
#endif /* __SIGNAL */

View file

@ -0,0 +1,28 @@
#ifndef __STDARG
#define __STDARG
#if !defined(_VA_LIST)
#define _VA_LIST
typedef struct {
char *_a0; /* pointer to first homed integer arg */
int _offset; /* byte offset of next param */
float _tmp;
} __va_list;
#endif
typedef __va_list va_list;
#define va_start(list, start) ((void)( \
(list)._a0 = (__typecode(__firstarg)==1 ? \
(char*)&__firstarg+48 : (char *)&__firstarg), \
(list)._offset = (__typecode(start)==1 ? \
(char*)&start+56 : (char *)&start+8)-(list)._a0))
#define va_arg(list, mode) (*(mode *)( \
(list)._offset += (int)((sizeof(mode)+7)&~7), \
(__typecode(mode)==1 && sizeof(mode)==4) ? \
((list)._tmp = (float)*(double *)((list)._a0 + (list)._offset - \
((list)._offset <= 48 ? 56 : 8))), (char *)&(list)._tmp : \
(__typecode(mode)==1 && (list)._offset <= 48) ? \
(list)._a0 + (list)._offset - 56 : \
(list)._a0 + (list)._offset - (int)((sizeof(mode)+7)&~7)))
#define va_end(list) ((void)0)
#endif

View file

@ -0,0 +1,22 @@
#ifndef __STDDEF
#define __STDDEF
#define NULL 0
#define offsetof(ty,mem) ((size_t)((char*)&((ty*)0)->mem - (char*)0))
typedef long ptrdiff_t;
#if !defined(_SIZE_T) && !defined(_SIZE_T_)
#define _SIZE_T
#define _SIZE_T_
typedef unsigned long size_t;
#endif
#if !defined(_WCHAR_T) && !defined(_WCHAR_T_)
#define _WCHAR_T
#define _WCHAR_T_
typedef unsigned short wchar_t;
#endif
#endif /* __STDDEF */

View file

@ -0,0 +1,113 @@
#ifndef __STDIO
#define __STDIO
#define _IOFBF 0
#define _IOLBF 0200
#define _IONBF 04
#define BUFSIZ 8192
#define EOF (-1)
typedef struct _iobuf {
int _cnt;
unsigned char *_ptr;
unsigned char *_base;
int _bufsiz;
short _flag;
short _file;
char *__newbase;
void *_lock;
unsigned char *_bufendp;
} FILE;
extern FILE _iob[];
#define FILENAME_MAX 255
#define FOPEN_MAX 64
#if !defined(_FPOS_T) && !defined(_FPOS_T_)
#define _FPOS_T
#define _FPOS_T_
typedef long fpos_t;
#endif
#define L_tmpnam 21
#define NULL 0
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
#if !defined(_SIZE_T) && !defined(_SIZE_T_)
#define _SIZE_T
#define _SIZE_T_
typedef unsigned long size_t;
#endif
#if !defined(_VA_LIST)
#define _VA_LIST
typedef struct {
char *_a0; /* pointer to first homed integer arg */
int _offset; /* byte offset of next param */
float _tmp;
} __va_list;
#endif
#define stderr (&_iob[2])
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define TMP_MAX 16384
extern int remove(const char *);
extern int rename(const char *, const char *);
extern FILE *tmpfile(void);
extern char *tmpnam(char *);
extern int fclose(FILE *);
extern int fflush(FILE *);
extern FILE *fopen(const char *, const char *);
extern FILE *freopen(const char *, const char *, FILE *);
extern void setbuf(FILE *, char *);
extern int setvbuf(FILE *, char *, int, size_t);
extern int fprintf(FILE *, const char *, ...);
extern int fscanf(FILE *, const char *, ...);
extern int printf(const char *, ...);
extern int scanf(const char *, ...);
extern int sprintf(char *, const char *, ...);
extern int sscanf(const char *, const char *, ...);
extern int vfprintf(FILE *, const char *, __va_list);
extern int vprintf(const char *, __va_list);
extern int vsprintf(char *, const char *, __va_list);
extern int fgetc(FILE *);
extern char *fgets(char *, int, FILE *);
extern int fputc(int, FILE *);
extern int fputs(const char *, FILE *);
extern int getc(FILE *);
extern int getchar(void);
extern char *gets(char *);
extern int putc(int, FILE *);
extern int putchar(int);
extern int puts(const char *);
extern int ungetc(int, FILE *);
extern size_t fread(void *, size_t, size_t, FILE *);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
extern int fgetpos(FILE *, fpos_t *);
extern int fseek(FILE *, long int, int);
extern int fsetpos(FILE *, const fpos_t *);
extern long int ftell(FILE *);
extern void rewind(FILE *);
extern void clearerr(FILE *);
extern int feof(FILE *);
extern int ferror(FILE *);
extern void perror(const char *);
#define _IOEOF 020
#define _IOERR 040
#define getc(p) (--(p)->_cnt < 0 ? _filbuf(p) : (int) *(p)->_ptr++)
#define putc(x, p) (--(p)->_cnt < 0 ? \
_flsbuf((unsigned char) (x), p) : \
(int) (*(p)->_ptr++ = (unsigned char) (x)))
extern int _filbuf(FILE *), _flsbuf(unsigned, FILE *);
#define feof(p) ((p)->_flag&_IOEOF)
#define ferror(p) ((p)->_flag&_IOERR)
#define clearerr(p) ((p)->_flag &= ~(_IOERR|_IOEOF))
#define getchar() getc(stdin)
#define putchar(x) putc((x),stdout)
#endif /* __STDIO */

Some files were not shown because too many files have changed in this diff Show more