forked from KolibriOS/kolibrios
scc 0.5.3
git-svn-id: svn://kolibrios.org@718 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
9a8b3fd945
commit
1967c25fac
4131
programs/develop/scc/CC4.ASM
Normal file
4131
programs/develop/scc/CC4.ASM
Normal file
File diff suppressed because it is too large
Load Diff
5066
programs/develop/scc/Cc1.asm
Normal file
5066
programs/develop/scc/Cc1.asm
Normal file
File diff suppressed because it is too large
Load Diff
3034
programs/develop/scc/Cc2.asm
Normal file
3034
programs/develop/scc/Cc2.asm
Normal file
File diff suppressed because it is too large
Load Diff
6740
programs/develop/scc/Cc3.asm
Normal file
6740
programs/develop/scc/Cc3.asm
Normal file
File diff suppressed because it is too large
Load Diff
128
programs/develop/scc/GETARG.ASM
Normal file
128
programs/develop/scc/GETARG.ASM
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
|
||||||
|
_getarg:
|
||||||
|
PUSH EBP
|
||||||
|
MOV EBP,ESP
|
||||||
|
ADD ESP,-8
|
||||||
|
LEA EAX,[EBP+24]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
MOV EBX,EAX
|
||||||
|
XOR EAX,EAX
|
||||||
|
CALL __lt
|
||||||
|
PUSH EAX
|
||||||
|
LEA EAX,[EBP+24]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
PUSH EAX
|
||||||
|
LEA EAX,[EBP+12]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
POP EBX
|
||||||
|
CALL __ge
|
||||||
|
POP EBX
|
||||||
|
OR EAX,EBX
|
||||||
|
OR EAX,EAX
|
||||||
|
JNE _0_3
|
||||||
|
JMP _0_2
|
||||||
|
_0_3:
|
||||||
|
LEA EAX,[EBP+20]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
MOV EBX,EAX
|
||||||
|
XOR EAX,EAX
|
||||||
|
MOV [EBX],AL
|
||||||
|
MOV EAX,-1
|
||||||
|
MOV ESP,EBP
|
||||||
|
POP EBP
|
||||||
|
RET
|
||||||
|
_0_2:
|
||||||
|
LEA EAX,[EBP-8]
|
||||||
|
MOV EBX,EAX
|
||||||
|
XOR EAX,EAX
|
||||||
|
MOV [EBX],EAX
|
||||||
|
LEA EAX,[EBP-4]
|
||||||
|
PUSH EAX
|
||||||
|
LEA EAX,[EBP+8]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
PUSH EAX
|
||||||
|
LEA EAX,[EBP+24]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
POP EBX
|
||||||
|
SHL EAX,1
|
||||||
|
SHL EAX,1
|
||||||
|
ADD EAX,EBX
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
POP EBX
|
||||||
|
MOV [EBX],EAX
|
||||||
|
_0_4:
|
||||||
|
LEA EAX,[EBP-8]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
PUSH EAX
|
||||||
|
LEA EAX,[EBP+16]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
POP EBX
|
||||||
|
CALL __lt
|
||||||
|
OR EAX,EAX
|
||||||
|
JNE _0_6
|
||||||
|
JMP _0_5
|
||||||
|
_0_6:
|
||||||
|
LEA EAX,[EBP+20]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
PUSH EAX
|
||||||
|
LEA EAX,[EBP-8]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
POP EBX
|
||||||
|
ADD EAX,EBX
|
||||||
|
PUSH EAX
|
||||||
|
LEA EAX,[EBP-4]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
PUSH EAX
|
||||||
|
LEA EAX,[EBP-8]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
POP EBX
|
||||||
|
ADD EAX,EBX
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOVSX EAX,BYTE [EBX]
|
||||||
|
POP EBX
|
||||||
|
MOV [EBX],AL
|
||||||
|
OR EAX,EAX
|
||||||
|
JE _0_8
|
||||||
|
JMP _0_7
|
||||||
|
_0_8:
|
||||||
|
JMP _0_5
|
||||||
|
_0_7:
|
||||||
|
LEA EAX,[EBP-8]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
INC EAX
|
||||||
|
MOV [EBX],EAX
|
||||||
|
JMP _0_4
|
||||||
|
_0_5:
|
||||||
|
LEA EAX,[EBP+20]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
PUSH EAX
|
||||||
|
LEA EAX,[EBP-8]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
POP EBX
|
||||||
|
ADD EAX,EBX
|
||||||
|
MOV EBX,EAX
|
||||||
|
XOR EAX,EAX
|
||||||
|
MOV [EBX],AL
|
||||||
|
LEA EAX,[EBP-8]
|
||||||
|
MOV EBX,EAX
|
||||||
|
MOV EAX, [EBX]
|
||||||
|
MOV ESP,EBP
|
||||||
|
POP EBP
|
||||||
|
RET
|
||||||
|
|
29
programs/develop/scc/GETARG.C
Normal file
29
programs/develop/scc/GETARG.C
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
/*
|
||||||
|
** Get command line argument.
|
||||||
|
** Entry: n = Number of the argument.
|
||||||
|
** s = Destination string pointer.
|
||||||
|
** size = Size of destination string.
|
||||||
|
** argc = Argument count from main().
|
||||||
|
** argv = Argument vector(s) from main().
|
||||||
|
** Returns number of characters moved on success,
|
||||||
|
** else EOF.
|
||||||
|
*/
|
||||||
|
getarg(n,s,size,argc,argv)
|
||||||
|
int n; char *s; int size,argc,argv[];
|
||||||
|
{char *str;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(n<0 | n>=argc)
|
||||||
|
{*s=NULL;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
i=0;
|
||||||
|
str=argv[n];
|
||||||
|
while(i<size)
|
||||||
|
{if((s[i]=str[i])==NULL) break;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
s[i]=NULL;
|
||||||
|
return i;
|
||||||
|
}
|
140
programs/develop/scc/INTRINS.ASM
Normal file
140
programs/develop/scc/INTRINS.ASM
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
;
|
||||||
|
; Small-C Run Time Library for Win NT
|
||||||
|
;
|
||||||
|
; Nasm version 17/Nov/98 H T Walheim
|
||||||
|
; Revised: 20/Nov/98 HTW [Bugs in switch]
|
||||||
|
;
|
||||||
|
|
||||||
|
_CCARGC:
|
||||||
|
;B+ Ellipses arguments ( ,...)
|
||||||
|
;cl - argument count
|
||||||
|
|
||||||
|
xor eax,eax
|
||||||
|
movzx eax,cl ; No sign-extension
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ Compare
|
||||||
|
|
||||||
|
__ult:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
ja true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__ugt:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
jb true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__ule:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
jae true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__uge:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
jbe true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__eq:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
je true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__ne:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
jne true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__lt:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
jg true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__gt:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
jl true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__le:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
jge true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__ge:
|
||||||
|
;B+ ???
|
||||||
|
cmp eax,ebx
|
||||||
|
jle true
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__lneg:
|
||||||
|
;B+ Logical Negate of Primary
|
||||||
|
or eax,eax
|
||||||
|
jnz false
|
||||||
|
true:
|
||||||
|
mov eax,1
|
||||||
|
ret
|
||||||
|
|
||||||
|
false:
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
__switch:
|
||||||
|
;B+ Execute "switch" statement
|
||||||
|
|
||||||
|
;eax - switch value
|
||||||
|
;[esp] - pointer to switch table
|
||||||
|
; dd addr1,value1
|
||||||
|
; ...
|
||||||
|
; dd 0
|
||||||
|
; [jmp default]
|
||||||
|
; continuation
|
||||||
|
;
|
||||||
|
; Revised: 20/Nov/98 [JECXZ needed]
|
||||||
|
|
||||||
|
pop ebx
|
||||||
|
jmp skip
|
||||||
|
back:
|
||||||
|
add ebx,8 ;next case-pair
|
||||||
|
skip:
|
||||||
|
mov ecx,[ebx] ;case-label location (adress)
|
||||||
|
jecxz default
|
||||||
|
cmp eax,[ebx+4] ;test case-value
|
||||||
|
jnz back
|
||||||
|
jmp ecx ;match -- jump to case
|
||||||
|
default:
|
||||||
|
add ebx,4
|
||||||
|
jmp ebx ;jump to default/continuation
|
||||||
|
;E:.
|
2699
programs/develop/scc/LIBSTD.ASM
Normal file
2699
programs/develop/scc/LIBSTD.ASM
Normal file
File diff suppressed because it is too large
Load Diff
440
programs/develop/scc/Libstd.c
Normal file
440
programs/develop/scc/Libstd.c
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
#include "stdio.h"
|
||||||
|
#include "clib.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Write string to standard output.
|
||||||
|
*/
|
||||||
|
puts(string) char *string;
|
||||||
|
{fputs(string,stdout);
|
||||||
|
OS_fputc('\n',stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** reverse string in place
|
||||||
|
*/
|
||||||
|
reverse(s) char *s;
|
||||||
|
{char *j; int c;
|
||||||
|
|
||||||
|
j=s+strlen(s)-1;
|
||||||
|
while(s<j)
|
||||||
|
{c=*s;
|
||||||
|
*s++ =*j;
|
||||||
|
*j-- =c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** copy t to s
|
||||||
|
*/
|
||||||
|
strcpy(s,t) char *s,*t;
|
||||||
|
{char *d;
|
||||||
|
|
||||||
|
d=s;
|
||||||
|
while(*s++ =*t++);
|
||||||
|
return (d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** return length of string s (fast version)
|
||||||
|
*/
|
||||||
|
strlen(s) char *s;
|
||||||
|
{char *ptr;
|
||||||
|
|
||||||
|
ptr=s;
|
||||||
|
while(*ptr)
|
||||||
|
{++ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ptr-s);
|
||||||
|
|
||||||
|
#ifdef _INASM
|
||||||
|
#asm
|
||||||
|
xor al,al ; set search value to zero
|
||||||
|
mov cx,65535 ; set huge maximum
|
||||||
|
mov di,[bp+4] ; get address of s
|
||||||
|
cld ; set direction flag forward
|
||||||
|
repne scasb ; scan for zero
|
||||||
|
mov ax,65534
|
||||||
|
sub ax,cx ; calc and return length
|
||||||
|
#endasm
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** return upper-case of c if it is lower-case, else c
|
||||||
|
*/
|
||||||
|
toupper(c) int c;
|
||||||
|
{if(c<='z' && c>='a') return (c-32);
|
||||||
|
return (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** atoi(s) - convert s to integer.
|
||||||
|
*/
|
||||||
|
atoi(s) char *s;
|
||||||
|
{int sign,n;
|
||||||
|
|
||||||
|
while(isspace(*s)) ++s;
|
||||||
|
sign = 1;
|
||||||
|
switch(*s)
|
||||||
|
{case '-': sign=-1;
|
||||||
|
case '+': ++s;
|
||||||
|
}
|
||||||
|
n=0;
|
||||||
|
while(isdigit(*s)) n=10*n+*s++ -'0';
|
||||||
|
return (sign*n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** atoib(s,b) - Convert s to "unsigned" integer in base b.
|
||||||
|
** NOTE: This is a non-standard function.
|
||||||
|
*/
|
||||||
|
atoib(s,b) char *s; int b;
|
||||||
|
{int n, digit;
|
||||||
|
|
||||||
|
n=0;
|
||||||
|
while(isspace(*s)) ++s;
|
||||||
|
while((digit=(127 & *s++))>='0')
|
||||||
|
{ if(digit>='a') digit-=87;
|
||||||
|
else if(digit>='A') digit-=55;
|
||||||
|
else digit -= '0';
|
||||||
|
if(digit>=b) break;
|
||||||
|
n=b*n+digit;
|
||||||
|
}
|
||||||
|
return (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Gets an entire string (including its newline
|
||||||
|
** terminator) or size-1 characters, whichever comes
|
||||||
|
** first. The input is terminated by a null character.
|
||||||
|
** Entry: str = Pointer to destination buffer.
|
||||||
|
** size = Size of the destination buffer.
|
||||||
|
** fd = File descriptor of pertinent file.
|
||||||
|
** Returns str on success, else NULL.
|
||||||
|
*/
|
||||||
|
fgets(str,size,fd) char *str; unsigned size,fd;
|
||||||
|
{return (_gets(str,size,fd,1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Gets an entire string from stdin (excluding its newline
|
||||||
|
** terminator) or size-1 characters, whichever comes
|
||||||
|
** first. The input is terminated by a null character.
|
||||||
|
** The user buffer must be large enough to hold the data.
|
||||||
|
** Entry: str = Pointer to destination buffer.
|
||||||
|
** Returns str on success, else NULL.
|
||||||
|
*/
|
||||||
|
gets(str) char *str;
|
||||||
|
{return (_gets(str,32767,stdin,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
_gets(str,size,fd,nl) char *str; unsigned size,fd,nl;
|
||||||
|
{int backup; char *next;
|
||||||
|
|
||||||
|
next=str;
|
||||||
|
while(--size>0)
|
||||||
|
{switch (*next=fgetc(fd))
|
||||||
|
{case EOF:
|
||||||
|
*next=NULL;
|
||||||
|
if(next==str) return (NULL);
|
||||||
|
return (str);
|
||||||
|
|
||||||
|
case '\n':
|
||||||
|
*(next+nl)=NULL;
|
||||||
|
return (str);
|
||||||
|
|
||||||
|
case RUB: /* \b */
|
||||||
|
if(next>str) backup=1;
|
||||||
|
else backup=0;
|
||||||
|
goto backout;
|
||||||
|
|
||||||
|
case WIPE: /* \r */
|
||||||
|
backup=next-str;
|
||||||
|
backout:
|
||||||
|
if(0/*iscons(fd)*/)
|
||||||
|
{++size;
|
||||||
|
while(backup--)
|
||||||
|
{fputs("\b \b",stderr);
|
||||||
|
--next;++size;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
++next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*next = NULL;
|
||||||
|
return (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** fprintf(fd, ctlstring, arg, arg, ...) - Formatted print.
|
||||||
|
** Operates as described by Kernighan & Ritchie.
|
||||||
|
** b, c, d, o, s, u, and x specifications are supported.
|
||||||
|
** Note: b (binary) is a non-standard extension.
|
||||||
|
*/
|
||||||
|
fprintf(argc) int argc;
|
||||||
|
{int *nxtarg;
|
||||||
|
|
||||||
|
nxtarg=CCARGC()+&argc;
|
||||||
|
return(_print(*(--nxtarg),--nxtarg));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** printf(ctlstring, arg, arg, ...) - Formatted print.
|
||||||
|
** Operates as described by Kernighan & Ritchie.
|
||||||
|
** b, c, d, o, s, u, and x specifications are supported.
|
||||||
|
** Note: b (binary) is a non-standard extension.
|
||||||
|
*/
|
||||||
|
printf(argc) int argc;
|
||||||
|
{return(_print(stdout,CCARGC()+&argc-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** _print(fd, ctlstring, arg, arg, ...)
|
||||||
|
** Called by fprintf() and printf().
|
||||||
|
*/
|
||||||
|
_print(fd,nxtarg) int fd,*nxtarg;
|
||||||
|
{int arg,left,pad,cc,len,maxchr,width;
|
||||||
|
char *ctl,*sptr,str[17];
|
||||||
|
|
||||||
|
cc=0;
|
||||||
|
ctl=*nxtarg--;
|
||||||
|
while(*ctl)
|
||||||
|
{if(*ctl!='%') {OS_fputc(*ctl++,fd); ++cc; continue;}
|
||||||
|
else ++ctl;
|
||||||
|
if(*ctl=='%') {OS_fputc(*ctl++,fd); ++cc; continue;}
|
||||||
|
if(*ctl=='-') {left=1; ++ctl;} else left=0;
|
||||||
|
if(*ctl=='0') pad='0';
|
||||||
|
else pad=' ';
|
||||||
|
if(isdigit(*ctl))
|
||||||
|
{width=atoi(ctl++);
|
||||||
|
while(isdigit(*ctl)) ++ctl;
|
||||||
|
}else width=0;
|
||||||
|
if(*ctl=='.')
|
||||||
|
{maxchr=atoi(++ctl);
|
||||||
|
while(isdigit(*ctl)) ++ctl;
|
||||||
|
}else maxchr=0;
|
||||||
|
arg=*nxtarg--;
|
||||||
|
sptr=str;
|
||||||
|
switch(*ctl++)
|
||||||
|
{case 'c': str[0]=arg; str[1]=NULL; break;
|
||||||
|
case 's': sptr=arg; break;
|
||||||
|
case 'd': itoa(arg,str); break;
|
||||||
|
case 'b': itoab(arg,str,2); break;
|
||||||
|
case 'o': itoab(arg,str,8); break;
|
||||||
|
case 'u': itoab(arg,str,10); break;
|
||||||
|
case 'x': itoab(arg,str,16); break;
|
||||||
|
default: return (cc);
|
||||||
|
}
|
||||||
|
len=strlen(sptr);
|
||||||
|
if(maxchr && maxchr<len) len=maxchr;
|
||||||
|
if(width>len) width=width-len; else width=0;
|
||||||
|
if(!left) while(width--) {OS_fputc(pad,fd); ++cc;}
|
||||||
|
while(len--) {OS_fputc(*sptr++,fd); ++cc;}
|
||||||
|
if(left) while(width--) {OS_fputc(pad,fd); ++cc;}
|
||||||
|
}
|
||||||
|
return (cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Write a string to fd.
|
||||||
|
** Entry: string = Pointer to null-terminated string.
|
||||||
|
** fd = File descriptor of pertinent file.
|
||||||
|
*/
|
||||||
|
fputs(string,fd) char *string; int fd;
|
||||||
|
{while(*string)
|
||||||
|
OS_fputc(*string++,fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** All character classification functions except isascii().
|
||||||
|
** Integer argument (c) must be in ASCII range (0-127) for
|
||||||
|
** dependable answers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ALNUM 1
|
||||||
|
#define ALPHA 2
|
||||||
|
#define CNTRL 4
|
||||||
|
#define DIGIT 8
|
||||||
|
#define GRAPH 16
|
||||||
|
#define LOWER 32
|
||||||
|
#define PRINT 64
|
||||||
|
#define PUNCT 128
|
||||||
|
#define BLANK 256
|
||||||
|
#define UPPER 512
|
||||||
|
#define XDIGIT 1024
|
||||||
|
|
||||||
|
int _is[128] =
|
||||||
|
{0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
|
||||||
|
0x004, 0x104, 0x104, 0x104, 0x104, 0x104, 0x004, 0x004,
|
||||||
|
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
|
||||||
|
0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
|
||||||
|
0x140, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
|
||||||
|
0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
|
||||||
|
0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459,
|
||||||
|
0x459, 0x459, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
|
||||||
|
0x0D0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253,
|
||||||
|
0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
|
||||||
|
0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
|
||||||
|
0x253, 0x253, 0x253, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x0D0,
|
||||||
|
0x0D0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073,
|
||||||
|
0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
|
||||||
|
0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
|
||||||
|
0x073, 0x073, 0x073, 0x0D0, 0x0D0, 0x0D0, 0x0D0, 0x004
|
||||||
|
};
|
||||||
|
|
||||||
|
isalnum (c) int c; {return (_is[c] & ALNUM );} /* 'a'-'z', 'A'-'Z', '0'-'9' */
|
||||||
|
isalpha (c) int c; {return (_is[c] & ALPHA );} /* 'a'-'z', 'A'-'Z' */
|
||||||
|
iscntrl (c) int c; {return (_is[c] & CNTRL );} /* 0-31, 127 */
|
||||||
|
isdigit (c) int c; {return (_is[c] & DIGIT );} /* '0'-'9' */
|
||||||
|
isgraph (c) int c; {return (_is[c] & GRAPH );} /* '!'-'~' */
|
||||||
|
islower (c) int c; {return (_is[c] & LOWER );} /* 'a'-'z' */
|
||||||
|
isprint (c) int c; {return (_is[c] & PRINT );} /* ' '-'~' */
|
||||||
|
ispunct (c) int c; {return (_is[c] & PUNCT );} /* !alnum && !cntrl && !space */
|
||||||
|
isspace (c) int c; {return (_is[c] & BLANK );} /* HT, LF, VT, FF, CR, ' ' */
|
||||||
|
isupper (c) int c; {return (_is[c] & UPPER );} /* 'A'-'Z' */
|
||||||
|
isxdigit(c) int c; {return (_is[c] & XDIGIT);} /* '0'-'9', 'a'-'f', 'A'-'F' */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** itoa(n,s) - Convert n to characters in s
|
||||||
|
*/
|
||||||
|
itoa(n,s) char *s; int n;
|
||||||
|
{int sign;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
ptr=s;
|
||||||
|
if((sign=n)<0) n=-n;
|
||||||
|
do
|
||||||
|
{*ptr++ =n%10+'0';
|
||||||
|
}while((n=n/10)>0);
|
||||||
|
if(sign<0) *ptr++='-';
|
||||||
|
*ptr='\0';
|
||||||
|
reverse(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** itoab(n,s,b) - Convert "unsigned" n to characters in s using base b.
|
||||||
|
** NOTE: This is a non-standard function.
|
||||||
|
*/
|
||||||
|
itoab(n,s,b) int n; char *s; int b;
|
||||||
|
{char *ptr;
|
||||||
|
int lowbit;
|
||||||
|
ptr=s;
|
||||||
|
b >>= 1;
|
||||||
|
do
|
||||||
|
{lowbit=n&1;
|
||||||
|
n=(n>>1)&32767;
|
||||||
|
*ptr=((n%b)<<1)+lowbit;
|
||||||
|
if(*ptr<10) *ptr+='0';
|
||||||
|
else *ptr+=55;
|
||||||
|
++ptr;
|
||||||
|
}while(n/=b);
|
||||||
|
*ptr=0;
|
||||||
|
reverse(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** itod -- convert nbr to signed decimal string of width sz
|
||||||
|
** right adjusted, blank filled; returns str
|
||||||
|
**
|
||||||
|
** if sz > 0 terminate with null byte
|
||||||
|
** if sz = 0 find end of string
|
||||||
|
** if sz < 0 use last byte for data
|
||||||
|
*/
|
||||||
|
itod(nbr,str,sz) int nbr; char str[]; int sz;
|
||||||
|
{char sgn;
|
||||||
|
|
||||||
|
if(nbr<0) {nbr=-nbr; sgn='-';}
|
||||||
|
else sgn=' ';
|
||||||
|
if(sz>0) str[--sz]=NULL;
|
||||||
|
else if(sz<0) sz=-sz;
|
||||||
|
else while(str[sz]!=NULL) ++sz;
|
||||||
|
while(sz)
|
||||||
|
{str[--sz]=(nbr%10+'0');
|
||||||
|
if((nbr=nbr/10)==0) break;
|
||||||
|
}
|
||||||
|
if(sz) str[--sz]=sgn;
|
||||||
|
while(sz>0) str[--sz]=' ';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** itoo -- converts nbr to octal string of length sz
|
||||||
|
** right adjusted and blank filled, returns str
|
||||||
|
**
|
||||||
|
** if sz > 0 terminate with null byte
|
||||||
|
** if sz = 0 find end of string
|
||||||
|
** if sz < 0 use last byte for data
|
||||||
|
*/
|
||||||
|
itoo(nbr,str,sz) int nbr; char str[]; int sz;
|
||||||
|
{int digit;
|
||||||
|
|
||||||
|
if(sz>0) str[--sz]=0;
|
||||||
|
else if(sz<0) sz=-sz;
|
||||||
|
else while(str[sz]!=0) ++sz;
|
||||||
|
while(sz)
|
||||||
|
{digit=nbr&7;nbr=(nbr>>3)&8191;
|
||||||
|
str[--sz]=digit+48;
|
||||||
|
if(nbr==0) break;
|
||||||
|
}
|
||||||
|
while(sz) str[--sz]=' ';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** itou -- convert nbr to unsigned decimal string of width sz
|
||||||
|
** right adjusted, blank filled; returns str
|
||||||
|
**
|
||||||
|
** if sz > 0 terminate with null byte
|
||||||
|
** if sz = 0 find end of string
|
||||||
|
** if sz < 0 use last byte for data
|
||||||
|
*/
|
||||||
|
itou(nbr,str,sz) int nbr; char str[]; int sz;
|
||||||
|
{int lowbit;
|
||||||
|
|
||||||
|
if(sz>0) str[--sz]=NULL;
|
||||||
|
else if(sz<0) sz=-sz;
|
||||||
|
else while(str[sz]!=NULL) ++sz;
|
||||||
|
while(sz)
|
||||||
|
{lowbit=nbr&1;
|
||||||
|
nbr=(nbr>>1)&32767; /* divide by 2 */
|
||||||
|
str[--sz]=((nbr%5)<<1)+lowbit+'0';
|
||||||
|
if((nbr=nbr/5)==0) break;
|
||||||
|
}
|
||||||
|
while(sz) str[--sz]=' ';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** itox -- converts nbr to hex string of length sz
|
||||||
|
** right adjusted and blank filled, returns str
|
||||||
|
**
|
||||||
|
** if sz > 0 terminate with null byte
|
||||||
|
** if sz = 0 find end of string
|
||||||
|
** if sz < 0 use last byte for data
|
||||||
|
*/
|
||||||
|
|
||||||
|
itox(nbr,str,sz) int nbr; char str[]; int sz;
|
||||||
|
{int digit,offset;
|
||||||
|
|
||||||
|
if(sz>0) str[--sz]=0;
|
||||||
|
else if(sz<0) sz=-sz;
|
||||||
|
else while(str[sz]!=0) ++sz;
|
||||||
|
while(sz)
|
||||||
|
{digit=nbr&15;
|
||||||
|
nbr=nbr/16;
|
||||||
|
/*
|
||||||
|
nbr=(nbr>>4)&4095; // 268435455; // 0xFFFFFFF
|
||||||
|
*/
|
||||||
|
if(digit<10) offset=48;
|
||||||
|
else offset=55;
|
||||||
|
str[--sz]=digit+offset;
|
||||||
|
if(nbr==0) break;
|
||||||
|
}
|
||||||
|
while(sz) str[--sz]=' ';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
268
programs/develop/scc/MACROS.INC
Normal file
268
programs/develop/scc/MACROS.INC
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
; new application structure
|
||||||
|
macro meos_app_start
|
||||||
|
{
|
||||||
|
use32
|
||||||
|
org 0x0
|
||||||
|
|
||||||
|
db 'MENUET01'
|
||||||
|
dd 0x01
|
||||||
|
dd __start
|
||||||
|
dd __end
|
||||||
|
dd __memory
|
||||||
|
dd __stack
|
||||||
|
|
||||||
|
if used __params & ~defined __params
|
||||||
|
dd __params
|
||||||
|
else
|
||||||
|
dd 0x0
|
||||||
|
end if
|
||||||
|
|
||||||
|
dd 0x0
|
||||||
|
}
|
||||||
|
MEOS_APP_START fix meos_app_start
|
||||||
|
|
||||||
|
macro code
|
||||||
|
{
|
||||||
|
__start:
|
||||||
|
}
|
||||||
|
CODE fix code
|
||||||
|
|
||||||
|
macro data
|
||||||
|
{
|
||||||
|
__data:
|
||||||
|
}
|
||||||
|
DATA fix data
|
||||||
|
|
||||||
|
macro udata
|
||||||
|
{
|
||||||
|
if used __params & ~defined __params
|
||||||
|
__params:
|
||||||
|
db 0
|
||||||
|
__end:
|
||||||
|
rb 255
|
||||||
|
else
|
||||||
|
__end:
|
||||||
|
end if
|
||||||
|
__udata:
|
||||||
|
}
|
||||||
|
UDATA fix udata
|
||||||
|
|
||||||
|
macro meos_app_end
|
||||||
|
{
|
||||||
|
align 32
|
||||||
|
rb 2048
|
||||||
|
__stack:
|
||||||
|
__memory:
|
||||||
|
}
|
||||||
|
MEOS_APP_END fix meos_app_end
|
||||||
|
|
||||||
|
|
||||||
|
; macro for defining multiline text data
|
||||||
|
struc mstr [sstring]
|
||||||
|
{
|
||||||
|
forward
|
||||||
|
local ssize
|
||||||
|
virtual at 0
|
||||||
|
db sstring
|
||||||
|
ssize = $
|
||||||
|
end virtual
|
||||||
|
dd ssize
|
||||||
|
db sstring
|
||||||
|
common
|
||||||
|
dd -1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; strings
|
||||||
|
macro sz name,[data] { ; from MFAR [mike.dld]
|
||||||
|
common
|
||||||
|
if used name
|
||||||
|
label name
|
||||||
|
end if
|
||||||
|
forward
|
||||||
|
if used name
|
||||||
|
db data
|
||||||
|
end if
|
||||||
|
common
|
||||||
|
if used name
|
||||||
|
.size = $-name
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
macro lsz name,[lng,data] { ; from MFAR [mike.dld]
|
||||||
|
common
|
||||||
|
if used name
|
||||||
|
label name
|
||||||
|
end if
|
||||||
|
forward
|
||||||
|
if (used name)&(lang eq lng)
|
||||||
|
db data
|
||||||
|
end if
|
||||||
|
common
|
||||||
|
if used name
|
||||||
|
.size = $-name
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; easy system call macro
|
||||||
|
macro mpack dest, hsrc, lsrc
|
||||||
|
{
|
||||||
|
if (hsrc eqtype 0) & (lsrc eqtype 0)
|
||||||
|
mov dest, (hsrc) shl 16 + lsrc
|
||||||
|
else
|
||||||
|
if (hsrc eqtype 0) & (~lsrc eqtype 0)
|
||||||
|
mov dest, (hsrc) shl 16
|
||||||
|
add dest, lsrc
|
||||||
|
else
|
||||||
|
mov dest, hsrc
|
||||||
|
shl dest, 16
|
||||||
|
add dest, lsrc
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
macro __mov reg,a,b { ; mike.dld
|
||||||
|
if (~a eq)&(~b eq)
|
||||||
|
mpack reg,a,b
|
||||||
|
else if (~a eq)&(b eq)
|
||||||
|
mov reg,a
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
macro mcall a,b,c,d,e,f { ; mike.dld
|
||||||
|
__mov eax,a
|
||||||
|
__mov ebx,b
|
||||||
|
__mov ecx,c
|
||||||
|
__mov edx,d
|
||||||
|
__mov esi,e
|
||||||
|
__mov edi,f
|
||||||
|
int 0x40
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; language for programs
|
||||||
|
lang fix ru ; ru en fr ge fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; optimize the code for size
|
||||||
|
__regs fix <eax,ebx,ecx,edx,esi,edi,ebp,esp>
|
||||||
|
|
||||||
|
macro add arg1,arg2
|
||||||
|
{
|
||||||
|
if (arg2 eqtype 0)
|
||||||
|
if (arg2) = 1
|
||||||
|
inc arg1
|
||||||
|
else
|
||||||
|
add arg1,arg2
|
||||||
|
end if
|
||||||
|
else
|
||||||
|
add arg1,arg2
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
macro sub arg1,arg2
|
||||||
|
{
|
||||||
|
if (arg2 eqtype 0)
|
||||||
|
if (arg2) = 1
|
||||||
|
dec arg1
|
||||||
|
else
|
||||||
|
sub arg1,arg2
|
||||||
|
end if
|
||||||
|
else
|
||||||
|
sub arg1,arg2
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
macro mov arg1,arg2
|
||||||
|
{
|
||||||
|
if (arg1 in __regs) & (arg2 eqtype 0)
|
||||||
|
if (arg2) = 0
|
||||||
|
xor arg1,arg1
|
||||||
|
else if (arg2) = 1
|
||||||
|
xor arg1,arg1
|
||||||
|
inc arg1
|
||||||
|
else if (arg2) = -1
|
||||||
|
or arg1,-1
|
||||||
|
else if (arg2) > -128 & (arg2) < 128
|
||||||
|
push arg2
|
||||||
|
pop arg1
|
||||||
|
else
|
||||||
|
mov arg1,arg2
|
||||||
|
end if
|
||||||
|
else
|
||||||
|
mov arg1,arg2
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
macro struct name
|
||||||
|
{
|
||||||
|
virtual at 0
|
||||||
|
name name
|
||||||
|
sizeof.#name = $ - name
|
||||||
|
end virtual
|
||||||
|
}
|
||||||
|
|
||||||
|
; structures used in MeOS
|
||||||
|
struc process_information
|
||||||
|
{
|
||||||
|
.cpu_usage dd ? ; +0
|
||||||
|
.window_stack_position dw ? ; +4
|
||||||
|
.window_stack_value dw ? ; +6
|
||||||
|
.not_used1 dw ? ; +8
|
||||||
|
.process_name rb 12 ; +10
|
||||||
|
.memory_start dd ? ; +22
|
||||||
|
.used_memory dd ? ; +26
|
||||||
|
.PID dd ? ; +30
|
||||||
|
.x_start dd ? ; +34
|
||||||
|
.y_start dd ? ; +38
|
||||||
|
.x_size dd ? ; +42
|
||||||
|
.y_size dd ? ; +46
|
||||||
|
.slot_state dw ? ; +50
|
||||||
|
rb (1024-52)
|
||||||
|
}
|
||||||
|
struct process_information
|
||||||
|
|
||||||
|
struc system_colors
|
||||||
|
{
|
||||||
|
.frame dd ?
|
||||||
|
.grab dd ?
|
||||||
|
.grab_button dd ?
|
||||||
|
.grab_button_text dd ?
|
||||||
|
.grab_text dd ?
|
||||||
|
.work dd ?
|
||||||
|
.work_button dd ?
|
||||||
|
.work_button_text dd ?
|
||||||
|
.work_text dd ?
|
||||||
|
.work_graph dd ?
|
||||||
|
}
|
||||||
|
struct system_colors
|
||||||
|
|
||||||
|
|
||||||
|
; constants
|
||||||
|
|
||||||
|
; events
|
||||||
|
EV_IDLE = 0
|
||||||
|
EV_TIMER = 0
|
||||||
|
EV_REDRAW = 1
|
||||||
|
EV_KEY = 2
|
||||||
|
EV_BUTTON = 3
|
||||||
|
EV_EXIT = 4
|
||||||
|
EV_BACKGROUND = 5
|
||||||
|
EV_MOUSE = 6
|
||||||
|
EV_IPC = 7
|
||||||
|
EV_STACK = 8
|
||||||
|
|
||||||
|
; event mask bits for function 40
|
||||||
|
EVM_REDRAW = 1b
|
||||||
|
EVM_KEY = 10b
|
||||||
|
EVM_BUTTON = 100b
|
||||||
|
EVM_EXIT = 1000b
|
||||||
|
EVM_BACKGROUND = 10000b
|
||||||
|
EVM_MOUSE = 100000b
|
||||||
|
EVM_IPC = 1000000b
|
||||||
|
EVM_STACK = 10000000b
|
6
programs/develop/scc/NOTICE.H
Normal file
6
programs/develop/scc/NOTICE.H
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/*
|
||||||
|
** NOTICE.H -- Small C Signon Notice.
|
||||||
|
*/
|
||||||
|
#define VERSION "Small C 386/NT, Version 3.1, Revision Level 1\n"
|
||||||
|
#define CRIGHT1 "Copyright 1982-1998 J. E. Hendrix H T Walheim\n"
|
||||||
|
#define CRIGHT2 "2008 - port to KolibriOS (jacekm.pl@gmail.com)\n\n"
|
681
programs/develop/scc/OSFUNC.ASM
Normal file
681
programs/develop/scc/OSFUNC.ASM
Normal file
@ -0,0 +1,681 @@
|
|||||||
|
include "macros.inc"
|
||||||
|
;
|
||||||
|
; OS function implementation
|
||||||
|
; SmallC for KolibriOS
|
||||||
|
;
|
||||||
|
|
||||||
|
;B+ General definitions
|
||||||
|
|
||||||
|
;B+ File defs
|
||||||
|
;const
|
||||||
|
;param
|
||||||
|
BAD equ -1
|
||||||
|
files equ 100
|
||||||
|
save_buffer equ 0x20000 ;32
|
||||||
|
save_buffer_w equ 0x400000 ;32
|
||||||
|
save_file_name equ 0x20000
|
||||||
|
|
||||||
|
;system
|
||||||
|
EOF equ -1
|
||||||
|
|
||||||
|
;memory
|
||||||
|
fileinfo equ I_END
|
||||||
|
start_data equ (fileinfo+16384)
|
||||||
|
;
|
||||||
|
mem_heap equ 0x100000
|
||||||
|
;
|
||||||
|
g_handle equ 0x300000
|
||||||
|
;dword - pointer - relative to file
|
||||||
|
;dword - begin of file
|
||||||
|
;dword - file size
|
||||||
|
;dword - 0/1 <=> read/write
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
init_osfunc:
|
||||||
|
;B+ Init OS functions
|
||||||
|
;B+ Clear file handles
|
||||||
|
mov edi,g_handle
|
||||||
|
mov ecx,files
|
||||||
|
shl ecx,2 ;*4
|
||||||
|
xor eax,eax
|
||||||
|
cld
|
||||||
|
rep stosd
|
||||||
|
;E:.
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ Main OS functions
|
||||||
|
ppp dd 70
|
||||||
|
|
||||||
|
_OS_fopen:
|
||||||
|
;B+ Implement "fopen"
|
||||||
|
;esp+4 - mode
|
||||||
|
;esp+8 - file name
|
||||||
|
|
||||||
|
; mov eax,-1
|
||||||
|
; int 0x40
|
||||||
|
|
||||||
|
; mov ebx,[esp+8];
|
||||||
|
; push dword 10
|
||||||
|
; push dword [ppp]
|
||||||
|
; push ebx
|
||||||
|
; push dword 12
|
||||||
|
; call _outstrg
|
||||||
|
; add esp,4*4
|
||||||
|
; add [ppp],10
|
||||||
|
|
||||||
|
; cmp byte [ebx+8],0
|
||||||
|
; jne .l
|
||||||
|
; mov byte [ebx+8],'?'
|
||||||
|
;.l:
|
||||||
|
; cmp [ppp],80
|
||||||
|
; je .l
|
||||||
|
|
||||||
|
mov ecx , [esp+4] ; file mode
|
||||||
|
mov [file_mode],ecx
|
||||||
|
;B+ Copy file name
|
||||||
|
|
||||||
|
|
||||||
|
mov esi,[esp+8]
|
||||||
|
mov edi,[p_filename]
|
||||||
|
mov ecx,12
|
||||||
|
.next_copy:
|
||||||
|
lodsb
|
||||||
|
;fill name (space)
|
||||||
|
or al,al
|
||||||
|
jz .fill_space
|
||||||
|
;set upper case
|
||||||
|
cmp al,'a'
|
||||||
|
jb .good_char
|
||||||
|
cmp al,'z'
|
||||||
|
ja .good_char
|
||||||
|
add al,'A'-'a'
|
||||||
|
.good_char:
|
||||||
|
stosb
|
||||||
|
dec ecx
|
||||||
|
jnz .next_copy
|
||||||
|
.fill_space:
|
||||||
|
mov al,' '
|
||||||
|
cld
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
mov eax,[file_mode]
|
||||||
|
cmp byte [eax],'w'
|
||||||
|
jne .no_wri
|
||||||
|
|
||||||
|
|
||||||
|
;B+ Copy file name
|
||||||
|
mov esi,[esp+8]
|
||||||
|
mov edi,[w_file_name]
|
||||||
|
mov ecx,12
|
||||||
|
.next_copy2:
|
||||||
|
lodsb
|
||||||
|
;fill name (space)
|
||||||
|
or al,al
|
||||||
|
jz .fill_space2
|
||||||
|
;set upper case
|
||||||
|
cmp al,'a'
|
||||||
|
jb .good_char2
|
||||||
|
cmp al,'z'
|
||||||
|
ja .good_char2
|
||||||
|
add al,'A'-'a'
|
||||||
|
.good_char2:
|
||||||
|
stosb
|
||||||
|
dec ecx
|
||||||
|
jnz .next_copy2
|
||||||
|
.fill_space2:
|
||||||
|
mov al,' '
|
||||||
|
cld
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
.no_wri:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;E:.
|
||||||
|
;B+ Find file handle
|
||||||
|
mov eax,g_handle
|
||||||
|
.new_handle:
|
||||||
|
cmp dword [eax+4],0
|
||||||
|
je .find_place
|
||||||
|
add eax,16
|
||||||
|
cmp eax,g_handle+files*16-16
|
||||||
|
jne .new_handle
|
||||||
|
xor eax,eax ; no free handle
|
||||||
|
ret
|
||||||
|
.find_place:
|
||||||
|
; TMP: mov eax,[.ccc]
|
||||||
|
; TMP: add [.ccc],16
|
||||||
|
;E:.
|
||||||
|
push eax
|
||||||
|
;B+ Test open mode
|
||||||
|
mov eax,[esp+4+4]
|
||||||
|
cmp byte [eax],'r'
|
||||||
|
je .open_read
|
||||||
|
cmp byte [eax],'w'
|
||||||
|
je .open_write
|
||||||
|
;bad mode
|
||||||
|
add esp,4
|
||||||
|
mov eax,eax ; invalid open mode
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
; TMP:.ccc dd g_handle
|
||||||
|
|
||||||
|
.open_read:
|
||||||
|
;B+ Open for read
|
||||||
|
;B+ Read file
|
||||||
|
|
||||||
|
;Wait to read correct
|
||||||
|
mov ebx,100
|
||||||
|
mov eax,5
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
mov eax,[g_fileend]
|
||||||
|
mov dword [file_parameters+2*4],2000 ;read all
|
||||||
|
mov dword [file_parameters+3*4],eax
|
||||||
|
|
||||||
|
mov dword [file_parameters],0
|
||||||
|
mov ebx,file_parameters
|
||||||
|
mov eax,58
|
||||||
|
int 0x40
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ TEST FILE FOUND
|
||||||
|
or eax,eax
|
||||||
|
jz .file_found
|
||||||
|
cmp eax,5
|
||||||
|
je .file_found
|
||||||
|
|
||||||
|
; mov ecx,eax ; eax
|
||||||
|
; mov ebx,8 shl 16 + 0x0100
|
||||||
|
; mov edx,100 shl 16 + 120
|
||||||
|
; mov esi,0xffffff
|
||||||
|
; mov eax,47
|
||||||
|
; int 0x40
|
||||||
|
|
||||||
|
;file not found - return 0
|
||||||
|
add esp,4
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
.file_found:
|
||||||
|
;E:.
|
||||||
|
pop eax
|
||||||
|
push ebx
|
||||||
|
xchg eax,ebx
|
||||||
|
;B+ Fill file handle
|
||||||
|
;save current pointer
|
||||||
|
xor eax,eax
|
||||||
|
mov [ebx],eax
|
||||||
|
|
||||||
|
;save file begin
|
||||||
|
mov eax,[g_fileend]
|
||||||
|
mov [ebx+4],eax
|
||||||
|
|
||||||
|
;save file size
|
||||||
|
pop eax
|
||||||
|
mov [ebx+8],eax
|
||||||
|
;reserve file zone
|
||||||
|
add eax,7
|
||||||
|
and eax,not 7
|
||||||
|
add [g_fileend],eax
|
||||||
|
|
||||||
|
;save file mode
|
||||||
|
mov eax,0 ;read
|
||||||
|
mov [ebx+12],eax
|
||||||
|
;E:.
|
||||||
|
xchg eax,ebx ;return pointer place
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
.open_write:
|
||||||
|
;B+ Open for write
|
||||||
|
;B+ Reserve filename
|
||||||
|
|
||||||
|
; p_filename -> w_file_name
|
||||||
|
|
||||||
|
;pusha
|
||||||
|
; mov eax, w_file_name
|
||||||
|
; mov ebx, [p_filename]
|
||||||
|
;.ncpy:
|
||||||
|
; mov ch, byte [ebx]
|
||||||
|
; cmp ch, 0
|
||||||
|
; je .ecpy
|
||||||
|
; mov [eax], ch
|
||||||
|
; inc dword [eax]
|
||||||
|
; inc dword [ebx]
|
||||||
|
;jmp .ncpy
|
||||||
|
;
|
||||||
|
;.ecpy:
|
||||||
|
;
|
||||||
|
;popa
|
||||||
|
|
||||||
|
mov [save_buffer_p], save_buffer_w
|
||||||
|
|
||||||
|
mov esi,[p_filename]
|
||||||
|
mov edi,[g_fileend]
|
||||||
|
mov ecx,12
|
||||||
|
cld
|
||||||
|
rep movsb
|
||||||
|
add [g_fileend],16
|
||||||
|
;E:.
|
||||||
|
pop ebx
|
||||||
|
;B+ Fill file handle
|
||||||
|
;save begin pointer
|
||||||
|
xor eax,eax
|
||||||
|
mov [ebx],eax
|
||||||
|
|
||||||
|
;save file begin
|
||||||
|
mov eax,[g_fileend]
|
||||||
|
mov [ebx+4],eax
|
||||||
|
|
||||||
|
;save file zone
|
||||||
|
mov dword [ebx+8],save_buffer
|
||||||
|
;reserve file zone
|
||||||
|
add [g_fileend],save_buffer
|
||||||
|
|
||||||
|
;save file mode
|
||||||
|
mov eax,1 ;write
|
||||||
|
mov [ebx+12],eax
|
||||||
|
;E:.
|
||||||
|
xchg eax,ebx ;return pointer place
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
_OS_fclos:
|
||||||
|
;B+ Close file
|
||||||
|
;esp+4 - file handle
|
||||||
|
|
||||||
|
;B+ Test write mode - save file
|
||||||
|
mov eax,[esp+4]
|
||||||
|
mov eax,[eax+12]
|
||||||
|
cmp eax,1
|
||||||
|
;E:.
|
||||||
|
jne .no_write
|
||||||
|
|
||||||
|
mov eax, [esp+4]
|
||||||
|
mov ecx, [eax]
|
||||||
|
mov ebx, [eax+8]
|
||||||
|
|
||||||
|
mov ebx, [save_buffer_p]
|
||||||
|
sub ebx, save_buffer_w
|
||||||
|
; ebx = number of read bytes = file size
|
||||||
|
; save loaded file
|
||||||
|
mov [dest_info.bytes],ebx ; file size in bytes
|
||||||
|
|
||||||
|
mov [dest_info.bytes+4], save_buffer_w
|
||||||
|
;mov eax, [p_filename];[w_file_name]
|
||||||
|
;mov [destination],eax
|
||||||
|
mov eax,70
|
||||||
|
mov ebx,dest_info
|
||||||
|
mcall
|
||||||
|
|
||||||
|
; check if 58 function failed
|
||||||
|
test eax,eax
|
||||||
|
je .ok_write
|
||||||
|
add eax,7 ; error number += 7
|
||||||
|
cmp eax,6+7
|
||||||
|
jna .copy_error
|
||||||
|
mov eax,7+7
|
||||||
|
jmp .copy_error
|
||||||
|
|
||||||
|
.copy_error:
|
||||||
|
.ok_write:
|
||||||
|
|
||||||
|
|
||||||
|
;E:.
|
||||||
|
jmp .read
|
||||||
|
|
||||||
|
.no_write:
|
||||||
|
;B+ Test read mode - if no error end
|
||||||
|
cmp eax,0
|
||||||
|
je .read
|
||||||
|
mov eax,BAD
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
.read:
|
||||||
|
|
||||||
|
;B+ Relace memory
|
||||||
|
;find file size
|
||||||
|
mov eax,[esp+4]
|
||||||
|
mov ecx,[eax+8]
|
||||||
|
add ecx,7
|
||||||
|
and ecx,not 7
|
||||||
|
push ecx
|
||||||
|
|
||||||
|
;mov memory
|
||||||
|
mov esi,[eax+4]
|
||||||
|
mov edi,esi
|
||||||
|
add esi,ecx
|
||||||
|
mov ecx,[g_fileend]
|
||||||
|
sub ecx,edi
|
||||||
|
jz .is_last
|
||||||
|
shr ecx,2
|
||||||
|
inc ecx ;not neccessery
|
||||||
|
cld
|
||||||
|
rep movsd
|
||||||
|
;update gl. memory
|
||||||
|
.is_last:
|
||||||
|
pop ecx
|
||||||
|
sub dword [g_fileend],ecx
|
||||||
|
|
||||||
|
;update file pointers
|
||||||
|
mov edx,ecx
|
||||||
|
mov ecx,[eax+4]
|
||||||
|
mov eax,g_handle
|
||||||
|
.new_handle1:
|
||||||
|
mov ebx,[eax+4]
|
||||||
|
cmp ebx,ecx
|
||||||
|
jbe .no_update
|
||||||
|
sub ebx,edx
|
||||||
|
mov [eax+4],ebx
|
||||||
|
.no_update:
|
||||||
|
add eax,16
|
||||||
|
cmp eax,g_handle+files*16
|
||||||
|
jne .new_handle1
|
||||||
|
|
||||||
|
;clear handle
|
||||||
|
mov edi,[esp+4]
|
||||||
|
xor eax,eax
|
||||||
|
cld
|
||||||
|
stosd
|
||||||
|
stosd
|
||||||
|
stosd
|
||||||
|
stosd
|
||||||
|
;E:.
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
_OS_fgetc:
|
||||||
|
;B+ Load char from file
|
||||||
|
;esp+4 - input file
|
||||||
|
|
||||||
|
mov eax,[esp+4]
|
||||||
|
mov ebx,[eax]
|
||||||
|
cmp ebx,[eax+8]
|
||||||
|
je .eof
|
||||||
|
inc dword [eax]
|
||||||
|
add ebx,[eax+4]
|
||||||
|
movzx eax,byte [ebx]
|
||||||
|
ret
|
||||||
|
.eof:
|
||||||
|
mov eax,EOF
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;rrr db 'g',0
|
||||||
|
|
||||||
|
_OS_fputc:
|
||||||
|
;B+ Save char to file
|
||||||
|
;esp+4 - output file
|
||||||
|
;esp+8 - char to write
|
||||||
|
|
||||||
|
;push dword '<'
|
||||||
|
;mov cl,1
|
||||||
|
;push dword 0
|
||||||
|
;call test_outch
|
||||||
|
;add esp,8
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;B+ Temp - write direct.
|
||||||
|
cmp dword [esp+4],__iob
|
||||||
|
jne .real_write0
|
||||||
|
jmp _OS_exit
|
||||||
|
.real_write0:
|
||||||
|
cmp dword [esp+4],__iob+32
|
||||||
|
jne .real_write1
|
||||||
|
mov [print_textcolor],0x00ffff
|
||||||
|
jmp test_outch
|
||||||
|
.real_write1:
|
||||||
|
cmp dword [esp+4],__iob+64
|
||||||
|
jne .real_write2
|
||||||
|
mov [print_textcolor],0x77ffff
|
||||||
|
jmp test_outch
|
||||||
|
.real_write2:
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
mov ebx,[save_buffer_p]
|
||||||
|
mov eax,[esp+8]
|
||||||
|
mov [ebx],eax
|
||||||
|
inc dword [save_buffer_p]
|
||||||
|
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
;push dword '<'
|
||||||
|
;mov cl,1
|
||||||
|
;push dword 0
|
||||||
|
;call test_outch
|
||||||
|
;add esp,8
|
||||||
|
|
||||||
|
mov eax,[esp+4]
|
||||||
|
mov ebx,[eax]
|
||||||
|
push ebx
|
||||||
|
cmp ebx,[eax+8]
|
||||||
|
jne .write_normal
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;B+ Alloc save_buffer bytes
|
||||||
|
;mov memory
|
||||||
|
mov ebx,[esp+4+4]
|
||||||
|
mov esi,[g_fileend]
|
||||||
|
mov edi,esi
|
||||||
|
add edi,save_buffer-4
|
||||||
|
mov ecx,esi
|
||||||
|
sub ecx,[ebx+4]
|
||||||
|
sub ecx,[ebx+8]
|
||||||
|
shr ecx,2
|
||||||
|
jz .is_last
|
||||||
|
sub esi,4
|
||||||
|
std
|
||||||
|
rep movsd
|
||||||
|
.is_last:
|
||||||
|
|
||||||
|
;expand file size
|
||||||
|
add dword [eax+8],save_buffer
|
||||||
|
|
||||||
|
;update file pointers
|
||||||
|
mov ebx,g_handle
|
||||||
|
.new_handle:
|
||||||
|
mov ecx,[ebx+4]
|
||||||
|
cmp [eax+4],ecx
|
||||||
|
jae .no_update
|
||||||
|
add dword [ebx+4],save_buffer
|
||||||
|
.no_update:
|
||||||
|
add ebx,16
|
||||||
|
cmp ebx,g_handle+files*16-16
|
||||||
|
jne .new_handle
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
.write_normal:
|
||||||
|
pop ebx
|
||||||
|
inc dword [eax]
|
||||||
|
add ebx,[eax+4]
|
||||||
|
mov cl,[esp+8]
|
||||||
|
mov byte [ebx],cl
|
||||||
|
|
||||||
|
;sub [test_outch.x_coord],2
|
||||||
|
;
|
||||||
|
;push dword '>'
|
||||||
|
;mov cl,1
|
||||||
|
;push dword 0
|
||||||
|
;call test_outch
|
||||||
|
;add esp,8
|
||||||
|
;
|
||||||
|
;sub [test_outch.x_coord],6
|
||||||
|
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
_OS_callo:
|
||||||
|
;B+ Alloc memory
|
||||||
|
;find all size
|
||||||
|
mov eax,[esp+4]
|
||||||
|
mov ebx,[esp+8]
|
||||||
|
mul ebx
|
||||||
|
push eax
|
||||||
|
|
||||||
|
;clear memory
|
||||||
|
mov edi,[.mem_p]
|
||||||
|
xor eax,eax
|
||||||
|
mov ecx,[esp]
|
||||||
|
cld
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
;update new memory pointer
|
||||||
|
pop ebx
|
||||||
|
push dword [.mem_p]
|
||||||
|
add ebx,7
|
||||||
|
and ebx,not 7
|
||||||
|
add [.mem_p],ebx
|
||||||
|
|
||||||
|
;return value
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.mem_p dd mem_heap
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
_OS_exit:
|
||||||
|
;B+ Exit program
|
||||||
|
; ;TMP
|
||||||
|
; mov eax,-1
|
||||||
|
; int 0x40
|
||||||
|
mov esp,[exit_esp]
|
||||||
|
sub esp,4
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;B+ Test procedures
|
||||||
|
|
||||||
|
;B+ Definitions
|
||||||
|
LEFTMARGIN equ 11
|
||||||
|
BEGIN_CHARS equ 20
|
||||||
|
NL equ 10
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
print_textcolor dd 0x00ffff
|
||||||
|
|
||||||
|
_file_beg:
|
||||||
|
;B+ Show begin of file - test fopen
|
||||||
|
;esp+4 - file handle (descriptor)
|
||||||
|
|
||||||
|
mov eax,[esp+4]
|
||||||
|
mov ebx,10 shl 16 + 30
|
||||||
|
mov ecx,[print_textcolor]
|
||||||
|
mov edx,[eax+4]
|
||||||
|
mov esi,BEGIN_CHARS
|
||||||
|
mov eax,4
|
||||||
|
int 0x40
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
_outstrg:
|
||||||
|
;B+ Draw black text - test function call
|
||||||
|
;esp+4*4 - x
|
||||||
|
;esp+4*3 - y
|
||||||
|
;esp+4*2 - *c
|
||||||
|
;esp+4*1 - len
|
||||||
|
|
||||||
|
mov ebx,[esp+4*4]
|
||||||
|
shl ebx,16
|
||||||
|
mov bx,[esp+4*3]
|
||||||
|
mov ecx,[print_textcolor]
|
||||||
|
mov edx,[esp+4*2]
|
||||||
|
mov esi,[esp+4]
|
||||||
|
mov eax,4
|
||||||
|
int 0x40
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
test_outch:
|
||||||
|
;B+ Draw one char - use as _OS_fputc, to test printf(...)
|
||||||
|
;esp+8 - char to write
|
||||||
|
|
||||||
|
;this is test! \b \r - not nesessary
|
||||||
|
|
||||||
|
mov al,[esp+8]
|
||||||
|
cmp al,NL
|
||||||
|
jne .no_newline
|
||||||
|
add [.y_coord],10
|
||||||
|
mov [.x_coord],LEFTMARGIN
|
||||||
|
ret
|
||||||
|
.no_newline:
|
||||||
|
|
||||||
|
mov ebx,[.x_coord]
|
||||||
|
shl ebx,16
|
||||||
|
mov bx,word [.y_coord]
|
||||||
|
mov ecx,[print_textcolor]
|
||||||
|
mov [.out_char],al
|
||||||
|
mov edx,.out_char
|
||||||
|
mov esi,1
|
||||||
|
mov eax,4
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
add [.x_coord],6
|
||||||
|
;mov eax,5
|
||||||
|
;mov ebx,5
|
||||||
|
;int 0x40
|
||||||
|
ret
|
||||||
|
|
||||||
|
.x_coord dd LEFTMARGIN
|
||||||
|
.y_coord dd 60
|
||||||
|
.out_char db 0
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ Data section
|
||||||
|
;B+ Memory managment
|
||||||
|
g_fileend dd g_handle+files*4*4 ;from 2MB+100*4*4
|
||||||
|
;w_buff dd
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
save_buffer_p dd save_buffer_w
|
||||||
|
;B+ File parameters
|
||||||
|
file_parameters:
|
||||||
|
dd 0x0 ; mode
|
||||||
|
dd 0x0 ; first block
|
||||||
|
dd 1000 ; block read
|
||||||
|
dd -1 ; return place
|
||||||
|
dd fileinfo ; work area
|
||||||
|
filepath: times 100 db 0
|
||||||
|
|
||||||
|
file_mode dd 0 ;file mode
|
||||||
|
|
||||||
|
dest_info: ; DESTINATION FILEINFO
|
||||||
|
dd 2
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
.bytes dd ?
|
||||||
|
dd save_buffer
|
||||||
|
db 0
|
||||||
|
destination:
|
||||||
|
dd save_file_name
|
||||||
|
;db "EXAMPLE.ASM",0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
w_file_name dd save_file_name
|
||||||
|
|
||||||
|
p_filename dd 0x0
|
||||||
|
;E:.
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;TO DO
|
||||||
|
mov eax,-1
|
||||||
|
int 0x40
|
||||||
|
;TO DO
|
||||||
|
|
18
programs/develop/scc/README.TXT
Normal file
18
programs/develop/scc/README.TXT
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
##############################
|
||||||
|
# SCC (simple c compiler)
|
||||||
|
# port of CCOMP to KolibriOS
|
||||||
|
#
|
||||||
|
######
|
||||||
|
# contact: jacekm.pl@gmail.com
|
||||||
|
##############################
|
||||||
|
|
||||||
|
KNOWN BUGS:
|
||||||
|
* only directiory /rd/1/ works
|
||||||
|
|
||||||
|
HISTORY:
|
||||||
|
* 0.5.3:
|
||||||
|
- output dir fixed
|
||||||
|
* 0.5.2:
|
||||||
|
- static output file
|
||||||
|
* 0.5.1:
|
||||||
|
- first realase
|
392
programs/develop/scc/SCC.ASM
Normal file
392
programs/develop/scc/SCC.ASM
Normal file
@ -0,0 +1,392 @@
|
|||||||
|
;
|
||||||
|
; Port to KolibliOS
|
||||||
|
; (jacekm.pl@gmail.com)
|
||||||
|
;
|
||||||
|
|
||||||
|
;B+ System header
|
||||||
|
use32
|
||||||
|
org 0x0
|
||||||
|
db 'MENUET01'
|
||||||
|
dd 0x01
|
||||||
|
dd START
|
||||||
|
dd I_END
|
||||||
|
dd 0x500000
|
||||||
|
dd 0x7fff0
|
||||||
|
dd 0x0,0x0
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ Include C files
|
||||||
|
; Compiler tools
|
||||||
|
include "INTRINS.ASM"
|
||||||
|
|
||||||
|
; C Library ("stdio.asm")
|
||||||
|
include "LIBSTD.ASM"
|
||||||
|
|
||||||
|
; MenuetOS implement
|
||||||
|
include "OSFUNC.ASM"
|
||||||
|
|
||||||
|
_fopen equ _OS_fopen
|
||||||
|
_fputc equ _OS_fputc
|
||||||
|
_fgetc equ _OS_fgetc
|
||||||
|
_fclose equ _OS_fclos
|
||||||
|
|
||||||
|
;Main program (compiled from C)
|
||||||
|
include "GETARG.ASM"
|
||||||
|
include "CC1.ASM"
|
||||||
|
include "CC2.ASM"
|
||||||
|
include "CC3.ASM"
|
||||||
|
include "CC4.ASM"
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
START:
|
||||||
|
;B+ Main cycle
|
||||||
|
call draw_window
|
||||||
|
still:
|
||||||
|
mov eax,10
|
||||||
|
int 0x40
|
||||||
|
still1:
|
||||||
|
|
||||||
|
cmp eax,1
|
||||||
|
je red
|
||||||
|
cmp eax,2
|
||||||
|
je key
|
||||||
|
cmp eax,3
|
||||||
|
je button
|
||||||
|
jmp still
|
||||||
|
|
||||||
|
red:
|
||||||
|
call draw_window
|
||||||
|
jmp still
|
||||||
|
|
||||||
|
key:
|
||||||
|
mov eax,2
|
||||||
|
int 0x40
|
||||||
|
jmp still
|
||||||
|
|
||||||
|
button:
|
||||||
|
mov eax,17
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
cmp ah,1
|
||||||
|
jne .noclose
|
||||||
|
mov eax,-1
|
||||||
|
int 0x40
|
||||||
|
.noclose:
|
||||||
|
|
||||||
|
cmp ah,2
|
||||||
|
jne .no_run
|
||||||
|
; call begin_osfunc
|
||||||
|
;B+ Copy file path
|
||||||
|
mov esi,inp_path
|
||||||
|
mov edi,filepath
|
||||||
|
mov ecx,[p_len]
|
||||||
|
push ecx
|
||||||
|
cld
|
||||||
|
rep movsb
|
||||||
|
pop ecx
|
||||||
|
add ecx,filepath
|
||||||
|
mov [p_filename],ecx
|
||||||
|
;E:.
|
||||||
|
;B+ Clear word area
|
||||||
|
mov ebx,10 shl 16 + 280
|
||||||
|
mov ecx,60 shl 16 + 250
|
||||||
|
mov edx,0x303030
|
||||||
|
mov eax,13
|
||||||
|
int 0x40
|
||||||
|
;E:.
|
||||||
|
;B+ Init parameters
|
||||||
|
mov ecx,_input
|
||||||
|
sub ecx,_nogo
|
||||||
|
mov edi,_nogo
|
||||||
|
xor eax,eax
|
||||||
|
cld
|
||||||
|
rep stosb
|
||||||
|
mov [_input],-1
|
||||||
|
mov [_input2],-1
|
||||||
|
mov [_usexpr],1
|
||||||
|
mov [_ccode],1
|
||||||
|
mov [_quote],34
|
||||||
|
mov [test_outch.y_coord],60
|
||||||
|
;E:.
|
||||||
|
call init_osfunc
|
||||||
|
push dword 4
|
||||||
|
push args
|
||||||
|
;B+ Save exit ESP
|
||||||
|
mov [exit_esp],esp
|
||||||
|
;E:.
|
||||||
|
call _main
|
||||||
|
add esp,8
|
||||||
|
; call end_osfunc
|
||||||
|
.no_run:
|
||||||
|
|
||||||
|
cmp ah,3
|
||||||
|
jne .no_path
|
||||||
|
mov eax,inp_path
|
||||||
|
mov bx,27
|
||||||
|
call read_string
|
||||||
|
mov edx,[r_pos]
|
||||||
|
mov [p_len],edx
|
||||||
|
;
|
||||||
|
cmp ah,10
|
||||||
|
je still
|
||||||
|
jmp still1
|
||||||
|
.no_path:
|
||||||
|
|
||||||
|
cmp ah,4
|
||||||
|
jne .no_file
|
||||||
|
mov eax,inp_file
|
||||||
|
mov bx,42
|
||||||
|
call read_string
|
||||||
|
mov edx,[r_pos]
|
||||||
|
mov [f_len],edx
|
||||||
|
;
|
||||||
|
cmp ah,10
|
||||||
|
je still
|
||||||
|
jmp still1
|
||||||
|
.no_file:
|
||||||
|
|
||||||
|
jmp still
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
read_string:
|
||||||
|
;B+ Read string
|
||||||
|
mov [c_place],eax
|
||||||
|
mov [r_pos],0
|
||||||
|
mov [rel_x],60
|
||||||
|
mov [rel_y],bx
|
||||||
|
|
||||||
|
mov ebx,60
|
||||||
|
shl ebx,16
|
||||||
|
mov bx,6*26+1
|
||||||
|
movzx ecx,[rel_y]
|
||||||
|
shl ecx,16
|
||||||
|
mov cx,10
|
||||||
|
mov edx,0x000000
|
||||||
|
mov eax,13
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
add ecx,11 shl 16
|
||||||
|
mov cx,2
|
||||||
|
mov edx,0x999999
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
.next:
|
||||||
|
mov ebx,[rel_x]
|
||||||
|
shl ebx,16
|
||||||
|
mov bx,7
|
||||||
|
movzx ecx,[rel_y]
|
||||||
|
shl ecx,16
|
||||||
|
mov cx,10
|
||||||
|
mov edx,0x000000
|
||||||
|
mov eax,13
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
mov ebx,[c_place]
|
||||||
|
mov byte [ebx],0
|
||||||
|
|
||||||
|
mov eax,10
|
||||||
|
int 0x40
|
||||||
|
cmp eax,2
|
||||||
|
je .key
|
||||||
|
jmp .to_ret
|
||||||
|
.key:
|
||||||
|
|
||||||
|
mov eax,2
|
||||||
|
int 0x40
|
||||||
|
cmp ah,13
|
||||||
|
jne .no_enter
|
||||||
|
jmp .to_ret
|
||||||
|
.no_enter:
|
||||||
|
|
||||||
|
cmp ah,8
|
||||||
|
jne .no_back
|
||||||
|
cmp [r_pos],0
|
||||||
|
je .next
|
||||||
|
dec [r_pos]
|
||||||
|
dec [c_place]
|
||||||
|
sub [rel_x],6
|
||||||
|
jmp .next
|
||||||
|
.no_back:
|
||||||
|
|
||||||
|
cmp [r_pos],25
|
||||||
|
je .next
|
||||||
|
|
||||||
|
cmp ah,'a'
|
||||||
|
jb .no_sm_l
|
||||||
|
cmp ah,'z'
|
||||||
|
ja .no_sm_l
|
||||||
|
add ah,'A'-'a'
|
||||||
|
.no_sm_l:
|
||||||
|
|
||||||
|
mov byte [ebx],ah
|
||||||
|
mov [char],ah
|
||||||
|
inc [c_place]
|
||||||
|
inc [r_pos]
|
||||||
|
|
||||||
|
mov ebx,[rel_x]
|
||||||
|
inc ebx
|
||||||
|
shl ebx,16
|
||||||
|
mov bx,[rel_y]
|
||||||
|
inc bx
|
||||||
|
mov ecx,0x00ffff
|
||||||
|
mov edx,char
|
||||||
|
mov esi,1
|
||||||
|
mov eax,4
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
add [rel_x],6
|
||||||
|
jmp .next
|
||||||
|
|
||||||
|
.to_ret:
|
||||||
|
push eax
|
||||||
|
mov ebx,60
|
||||||
|
shl ebx,16
|
||||||
|
mov bx,6*26+1
|
||||||
|
movzx ecx,[rel_y]
|
||||||
|
add ecx,11
|
||||||
|
shl ecx,16
|
||||||
|
mov cx,2
|
||||||
|
mov edx,0x000000
|
||||||
|
mov eax,13
|
||||||
|
int 0x40
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
rel_x dd 60
|
||||||
|
rel_y dw 0x0
|
||||||
|
c_place dd 0x0
|
||||||
|
r_pos dd 0x0
|
||||||
|
char db '?'
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
draw_window:
|
||||||
|
;B+ Draw window
|
||||||
|
mov eax,12
|
||||||
|
mov ebx,1
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
mov ebx,100*65536+300
|
||||||
|
mov ecx,100*65536+320
|
||||||
|
mov edx,0x035555DD
|
||||||
|
mov esi,0x805080d0
|
||||||
|
mov edi,0x005080d0
|
||||||
|
mov eax,0
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
mov ebx,8*65536+8
|
||||||
|
mov ecx,0x10ddeeff
|
||||||
|
mov edx,caption
|
||||||
|
mov esi,caption_end-caption
|
||||||
|
mov eax,4
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
;mov ebx,(300-19)*65536+12
|
||||||
|
;mov ecx,5*65536+12
|
||||||
|
;mov edx,1
|
||||||
|
;mov esi,0x6688dd
|
||||||
|
;mov eax,8
|
||||||
|
;int 0x40
|
||||||
|
|
||||||
|
;B+ Hot buttons
|
||||||
|
mov ebx,220 shl 16 + 70
|
||||||
|
mov ecx,25 shl 16 + 29
|
||||||
|
mov edx,2 ; compile
|
||||||
|
mov esi,0x6688dd
|
||||||
|
mov eax,8
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
mov ebx,10 shl 16 + 47
|
||||||
|
mov ecx,26 shl 16 + 12
|
||||||
|
mov edx,3 ; path
|
||||||
|
mov esi,0x6688dd
|
||||||
|
mov eax,8
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
mov ebx,10 shl 16 + 47
|
||||||
|
mov ecx,41 shl 16 + 12
|
||||||
|
mov edx,4 ; file name
|
||||||
|
mov esi,0x6688dd
|
||||||
|
mov eax,8
|
||||||
|
int 0x40
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ Text in buttons
|
||||||
|
mov ebx,231 shl 16 + 36
|
||||||
|
mov ecx,0x10ffffff
|
||||||
|
mov edx,txt_compile
|
||||||
|
mov esi,txt_compile_end-txt_compile
|
||||||
|
mov eax,4
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
mov ebx,14 shl 16 + 28
|
||||||
|
mov ecx,0xffffff
|
||||||
|
mov edx,txt_path
|
||||||
|
mov esi,txt_path_end-txt_path
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
mov ebx,14 shl 16 + 43
|
||||||
|
mov edx,txt_file
|
||||||
|
mov esi,txt_file_end-txt_file
|
||||||
|
int 0x40
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ Draw path / file name
|
||||||
|
mov ebx,61 shl 16 + 28
|
||||||
|
mov ecx,0x00ffff
|
||||||
|
mov edx,inp_path
|
||||||
|
mov esi,[p_len]
|
||||||
|
mov eax,4
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
mov ebx,61 shl 16 + 43
|
||||||
|
mov ecx,0x00ffff
|
||||||
|
mov edx,inp_file
|
||||||
|
mov esi,[f_len]
|
||||||
|
mov eax,4
|
||||||
|
int 0x40
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
mov eax,12
|
||||||
|
mov ebx,2
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
ret
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ Data area
|
||||||
|
|
||||||
|
;B+ Interface
|
||||||
|
inp_path: times 100 db '/RD/1/',0
|
||||||
|
p_len dd 6
|
||||||
|
inp_file: times 100 db 'EXAMPLE',0
|
||||||
|
f_len dd 7
|
||||||
|
|
||||||
|
txt_compile db 'Compile'
|
||||||
|
txt_compile_end:
|
||||||
|
txt_path db 'Path ->'
|
||||||
|
txt_path_end:
|
||||||
|
txt_file db 'File ->'
|
||||||
|
txt_file_end:
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ Main arguments
|
||||||
|
args dd arg_str0,inp_file,arg_str2,arg_str3,arg_str4
|
||||||
|
|
||||||
|
arg_str0 db 'CC',0
|
||||||
|
arg_str1 db 'prog',0
|
||||||
|
arg_str2 db '-m',0
|
||||||
|
arg_str3 db '-a',0
|
||||||
|
arg_str4 db '-p',0
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
;B+ System parameters
|
||||||
|
exit_esp dd 0x0
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
caption db 'Small C compiler for KolibriOS v 0.5.3'
|
||||||
|
caption_end:
|
||||||
|
|
||||||
|
times 8-($ mod 8) db 0
|
||||||
|
;E:.
|
||||||
|
|
||||||
|
I_END:
|
33
programs/develop/scc/STDIO.H
Normal file
33
programs/develop/scc/STDIO.H
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
** STDIO.H -- Standard Small C Definitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern char _iob[];
|
||||||
|
|
||||||
|
#define exit OS_exit
|
||||||
|
#define fopen OS_fopen
|
||||||
|
#define fgetc OS_fgetc
|
||||||
|
#define fputc OS_fputc
|
||||||
|
#define fclose OS_fclose
|
||||||
|
#define calloc OS_calloc // stdlib.h
|
||||||
|
|
||||||
|
#define SIZEOF_FILE 32 // sizeof (FILE)
|
||||||
|
|
||||||
|
#define stdin (&_iob[0])
|
||||||
|
#define stdout (&_iob[1*SIZEOF_FILE])
|
||||||
|
#define stderr (&_iob[2*SIZEOF_FILE])
|
||||||
|
|
||||||
|
#define stdaux 3 /* file descriptor for standard auxiliary port */
|
||||||
|
#define stdprn 4 /* file descriptor for standard printer */
|
||||||
|
#define FILE char /* supports "FILE *fp;" declarations */
|
||||||
|
#define ERR (-2) /* return value for errors */
|
||||||
|
#define EOF (-1) /* return value for end-of-file */
|
||||||
|
#define YES 1 /* true */
|
||||||
|
#define NO 0 /* false */
|
||||||
|
#define NULL 0 /* zero */
|
||||||
|
#define CR 13 /* ASCII carriage return */
|
||||||
|
#define LF 10 /* ASCII line feed */
|
||||||
|
#define BELL 7 /* ASCII bell */
|
||||||
|
#define SPACE ' ' /* ASCII space */
|
||||||
|
#define NEWLINE LF /* Small C newline character */
|
||||||
|
|
320
programs/develop/scc/cc.h
Normal file
320
programs/develop/scc/cc.h
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
/*
|
||||||
|
** CC.H -- Symbol Definitions for Small-C compiler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define YES 1 /* true */
|
||||||
|
#define NO 0 /* false */
|
||||||
|
#define CR 13 /* ASCII carriage return */
|
||||||
|
#define LF 10 /* ASCII line feed */
|
||||||
|
#define BELL 7 /* ASCII bell */
|
||||||
|
#define SPACE ' ' /* ASCII space */
|
||||||
|
#define NEWLINE LF /* Small C newline character */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** size of 'int'
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INT32 /* if #defined int = 32 bits, else 16 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** ALIGNMENT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ALIGN 4
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** machine dependent parameters
|
||||||
|
*/
|
||||||
|
#define BPD 4 /* bytes per dword */
|
||||||
|
#define LBPD 2 /* log2(BPD) */
|
||||||
|
#define BPW 2 /* bytes per word */
|
||||||
|
#define LBPW 1 /* log2(BPW) */
|
||||||
|
#define SBPC 1 /* stack bytes per character */
|
||||||
|
#define ERRCODE 7 /* op sys return code */
|
||||||
|
#define INTSIZE 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
** symbol table format
|
||||||
|
*/
|
||||||
|
#define IDENT 0
|
||||||
|
#define TYPE 1
|
||||||
|
#define CLASS 2
|
||||||
|
#define SIZE 3
|
||||||
|
#define OFFSET 5+2
|
||||||
|
#define NAME (7+4)
|
||||||
|
|
||||||
|
#define SYMAVG (12+4)
|
||||||
|
#define SYMMAX (16+4)
|
||||||
|
|
||||||
|
/*
|
||||||
|
** symbol table parameters
|
||||||
|
*/
|
||||||
|
#define NUMLOCS 25
|
||||||
|
#define STARTLOC symtab
|
||||||
|
#define ENDLOC (symtab+NUMLOCS*SYMAVG)
|
||||||
|
#define NUMGLBS 200
|
||||||
|
#define STARTGLB ENDLOC
|
||||||
|
#define ENDGLB (ENDLOC+(NUMGLBS-1)*SYMMAX)
|
||||||
|
#define SYMTBSZ /*3050*/ (NUMLOCS*SYMAVG + NUMGLBS*SYMMAX)
|
||||||
|
|
||||||
|
/*
|
||||||
|
** system wide name size (for symbols)
|
||||||
|
*/
|
||||||
|
#define NAMESIZE 9
|
||||||
|
#define NAMEMAX 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
** values for "IDENT"
|
||||||
|
*/
|
||||||
|
#define LABEL 0
|
||||||
|
#define VARIABLE 1
|
||||||
|
#define ARRAY 2
|
||||||
|
#define POINTER 3
|
||||||
|
#define FUNCTION 4
|
||||||
|
|
||||||
|
#define PTRSIZE INTSIZE /* Size of pointer (must match an int!) */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** values for "TYPE"
|
||||||
|
** high order 14 bits give length of object
|
||||||
|
** low order 2 bits make type unique within length
|
||||||
|
*/
|
||||||
|
/* LABEL 0 */
|
||||||
|
#define CHR ( 1 << 2)
|
||||||
|
#define SHORT (BPW << 2)
|
||||||
|
#define INT (INTSIZE << 2)
|
||||||
|
#define UCHR (( 1 << 2) + 1)
|
||||||
|
#define USHORT ((BPW << 2) + 1)
|
||||||
|
#define UINT ((INTSIZE << 2) + 1)
|
||||||
|
#define UNSIGNED 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
** values for "CLASS"
|
||||||
|
*/
|
||||||
|
/* LABEL 0 */
|
||||||
|
#define AUTOMATIC 1
|
||||||
|
#define STATIC 2
|
||||||
|
#define EXTERNAL 3
|
||||||
|
#define AUTOEXT 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
** segment types
|
||||||
|
*/
|
||||||
|
#define DATASEG 1
|
||||||
|
#define CODESEG 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
** "switch" table
|
||||||
|
*/
|
||||||
|
#define SWSIZ (2*BPW)
|
||||||
|
#define SWTABSZ (90*SWSIZ)
|
||||||
|
|
||||||
|
/*
|
||||||
|
** "while" queue
|
||||||
|
*/
|
||||||
|
#define WQTABSZ 30
|
||||||
|
#define WQSIZ 3
|
||||||
|
#define WQMAX (wq+WQTABSZ-WQSIZ)
|
||||||
|
|
||||||
|
/*
|
||||||
|
** field offsets in "while" queue
|
||||||
|
*/
|
||||||
|
#define WQSP 0
|
||||||
|
#define WQLOOP 1
|
||||||
|
#define WQEXIT 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
** literal pool
|
||||||
|
*/
|
||||||
|
#define LITABSZ 3000
|
||||||
|
#define LITMAX (LITABSZ-1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
** input line
|
||||||
|
*/
|
||||||
|
#define LINEMAX 127
|
||||||
|
#define LINESIZE 128
|
||||||
|
|
||||||
|
/*
|
||||||
|
** entries in staging buffer
|
||||||
|
*/
|
||||||
|
#define STAGESIZE 200
|
||||||
|
|
||||||
|
/*
|
||||||
|
** macro (#define) pool
|
||||||
|
*/
|
||||||
|
#define MACNBR 300
|
||||||
|
#define MACNSIZE (MACNBR*(NAMESIZE+2))
|
||||||
|
#define MACNEND (macn+MACNSIZE)
|
||||||
|
#define MACQSIZE (MACNBR*7)
|
||||||
|
#define MACMAX (MACQSIZE-1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
** statement types
|
||||||
|
*/
|
||||||
|
#define STIF 1
|
||||||
|
#define STWHILE 2
|
||||||
|
#define STRETURN 3
|
||||||
|
#define STBREAK 4
|
||||||
|
#define STCONT 5
|
||||||
|
#define STASM 6
|
||||||
|
#define STEXPR 7
|
||||||
|
#define STDO 8
|
||||||
|
#define STFOR 9
|
||||||
|
#define STSWITCH 10
|
||||||
|
#define STCASE 11
|
||||||
|
#define STDEF 12
|
||||||
|
#define STGOTO 13
|
||||||
|
#define STLABEL 14
|
||||||
|
|
||||||
|
/*
|
||||||
|
** p-code symbols
|
||||||
|
**
|
||||||
|
** legend:
|
||||||
|
** 1 = primary register (pr in comments)
|
||||||
|
** 2 = secondary register (sr in comments)
|
||||||
|
** b = byte
|
||||||
|
** f = jump on false condition
|
||||||
|
** l = current literal pool label number
|
||||||
|
** m = memory reference by label
|
||||||
|
** n = numeric constant
|
||||||
|
** p = indirect reference thru pointer in sr
|
||||||
|
** r = repeated r times
|
||||||
|
** s = stack frame reference
|
||||||
|
** u = unsigned
|
||||||
|
** w = word
|
||||||
|
** _ (tail) = another p-code completes this one
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* compiler-generated */
|
||||||
|
#define ADD12 1 /* add sr to pr */
|
||||||
|
#define ADDSP 2 /* add to stack pointer */
|
||||||
|
#define AND12 3 /* AND sr to pr */
|
||||||
|
#define ANEG1 4 /* arith negate pr */
|
||||||
|
#define ARGCNTn 5 /* pass arg count to function */
|
||||||
|
#define ASL12 6 /* arith shift left sr by pr into pr */
|
||||||
|
#define ASR12 7 /* arith shift right sr by pr into pr */
|
||||||
|
#define CALL1 8 /* call function thru pr */
|
||||||
|
#define CALLm 9 /* call function directly */
|
||||||
|
#define BYTE_ 10 /* define bytes (part 1) */
|
||||||
|
#define BYTEn 11 /* define byte of value n */
|
||||||
|
#define BYTEr0 12 /* define r bytes of value 0 */
|
||||||
|
#define COM1 13 /* ones complement pr */
|
||||||
|
#define DBL1 14 /* double pr */
|
||||||
|
#define DBL2 15 /* double sr */
|
||||||
|
#define DIV12 16 /* div pr by sr */
|
||||||
|
#define DIV12u 17 /* div pr by sr unsigned */
|
||||||
|
|
||||||
|
#define DWORD_ 111 /* define dword (part 1) */
|
||||||
|
#define DWORDn 112 /* define dword of value n */
|
||||||
|
#define DWORDr0 113 /* define r dwords of value 0 */
|
||||||
|
|
||||||
|
#define ENTER 18 /* set stack frame on function entry */
|
||||||
|
#define EQ10f 19 /* jump if (pr == 0) is false */
|
||||||
|
#define EQ12 20 /* set pr TRUE if (sr == pr) */
|
||||||
|
#define GE10f 21 /* jump if (pr >= 0) is false */
|
||||||
|
#define GE12 22 /* set pr TRUE if (sr >= pr) */
|
||||||
|
#define GE12u 23 /* set pr TRUE if (sr >= pr) unsigned */
|
||||||
|
#define POINT1l 24 /* point pr to function's literal pool */
|
||||||
|
#define POINT1m 25 /* point pr to mem item thru label */
|
||||||
|
#define GETb1m 26 /* get byte into pr from mem thru label */
|
||||||
|
#define GETb1mu 27 /* get unsigned byte into pr from mem thru label */
|
||||||
|
#define GETb1p 28 /* get byte into pr from mem thru sr ptr */
|
||||||
|
#define GETb1pu 29 /* get unsigned byte into pr from mem thru sr ptr */
|
||||||
|
|
||||||
|
#define GETd1m 107 /* get dword into pr from mem thru label */
|
||||||
|
#define GETd1n 108 /* get dword of value n into pr */
|
||||||
|
#define GETd1p 109 /* get dword into pr from mem thru sr ptr */
|
||||||
|
#define GETd2n 110 /* get word of value n into sr */
|
||||||
|
|
||||||
|
#define GETw1m 30 /* get word into pr from mem thru label */
|
||||||
|
#define GETw1n 31 /* get word of value n into pr */
|
||||||
|
#define GETw1p 32 /* get word into pr from mem thru sr ptr */
|
||||||
|
#define GETw2n 33 /* get word of value n into sr */
|
||||||
|
#define GT10f 34 /* jump if (pr > 0) is false */
|
||||||
|
#define GT12 35 /* set pr TRUE if (sr > pr) */
|
||||||
|
#define GT12u 36 /* set pr TRUE if (sr > pr) unsigned */
|
||||||
|
#define WORD_ 37 /* define word (part 1) */
|
||||||
|
#define WORDn 38 /* define word of value n */
|
||||||
|
#define WORDr0 39 /* define r words of value 0 */
|
||||||
|
#define JMPm 40 /* jump to label */
|
||||||
|
#define LABm 41 /* define label m */
|
||||||
|
#define LE10f 42 /* jump if (pr <= 0) is false */
|
||||||
|
#define LE12 43 /* set pr TRUE if (sr <= pr) */
|
||||||
|
#define LE12u 44 /* set pr TRUE if (sr <= pr) unsigned */
|
||||||
|
#define LNEG1 45 /* logical negate pr */
|
||||||
|
#define LT10f 46 /* jump if (pr < 0) is false */
|
||||||
|
#define LT12 47 /* set pr TRUE if (sr < pr) */
|
||||||
|
#define LT12u 48 /* set pr TRUE if (sr < pr) unsigned */
|
||||||
|
#define MOD12 49 /* modulo pr by sr */
|
||||||
|
#define MOD12u 50 /* modulo pr by sr unsigned */
|
||||||
|
#define MOVE21 51 /* move pr to sr */
|
||||||
|
#define MUL12 52 /* multiply pr by sr */
|
||||||
|
#define MUL12u 53 /* multiply pr by sr unsigned */
|
||||||
|
#define NE10f 54 /* jump if (pr != 0) is false */
|
||||||
|
#define NE12 55 /* set pr TRUE if (sr != pr) */
|
||||||
|
#define NEARm 56 /* define near pointer thru label */
|
||||||
|
#define OR12 57 /* OR sr onto pr */
|
||||||
|
#define POINT1s 58 /* point pr to stack item */
|
||||||
|
#define POP2 59 /* pop stack into sr */
|
||||||
|
#define PUSH1 60 /* push pr onto stack */
|
||||||
|
#define PUTbm1 61 /* put pr byte in mem thru label */
|
||||||
|
#define PUTbp1 62 /* put pr byte in mem thru sr ptr */
|
||||||
|
|
||||||
|
#define PUTdm1 114 /* put pr dword in mem thru label */
|
||||||
|
#define PUTdp1 115 /* put pr dword in mem thru sr ptr */
|
||||||
|
|
||||||
|
#define PUTwm1 63 /* put pr word in mem thru label */
|
||||||
|
#define PUTwp1 64 /* put pr word in mem thru sr ptr */
|
||||||
|
#define rDEC1 65 /* dec pr (may repeat) */
|
||||||
|
#define REFm 66 /* finish instruction with label */
|
||||||
|
#define RETURN 67 /* restore stack and return */
|
||||||
|
#define rINC1 68 /* inc pr (may repeat) */
|
||||||
|
#define SUB12 69 /* sub sr from pr */
|
||||||
|
#define SWAP12 70 /* swap pr and sr */
|
||||||
|
#define SWAP1s 71 /* swap pr and top of stack */
|
||||||
|
#define SWITCH 72 /* find switch case */
|
||||||
|
#define XOR12 73 /* XOR pr with sr */
|
||||||
|
|
||||||
|
/* optimizer-generated */
|
||||||
|
#define ADD1n 74 /* add n to pr */
|
||||||
|
#define ADD21 75 /* add pr to sr */
|
||||||
|
#define ADD2n 76 /* add immediate to sr */
|
||||||
|
#define ADDbpn 77 /* add n to mem byte thru sr ptr */
|
||||||
|
#define ADDwpn 78 /* add n to mem word thru sr ptr */
|
||||||
|
#define ADDm_ 79 /* add n to mem byte/word thru label (part 1) */
|
||||||
|
#define COMMAn 80 /* finish instruction with ,n */
|
||||||
|
#define DECbp 81 /* dec mem byte thru sr ptr */
|
||||||
|
#define DECwp 82 /* dec mem word thru sr ptr */
|
||||||
|
#define POINT2m 83 /* point sr to mem thru label */
|
||||||
|
#define POINT2m_ 84 /* point sr to mem thru label (part 1) */
|
||||||
|
#define GETb1s 85 /* get byte into pr from stack */
|
||||||
|
#define GETb1su 86 /* get unsigned byte into pr from stack */
|
||||||
|
#define GETw1m_ 87 /* get word into pr from mem thru label (part 1) */
|
||||||
|
#define GETw1s 88 /* get word into pr from stack */
|
||||||
|
#define GETw2m 89 /* get word into sr from mem (label) */
|
||||||
|
#define GETw2p 90 /* get word into sr thru sr ptr */
|
||||||
|
#define GETw2s 91 /* get word into sr from stack */
|
||||||
|
#define INCbp 92 /* inc byte in mem thru sr ptr */
|
||||||
|
#define INCwp 93 /* inc word in mem thru sr ptr */
|
||||||
|
#define PLUSn 94 /* finish instruction with +n */
|
||||||
|
#define POINT2s 95 /* point sr to stack */
|
||||||
|
#define PUSH2 96 /* push sr */
|
||||||
|
#define PUSHm 97 /* push word from mem thru label */
|
||||||
|
#define PUSHp 98 /* push word from mem thru sr ptr */
|
||||||
|
#define PUSHs 99 /* push word from stack */
|
||||||
|
#define PUT_m_ 100 /* put byte/word into mem thru label (part 1) */
|
||||||
|
#define rDEC2 101 /* dec sr (may repeat) */
|
||||||
|
#define rINC2 102 /* inc sr (may repeat) */
|
||||||
|
#define SUB_m_ 103 /* sub from mem byte/word thru label (part 1) */
|
||||||
|
#define SUB1n 104 /* sub n from pr */
|
||||||
|
#define SUBbpn 105 /* sub n from mem byte thru sr ptr */
|
||||||
|
#define SUBwpn 106 /* sub n from mem word thru sr ptr */
|
||||||
|
|
||||||
|
#define PCODES 116 /* size of code[] (it's a [+ 1]) */
|
||||||
|
|
911
programs/develop/scc/cc1.c
Normal file
911
programs/develop/scc/cc1.c
Normal file
@ -0,0 +1,911 @@
|
|||||||
|
/*
|
||||||
|
** Small-C Compiler -- Part 1 -- Top End.
|
||||||
|
** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix
|
||||||
|
** Copyright 1998 H T Walheim
|
||||||
|
** All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "notice.h"
|
||||||
|
#include "cc.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** miscellaneous storage
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
nogo, /* disable goto statements? */
|
||||||
|
noloc, /* disable block locals? */
|
||||||
|
opindex, /* index to matched operator */
|
||||||
|
opsize, /* size of operator in characters */
|
||||||
|
swactive, /* inside a switch? */
|
||||||
|
swdefault,/* default label #, else 0 */
|
||||||
|
*swnext, /* address of next entry */
|
||||||
|
*swend, /* address of last entry */
|
||||||
|
*stage, /* staging buffer address */
|
||||||
|
*wq, /* while queue */
|
||||||
|
argcs, /* static argc */
|
||||||
|
*argvs, /* static argv */
|
||||||
|
*wqptr, /* ptr to next entry */
|
||||||
|
litptr, /* ptr to next entry */
|
||||||
|
macptr, /* macro buffer index */
|
||||||
|
pptr, /* ptr to parsing buffer */
|
||||||
|
ch, /* current character of input line */
|
||||||
|
nch, /* next character of input line */
|
||||||
|
declared, /* # of local bytes to declare, -1 when declared */
|
||||||
|
iflevel, /* #if... nest level */
|
||||||
|
skiplevel,/* level at which #if... skipping started */
|
||||||
|
nxtlab, /* next avail label # */
|
||||||
|
litlab, /* label # assigned to literal pool */
|
||||||
|
csp, /* compiler relative stk ptr */
|
||||||
|
argstk, /* function arg sp */
|
||||||
|
argtop, /* highest formal argument offset */
|
||||||
|
ncmp, /* # open compound statements */
|
||||||
|
errflag, /* true after 1st error in statement */
|
||||||
|
eof, /* true on final input eof */
|
||||||
|
output, /* fd for output file */
|
||||||
|
files, /* true if file list specified on cmd line */
|
||||||
|
filearg = 0, /* cur file arg index */
|
||||||
|
input = EOF, /* fd for input file */
|
||||||
|
input2 = EOF, /* fd for "#include" file */
|
||||||
|
usexpr = YES, /* true if value of expression is used */
|
||||||
|
ccode = YES, /* true while parsing C code */
|
||||||
|
*snext, /* next addr in stage */
|
||||||
|
*stail, /* last addr of data in stage */
|
||||||
|
*slast, /* last addr in stage */
|
||||||
|
listfp, /* file pointer to list device */
|
||||||
|
lastst, /* last parsed statement type */
|
||||||
|
oldseg; /* current segment (0, DATASEG, CODESEG) */
|
||||||
|
|
||||||
|
char
|
||||||
|
optimize, /* optimize output of staging buffer? */
|
||||||
|
alarm, /* audible alarm on errors? */
|
||||||
|
monitor, /* monitor function headers? */
|
||||||
|
pause, /* pause for operator on errors? */
|
||||||
|
*symtab, /* symbol table */
|
||||||
|
*litq, /* literal pool */
|
||||||
|
*macn, /* macro name buffer */
|
||||||
|
*macq, /* macro string buffer */
|
||||||
|
*pline, /* parsing buffer */
|
||||||
|
*mline, /* macro buffer */
|
||||||
|
*line, /* ptr to pline or mline */
|
||||||
|
*lptr, /* ptr to current character in "line" */
|
||||||
|
*glbptr, /* global symbol table */
|
||||||
|
*locptr, /* next local symbol table entry */
|
||||||
|
quote[2] = {'"'}, /* literal string for '"' */
|
||||||
|
*cptr, /* work ptrs to any char buffer */
|
||||||
|
*cptr2,
|
||||||
|
*cptr3,
|
||||||
|
msname[NAMESIZE], /* macro symbol name */
|
||||||
|
ssname[NAMESIZE]; /* static symbol name */
|
||||||
|
|
||||||
|
int op[16] = { /* p-codes of signed binary operators */
|
||||||
|
OR12, /* level5 */
|
||||||
|
XOR12, /* level6 */
|
||||||
|
AND12, /* level7 */
|
||||||
|
EQ12, NE12, /* level8 */
|
||||||
|
LE12, GE12, LT12, GT12, /* level9 */
|
||||||
|
ASR12, ASL12, /* level10 */
|
||||||
|
ADD12, SUB12, /* level11 */
|
||||||
|
MUL12, DIV12, MOD12 /* level12 */
|
||||||
|
};
|
||||||
|
|
||||||
|
int op2[16] = { /* p-codes of unsigned binary operators */
|
||||||
|
OR12, /* level5 */
|
||||||
|
XOR12, /* level6 */
|
||||||
|
AND12, /* level7 */
|
||||||
|
EQ12, NE12, /* level8 */
|
||||||
|
LE12u, GE12u, LT12u, GT12u, /* level9 */
|
||||||
|
ASR12, ASL12, /* level10 */
|
||||||
|
ADD12, SUB12, /* level11 */
|
||||||
|
MUL12u, DIV12u, MOD12u /* level12 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** execution begins here
|
||||||
|
*/
|
||||||
|
main(argc, argv) int argc, *argv; {
|
||||||
|
fputs(VERSION, stdout);
|
||||||
|
fputs(CRIGHT1, stdout);
|
||||||
|
fputs(CRIGHT2, stdout);
|
||||||
|
argcs = argc;
|
||||||
|
argvs = argv;
|
||||||
|
swnext = calloc(SWTABSZ, 1);
|
||||||
|
swend = swnext+(SWTABSZ-SWSIZ);
|
||||||
|
stage = calloc(STAGESIZE, 2*INTSIZE);
|
||||||
|
wqptr =
|
||||||
|
wq = calloc(WQTABSZ, INTSIZE);
|
||||||
|
litq = calloc(LITABSZ, 1);
|
||||||
|
macn = calloc(MACNSIZE, 1);
|
||||||
|
macq = calloc(MACQSIZE, 1);
|
||||||
|
pline = calloc(LINESIZE, 1);
|
||||||
|
mline = calloc(LINESIZE, 1);
|
||||||
|
slast = stage+(STAGESIZE*2*INTSIZE);
|
||||||
|
symtab = calloc((NUMLOCS*SYMAVG + NUMGLBS*SYMMAX), 1);
|
||||||
|
locptr = STARTLOC;
|
||||||
|
glbptr = STARTGLB;
|
||||||
|
|
||||||
|
ask(); /* get user options */
|
||||||
|
openfile(); /* and initial input file */
|
||||||
|
preprocess(); /* fetch first line */
|
||||||
|
header(); /* intro code */
|
||||||
|
setcodes(); /* initialize code pointer array */
|
||||||
|
parse(); /* process ALL input */
|
||||||
|
trailer(); /* follow-up code */
|
||||||
|
fclose(output); /* explicitly close output */
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************** high level parsing *******************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** process all input text
|
||||||
|
**
|
||||||
|
** At this level, only static declarations,
|
||||||
|
** defines, includes and function
|
||||||
|
** definitions are legal...
|
||||||
|
*/
|
||||||
|
parse() {
|
||||||
|
while (eof == 0) {
|
||||||
|
if (amatch("extern", 6)) dodeclare(EXTERNAL);
|
||||||
|
else if(dodeclare(STATIC)) ;
|
||||||
|
else if( match("#asm")) doasm();
|
||||||
|
else if( match("#include")) doinclude();
|
||||||
|
else if( match("#define")) dodefine();
|
||||||
|
else dofunction();
|
||||||
|
blanks(); /* force eof if pending */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** test for global declarations
|
||||||
|
*/
|
||||||
|
dodeclare(class) int class; {
|
||||||
|
if (amatch("char", 4)) declglb(CHR, class);
|
||||||
|
else if(amatch("unsigned", 8)) {
|
||||||
|
if (amatch("char", 4)) declglb(UCHR, class);
|
||||||
|
else {amatch("int", 3); declglb(UINT, class);}
|
||||||
|
}
|
||||||
|
else if(amatch("int", 3)
|
||||||
|
|| class == EXTERNAL) declglb(INT, class);
|
||||||
|
else return 0;
|
||||||
|
ns();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** declare a static variable
|
||||||
|
*/
|
||||||
|
declglb(type, class)
|
||||||
|
int type, class;
|
||||||
|
{
|
||||||
|
int id, dim;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(endst())
|
||||||
|
return; /* do line */
|
||||||
|
if(match("*"))
|
||||||
|
{
|
||||||
|
id = POINTER; dim = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id = VARIABLE; dim = 1;
|
||||||
|
}
|
||||||
|
if(symname(ssname) == 0)
|
||||||
|
illname();
|
||||||
|
if(findglb(ssname))
|
||||||
|
multidef(ssname);
|
||||||
|
if(id == VARIABLE)
|
||||||
|
{
|
||||||
|
if (match("("))
|
||||||
|
{
|
||||||
|
id = FUNCTION; need(")");
|
||||||
|
}
|
||||||
|
else if(match("["))
|
||||||
|
{
|
||||||
|
id = ARRAY; dim = needsub();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (class == EXTERNAL)
|
||||||
|
external(ssname, type >> 2, id);
|
||||||
|
else if (id != FUNCTION)
|
||||||
|
initials(type >> 2, id, dim);
|
||||||
|
if(id == POINTER)
|
||||||
|
addsym(ssname, id, type, PTRSIZE, 0, &glbptr, class);
|
||||||
|
else
|
||||||
|
addsym(ssname, id, type, dim * (type >> 2), 0, &glbptr, class);
|
||||||
|
if(match(",") == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** initialize global objects
|
||||||
|
*/
|
||||||
|
initials(size, ident, dim) int size, ident, dim; {
|
||||||
|
int savedim;
|
||||||
|
litptr = 0;
|
||||||
|
if(dim == 0) dim = -1; /* *... or ...[] */
|
||||||
|
savedim = dim;
|
||||||
|
/* public(ident); */
|
||||||
|
if(match("=")) {
|
||||||
|
if(match("{")) {
|
||||||
|
while(dim) {
|
||||||
|
init(size, ident, &dim);
|
||||||
|
if(match(",") == 0) break;
|
||||||
|
}
|
||||||
|
need("}");
|
||||||
|
}
|
||||||
|
else init(size, ident, &dim);
|
||||||
|
}
|
||||||
|
if(savedim == -1 && dim == -1) {
|
||||||
|
if(ident == ARRAY) error("need array size");
|
||||||
|
stowlit(0, size = PTRSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FASM */
|
||||||
|
public(ident);
|
||||||
|
if(litptr>0) dumplits(size);
|
||||||
|
else if(dim>0)
|
||||||
|
{/*In FASM: "<variable>: TIMES <number> D<type> 0" */
|
||||||
|
fputc(':',output);
|
||||||
|
}
|
||||||
|
dumpzero(size, dim); /* only if dim > 0 */
|
||||||
|
/* FASM */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** evaluate one initializer
|
||||||
|
*/
|
||||||
|
init(size, ident, dim) int size, ident, *dim; {
|
||||||
|
int value;
|
||||||
|
if(string(&value)) {
|
||||||
|
if(ident == VARIABLE || size != 1)
|
||||||
|
error("must assign to char pointer or char array");
|
||||||
|
*dim -= (litptr - value);
|
||||||
|
if(ident == POINTER) point();
|
||||||
|
}
|
||||||
|
else if(constexpr(&value)) {
|
||||||
|
if(ident == POINTER) error("cannot assign to pointer");
|
||||||
|
stowlit(value, size);
|
||||||
|
*dim -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** get required array size
|
||||||
|
*/
|
||||||
|
needsub() {
|
||||||
|
int val;
|
||||||
|
if(match("]")) return 0; /* null size */
|
||||||
|
if(constexpr(&val) == 0) val = 1;
|
||||||
|
if(val < 0) {
|
||||||
|
error("negative size illegal");
|
||||||
|
val = -val;
|
||||||
|
}
|
||||||
|
need("]"); /* force single dimension */
|
||||||
|
return val; /* and return size */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** open an include file
|
||||||
|
*/
|
||||||
|
doinclude() {
|
||||||
|
int i; char str[30];
|
||||||
|
blanks(); /* skip over to name */
|
||||||
|
if(*lptr == '"' || *lptr == '<') ++lptr;
|
||||||
|
i = 0;
|
||||||
|
while(lptr[i]
|
||||||
|
&& lptr[i] != '"'
|
||||||
|
&& lptr[i] != '>'
|
||||||
|
&& lptr[i] != '\n') {
|
||||||
|
str[i] = lptr[i];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
str[i] = NULL;
|
||||||
|
if((input2 = fopen(str,"r")) == NULL) {
|
||||||
|
input2 = EOF;
|
||||||
|
error("open failure on include file");
|
||||||
|
}
|
||||||
|
kill(); /* make next read come from new file (if open) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** define a macro symbol
|
||||||
|
*/
|
||||||
|
dodefine() {
|
||||||
|
int k;
|
||||||
|
if(symname(msname) == 0) {
|
||||||
|
illname();
|
||||||
|
kill();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
puts (msname);
|
||||||
|
puts (" is #defined\n");
|
||||||
|
*/
|
||||||
|
k = 0;
|
||||||
|
if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0) == 0) {
|
||||||
|
if(cptr2 = cptr)
|
||||||
|
while(*cptr2++ = msname[k++]) ;
|
||||||
|
else {
|
||||||
|
error("macro name table full");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putint(macptr, cptr+NAMESIZE, 2 /*INTSIZE*/);
|
||||||
|
while(white()) gch();
|
||||||
|
while(putmac(gch()));
|
||||||
|
if(macptr >= MACMAX) {
|
||||||
|
error("macro string queue full");
|
||||||
|
exit(ERRCODE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putmac(c) char c; {
|
||||||
|
macq[macptr] = c;
|
||||||
|
if(macptr < MACMAX) ++macptr;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** begin a function
|
||||||
|
**
|
||||||
|
** called from "parse" and tries to make a function
|
||||||
|
** out of the following text
|
||||||
|
*/
|
||||||
|
dofunction() {
|
||||||
|
char *ptr;
|
||||||
|
nogo = /* enable goto statements */
|
||||||
|
noloc = /* enable block-local declarations */
|
||||||
|
lastst = /* no statement yet */
|
||||||
|
litptr = 0; /* clear lit pool */
|
||||||
|
litlab = getlabel(); /* label next lit pool */
|
||||||
|
locptr = STARTLOC; /* clear local variables */
|
||||||
|
if(match("void")) blanks(); /* skip "void" & locate header */
|
||||||
|
if(monitor) lout(line, stderr);
|
||||||
|
if(symname(ssname) == 0) {
|
||||||
|
error("illegal function or declaration");
|
||||||
|
errflag = 0;
|
||||||
|
kill(); /* invalidate line */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(ptr = findglb(ssname)) { /* already in symbol table? */
|
||||||
|
if(ptr[CLASS] == AUTOEXT)
|
||||||
|
ptr[CLASS] = STATIC;
|
||||||
|
else multidef(ssname);
|
||||||
|
}
|
||||||
|
else addsym(ssname, FUNCTION, INT, 0, 0, &glbptr, STATIC);
|
||||||
|
public(FUNCTION);
|
||||||
|
argstk = 0; /* init arg count */
|
||||||
|
if(match("(") == 0) error("no open paren");
|
||||||
|
while(match(")") == 0) { /* then count args */
|
||||||
|
if(symname(ssname)) {
|
||||||
|
if(findloc(ssname)) multidef(ssname);
|
||||||
|
else {
|
||||||
|
addsym(ssname, 0, 0, 0, argstk, &locptr, AUTOMATIC);
|
||||||
|
argstk += INTSIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error("illegal argument name");
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
blanks();
|
||||||
|
if(streq(lptr,")") == 0 && match(",") == 0)
|
||||||
|
error("no comma");
|
||||||
|
if(endst()) break;
|
||||||
|
}
|
||||||
|
csp = 0; /* preset stack ptr */
|
||||||
|
argtop = argstk+INTSIZE; /* account for the pushed BP */
|
||||||
|
while(argstk) {
|
||||||
|
if (amatch("char", 4)) {doargs(CHR); ns();}
|
||||||
|
else if(amatch("int", 3)) {doargs(INT); ns();}
|
||||||
|
else if(amatch("unsigned", 8)) {
|
||||||
|
if (amatch("char", 4)) {doargs(UCHR); ns();}
|
||||||
|
else {amatch("int", 3); doargs(UINT); ns();}
|
||||||
|
}
|
||||||
|
else {error("wrong number of arguments"); break;}
|
||||||
|
}
|
||||||
|
gen(ENTER, 0);
|
||||||
|
statement();
|
||||||
|
if(lastst != STRETURN && lastst != STGOTO)
|
||||||
|
gen(RETURN, 0);
|
||||||
|
if(litptr) {
|
||||||
|
toseg(DATASEG);
|
||||||
|
gen(REFm, litlab);
|
||||||
|
dumplits(1); /* dump literals */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** declare argument types
|
||||||
|
*/
|
||||||
|
doargs(type) int type; {
|
||||||
|
int id, sz;
|
||||||
|
char c, *ptr;
|
||||||
|
while(1) {
|
||||||
|
if(argstk == 0) return; /* no arguments */
|
||||||
|
if(decl(type, POINTER, &id, &sz)) {
|
||||||
|
if(ptr = findloc(ssname)) {
|
||||||
|
ptr[IDENT] = id;
|
||||||
|
ptr[TYPE] = type;
|
||||||
|
putint(sz, ptr+SIZE, INTSIZE);
|
||||||
|
putint(argtop-getint(ptr+OFFSET, INTSIZE), ptr+OFFSET, INTSIZE);
|
||||||
|
}
|
||||||
|
else error("not an argument");
|
||||||
|
}
|
||||||
|
argstk = argstk - INTSIZE; /* cnt down */
|
||||||
|
if(endst()) return;
|
||||||
|
if(match(",") == 0) error("no comma");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** parse next local or argument declaration
|
||||||
|
*/
|
||||||
|
decl(type, aid, id, sz)
|
||||||
|
int type, aid, *id, *sz;
|
||||||
|
{
|
||||||
|
int n, p;
|
||||||
|
int mod;
|
||||||
|
if(match("(")) p = 1;
|
||||||
|
else p = 0;
|
||||||
|
if(match("*")) {*id = POINTER; *sz = PTRSIZE;}
|
||||||
|
else {*id = VARIABLE; *sz = type >> 2;}
|
||||||
|
if((n = symname(ssname)) == 0) illname();
|
||||||
|
if(p && match(")")) ;
|
||||||
|
if(match("("))
|
||||||
|
{
|
||||||
|
if(!p || *id != POINTER)
|
||||||
|
error("try (*...)()");
|
||||||
|
need(")");
|
||||||
|
}
|
||||||
|
else if(*id == VARIABLE && match("["))
|
||||||
|
{
|
||||||
|
*id = aid;
|
||||||
|
if((*sz *= needsub()) == 0)
|
||||||
|
{
|
||||||
|
if(aid == ARRAY) error("need array size");
|
||||||
|
*sz = PTRSIZE; /* size of pointer argument */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mod = *sz % ALIGN;
|
||||||
|
|
||||||
|
if (mod)
|
||||||
|
{
|
||||||
|
*sz = *sz + (ALIGN-mod);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************** start 2nd level parsing *******************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** statement parser
|
||||||
|
*/
|
||||||
|
statement() {
|
||||||
|
if(ch == 0 && eof) return;
|
||||||
|
else if(amatch("char", 4)) {declloc(CHR); ns();}
|
||||||
|
else if(amatch("int", 3)) {declloc(INT); ns();}
|
||||||
|
else if(amatch("unsigned", 8)) {
|
||||||
|
if (amatch("char", 4)) {declloc(UCHR); ns();}
|
||||||
|
else {amatch("int", 3); declloc(UINT); ns();}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(declared >= 0) {
|
||||||
|
if(ncmp > 1) nogo = declared; /* disable goto */
|
||||||
|
gen(ADDSP, csp - declared);
|
||||||
|
declared = -1;
|
||||||
|
}
|
||||||
|
if(match("{")) compound();
|
||||||
|
else if(amatch("if", 2)) {doif(); lastst = STIF;}
|
||||||
|
else if(amatch("while", 5)) {dowhile(); lastst = STWHILE;}
|
||||||
|
else if(amatch("do", 2)) {dodo(); lastst = STDO;}
|
||||||
|
else if(amatch("for", 3)) {dofor(); lastst = STFOR;}
|
||||||
|
else if(amatch("switch", 6)) {doswitch(); lastst = STSWITCH;}
|
||||||
|
else if(amatch("case", 4)) {docase(); lastst = STCASE;}
|
||||||
|
else if(amatch("default", 7)) {dodefault(); lastst = STDEF;}
|
||||||
|
else if(amatch("goto", 4)) {dogoto(); lastst = STGOTO;}
|
||||||
|
else if(dolabel()) lastst = STLABEL;
|
||||||
|
else if(amatch("return", 6)) {doreturn(); ns(); lastst = STRETURN;}
|
||||||
|
else if(amatch("break", 5)) {dobreak(); ns(); lastst = STBREAK;}
|
||||||
|
else if(amatch("continue", 8)) {docont(); ns(); lastst = STCONT;}
|
||||||
|
else if(match(";")) errflag = 0;
|
||||||
|
else if(match("#asm")) {doasm(); lastst = STASM;}
|
||||||
|
else {doexpr(NO); ns(); lastst = STEXPR;}
|
||||||
|
}
|
||||||
|
return lastst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** declare local variables
|
||||||
|
*/
|
||||||
|
declloc(type) int type; {
|
||||||
|
int id, sz;
|
||||||
|
if(swactive) error("not allowed in switch");
|
||||||
|
if(noloc) error("not allowed with goto");
|
||||||
|
if(declared < 0) error("must declare first in block");
|
||||||
|
while(1) {
|
||||||
|
if(endst()) return;
|
||||||
|
decl(type, ARRAY, &id, &sz);
|
||||||
|
declared += sz;
|
||||||
|
addsym(ssname, id, type, sz, csp - declared, &locptr, AUTOMATIC);
|
||||||
|
if(match(",") == 0) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compound() {
|
||||||
|
int savcsp;
|
||||||
|
char *savloc;
|
||||||
|
savcsp = csp;
|
||||||
|
savloc = locptr;
|
||||||
|
declared = 0; /* may now declare local variables */
|
||||||
|
++ncmp; /* new level open */
|
||||||
|
while (match("}") == 0)
|
||||||
|
if(eof) {
|
||||||
|
error("no final }");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else statement(); /* do one */
|
||||||
|
if(--ncmp /* close current level */
|
||||||
|
&& lastst != STRETURN
|
||||||
|
&& lastst != STGOTO)
|
||||||
|
gen(ADDSP, savcsp); /* delete local variable space */
|
||||||
|
cptr = savloc; /* retain labels */
|
||||||
|
while(cptr < locptr) {
|
||||||
|
cptr2 = nextsym(cptr);
|
||||||
|
if(cptr[IDENT] == LABEL) {
|
||||||
|
while(cptr < cptr2) *savloc++ = *cptr++;
|
||||||
|
}
|
||||||
|
else cptr = cptr2;
|
||||||
|
}
|
||||||
|
locptr = savloc; /* delete local symbols */
|
||||||
|
declared = -1; /* may not declare variables */
|
||||||
|
}
|
||||||
|
|
||||||
|
doif() {
|
||||||
|
int flab1, flab2;
|
||||||
|
test(flab1 = getlabel(), YES); /* get expr, and branch false */
|
||||||
|
statement(); /* if true, do a statement */
|
||||||
|
if(amatch("else", 4) == 0) { /* if...else ? */
|
||||||
|
/* simple "if"...print false label */
|
||||||
|
gen(LABm, flab1);
|
||||||
|
return; /* and exit */
|
||||||
|
}
|
||||||
|
flab2 = getlabel();
|
||||||
|
if(lastst != STRETURN && lastst != STGOTO)
|
||||||
|
gen(JMPm, flab2);
|
||||||
|
gen(LABm, flab1); /* print false label */
|
||||||
|
statement(); /* and do "else" clause */
|
||||||
|
gen(LABm, flab2); /* print true label */
|
||||||
|
}
|
||||||
|
|
||||||
|
dowhile() {
|
||||||
|
int wq[4]; /* allocate local queue */
|
||||||
|
addwhile(wq); /* add entry to queue for "break" */
|
||||||
|
gen(LABm, wq[WQLOOP]); /* loop label */
|
||||||
|
test(wq[WQEXIT], YES); /* see if true */
|
||||||
|
statement(); /* if so, do a statement */
|
||||||
|
gen(JMPm, wq[WQLOOP]); /* loop to label */
|
||||||
|
gen(LABm, wq[WQEXIT]); /* exit label */
|
||||||
|
delwhile(); /* delete queue entry */
|
||||||
|
}
|
||||||
|
|
||||||
|
dodo() {
|
||||||
|
int wq[4];
|
||||||
|
addwhile(wq);
|
||||||
|
gen(LABm, wq[WQLOOP]);
|
||||||
|
statement();
|
||||||
|
need("while");
|
||||||
|
test(wq[WQEXIT], YES);
|
||||||
|
gen(JMPm, wq[WQLOOP]);
|
||||||
|
gen(LABm, wq[WQEXIT]);
|
||||||
|
delwhile();
|
||||||
|
ns();
|
||||||
|
}
|
||||||
|
|
||||||
|
dofor() {
|
||||||
|
int wq[4], lab1, lab2;
|
||||||
|
addwhile(wq);
|
||||||
|
lab1 = getlabel();
|
||||||
|
lab2 = getlabel();
|
||||||
|
need("(");
|
||||||
|
if(match(";") == 0) {
|
||||||
|
doexpr(NO); /* expr 1 */
|
||||||
|
ns();
|
||||||
|
}
|
||||||
|
gen(LABm, lab1);
|
||||||
|
if(match(";") == 0) {
|
||||||
|
test(wq[WQEXIT], NO); /* expr 2 */
|
||||||
|
ns();
|
||||||
|
}
|
||||||
|
gen(JMPm, lab2);
|
||||||
|
gen(LABm, wq[WQLOOP]);
|
||||||
|
if(match(")") == 0) {
|
||||||
|
doexpr(NO); /* expr 3 */
|
||||||
|
need(")");
|
||||||
|
}
|
||||||
|
gen(JMPm, lab1);
|
||||||
|
gen(LABm, lab2);
|
||||||
|
statement();
|
||||||
|
gen(JMPm, wq[WQLOOP]);
|
||||||
|
gen(LABm, wq[WQEXIT]);
|
||||||
|
delwhile();
|
||||||
|
}
|
||||||
|
|
||||||
|
doswitch() {
|
||||||
|
int wq[4], endlab, swact, swdef, *swnex, *swptr;
|
||||||
|
swact = swactive;
|
||||||
|
swdef = swdefault;
|
||||||
|
swnex = swptr = swnext;
|
||||||
|
addwhile(wq);
|
||||||
|
*(wqptr + WQLOOP - WQSIZ) = 0;
|
||||||
|
need("(");
|
||||||
|
doexpr(YES); /* evaluate switch expression */
|
||||||
|
need(")");
|
||||||
|
swdefault = 0;
|
||||||
|
swactive = 1;
|
||||||
|
gen(JMPm, endlab = getlabel());
|
||||||
|
statement(); /* cases, etc. */
|
||||||
|
gen(JMPm, wq[WQEXIT]);
|
||||||
|
gen(LABm, endlab);
|
||||||
|
gen(SWITCH, 0); /* match cases */
|
||||||
|
while(swptr < swnext) {
|
||||||
|
gen(NEARm, *swptr++);
|
||||||
|
#ifdef INT32
|
||||||
|
gen(DWORDn, *swptr++); /* case value */
|
||||||
|
#else
|
||||||
|
gen(WORDn, *swptr++); /* case value */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef INT32
|
||||||
|
gen(DWORDn, 0);
|
||||||
|
#else
|
||||||
|
gen(WORDn, 0);
|
||||||
|
#endif
|
||||||
|
if(swdefault) gen(JMPm, swdefault);
|
||||||
|
gen(LABm, wq[WQEXIT]);
|
||||||
|
delwhile();
|
||||||
|
swnext = swnex;
|
||||||
|
swdefault = swdef;
|
||||||
|
swactive = swact;
|
||||||
|
}
|
||||||
|
|
||||||
|
docase() {
|
||||||
|
if(swactive == 0) error("not in switch");
|
||||||
|
if(swnext > swend) {
|
||||||
|
error("too many cases");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen(LABm, *swnext++ = getlabel());
|
||||||
|
constexpr(swnext++);
|
||||||
|
need(":");
|
||||||
|
}
|
||||||
|
|
||||||
|
dodefault() {
|
||||||
|
if(swactive) {
|
||||||
|
if(swdefault) error("multiple defaults");
|
||||||
|
}
|
||||||
|
else error("not in switch");
|
||||||
|
need(":");
|
||||||
|
gen(LABm, swdefault = getlabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
dogoto() {
|
||||||
|
if(nogo > 0) error("not allowed with block-locals");
|
||||||
|
else noloc = 1;
|
||||||
|
if(symname(ssname)) gen(JMPm, addlabel(NO));
|
||||||
|
else error("bad label");
|
||||||
|
ns();
|
||||||
|
}
|
||||||
|
|
||||||
|
dolabel() {
|
||||||
|
char *savelptr;
|
||||||
|
blanks();
|
||||||
|
savelptr = lptr;
|
||||||
|
if(symname(ssname)) {
|
||||||
|
if(gch() == ':') {
|
||||||
|
gen(LABm, addlabel(YES));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else bump(savelptr-lptr);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addlabel(def) int def; {
|
||||||
|
if(cptr = findloc(ssname)) {
|
||||||
|
if(cptr[IDENT] != LABEL) error("not a label");
|
||||||
|
else if(def) {
|
||||||
|
if(cptr[TYPE]) error("duplicate label");
|
||||||
|
else cptr[TYPE] = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else cptr = addsym(ssname, LABEL, def, 0, getlabel(), &locptr, LABEL);
|
||||||
|
return (getint(cptr+OFFSET, INTSIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
doreturn() {
|
||||||
|
int savcsp;
|
||||||
|
if(endst() == 0) doexpr(YES);
|
||||||
|
savcsp = csp;
|
||||||
|
gen(RETURN, 0);
|
||||||
|
csp = savcsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
dobreak() {
|
||||||
|
int *ptr;
|
||||||
|
if((ptr = readwhile(wqptr)) == 0) return;
|
||||||
|
gen(ADDSP, ptr[WQSP]);
|
||||||
|
gen(JMPm, ptr[WQEXIT]);
|
||||||
|
}
|
||||||
|
|
||||||
|
docont() {
|
||||||
|
int *ptr;
|
||||||
|
ptr = wqptr;
|
||||||
|
while (1) {
|
||||||
|
if((ptr = readwhile(ptr)) == 0) return;
|
||||||
|
if(ptr[WQLOOP]) break;
|
||||||
|
}
|
||||||
|
gen(ADDSP, ptr[WQSP]);
|
||||||
|
gen(JMPm, ptr[WQLOOP]);
|
||||||
|
}
|
||||||
|
|
||||||
|
doasm() {
|
||||||
|
ccode = 0; /* mark mode as "asm" */
|
||||||
|
while (1) {
|
||||||
|
inline();
|
||||||
|
if(match("#endasm")) break;
|
||||||
|
if(eof)break;
|
||||||
|
fputs(line, output);
|
||||||
|
}
|
||||||
|
kill();
|
||||||
|
ccode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
doexpr(use) int use; {
|
||||||
|
int constant, val;
|
||||||
|
int *before, *start;
|
||||||
|
usexpr = use; /* tell isfree() whether expr value is used */
|
||||||
|
while(1) {
|
||||||
|
setstage(&before, &start);
|
||||||
|
expression(&constant, &val);
|
||||||
|
clearstage(before, start);
|
||||||
|
if(ch != ',') break;
|
||||||
|
bump(1);
|
||||||
|
}
|
||||||
|
usexpr = YES; /* return to normal value */
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************** miscellaneous functions *******************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** get run options
|
||||||
|
*/
|
||||||
|
ask()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
i = listfp = nxtlab = 0;
|
||||||
|
output = stdout;
|
||||||
|
#ifdef LATER
|
||||||
|
optimize = YES; // Not working for 32 bit int's yer
|
||||||
|
#else
|
||||||
|
optimize = NO;
|
||||||
|
#endif
|
||||||
|
alarm = monitor = pause = NO;
|
||||||
|
line = mline;
|
||||||
|
while(getarg(++i, line, LINESIZE, argcs, argvs) != EOF)
|
||||||
|
{
|
||||||
|
if(line[0] != '-' && line[0] != '/')
|
||||||
|
continue;
|
||||||
|
if(toupper(line[1]) == 'L' // List
|
||||||
|
&& isdigit(line[2])
|
||||||
|
&& line[3] <= ' ')
|
||||||
|
{
|
||||||
|
listfp = line[2]-'0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(toupper(line[1]) == 'N' // No optimize
|
||||||
|
&& toupper(line[2]) == 'O'
|
||||||
|
&& line[3] <= ' ')
|
||||||
|
{
|
||||||
|
optimize = NO;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(toupper(line[1]) == 'D')
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
ch = line[j+2];
|
||||||
|
lptr = line + j+2;
|
||||||
|
/*
|
||||||
|
while (line[j+2] != ' ')
|
||||||
|
{
|
||||||
|
if (j < (NAMEMAX-1))
|
||||||
|
{
|
||||||
|
msname[j] = line[j+1];
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msname[j] = '\0';
|
||||||
|
*/
|
||||||
|
dodefine ();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(line[2] <= ' ')
|
||||||
|
{
|
||||||
|
if(toupper(line[1]) == 'A') {alarm = YES; continue;}
|
||||||
|
if(toupper(line[1]) == 'M') {monitor = YES; continue;}
|
||||||
|
if(toupper(line[1]) == 'P') {pause = YES; continue;}
|
||||||
|
}
|
||||||
|
fputs("usage: cc [file]... [-m] [-a] [-p] [-l#] [-no] [-d<id>]\n", stderr);
|
||||||
|
fputs(" -m monitor\n", stderr);
|
||||||
|
fputs(" -a alarm\n", stderr);
|
||||||
|
fputs(" -p pause\n", stderr);
|
||||||
|
fputs(" -l# list\n", stderr);
|
||||||
|
fputs(" -no no optimize\n", stderr);
|
||||||
|
fputs(" -d<id> pre-#define id\n", stderr);
|
||||||
|
exit(ERRCODE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** input and output file opens
|
||||||
|
*/
|
||||||
|
openfile() { /* entire function revised */
|
||||||
|
char outfn[15];
|
||||||
|
int i, j, ext;
|
||||||
|
input = EOF;
|
||||||
|
while(getarg(++filearg, pline, LINESIZE, argcs, argvs) != EOF) {
|
||||||
|
if(pline[0] == '-' || pline[0] == '/') continue;
|
||||||
|
ext = NO;
|
||||||
|
i = -1;
|
||||||
|
j = 0;
|
||||||
|
while(pline[++i]) {
|
||||||
|
if(pline[i] == '.') {
|
||||||
|
ext = YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(j < 10) outfn[j++] = pline[i];
|
||||||
|
}
|
||||||
|
if(!ext) strcpy(pline + i, ".C");
|
||||||
|
input = mustopen(pline, "r");
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
if(!files) {
|
||||||
|
strcpy(outfn + j, ".ASM");
|
||||||
|
output = mustopen(outfn, "w");
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
if(!files /* && iscons(stdout)*/) {
|
||||||
|
strcpy(outfn + j, ".ASM");
|
||||||
|
output = mustopen(outfn, "w");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
files = YES;
|
||||||
|
kill();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(files++) eof = YES;
|
||||||
|
else input = stdin;
|
||||||
|
kill();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** open a file with error checking
|
||||||
|
*/
|
||||||
|
mustopen(fn, mode) char *fn, *mode; {
|
||||||
|
int fd;
|
||||||
|
if(fd = fopen(fn, mode)) return fd;
|
||||||
|
fputs("open error on ", stderr);
|
||||||
|
lout(fn, stderr);
|
||||||
|
exit(ERRCODE);
|
||||||
|
}
|
||||||
|
|
557
programs/develop/scc/cc2.c
Normal file
557
programs/develop/scc/cc2.c
Normal file
@ -0,0 +1,557 @@
|
|||||||
|
/*
|
||||||
|
** Small-C Compiler -- Part 2 -- Front End and Miscellaneous.
|
||||||
|
** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix
|
||||||
|
** Copyright 1998 H T Walheim
|
||||||
|
** All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "cc.h"
|
||||||
|
|
||||||
|
extern char
|
||||||
|
*symtab, *macn, *macq, *pline, *mline, optimize,
|
||||||
|
alarm, *glbptr, *line, *lptr, *cptr, *cptr2, *cptr3,
|
||||||
|
*locptr, msname[NAMESIZE], pause, quote[2];
|
||||||
|
|
||||||
|
extern int
|
||||||
|
*wq, ccode, ch, csp, eof, errflag, iflevel,
|
||||||
|
input, input2, listfp, macptr, nch,
|
||||||
|
nxtlab, op[16], opindex, opsize, output, pptr,
|
||||||
|
skiplevel, *wqptr;
|
||||||
|
|
||||||
|
/********************** input functions **********************/
|
||||||
|
|
||||||
|
preprocess() {
|
||||||
|
int k;
|
||||||
|
char c;
|
||||||
|
if(ccode) {
|
||||||
|
line = mline;
|
||||||
|
ifline();
|
||||||
|
if(eof) return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
inline();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pptr = -1;
|
||||||
|
while(ch != NEWLINE && ch) {
|
||||||
|
if(white()) {
|
||||||
|
keepch(' ');
|
||||||
|
while(white()) gch();
|
||||||
|
}
|
||||||
|
else if(ch == '"') {
|
||||||
|
keepch(ch);
|
||||||
|
gch();
|
||||||
|
while(ch != '"' || (*(lptr-1) == 92 && *(lptr-2) != 92)) {
|
||||||
|
if(ch == NULL) {
|
||||||
|
error("no quote");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
keepch(gch());
|
||||||
|
}
|
||||||
|
gch();
|
||||||
|
keepch('"');
|
||||||
|
}
|
||||||
|
else if(ch == 39) {
|
||||||
|
keepch(39);
|
||||||
|
gch();
|
||||||
|
while(ch != 39 || (*(lptr-1) == 92 && *(lptr-2) != 92)) {
|
||||||
|
if(ch == NULL) {
|
||||||
|
error("no apostrophe");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
keepch(gch());
|
||||||
|
}
|
||||||
|
gch();
|
||||||
|
keepch(39);
|
||||||
|
}
|
||||||
|
else if(ch == '/' && nch == '*')
|
||||||
|
{
|
||||||
|
bump(2);
|
||||||
|
while((ch == '*' && nch == '/') == 0)
|
||||||
|
{
|
||||||
|
if(ch)
|
||||||
|
bump(1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ifline();
|
||||||
|
if(eof)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bump(2);
|
||||||
|
}
|
||||||
|
else if(ch == '/' && nch == '/')
|
||||||
|
{
|
||||||
|
bump(2);
|
||||||
|
while(ch != NEWLINE)
|
||||||
|
{
|
||||||
|
if(ch)
|
||||||
|
bump(1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(eof)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bump(1);
|
||||||
|
}
|
||||||
|
else if(an(ch)) {
|
||||||
|
k = 0;
|
||||||
|
while(an(ch) && k < NAMEMAX) {
|
||||||
|
msname[k++] = ch;
|
||||||
|
gch();
|
||||||
|
}
|
||||||
|
msname[k] = NULL;
|
||||||
|
if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)) {
|
||||||
|
k = getint(cptr+NAMESIZE, 2/*INTSIZE*/);
|
||||||
|
while(c = macq[k++]) keepch(c);
|
||||||
|
while(an(ch)) gch();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
k = 0;
|
||||||
|
while(c = msname[k++]) keepch(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else keepch(gch());
|
||||||
|
}
|
||||||
|
if(pptr >= LINEMAX) error("line too long");
|
||||||
|
keepch(NULL);
|
||||||
|
line = pline;
|
||||||
|
bump(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
keepch(c) char c; {
|
||||||
|
if(pptr < LINEMAX) pline[++pptr] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
ifline() {
|
||||||
|
while(1) {
|
||||||
|
inline();
|
||||||
|
if(eof) return;
|
||||||
|
if(match("#ifdef")) {
|
||||||
|
++iflevel;
|
||||||
|
if(skiplevel) continue;
|
||||||
|
symname(msname);
|
||||||
|
if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0) == 0)
|
||||||
|
skiplevel = iflevel;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(match("#ifndef")) {
|
||||||
|
++iflevel;
|
||||||
|
if(skiplevel) continue;
|
||||||
|
symname(msname);
|
||||||
|
if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0))
|
||||||
|
skiplevel = iflevel;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(match("#else")) {
|
||||||
|
if(iflevel) {
|
||||||
|
if(skiplevel == iflevel) skiplevel = 0;
|
||||||
|
else if(skiplevel == 0) skiplevel = iflevel;
|
||||||
|
}
|
||||||
|
else noiferr();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(match("#endif")) {
|
||||||
|
if(iflevel) {
|
||||||
|
if(skiplevel == iflevel) skiplevel = 0;
|
||||||
|
--iflevel;
|
||||||
|
}
|
||||||
|
else noiferr();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(skiplevel) continue;
|
||||||
|
if(ch == 0) continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline() { /* numerous revisions */
|
||||||
|
int k, unit;
|
||||||
|
|
||||||
|
if(input == EOF) openfile();
|
||||||
|
if(eof) return;
|
||||||
|
if((unit = input2) == EOF) unit = input;
|
||||||
|
if(fgets(line, LINEMAX, unit) == NULL) {
|
||||||
|
fclose(unit);
|
||||||
|
if(input2 != EOF)
|
||||||
|
input2 = EOF;
|
||||||
|
else input = EOF;
|
||||||
|
*line = NULL;
|
||||||
|
}
|
||||||
|
else if(listfp)
|
||||||
|
{
|
||||||
|
if(listfp == output) fputc(';', output);
|
||||||
|
fputs(line, listfp);
|
||||||
|
}
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fputc(';', output);
|
||||||
|
fputs(line, output);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
bump(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inbyte() {
|
||||||
|
while(ch == 0) {
|
||||||
|
if(eof) return 0;
|
||||||
|
preprocess();
|
||||||
|
}
|
||||||
|
return gch();
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************* scanning functions ********************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** test if next input string is legal symbol name
|
||||||
|
*/
|
||||||
|
symname(sname) char *sname; {
|
||||||
|
int k;char c;
|
||||||
|
blanks();
|
||||||
|
if(alpha(ch) == 0) return (*sname = 0);
|
||||||
|
k = 0;
|
||||||
|
while(an(ch)) {
|
||||||
|
sname[k] = gch();
|
||||||
|
if(k < NAMEMAX) ++k;
|
||||||
|
}
|
||||||
|
sname[k] = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
need(str) char *str; {
|
||||||
|
if(match(str) == 0) error("missing token");
|
||||||
|
}
|
||||||
|
|
||||||
|
ns() {
|
||||||
|
if(match(";") == 0) error("no semicolon");
|
||||||
|
else errflag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
match(lit) char *lit; {
|
||||||
|
int k;
|
||||||
|
blanks();
|
||||||
|
if(k = streq(lptr, lit)) {
|
||||||
|
bump(k);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
streq(str1, str2) char str1[], str2[]; {
|
||||||
|
int k;
|
||||||
|
k = 0;
|
||||||
|
while (str2[k]) {
|
||||||
|
if(str1[k] != str2[k]) return 0;
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
amatch(lit, len) char *lit; int len; {
|
||||||
|
int k;
|
||||||
|
blanks();
|
||||||
|
if(k = astreq(lptr, lit, len)) {
|
||||||
|
bump(k);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
astreq(str1, str2, len) char str1[], str2[]; int len; {
|
||||||
|
int k;
|
||||||
|
k = 0;
|
||||||
|
while (k < len) {
|
||||||
|
if(str1[k] != str2[k]) break;
|
||||||
|
/*
|
||||||
|
** must detect end of symbol table names terminated by
|
||||||
|
** symbol length in binary
|
||||||
|
*/
|
||||||
|
if(str2[k] < ' ') break;
|
||||||
|
if(str1[k] < ' ') break;
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
if(an(str1[k]) || an(str2[k])) return 0;
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextop(list) char *list; {
|
||||||
|
char op[4];
|
||||||
|
opindex = 0;
|
||||||
|
blanks();
|
||||||
|
while(1) {
|
||||||
|
opsize = 0;
|
||||||
|
while(*list > ' ') op[opsize++] = *list++;
|
||||||
|
op[opsize] = 0;
|
||||||
|
if(opsize = streq(lptr, op))
|
||||||
|
if(*(lptr+opsize) != '=' &&
|
||||||
|
*(lptr+opsize) != *(lptr+opsize-1))
|
||||||
|
return 1;
|
||||||
|
if(*list) {
|
||||||
|
++list;
|
||||||
|
++opindex;
|
||||||
|
}
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blanks() {
|
||||||
|
while(1) {
|
||||||
|
while(ch) {
|
||||||
|
if(white()) gch();
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
if(line == mline) return;
|
||||||
|
preprocess();
|
||||||
|
if(eof) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
white() {
|
||||||
|
return (*lptr <= ' ' && *lptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
gch() {
|
||||||
|
int c;
|
||||||
|
if(c = ch) bump(1);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
bump(n) int n; {
|
||||||
|
if(n) lptr += n;
|
||||||
|
else lptr = line;
|
||||||
|
if(ch = nch = *lptr) nch = *(lptr+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
kill() {
|
||||||
|
*line = 0;
|
||||||
|
bump(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip() {
|
||||||
|
if(an(inbyte()))
|
||||||
|
while(an(ch)) gch();
|
||||||
|
else while(an(ch) == 0) {
|
||||||
|
if(ch == 0) break;
|
||||||
|
gch();
|
||||||
|
}
|
||||||
|
blanks();
|
||||||
|
}
|
||||||
|
|
||||||
|
endst() {
|
||||||
|
blanks();
|
||||||
|
return (streq(lptr, ";") || ch == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********** symbol table management functions ***********/
|
||||||
|
|
||||||
|
addsym(sname, id, type, size, value, lgpp, class)
|
||||||
|
char *sname, id, type;
|
||||||
|
int size, value, *lgpp, class;
|
||||||
|
{
|
||||||
|
if(lgpp == &glbptr)
|
||||||
|
{
|
||||||
|
if(cptr2 = findglb(sname))
|
||||||
|
return cptr2;
|
||||||
|
if(cptr == 0)
|
||||||
|
{
|
||||||
|
error("global symbol table overflow");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(locptr > (ENDLOC-SYMMAX))
|
||||||
|
{
|
||||||
|
error("local symbol table overflow");
|
||||||
|
exit(ERRCODE);
|
||||||
|
}
|
||||||
|
cptr = *lgpp;
|
||||||
|
}
|
||||||
|
cptr[IDENT] = id;
|
||||||
|
cptr[TYPE] = type;
|
||||||
|
cptr[CLASS] = class;
|
||||||
|
putint(size, cptr + SIZE, INTSIZE);
|
||||||
|
putint(value, cptr + OFFSET, INTSIZE);
|
||||||
|
cptr3 = cptr2 = cptr + NAME;
|
||||||
|
while(an(*sname))
|
||||||
|
*cptr2++ = *sname++;
|
||||||
|
|
||||||
|
if(lgpp == &locptr)
|
||||||
|
{
|
||||||
|
*cptr2 = cptr2 - cptr3; /* set length */
|
||||||
|
*lgpp = ++cptr2;
|
||||||
|
}
|
||||||
|
return cptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** search for symbol match
|
||||||
|
** on return cptr points to slot found or empty slot
|
||||||
|
*/
|
||||||
|
search(sname, buf, len, end, max, off)
|
||||||
|
char *sname, *buf, *end; int len, max, off; {
|
||||||
|
cptr =
|
||||||
|
cptr2 = buf+((hash(sname)%(max-1))*len);
|
||||||
|
while(*cptr != NULL) {
|
||||||
|
if(astreq(sname, cptr+off, NAMEMAX)) return 1;
|
||||||
|
if((cptr = cptr+len) >= end) cptr = buf;
|
||||||
|
if(cptr == cptr2) return (cptr = 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash(sname) char *sname; {
|
||||||
|
int i, c;
|
||||||
|
i = 0;
|
||||||
|
while(c = *sname++) i = (i << 1) + c;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
findglb(sname) char *sname; {
|
||||||
|
if(search(sname, STARTGLB, SYMMAX, ENDGLB, NUMGLBS, NAME))
|
||||||
|
return cptr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
findloc(sname) char *sname; {
|
||||||
|
cptr = locptr - 1; /* search backward for block locals */
|
||||||
|
while(cptr > STARTLOC) {
|
||||||
|
cptr = cptr - *cptr;
|
||||||
|
if(astreq(sname, cptr, NAMEMAX)) return (cptr - NAME);
|
||||||
|
cptr = cptr - NAME - 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextsym(entry) char *entry; {
|
||||||
|
entry = entry + NAME;
|
||||||
|
while(*entry++ >= ' '); /* find length byte */
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******** while queue management functions *********/
|
||||||
|
|
||||||
|
addwhile(ptr) int ptr[]; {
|
||||||
|
int k;
|
||||||
|
ptr[WQSP] = csp; /* and stk ptr */
|
||||||
|
ptr[WQLOOP] = getlabel(); /* and looping label */
|
||||||
|
ptr[WQEXIT] = getlabel(); /* and exit label */
|
||||||
|
if(wqptr == WQMAX) {
|
||||||
|
error("control statement nesting limit");
|
||||||
|
exit(ERRCODE);
|
||||||
|
}
|
||||||
|
k = 0;
|
||||||
|
while (k < WQSIZ) *wqptr++ = ptr[k++];
|
||||||
|
}
|
||||||
|
|
||||||
|
readwhile(ptr) int *ptr; {
|
||||||
|
if(ptr <= wq) {
|
||||||
|
error("out of context");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else return (ptr - WQSIZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
delwhile() {
|
||||||
|
if(wqptr > wq) wqptr -= WQSIZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************** utility functions ********************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** test if c is alphabetic
|
||||||
|
*/
|
||||||
|
alpha(c) char c; {
|
||||||
|
return (isalpha(c) || c == '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** test if given character is alphanumeric
|
||||||
|
*/
|
||||||
|
an(c) char c; {
|
||||||
|
return (alpha(c) || isdigit(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** return next avail internal label number
|
||||||
|
*/
|
||||||
|
getlabel() {
|
||||||
|
return(++nxtlab);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** get integer of length len from address addr
|
||||||
|
** (byte sequence set by "putint")
|
||||||
|
*/
|
||||||
|
getint(addr, len) char *addr; int len; {
|
||||||
|
int i;
|
||||||
|
i = *(addr + --len); /* high order byte sign extended */
|
||||||
|
while(len--) i = (i << 8) | *(addr + len) & 255;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** put integer i of length len into address addr
|
||||||
|
** (low byte first)
|
||||||
|
*/
|
||||||
|
putint(i, addr, len) char *addr; int i, len; {
|
||||||
|
while(len--) {
|
||||||
|
*addr++ = i;
|
||||||
|
i = i >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lout(line, fd) char *line; int fd; {
|
||||||
|
fputs(line, fd);
|
||||||
|
fputc(NEWLINE, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************* error functions *********************/
|
||||||
|
|
||||||
|
illname() {
|
||||||
|
error("illegal symbol");
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
multidef(sname) char *sname; {
|
||||||
|
error("already defined");
|
||||||
|
}
|
||||||
|
|
||||||
|
needlval() {
|
||||||
|
error("must be lvalue");
|
||||||
|
}
|
||||||
|
|
||||||
|
noiferr() {
|
||||||
|
error("no matching #if...");
|
||||||
|
errflag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
error(msg)
|
||||||
|
char msg[];
|
||||||
|
{
|
||||||
|
if(errflag)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
errflag = 1;
|
||||||
|
|
||||||
|
lout(line, stderr);
|
||||||
|
errout(msg, stderr);
|
||||||
|
if(alarm)
|
||||||
|
fputc(7, stderr);
|
||||||
|
if(pause)
|
||||||
|
while(fgetc(stderr) != NEWLINE);
|
||||||
|
if(listfp > 0)
|
||||||
|
errout(msg, listfp);
|
||||||
|
}
|
||||||
|
|
||||||
|
errout(msg, fp) char msg[]; int fp; {
|
||||||
|
int k;
|
||||||
|
k = line+2;
|
||||||
|
while(k++ <= lptr) fputc(' ', fp);
|
||||||
|
lout("/\\", fp);
|
||||||
|
fputs("**** ", fp); lout(msg, fp);
|
||||||
|
}
|
||||||
|
|
1093
programs/develop/scc/cc3.c
Normal file
1093
programs/develop/scc/cc3.c
Normal file
File diff suppressed because it is too large
Load Diff
985
programs/develop/scc/cc4.c
Normal file
985
programs/develop/scc/cc4.c
Normal file
@ -0,0 +1,985 @@
|
|||||||
|
/*
|
||||||
|
** Small-C Compiler -- Part 4 -- Back End.
|
||||||
|
** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix
|
||||||
|
** Copyright 1998 H T Walheim
|
||||||
|
** All rights reserved.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "cc.h"
|
||||||
|
|
||||||
|
/* #define DISOPT */ /* display optimizations values */
|
||||||
|
|
||||||
|
/*************************** externals ****************************/
|
||||||
|
|
||||||
|
extern char
|
||||||
|
*cptr, *macn, *litq, *symtab, optimize, ssname[NAMESIZE];
|
||||||
|
|
||||||
|
extern int
|
||||||
|
*stage, litlab, litptr, csp, output, oldseg, usexpr,
|
||||||
|
*snext, *stail, *slast;
|
||||||
|
|
||||||
|
|
||||||
|
/***************** optimizer command definitions ******************/
|
||||||
|
|
||||||
|
/* -- p-codes must not overlap these */
|
||||||
|
#define any 0x00FF /* matches any p-code */
|
||||||
|
#define _pop 0x00FE /* matches if corresponding POP2 exists */
|
||||||
|
#define pfree 0x00FD /* matches if pri register free */
|
||||||
|
#define sfree 0x00FC /* matches if sec register free */
|
||||||
|
#define comm 0x00FB /* matches if registers are commutative */
|
||||||
|
|
||||||
|
/* -- these digits are reserved for n */
|
||||||
|
#define go 0x0100 /* go n entries */
|
||||||
|
#define gc 0x0200 /* get code from n entries away */
|
||||||
|
#define gv 0x0300 /* get value from n entries away */
|
||||||
|
#define sum 0x0400 /* add value from nth entry away */
|
||||||
|
#define neg 0x0500 /* negate the value */
|
||||||
|
#define ife 0x0600 /* if value == n do commands to next 0 */
|
||||||
|
#define ifl 0x0700 /* if value < n do commands to next 0 */
|
||||||
|
#define swv 0x0800 /* swap value with value n entries away */
|
||||||
|
#define topop 0x0900 /* moves |code and current value to POP2 */
|
||||||
|
|
||||||
|
#define p1 0x0001 /* plus 1 */
|
||||||
|
#define p2 0x0002 /* plus 2 */
|
||||||
|
#define p3 0x0003 /* plus 3 */
|
||||||
|
#define p4 0x0004 /* plus 4 */
|
||||||
|
#define m1 0x00FF /* minus 1 */
|
||||||
|
#define m2 0x00FE /* minus 2 */
|
||||||
|
#define m3 0x00FD /* minus 3 */
|
||||||
|
#define m4 0x00FC /* minus 4 */
|
||||||
|
|
||||||
|
#define PRI 0030 /* primary register bits */
|
||||||
|
#define SEC 0003 /* secondary register bits */
|
||||||
|
#define USES 0011 /* use register contents */
|
||||||
|
#define ZAPS 0022 /* zap register contents */
|
||||||
|
#define PUSHES 0100 /* pushes onto the stack */
|
||||||
|
#define COMMUTES 0200 /* commutative p-code */
|
||||||
|
|
||||||
|
/******************** optimizer command lists *********************/
|
||||||
|
|
||||||
|
int
|
||||||
|
seq00[] = {0,ADD12,MOVE21,0, /* ADD21 */
|
||||||
|
go|p1,ADD21,0},
|
||||||
|
|
||||||
|
seq01[] = {0,ADD1n,0, /* rINC1 or rDEC1 ? */
|
||||||
|
ifl|m2,0,ifl|0,rDEC1,neg,0,ifl|p3,rINC1,0,0},
|
||||||
|
|
||||||
|
seq02[] = {0,ADD2n,0, /* rINC2 or rDEC2 ? */
|
||||||
|
ifl|m2,0,ifl|0,rDEC2,neg,0,ifl|p3,rINC2,0,0},
|
||||||
|
|
||||||
|
seq03[] = {0,rDEC1,PUTbp1,rINC1,0, /* SUBbpn or DECbp */
|
||||||
|
go|p2,ife|p1,DECbp,0,SUBbpn,0},
|
||||||
|
|
||||||
|
seq04[] = {0,rDEC1,PUTwp1,rINC1,0, /* SUBwpn or DECwp */
|
||||||
|
go|p2,ife|p1,DECwp,0,SUBwpn,0},
|
||||||
|
|
||||||
|
seq05[] = {0,rDEC1,PUTbm1,rINC1,0, /* SUB_m_ COMMAn */
|
||||||
|
go|p1,SUB_m_,go|p1,COMMAn,go|m1,0},
|
||||||
|
|
||||||
|
seq06[] = {0,rDEC1,PUTwm1,rINC1,0, /* SUB_m_ COMMAn */
|
||||||
|
go|p1,SUB_m_,go|p1,COMMAn,go|m1,0},
|
||||||
|
|
||||||
|
seq07[] = {0,GETw1m,GETw2n,ADD12,MOVE21,GETb1p,0, /* GETw2m GETb1p */
|
||||||
|
go|p4,gv|m3,go|m1,GETw2m,gv|m3,0},
|
||||||
|
|
||||||
|
seq08[] = {0,GETw1m,GETw2n,ADD12,MOVE21,GETb1pu,0, /* GETw2m GETb1pu */
|
||||||
|
go|p4,gv|m3,go|m1,GETw2m,gv|m3,0},
|
||||||
|
|
||||||
|
seq09[] = {0,GETw1m,GETw2n,ADD12,MOVE21,GETw1p,0, /* GETw2m GETw1p */
|
||||||
|
go|p4,gv|m3,go|m1,GETw2m,gv|m3,0},
|
||||||
|
|
||||||
|
seq10[] = {0,GETw1m,GETw2m,SWAP12,0, /* GETw2m GETw1m */
|
||||||
|
go|p2,GETw1m,gv|m1,go|m1,gv|m1,0},
|
||||||
|
|
||||||
|
seq11[] = {0,GETw1m,MOVE21,0, /* GETw2m */
|
||||||
|
go|p1,GETw2m,gv|m1,0},
|
||||||
|
|
||||||
|
seq12[] = {0,GETw1m,PUSH1,pfree,0, /* PUSHm */
|
||||||
|
go|p1,PUSHm,gv|m1,0},
|
||||||
|
|
||||||
|
seq13[] = {0,GETw1n,PUTbm1,pfree,0, /* PUT_m_ COMMAn */
|
||||||
|
PUT_m_,go|p1,COMMAn,go|m1,swv|p1,0},
|
||||||
|
|
||||||
|
seq14[] = {0,GETw1n,PUTwm1,pfree,0, /* PUT_m_ COMMAn */
|
||||||
|
PUT_m_,go|p1,COMMAn,go|m1,swv|p1,0},
|
||||||
|
|
||||||
|
seq15[] = {0,GETw1p,PUSH1,pfree,0, /* PUSHp */
|
||||||
|
go|p1,PUSHp,gv|m1,0},
|
||||||
|
|
||||||
|
seq16[] = {0,GETw1s,GETw2n,ADD12,MOVE21,0, /* GETw2s ADD2n */
|
||||||
|
go|p3,ADD2n,gv|m2,go|m1,GETw2s,gv|m2,0},
|
||||||
|
|
||||||
|
seq17[] = {0,GETw1s,GETw2s,SWAP12,0, /* GETw2s GETw1s */
|
||||||
|
go|p2,GETw1s,gv|m1,go|m1,GETw2s,gv|m1,0},
|
||||||
|
|
||||||
|
seq18[] = {0,GETw1s,MOVE21,0, /* GETw2s */
|
||||||
|
go|p1,GETw2s,gv|m1,0},
|
||||||
|
|
||||||
|
seq19[] = {0,GETw2m,GETw1n,SWAP12,SUB12,0, /* GETw1m SUB1n */
|
||||||
|
go|p3,SUB1n,gv|m2,go|m1,GETw1m,gv|m2,0},
|
||||||
|
|
||||||
|
seq20[] = {0,GETw2n,ADD12,0, /* ADD1n */
|
||||||
|
go|p1,ADD1n,gv|m1,0},
|
||||||
|
|
||||||
|
seq21[] = {0,GETw2s,GETw1n,SWAP12,SUB12,0, /* GETw1s SUB1n */
|
||||||
|
go|p3,SUB1n,gv|m2,go|m1,GETw1s,gv|m2,0},
|
||||||
|
|
||||||
|
seq22[] = {0,rINC1,PUTbm1,rDEC1,0, /* ADDm_ COMMAn */
|
||||||
|
go|p1,ADDm_,go|p1,COMMAn,go|m1,0},
|
||||||
|
|
||||||
|
seq23[] = {0,rINC1,PUTwm1,rDEC1,0, /* ADDm_ COMMAn */
|
||||||
|
go|p1,ADDm_,go|p1,COMMAn,go|m1,0},
|
||||||
|
|
||||||
|
seq24[] = {0,rINC1,PUTbp1,rDEC1,0, /* ADDbpn or INCbp */
|
||||||
|
go|p2,ife|p1,INCbp,0,ADDbpn,0},
|
||||||
|
|
||||||
|
seq25[] = {0,rINC1,PUTwp1,rDEC1,0, /* ADDwpn or INCwp */
|
||||||
|
go|p2,ife|p1,INCwp,0,ADDwpn,0},
|
||||||
|
|
||||||
|
seq26[] = {0,MOVE21,GETw1n,SWAP12,SUB12,0, /* SUB1n */
|
||||||
|
go|p3,SUB1n,gv|m2,0},
|
||||||
|
|
||||||
|
seq27[] = {0,MOVE21,GETw1n,comm,0, /* GETw2n comm */
|
||||||
|
go|p1,GETw2n,0},
|
||||||
|
|
||||||
|
seq28[] = {0,POINT1m,GETw2n,ADD12,MOVE21,0, /* POINT2m_ PLUSn */
|
||||||
|
go|p3,PLUSn,gv|m2,go|m1,POINT2m_,gv|m2,0},
|
||||||
|
|
||||||
|
seq29[] = {0,POINT1m,MOVE21,pfree,0, /* POINT2m */
|
||||||
|
go|p1,POINT2m,gv|m1,0},
|
||||||
|
|
||||||
|
seq30[] = {0,POINT1m,PUSH1,pfree,_pop,0, /* ... POINT2m */
|
||||||
|
topop|POINT2m,go|p2,0},
|
||||||
|
|
||||||
|
seq31[] = {0,POINT1s,GETw2n,ADD12,MOVE21,0, /* POINT2s */
|
||||||
|
sum|p1,go|p3,POINT2s,gv|m3,0},
|
||||||
|
|
||||||
|
seq32[] = {0,POINT1s,PUSH1,MOVE21,0, /* POINT2s PUSH2 */
|
||||||
|
go|p1,POINT2s,gv|m1,go|p1,PUSH2,go|m1,0},
|
||||||
|
|
||||||
|
seq33[] = {0,POINT1s,PUSH1,pfree,_pop,0, /* ... POINT2s */
|
||||||
|
topop|POINT2s,go|p2,0},
|
||||||
|
|
||||||
|
seq34[] = {0,POINT1s,MOVE21,0, /* POINT2s */
|
||||||
|
go|p1,POINT2s,gv|m1,0},
|
||||||
|
|
||||||
|
seq35[] = {0,POINT2m,GETb1p,sfree,0, /* GETb1m */
|
||||||
|
go|p1,GETb1m,gv|m1,0},
|
||||||
|
|
||||||
|
seq36[] = {0,POINT2m,GETb1pu,sfree,0, /* GETb1mu */
|
||||||
|
go|p1,GETb1mu,gv|m1,0},
|
||||||
|
|
||||||
|
seq37[] = {0,POINT2m,GETw1p,sfree,0, /* GETw1m */
|
||||||
|
go|p1,GETw1m,gv|m1,0},
|
||||||
|
|
||||||
|
seq38[] = {0,POINT2m_,PLUSn,GETw1p,sfree,0, /* GETw1m_ PLUSn */
|
||||||
|
go|p2,gc|m1,gv|m1,go|m1,GETw1m_,gv|m1,0},
|
||||||
|
|
||||||
|
seq39[] = {0,POINT2s,GETb1p,sfree,0, /* GETb1s */
|
||||||
|
sum|p1,go|p1,GETb1s,gv|m1,0},
|
||||||
|
|
||||||
|
seq40[] = {0,POINT2s,GETb1pu,sfree,0, /* GETb1su */
|
||||||
|
sum|p1,go|p1,GETb1su,gv|m1,0},
|
||||||
|
|
||||||
|
seq41[] = {0,POINT2s,GETw1p,PUSH1,pfree,0, /* PUSHs */
|
||||||
|
sum|p1,go|p2,PUSHs,gv|m2,0},
|
||||||
|
|
||||||
|
seq42[] = {0,POINT2s,GETw1p,sfree,0, /* GETw1s */
|
||||||
|
sum|p1,go|p1,GETw1s,gv|m1,0},
|
||||||
|
|
||||||
|
seq43[] = {0,PUSH1,any,POP2,0, /* MOVE21 any */
|
||||||
|
go|p2,gc|m1,gv|m1,go|m1,MOVE21,0},
|
||||||
|
|
||||||
|
seq44[] = {0,PUSHm,_pop,0, /* ... GETw2m */
|
||||||
|
topop|GETw2m,go|p1,0},
|
||||||
|
|
||||||
|
seq45[] = {0,PUSHp,any,POP2,0, /* GETw2p ... */
|
||||||
|
go|p2,gc|m1,gv|m1,go|m1,GETw2p,gv|m1,0},
|
||||||
|
|
||||||
|
seq46[] = {0,PUSHs,_pop,0, /* ... GETw2s */
|
||||||
|
topop|GETw2s,go|p1,0},
|
||||||
|
|
||||||
|
seq47[] = {0,SUB1n,0, /* rDEC1 or rINC1 ? */
|
||||||
|
ifl|m2,0,ifl|0,rINC1,neg,0,ifl|p3,rDEC1,0,0};
|
||||||
|
|
||||||
|
#define HIGH_SEQ 47
|
||||||
|
int seq[HIGH_SEQ + 1];
|
||||||
|
setseq() {
|
||||||
|
seq[ 0] = seq00; seq[ 1] = seq01; seq[ 2] = seq02; seq[ 3] = seq03;
|
||||||
|
seq[ 4] = seq04; seq[ 5] = seq05; seq[ 6] = seq06; seq[ 7] = seq07;
|
||||||
|
seq[ 8] = seq08; seq[ 9] = seq09; seq[10] = seq10; seq[11] = seq11;
|
||||||
|
seq[12] = seq12; seq[13] = seq13; seq[14] = seq14; seq[15] = seq15;
|
||||||
|
seq[16] = seq16; seq[17] = seq17; seq[18] = seq18; seq[19] = seq19;
|
||||||
|
seq[20] = seq20; seq[21] = seq21; seq[22] = seq22; seq[23] = seq23;
|
||||||
|
seq[24] = seq24; seq[25] = seq25; seq[26] = seq26; seq[27] = seq27;
|
||||||
|
seq[28] = seq28; seq[29] = seq29; seq[30] = seq30; seq[31] = seq31;
|
||||||
|
seq[32] = seq32; seq[33] = seq33; seq[34] = seq34; seq[35] = seq35;
|
||||||
|
seq[36] = seq36; seq[37] = seq37; seq[38] = seq38; seq[39] = seq39;
|
||||||
|
seq[40] = seq40; seq[41] = seq41; seq[42] = seq42; seq[43] = seq43;
|
||||||
|
seq[44] = seq44; seq[45] = seq45; seq[46] = seq46; seq[47] = seq47;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************** assembly-code strings ******************/
|
||||||
|
|
||||||
|
int code[PCODES];
|
||||||
|
|
||||||
|
/*
|
||||||
|
** First byte contains flag bits indicating:
|
||||||
|
** the value in ax is needed (010) or zapped (020)
|
||||||
|
** the value in bx is needed (001) or zapped (002)
|
||||||
|
*/
|
||||||
|
setcodes() {
|
||||||
|
setseq();
|
||||||
|
code[ADD12] = "\211ADD EAX,EBX\15\n";
|
||||||
|
code[ADD1n] = "\010?ADD EAX,<n>\15\n??";
|
||||||
|
code[ADD21] = "\211ADD EBX,EAX\15\n";
|
||||||
|
code[ADD2n] = "\010?ADD EBX,<n>\15\n??";
|
||||||
|
code[ADDbpn] = "\001ADD BYTE [EBX],<n>\15\n";
|
||||||
|
code[ADDwpn] = "\001ADD WORD [EBX],<n>\15\n";
|
||||||
|
code[ADDm_] = "\000ADD <m>";
|
||||||
|
code[ADDSP] = "\000?ADD ESP,<n>\15\n??";
|
||||||
|
code[AND12] = "\211AND EAX,EBX\15\n";
|
||||||
|
code[ANEG1] = "\010NEG EAX\15\n";
|
||||||
|
code[ARGCNTn] = "\000?MOV CL,<n>?XOR CL,CL?\15\n";
|
||||||
|
code[ASL12] = "\011MOV ECX,EAX\15\nMOV EAX,EBX\15\nSAL EAX,CL\15\n";
|
||||||
|
code[ASR12] = "\011MOV ECX,EAX\15\nMOV EAX,EBX\15\nSAR EAX,CL\15\n";
|
||||||
|
code[CALL1] = "\010CALL EAX\15\n";
|
||||||
|
code[CALLm] = "\020CALL <m>\15\n";
|
||||||
|
code[BYTE_] = "\000 DB ";
|
||||||
|
code[BYTEn] = "\000 RESB <n>\15\n";
|
||||||
|
code[BYTEr0] = "\000 TIMES <n> DB 0\15\n";
|
||||||
|
code[COM1] = "\010NOT EAX\15\n";
|
||||||
|
code[COMMAn] = "\000,<n>\15\n";
|
||||||
|
code[DBL1] = "\010SHL EAX,1\15\n";
|
||||||
|
code[DBL2] = "\001SHL EBX,1\15\n";
|
||||||
|
code[DECbp] = "\001DEC BYTE [EBX]\15\n";
|
||||||
|
code[DECwp] = "\001DEC WORD [EBX]\15\n";
|
||||||
|
code[DIV12] = "\011CDQ\15\nIDIV EBX\15\n"; /* see gen() */
|
||||||
|
code[DIV12u] = "\011XOR EDX,EDX\15\nDIV EBX\15\n"; /* see gen() */
|
||||||
|
|
||||||
|
code[DWORD_] = "\000 DD ";
|
||||||
|
code[DWORDn] = "\000 DD <n>\15\n";
|
||||||
|
code[DWORDr0] = "\000 TIMES <n> DD 0\15\n";
|
||||||
|
|
||||||
|
code[ENTER] = "\100PUSH EBP\15\nMOV EBP,ESP\15\n";
|
||||||
|
code[EQ10f] = "\010<g>OR EAX,EAX\15\nJE _<d>\15\nJMP _<n>\15\n_<d>:\15\n";
|
||||||
|
code[EQ12] = "\211CALL __eq\15\n";
|
||||||
|
code[GE10f] = "\010<g>OR EAX,EAX\15\nJGE _<d>\15\nJMP _<n>\15\n_<d>:\15\n";
|
||||||
|
code[GE12] = "\011CALL __ge\15\n";
|
||||||
|
code[GE12u] = "\011CALL __uge\15\n";
|
||||||
|
code[GETb1m] = "\020MOVSX EAX,BYTE [<m>]\15\n";
|
||||||
|
code[GETb1mu] = "\020MOVZX EAX,BYTE [<m>]\15\n";
|
||||||
|
code[GETb1p] = "\021MOVSX EAX,BYTE [EBX?<o>??]\15\n"; /* see gen() */
|
||||||
|
code[GETb1pu] = "\021MOVZX EAX,BYTE [EBX?<o>??]\15\n"; /* see gen() */
|
||||||
|
code[GETb1s] = "\020MOVSX EAX,BYTE [EBP<o>]\15\n";
|
||||||
|
code[GETb1su] = "\020MOVZX EAX,BYTE [EBP<o>]\15\n";
|
||||||
|
|
||||||
|
code[GETd1m] = "\020MOV EAX,[<m>]\15\n";
|
||||||
|
code[GETd1n] = "\020?MOV EAX,<n>?XOR EAX,EAX?\15\n";
|
||||||
|
code[GETd1p] = "\021MOV EAX, [EBX?<o>??]\15\n"; /* see gen() */
|
||||||
|
code[GETd2n] = "\002?MOV EBX,<n>?XOR EBX,EBX?\15\n";
|
||||||
|
|
||||||
|
code[GETw1m] = "\020MOVSX EAX,WORD [<m>]\15\n";
|
||||||
|
code[GETw1m_] = "\020MOVSX EAX,WORD [<m>]";
|
||||||
|
code[GETw1n] = "\020?MOV EAX,<n>?XOR EAX,EAX?\15\n";
|
||||||
|
code[GETw1p] = "\021MOVSX EAX, WORD [EBX?<o>??]\15\n"; /* see gen() */
|
||||||
|
code[GETw1s] = "\020MOVSX EAX, WORD [EBP<o>]\15\n";
|
||||||
|
code[GETw2m] = "\002MOVSX EBX,WORD <m>\15\n";
|
||||||
|
code[GETw2n] = "\002?MOV EBX,<n>?XOR EBX,EBX?\15\n";
|
||||||
|
code[GETw2p] = "\021MOVSX EBX,WORD [EBX?<o>??]\15\n";
|
||||||
|
code[GETw2s] = "\002MOVSX EBX,WORD [EBP<o>]\15\n";
|
||||||
|
code[GT10f] = "\010<g>OR EAX,EAX\15\nJG _<d>\15\nJMP _<n>\15\n_<d>:\15\n";
|
||||||
|
code[GT12] = "\010CALL __gt\15\n";
|
||||||
|
code[GT12u] = "\011CALL __ugt\15\n";
|
||||||
|
code[INCbp] = "\001INC BYTE [EBX]\15\n";
|
||||||
|
code[INCwp] = "\001INC WORD [EBX]\15\n";
|
||||||
|
code[WORD_] = "\000 DW ";
|
||||||
|
code[WORDn] = "\000 RESW <n>\15\n";
|
||||||
|
code[WORDr0] = "\000 TIMES <n> DW 0\15\n";
|
||||||
|
code[JMPm] = "\000JMP _<n>\15\n";
|
||||||
|
code[LABm] = "\000_<n>:\15\n";
|
||||||
|
code[LE10f] = "\010<g>OR EAX,EAX\15\nJLE _<d>\15\nJMP _<n>\15\n_<d>:\15\n";
|
||||||
|
code[LE12] = "\011CALL __le\15\n";
|
||||||
|
code[LE12u] = "\011CALL __ule\15\n";
|
||||||
|
code[LNEG1] = "\010CALL __lneg\15\n";
|
||||||
|
code[LT10f] = "\010<g>OR EAX,EAX\15\nJL _<d>\15\nJMP _<n>\15\n_<d>:\15\n";
|
||||||
|
code[LT12] = "\011CALL __lt\15\n";
|
||||||
|
code[LT12u] = "\011CALL __ult\15\n";
|
||||||
|
code[MOD12] = "\011CDQ\15\nIDIV EBX\15\nMOV EAX,EDX\15\n"; /* see gen() */
|
||||||
|
code[MOD12u] = "\011XOR EDX,EDX\15\nDIV EBX\15\nMOV EAX,EDX\15\n"; /* see gen() */
|
||||||
|
code[MOVE21] = "\012MOV EBX,EAX\15\n";
|
||||||
|
code[MUL12] = "\211IMUL EBX\15\n";
|
||||||
|
code[MUL12u] = "\211MUL EBX\15\n";
|
||||||
|
code[NE10f] = "\010<g>OR EAX,EAX\15\nJNE _<d>\15\nJMP _<n>\15\n_<d>:\15\n";
|
||||||
|
code[NE12] = "\211CALL __ne\15\n";
|
||||||
|
code[NEARm] = "\000 DD _<n>\15\n";
|
||||||
|
code[OR12] = "\211OR EAX,EBX\15\n";
|
||||||
|
code[PLUSn] = "\000?+<n>??\15\n";
|
||||||
|
code[POINT1l] = "\020MOV EAX,_<l>+<n>\15\n";
|
||||||
|
code[POINT1m] = "\020MOV EAX,<m>\15\n";
|
||||||
|
code[POINT1s] = "\020LEA EAX,[EBP<o>]\15\n";
|
||||||
|
code[POINT2m] = "\002MOV EBX,<m>\15\n";
|
||||||
|
code[POINT2m_]= "\002MOV EBX,<m>";
|
||||||
|
code[POINT2s] = "\002LEA EBX,[EBP<o>]\15\n";
|
||||||
|
code[POP2] = "\002POP EBX\15\n";
|
||||||
|
code[PUSH1] = "\110PUSH EAX\15\n";
|
||||||
|
code[PUSH2] = "\101PUSH EBX\15\n";
|
||||||
|
code[PUSHm] = "\100PUSH <m>\15\n";
|
||||||
|
code[PUSHp] = "\100PUSH [EBX?<o>??]\15\n";
|
||||||
|
code[PUSHs] = "\100PUSH [EBP?<o>??]\15\n";
|
||||||
|
code[PUT_m_] = "\000MOV <m>";
|
||||||
|
code[PUTbm1] = "\010MOV BYTE [<m>],AL\15\n";
|
||||||
|
code[PUTbp1] = "\011MOV [EBX],AL\15\n";
|
||||||
|
code[PUTdm1] = "\010MOV DWORD [<m>],EAX\15\n";
|
||||||
|
code[PUTdp1] = "\011MOV [EBX],EAX\15\n";
|
||||||
|
code[PUTwm1] = "\010MOV WORD [<m>],AX\15\n";
|
||||||
|
code[PUTwp1] = "\011MOV [EBX],AX\15\n";
|
||||||
|
code[rDEC1] = "\010#DEC EAX\15\n#";
|
||||||
|
code[rDEC2] = "\010#DEC EBX\15\n#";
|
||||||
|
code[REFm] = "\000_<n>";
|
||||||
|
code[RETURN] = "\000?MOV ESP,EBP\15\n??POP EBP\15\nRET\15\n";
|
||||||
|
code[rINC1] = "\010#INC EAX\15\n#";
|
||||||
|
code[rINC2] = "\010#INC EBX\15\n#";
|
||||||
|
code[SUB_m_] = "\000SUB <m>";
|
||||||
|
code[SUB12] = "\011SUB EAX,EBX\15\n"; /* see gen() */
|
||||||
|
code[SUB1n] = "\010?SUB EAX,<n>\15\n??";
|
||||||
|
code[SUBbpn] = "\001SUB [EBX],<n>\15\n";
|
||||||
|
code[SUBwpn] = "\001SUB [EBX],<n>\15\n";
|
||||||
|
code[SWAP12] = "\011XCHG EAX,EBX\15\n";
|
||||||
|
code[SWAP1s] = "\012POP EBX\15\nXCHG EAX,EBX\15\nPUSH EBX\15\n";
|
||||||
|
code[SWITCH] = "\012CALL __switch\15\n";
|
||||||
|
code[XOR12] = "\211XOR EAX,EBX\15\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************** code generation functions *****************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** print all assembler info before any code is generated
|
||||||
|
** and ensure that the segments appear in the correct order.
|
||||||
|
*/
|
||||||
|
header() {
|
||||||
|
/* outline(" .386");
|
||||||
|
outline(" .MODEL FLAT");
|
||||||
|
*/ toseg(CODESEG);
|
||||||
|
|
||||||
|
/* - FASM
|
||||||
|
outline("EXTERN __eq");
|
||||||
|
outline("EXTERN __ne");
|
||||||
|
outline("EXTERN __le");
|
||||||
|
outline("EXTERN __lt");
|
||||||
|
outline("EXTERN __ge");
|
||||||
|
outline("EXTERN __gt");
|
||||||
|
outline("EXTERN __ule");
|
||||||
|
outline("EXTERN __ult");
|
||||||
|
outline("EXTERN __uge");
|
||||||
|
outline("EXTERN __ugt");
|
||||||
|
outline("EXTERN __lneg");
|
||||||
|
outline("EXTERN __switch");
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* outline("dw 0"); *//* force non-zero code pointers, word alignment */
|
||||||
|
toseg(DATASEG);
|
||||||
|
/* outline("dw 0"); *//* force non-zero data pointers, word alignment */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** print any assembler stuff needed at the end
|
||||||
|
*/
|
||||||
|
trailer() {
|
||||||
|
char *cp;
|
||||||
|
cptr = STARTGLB;
|
||||||
|
while(cptr < ENDGLB) {
|
||||||
|
if(cptr[IDENT] == FUNCTION && cptr[CLASS] == AUTOEXT)
|
||||||
|
external(cptr + NAME, 0, FUNCTION);
|
||||||
|
cptr += SYMMAX;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if((cp = findglb("main")) && cp[CLASS]==STATIC)
|
||||||
|
external("_main", 0, FUNCTION);
|
||||||
|
*/
|
||||||
|
toseg(NULL);
|
||||||
|
/* outline("END"); */
|
||||||
|
#ifdef DISOPT
|
||||||
|
{
|
||||||
|
int i, *count;
|
||||||
|
printf(";opt count\n");
|
||||||
|
for(i = -1; ++i <= HIGH_SEQ; ) {
|
||||||
|
count = seq[i];
|
||||||
|
printf("; %2u %5u\n", i, *count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** remember where we are in the queue in case we have to back up.
|
||||||
|
*/
|
||||||
|
setstage(before, start) int *before, *start; {
|
||||||
|
if((*before = snext) == 0)
|
||||||
|
snext = stage;
|
||||||
|
*start = snext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** generate code in staging buffer.
|
||||||
|
*/
|
||||||
|
gen(pcode, value)
|
||||||
|
int pcode, value;
|
||||||
|
{
|
||||||
|
int newcsp;
|
||||||
|
switch(pcode)
|
||||||
|
{
|
||||||
|
case GETb1pu:
|
||||||
|
case GETb1p:
|
||||||
|
case GETw1p:
|
||||||
|
case GETd1p:
|
||||||
|
gen(MOVE21, 0);
|
||||||
|
break;
|
||||||
|
case SUB12:
|
||||||
|
case MOD12:
|
||||||
|
case MOD12u:
|
||||||
|
case DIV12:
|
||||||
|
case DIV12u:
|
||||||
|
gen(SWAP12, 0);
|
||||||
|
break;
|
||||||
|
case PUSH1:
|
||||||
|
#ifdef INT32
|
||||||
|
csp -= BPD;
|
||||||
|
#else
|
||||||
|
csp -= BPW;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case POP2:
|
||||||
|
#ifdef INT32
|
||||||
|
csp += BPD;
|
||||||
|
#else
|
||||||
|
csp += BPW;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case ADDSP:
|
||||||
|
case RETURN:
|
||||||
|
newcsp = value;
|
||||||
|
value -= csp;
|
||||||
|
csp = newcsp;
|
||||||
|
}
|
||||||
|
if(snext == 0)
|
||||||
|
{
|
||||||
|
outcode(pcode, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(snext >= slast)
|
||||||
|
{
|
||||||
|
error("staging buffer overflow");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
snext[0] = pcode;
|
||||||
|
snext[1] = value;
|
||||||
|
snext += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** dump the contents of the queue.
|
||||||
|
** If start = 0, throw away contents.
|
||||||
|
** If before != 0, don't dump queue yet.
|
||||||
|
*/
|
||||||
|
clearstage(before, start)
|
||||||
|
int *before, *start;
|
||||||
|
{
|
||||||
|
if(before)
|
||||||
|
{
|
||||||
|
snext = before;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(start)
|
||||||
|
dumpstage();
|
||||||
|
snext = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** dump the staging buffer
|
||||||
|
*/
|
||||||
|
dumpstage()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
stail = snext;
|
||||||
|
snext = stage;
|
||||||
|
while(snext < stail)
|
||||||
|
{
|
||||||
|
if(optimize)
|
||||||
|
{
|
||||||
|
restart:
|
||||||
|
i = -1;
|
||||||
|
while(++i <= HIGH_SEQ)
|
||||||
|
if(peep(seq[i]))
|
||||||
|
{
|
||||||
|
#ifdef DISOPT
|
||||||
|
if(isatty(output))
|
||||||
|
fprintf(stderr, " optimized %2u\n", i);
|
||||||
|
#endif
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outcode(snext[0], snext[1]);
|
||||||
|
snext += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** change to a new segment
|
||||||
|
** may be called with NULL, CODESEG, or DATASEG
|
||||||
|
** With NASM the section names are case-sensitive
|
||||||
|
*/
|
||||||
|
toseg(newseg)
|
||||||
|
int newseg;
|
||||||
|
{
|
||||||
|
if(oldseg == newseg)
|
||||||
|
return;
|
||||||
|
/* if(oldseg == CODESEG)
|
||||||
|
outline("_TEXT ENDS");
|
||||||
|
else if(oldseg == DATASEG)
|
||||||
|
outline("_DATA ENDS"); <-- */
|
||||||
|
|
||||||
|
/* - FASM
|
||||||
|
if(newseg == CODESEG)
|
||||||
|
{
|
||||||
|
outline("SECTION .text");
|
||||||
|
}
|
||||||
|
else if(newseg == DATASEG)
|
||||||
|
outline("SECTION .data");
|
||||||
|
*/
|
||||||
|
oldseg = newseg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** declare entry point
|
||||||
|
*/
|
||||||
|
public(ident) int ident;{
|
||||||
|
if(ident == FUNCTION)
|
||||||
|
toseg(CODESEG);
|
||||||
|
else toseg(DATASEG);
|
||||||
|
/* - FASM
|
||||||
|
outstr("GLOBAL ");
|
||||||
|
outname(ssname);
|
||||||
|
*/
|
||||||
|
newline();
|
||||||
|
outname(ssname);
|
||||||
|
if(ident == FUNCTION) {
|
||||||
|
colon();
|
||||||
|
newline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** declare external reference
|
||||||
|
*/
|
||||||
|
external(name, size, ident) char *name; int size, ident; {
|
||||||
|
if(ident == FUNCTION)
|
||||||
|
toseg(CODESEG);
|
||||||
|
else toseg(DATASEG);
|
||||||
|
/* - FASM
|
||||||
|
outstr("EXTERN ");
|
||||||
|
outname(name);
|
||||||
|
/# colon();
|
||||||
|
outsize(size, ident); <-- #/
|
||||||
|
newline();
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** output the size of the object pointed to.
|
||||||
|
*/
|
||||||
|
outsize(size, ident) int size, ident;
|
||||||
|
{
|
||||||
|
/* why not size on FUNCTION and POINTER ? */
|
||||||
|
if (ident == FUNCTION)
|
||||||
|
outstr("NEAR");
|
||||||
|
else if (ident == POINTER)
|
||||||
|
outstr("DWORD");
|
||||||
|
else if(size == 1)
|
||||||
|
outstr("BYTE");
|
||||||
|
else if(size == 2)
|
||||||
|
outstr("WORD");
|
||||||
|
else
|
||||||
|
outstr("DWORD");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** point to following object(s)
|
||||||
|
*/
|
||||||
|
point() {
|
||||||
|
outline(" DW $+2");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** dump the literal pool
|
||||||
|
*/
|
||||||
|
dumplits(size) int size;
|
||||||
|
{
|
||||||
|
int j, k;
|
||||||
|
k = 0;
|
||||||
|
while (k < litptr)
|
||||||
|
{
|
||||||
|
if(size == 1)
|
||||||
|
{
|
||||||
|
gen(BYTE_, NULL);
|
||||||
|
}
|
||||||
|
else if (size == 2)
|
||||||
|
{
|
||||||
|
gen(WORD_, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gen(DWORD_,NULL);
|
||||||
|
}
|
||||||
|
j = 10;
|
||||||
|
while(j--)
|
||||||
|
{
|
||||||
|
outdec(getint(litq + k, size));
|
||||||
|
k += size;
|
||||||
|
if(j == 0 || k >= litptr)
|
||||||
|
{
|
||||||
|
newline();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fputc(',', output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** dump zeroes for default initial values
|
||||||
|
*/
|
||||||
|
dumpzero(size, count)
|
||||||
|
int size, count;
|
||||||
|
{
|
||||||
|
if(count > 0)
|
||||||
|
{
|
||||||
|
if(size == 1)
|
||||||
|
gen(BYTEr0, count);
|
||||||
|
else if (size == 2)
|
||||||
|
gen(WORDr0, count);
|
||||||
|
else
|
||||||
|
gen(DWORDr0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************** optimizer functions ***********************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Try to optimize sequence at snext in the staging buffer.
|
||||||
|
*/
|
||||||
|
peep(seq) int *seq; {
|
||||||
|
int *next, *count, *pop, n, skip, tmp, reply;
|
||||||
|
char c;
|
||||||
|
next = snext;
|
||||||
|
count = seq++;
|
||||||
|
while(*seq) {
|
||||||
|
switch(*seq) {
|
||||||
|
case any: if(next < stail) break; return (NO);
|
||||||
|
case pfree: if(isfree(PRI, next)) break; return (NO);
|
||||||
|
case sfree: if(isfree(SEC, next)) break; return (NO);
|
||||||
|
case comm: if(*next & COMMUTES) break; return (NO);
|
||||||
|
case _pop: if(pop = getpop(next)) break; return (NO);
|
||||||
|
default: if(next >= stail || *next != *seq) return (NO);
|
||||||
|
}
|
||||||
|
next += 2; ++seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****** have a match, now optimize it ******/
|
||||||
|
|
||||||
|
*count += 1;
|
||||||
|
reply = skip = NO;
|
||||||
|
while(*(++seq) || skip) {
|
||||||
|
if(skip) {
|
||||||
|
if(*seq == 0) skip = NO;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(*seq >= PCODES) {
|
||||||
|
c = *seq & 0xFF; /* get low byte of command */
|
||||||
|
n = c; /* and sign extend into n */
|
||||||
|
switch(*seq & 0xFF00) {
|
||||||
|
case ife: if(snext[1] != n) skip = YES; break;
|
||||||
|
case ifl: if(snext[1] >= n) skip = YES; break;
|
||||||
|
case go: snext += (n<<1); break;
|
||||||
|
case gc: snext[0] = snext[(n<<1)]; goto done;
|
||||||
|
case gv: snext[1] = snext[(n<<1)+1]; goto done;
|
||||||
|
case sum: snext[1] += snext[(n<<1)+1]; goto done;
|
||||||
|
case neg: snext[1] = -snext[1]; goto done;
|
||||||
|
case topop: pop[0] = n; pop[1] = snext[1]; goto done;
|
||||||
|
case swv: tmp = snext[1];
|
||||||
|
snext[1] = snext[(n<<1)+1];
|
||||||
|
snext[(n<<1)+1] = tmp;
|
||||||
|
done: reply = YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else snext[0] = *seq; /* set p-code */
|
||||||
|
}
|
||||||
|
return (reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Is the primary or secondary register free?
|
||||||
|
** Is it zapped or unused by the p-code at pp
|
||||||
|
** or a successor? If the primary register is
|
||||||
|
** unused by it still may not be free if the
|
||||||
|
** context uses the value of the expression.
|
||||||
|
*/
|
||||||
|
isfree(reg, pp) int reg, *pp; {
|
||||||
|
char *cp;
|
||||||
|
while(pp < stail) {
|
||||||
|
cp = code[*pp];
|
||||||
|
if(*cp & USES & reg) return (NO);
|
||||||
|
if(*cp & ZAPS & reg) return (YES);
|
||||||
|
pp += 2;
|
||||||
|
}
|
||||||
|
if(usexpr) return (reg & 001); /* PRI => NO, SEC => YES at end */
|
||||||
|
else return (YES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Get place where the currently pushed value is popped?
|
||||||
|
** NOTE: Function arguments are not popped, they are
|
||||||
|
** wasted with an ADDSP.
|
||||||
|
*/
|
||||||
|
getpop(next) int *next; {
|
||||||
|
char *cp;
|
||||||
|
int level; level = 0;
|
||||||
|
while(YES) {
|
||||||
|
if(next >= stail) /* compiler error */
|
||||||
|
return 0;
|
||||||
|
if(*next == POP2)
|
||||||
|
if(level) --level;
|
||||||
|
else return next; /* have a matching POP2 */
|
||||||
|
else if(*next == ADDSP) { /* after func call */
|
||||||
|
if((level -= (next[1]>>LBPW)) < 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cp = code[*next]; /* code string ptr */
|
||||||
|
if(*cp & PUSHES) ++level; /* must be a push */
|
||||||
|
}
|
||||||
|
next += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************* output functions *********************/
|
||||||
|
|
||||||
|
colon() {
|
||||||
|
fputc(':', output);
|
||||||
|
}
|
||||||
|
|
||||||
|
newline() {
|
||||||
|
fputc('\15', output);
|
||||||
|
fputc(NEWLINE, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** output assembly code.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
outcode(pcode, value)
|
||||||
|
int pcode, value;
|
||||||
|
{
|
||||||
|
int part, skip, count;
|
||||||
|
int byte_opt;
|
||||||
|
char *cp, *back;
|
||||||
|
int loc_label;
|
||||||
|
part = back = 0;
|
||||||
|
skip = NO;
|
||||||
|
byte_opt = 0;
|
||||||
|
|
||||||
|
cp = code[pcode] + 1; /* skip 1st byte of code string */
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
switch (pcode)
|
||||||
|
{
|
||||||
|
case BYTE_:
|
||||||
|
case BYTEn:
|
||||||
|
case BYTEr0:
|
||||||
|
case WORD_:
|
||||||
|
case WORDn:
|
||||||
|
case WORDr0:
|
||||||
|
case DWORD_:
|
||||||
|
case DWORDn:
|
||||||
|
case DWORDr0:
|
||||||
|
case REFm:
|
||||||
|
case COMMAn:
|
||||||
|
case PLUSn:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
dump_debug (pcode, value);
|
||||||
|
outtab ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pcode == ADD1n)
|
||||||
|
{
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
pcode = SUB1n;
|
||||||
|
value = -value;
|
||||||
|
}
|
||||||
|
if (value < 128)
|
||||||
|
{
|
||||||
|
byte_opt = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while(*cp)
|
||||||
|
{
|
||||||
|
if(*cp == '<')
|
||||||
|
{
|
||||||
|
++cp; /* skip to action code */
|
||||||
|
if(skip == NO)
|
||||||
|
switch(*cp)
|
||||||
|
{
|
||||||
|
case 'm':
|
||||||
|
outname(value+NAME);
|
||||||
|
break; /* mem ref by label */
|
||||||
|
case 'n':
|
||||||
|
if (byte_opt)
|
||||||
|
{
|
||||||
|
outstr ("BYTE ");
|
||||||
|
}
|
||||||
|
outdec(value);
|
||||||
|
break; /* numeric constant */
|
||||||
|
case 'o':
|
||||||
|
offset(value);
|
||||||
|
break; /* numeric constant */
|
||||||
|
case 'l':
|
||||||
|
outdec(litlab);
|
||||||
|
break; /* current literal label */
|
||||||
|
case 'g': /* generate local label */
|
||||||
|
loc_label = getlabel ();
|
||||||
|
break;
|
||||||
|
case 'd': /* dump local label */
|
||||||
|
outdec(loc_label);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cp += 2; /* skip past > */
|
||||||
|
}
|
||||||
|
else if(*cp == '?') /* ?..if value...?...if not value...? */
|
||||||
|
{
|
||||||
|
switch(++part)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if(value == 0)
|
||||||
|
skip = YES;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
skip = !skip;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
part = 0;
|
||||||
|
skip = NO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++cp; /* skip past ? */
|
||||||
|
}
|
||||||
|
else if(*cp == '#')
|
||||||
|
{ /* repeat #...# value times */
|
||||||
|
++cp;
|
||||||
|
if(back == 0)
|
||||||
|
{
|
||||||
|
if((count = value) < 1)
|
||||||
|
{
|
||||||
|
while(*cp && *cp++ != '#')
|
||||||
|
;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
back = cp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(--count > 0)
|
||||||
|
cp = back;
|
||||||
|
else
|
||||||
|
back = 0;
|
||||||
|
}
|
||||||
|
else if(skip == NO)
|
||||||
|
fputc(*cp++, output);
|
||||||
|
else
|
||||||
|
++cp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outdec(number) int number; {
|
||||||
|
int k, zs;
|
||||||
|
char c, *q, *r;
|
||||||
|
zs = 0;
|
||||||
|
k = 1000000000;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// fprintf(output, "/* %d */", number);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(number < 0) {
|
||||||
|
number = -number;
|
||||||
|
fputc('-', output);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (k >= 1) {
|
||||||
|
q = 0;
|
||||||
|
r = number;
|
||||||
|
while(r >= k) {++q; r = r - k;}
|
||||||
|
c = q + '0';
|
||||||
|
if(c != '0' || k == 1 || zs) {
|
||||||
|
zs = 1;
|
||||||
|
fputc(c, output);
|
||||||
|
}
|
||||||
|
number = r;
|
||||||
|
k /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset(number)
|
||||||
|
int number;
|
||||||
|
{
|
||||||
|
int k, zs;
|
||||||
|
char c, *q, *r;
|
||||||
|
zs = 0;
|
||||||
|
k = 1000000000;
|
||||||
|
if(number < 0) {
|
||||||
|
number = -number;
|
||||||
|
fputc('-', output);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fputc('+',output);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (k >= 1) {
|
||||||
|
q = 0;
|
||||||
|
r = number;
|
||||||
|
while(r >= k) {++q; r = r - k;}
|
||||||
|
c = q + '0';
|
||||||
|
if(c != '0' || k == 1 || zs) {
|
||||||
|
zs = 1;
|
||||||
|
fputc(c, output);
|
||||||
|
}
|
||||||
|
number = r;
|
||||||
|
k /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outline(ptr) char ptr[]; {
|
||||||
|
outstr(ptr);
|
||||||
|
newline();
|
||||||
|
}
|
||||||
|
|
||||||
|
outname(ptr) char ptr[]; {
|
||||||
|
outstr("_");
|
||||||
|
while(*ptr >= ' ') fputc(*ptr++, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
outstr(ptr) char ptr[]; {
|
||||||
|
while(*ptr == '\t' || *ptr >= ' ') fputc(*ptr++, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
outtab ()
|
||||||
|
{
|
||||||
|
fputc ('\t', output);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user