Merge pull request #60 from alexfru/master

Update Smaller C.
This commit is contained in:
Serge Vakulenko
2015-08-20 23:19:59 -07:00
6 changed files with 300 additions and 102 deletions

View File

@@ -21,10 +21,6 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/ */
/*****************************************************************************/ /*****************************************************************************/
@@ -519,6 +515,26 @@ void GenJumpIfNotZero(int label)
MipsOpNumLabel, label); MipsOpNumLabel, label);
} }
fpos_t GenPrologPos;
STATIC
void GenWriteFrameSize(void)
{
unsigned size = -CurFxnMinLocalOfs;
int pfx = size ? ' ' : '#';
printf2("\t%csubu\t$29, $29, %10u\n", pfx, size); // 10 chars are enough for 32-bit unsigned ints
}
STATIC
void GenUpdateFrameSize(void)
{
fpos_t pos;
fgetpos(OutFile, &pos);
fsetpos(OutFile, &GenPrologPos);
GenWriteFrameSize();
fsetpos(OutFile, &pos);
}
STATIC STATIC
void GenFxnProlog(void) void GenFxnProlog(void)
{ {
@@ -549,6 +565,9 @@ void GenFxnProlog(void)
MipsOpRegA0 + i, 0, MipsOpRegA0 + i, 0,
MipsOpIndRegFp, 8 + 4 * i); MipsOpIndRegFp, 8 + 4 * i);
} }
fgetpos(OutFile, &GenPrologPos);
GenWriteFrameSize();
} }
STATIC STATIC
@@ -562,15 +581,11 @@ void GenGrowStack(int size)
MipsOpConst, size); MipsOpConst, size);
} }
STATIC
void GenFxnProlog2(void)
{
GenGrowStack(-CurFxnMinLocalOfs);
}
STATIC STATIC
void GenFxnEpilog(void) void GenFxnEpilog(void)
{ {
GenUpdateFrameSize();
GenPrintInstr2Operands(MipsInstrMov, 0, GenPrintInstr2Operands(MipsInstrMov, 0,
MipsOpRegSp, 0, MipsOpRegSp, 0,
MipsOpRegFp, 0); MipsOpRegFp, 0);
@@ -2225,3 +2240,4 @@ void GenFin(void)
} }
#endif #endif
} }

View File

@@ -21,10 +21,6 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/ */
/*****************************************************************************/ /*****************************************************************************/
@@ -791,6 +787,50 @@ void GenJumpIfNotZero(int label)
X86OpNumLabel, label); X86OpNumLabel, label);
} }
fpos_t GenPrologPos;
STATIC
void GenWriteFrameSize(void)
{
unsigned size = -CurFxnMinLocalOfs;
int pfx = size ? ' ' : ';';
#ifdef CAN_COMPILE_32BIT
if (SizeOfWord == 4 &&
OutputFormat != FormatSegHuge &&
WindowsStack)
{
int pfx = (size >= 4096) ? ' ' : ';';
// When targeting Windows, call equivalent of _chkstk() to
// correctly grow the stack page by page by probing it
if (!WinChkStkLabel)
WinChkStkLabel = -LabelCnt++; // reserve a label for _chkstk() and mark unused
if (WinChkStkLabel < 0 && pfx == ' ')
WinChkStkLabel = -WinChkStkLabel; // _chkstk() has been used at least once
printf2("\t%cmov\teax, %10u\n", pfx, size); // 10 chars are enough for 32-bit unsigned ints
printf2("\t%ccall\t", pfx);
GenPrintNumLabel((WinChkStkLabel < 0) ? -WinChkStkLabel : WinChkStkLabel);
puts2("");
}
#endif
if (SizeOfWord == 2)
printf2("\t%csub\tsp, %10u\n", pfx, size); // 10 chars are enough for 32-bit unsigned ints
#ifdef CAN_COMPILE_32BIT
else
printf2("\t%csub\tesp, %10u\n", pfx, size); // 10 chars are enough for 32-bit unsigned ints
#endif
}
STATIC
void GenUpdateFrameSize(void)
{
fpos_t pos;
fgetpos(OutFile, &pos);
fsetpos(OutFile, &GenPrologPos);
GenWriteFrameSize();
fsetpos(OutFile, &pos);
}
STATIC STATIC
void GenFxnProlog(void) void GenFxnProlog(void)
{ {
@@ -799,6 +839,8 @@ void GenFxnProlog(void)
GenPrintInstr2Operands(X86InstrMov, 0, GenPrintInstr2Operands(X86InstrMov, 0,
X86OpRegBpWord, 0, X86OpRegBpWord, 0,
X86OpRegSpWord, 0); X86OpRegSpWord, 0);
fgetpos(OutFile, &GenPrologPos);
GenWriteFrameSize();
} }
STATIC STATIC
@@ -806,39 +848,15 @@ void GenGrowStack(int size)
{ {
if (!size) if (!size)
return; return;
#ifdef CAN_COMPILE_32BIT
if (SizeOfWord == 4 &&
OutputFormat != FormatSegHuge &&
WindowsStack &&
size >= 4096)
{
// When targeting Windows, call equivalent of _chkstk() to
// correctly grow the stack page by page by probing it
if (!WinChkStkLabel)
WinChkStkLabel = LabelCnt++;
GenPrintInstr2Operands(X86InstrMov, 0,
X86OpRegAWord, 0,
X86OpConst, size);
printf2("\tcall\t");
GenPrintNumLabel(WinChkStkLabel); // TBD??? use dedicated instr/op fxn???
puts2("");
}
#endif
GenPrintInstr2Operands(X86InstrSub, 0, GenPrintInstr2Operands(X86InstrSub, 0,
X86OpRegSpWord, 0, X86OpRegSpWord, 0,
X86OpConst, size); X86OpConst, size);
} }
STATIC
void GenFxnProlog2(void)
{
GenGrowStack(-CurFxnMinLocalOfs);
}
STATIC STATIC
void GenFxnEpilog(void) void GenFxnEpilog(void)
{ {
GenUpdateFrameSize();
GenPrintInstrNoOperand(X86InstrLeave); GenPrintInstrNoOperand(X86InstrLeave);
GenPrintInstrNoOperand(X86InstrRet); GenPrintInstrNoOperand(X86InstrRet);
} }
@@ -899,10 +917,13 @@ void GenIsrProlog(void)
puts2("\tpush\tebp\n" puts2("\tpush\tebp\n"
"\tmov\tebp, esp"); "\tmov\tebp, esp");
fgetpos(OutFile, &GenPrologPos);
GenWriteFrameSize();
} }
void GenIsrEpilog(void) void GenIsrEpilog(void)
{ {
GenUpdateFrameSize();
puts2("\tdb\t0x66\n\tleave"); puts2("\tdb\t0x66\n\tleave");
puts2("\tpop\teax"); // fake return address puts2("\tpop\teax"); // fake return address
@@ -3171,6 +3192,7 @@ void GenFin(void)
puts2(CodeHeaderFooter[0]); puts2(CodeHeaderFooter[0]);
GenNumLabel(StructCpyLabel); GenNumLabel(StructCpyLabel);
CurFxnMinLocalOfs = 0;
GenFxnProlog(); GenFxnProlog();
if (SizeOfWord == 2) if (SizeOfWord == 2)
@@ -3248,6 +3270,7 @@ void GenFin(void)
puts2(CodeHeaderFooter[0]); puts2(CodeHeaderFooter[0]);
GenNumLabel(StructPushLabel); GenNumLabel(StructPushLabel);
CurFxnMinLocalOfs = 0;
GenFxnProlog(); GenFxnProlog();
if (SizeOfWord == 2) if (SizeOfWord == 2)
@@ -3336,7 +3359,7 @@ void GenFin(void)
#endif #endif
#ifdef CAN_COMPILE_32BIT #ifdef CAN_COMPILE_32BIT
if (WinChkStkLabel) if (WinChkStkLabel > 0) // if _chkstk() has been used at least once
{ {
// When targeting Windows, simulate _chkstk() to // When targeting Windows, simulate _chkstk() to
// correctly grow the stack page by page by probing it // correctly grow the stack page by page by probing it
@@ -3378,3 +3401,4 @@ void GenFin(void)
} }
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2013-2014, Alexey Frunze Copyright (c) 2013-2015, Alexey Frunze
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -21,10 +21,6 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/ */
#ifndef __APPLE__ #ifndef __APPLE__
@@ -749,6 +745,22 @@ int WriteFile(unsigned Handle,
"push dword [ebp+8]\n" "push dword [ebp+8]\n"
"call [__imp__WriteFile]"); "call [__imp__WriteFile]");
} }
extern unsigned (*_imp__SetFilePointer)(unsigned Handle,
int lDistanceToMove,
int* lpDistanceToMoveHigh,
unsigned dwMoveMethod);
unsigned SetFilePointer(unsigned Handle,
int lDistanceToMove,
int* lpDistanceToMoveHigh,
unsigned dwMoveMethod)
{
asm("push dword [ebp+20]\n"
"push dword [ebp+16]\n"
"push dword [ebp+12]\n"
"push dword [ebp+8]\n"
"call [__imp__SetFilePointer]");
}
#endif // _WIN32 #endif // _WIN32
#ifdef _RETROBSD #ifdef _RETROBSD
@@ -786,7 +798,7 @@ int OsCreateOrTruncate(char* name)
#ifdef _LINUX #ifdef _LINUX
asm("mov eax, 5\n" // sys_open asm("mov eax, 5\n" // sys_open
"mov ebx, [ebp + 8]\n" "mov ebx, [ebp + 8]\n"
"mov ecx, 0x641\n" // truncate if exists, else create, writing only "mov ecx, 0x241\n" // truncate if exists, else create, writing only
"mov edx, 664o\n" // rw-rw-r-- "mov edx, 664o\n" // rw-rw-r--
"int 0x80\n" "int 0x80\n"
"mov ebx, eax\n" "mov ebx, eax\n"
@@ -1055,6 +1067,67 @@ int OsWrite(int fd, void* p, unsigned s)
#endif #endif
} }
#ifndef __SMALLER_C_16__
long OsLseek(int fd, long ofs, int whence)
{
#ifdef _RETROBSD
long pos;
asm volatile ("move $4, %1\n"
"move $5, %2\n"
"move $6, %3\n"
"syscall 19\n" // SYS_lseek
"nop\n"
"nop\n"
"move %0, $2\n"
: "=r" (pos)
: "r" (fd), "r" (ofs), "r" (whence)
: "$2", "$4", "$5", "$6");
return pos;
#else
#ifdef _LINUX
asm("mov eax, 19\n" // sys_lseek
"mov ebx, [ebp + 8]\n"
"mov ecx, [ebp + 12]\n"
"mov edx, [ebp + 16]\n"
"int 0x80");
#else
#ifdef _WIN32
return SetFilePointer(fd, ofs, 0, whence);
#else
asm("mov ah, 0x42\n"
"mov bx, [bp + 8]\n"
"mov dx, [bp + 12]\n"
"mov cx, [bp + 12 + 2]\n"
"mov al, [bp + 16]\n"
"int 0x21");
asm("sbb ebx, ebx\n"
"and eax, 0xffff\n"
"shl edx, 16\n"
"or eax, edx\n"
"or eax, ebx");
#endif
#endif
#endif
}
#else
int OsLseek16(int fd, unsigned short ofs[2], int whence)
{
asm("mov ah, 0x42\n"
"mov bx, [bp + 4]\n"
"mov si, [bp + 6]");
asm("mov dx, [si]\n"
"mov cx, [si + 2]\n"
"mov al, [bp + 8]\n"
"int 0x21");
asm("sbb bx, bx\n"
"or ax, bx\n"
"or dx, bx\n"
"mov [si], ax\n"
"mov [si + 2], dx\n"
"mov ax, bx");
}
#endif
#ifdef _DOS #ifdef _DOS
unsigned DosGetPspSeg(void) unsigned DosGetPspSeg(void)
{ {
@@ -1398,4 +1471,81 @@ int fclose(FILE* stream)
--__FileCnt__; --__FileCnt__;
return OsClose(fd); return OsClose(fd);
} }
struct fpos_t_
{
union
{
unsigned short halves[2]; // for 16-bit memory models without 32-bit longs
int align; // for alignment on machine word boundary
} u;
}; // keep in sync with stdio.h !!!
#define fpos_t struct fpos_t_
// Note, these fgetpos() and fsetpos() are implemented for write-only files
int fgetpos(FILE* stream, fpos_t* pos)
{
unsigned i = (unsigned)stream, fd;
fd = __FileHandles__[--i];
#ifndef __SMALLER_C_16__
{
long p;
if ((p = OsLseek(fd, 0, 1/*SEEK_CUR*/)) < 0)
return -1;
p += __FileBufPos__[i];
pos->u.align = p;
}
#else
{
unsigned short p[2];
p[0] = p[1] = 0;
if (OsLseek16(fd, p, 1/*SEEK_CUR*/) < 0)
return -1;
p[1] += __FileBufPos__[i] > 0xFFFF - p[0];
p[0] += __FileBufPos__[i];
pos->u.halves[0] = p[0];
pos->u.halves[1] = p[1];
}
#endif
return 0;
}
int fsetpos(FILE* stream, fpos_t* pos)
{
unsigned i = (unsigned)stream, fd;
unsigned sz;
fd = __FileHandles__[--i];
// flush
sz = __FileBufPos__[i];
if (sz)
{
if ((unsigned)OsWrite(fd, __FileBufs__[i], sz) != sz)
return -1;
}
// seek
#ifndef __SMALLER_C_16__
{
long p = pos->u.align;
if ((p = OsLseek(fd, p, 0/*SEEK_SET*/)) < 0)
return -1;
}
#else
{
if (OsLseek16(fd, pos->u.halves, 0/*SEEK_SET*/) < 0)
return -1;
}
#endif
__FileBufDirty__[i] = 0;
__FileBufSize__[i] = __FileBufPos__[i] = 0;
return 0;
}
#endif /*__APPLE__*/ #endif /*__APPLE__*/

View File

@@ -1,4 +1,4 @@
Copyright (c) 2012, Alexey Frunze Copyright (c) 2012-2015, Alexey Frunze
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@@ -21,6 +21,3 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.

View File

@@ -7,14 +7,39 @@ that can then be assembled and linked into DOS, Windows and Linux programs.
Code generation for MIPS CPUs is also supported (primarily for RetroBSD). Code generation for MIPS CPUs is also supported (primarily for RetroBSD).
The compiler is capable of compiling its own source code. Code generation for the TR3200 CPU and VASM is supported (see Trillek).
You can fully recompile the compiler only with itself and NASM for the The compiler is capable of compiling itself.
x86 platform (no linker is necessary).
The core compiler comes with a linker and a compiler driver (the driver
invokes the core compiler, the assembler, and the linker and supports
options similar to those of gcc).
There's no decent preprocessor in Smaller C as of now, but the compiler
driver can invoke gcc (or gcc.exe) for preprocessing if instructed.
The standard C library is work-in-progress and it's close to completion.
See the Wiki for more up-to-date details: See the Wiki for more up-to-date details:
http://github.com/alexfru/SmallerC/wiki http://github.com/alexfru/SmallerC/wiki
For the lack of a better place, you can discuss Smaller C here:
https://hackaday.io/project/5569-smaller-c
Links: Links:
NASM: http://nasm.us/ NASM: http://nasm.us/
YASM: http://yasm.tortall.net/
CWSDPMI: http://homer.rice.edu/~sandmann/cwsdpmi/
HX DOS Extender: https://web.archive.org/web/20141003032346/http://www.japheth.de/
RetroBSD: http://retrobsd.org/ RetroBSD: http://retrobsd.org/
VASM: http://sun.hasenbraten.de/vasm/
Trillek: http://trillek.org/
Normative and other useful documents on C:
C99 + TC1 + TC2 + TC3, WG14 N1256:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
Rationale for C99:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/C99RationaleV5.10.pdf
The New C Standard: An Economic and Cultural Commentary:
http://www.knosof.co.uk/cbook/cbook.html

View File

@@ -21,10 +21,6 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/ */
/*****************************************************************************/ /*****************************************************************************/
@@ -159,6 +155,17 @@ int fprintf(FILE*, char*, ...);
int vprintf(char*, void*); int vprintf(char*, void*);
//int vfprintf(FILE*, char*, va_list); //int vfprintf(FILE*, char*, va_list);
int vfprintf(FILE*, char*, void*); int vfprintf(FILE*, char*, void*);
struct fpos_t_
{
union
{
unsigned short halves[2]; // for 16-bit memory models without 32-bit longs
int align; // for alignment on machine word boundary
} u;
}; // keep in sync with stdio.h !!!
#define fpos_t struct fpos_t_
int fgetpos(FILE*, fpos_t*);
int fsetpos(FILE*, fpos_t*);
#endif // #ifndef __SMALLER_C__ #endif // #ifndef __SMALLER_C__
@@ -406,8 +413,6 @@ void GenJumpIfEqual(int val, int Label);
STATIC STATIC
void GenFxnProlog(void); void GenFxnProlog(void);
STATIC STATIC
void GenFxnProlog2(void);
STATIC
void GenFxnEpilog(void); void GenFxnEpilog(void);
void GenIsrProlog(void); void GenIsrProlog(void);
void GenIsrEpilog(void); void GenIsrEpilog(void);
@@ -4726,14 +4731,13 @@ void DetermineVaListType(void)
#endif // DETERMINE_VA_LIST #endif // DETERMINE_VA_LIST
#endif // __SMALLER_C__ #endif // __SMALLER_C__
// Equivalent to puts() but outputs to OutFile // Equivalent to puts() but outputs to OutFile.
// if it's not NULL.
STATIC STATIC
int puts2(char* s) int puts2(char* s)
{ {
int res; int res;
if (OutFile) if (!OutFile)
{ return 0;
// Turbo C++ 1.01's fputs() returns EOF if s is empty, which is wrong. // Turbo C++ 1.01's fputs() returns EOF if s is empty, which is wrong.
// Hence the workaround. // Hence the workaround.
if (*s == '\0' || (res = fputs(s, OutFile)) >= 0) if (*s == '\0' || (res = fputs(s, OutFile)) >= 0)
@@ -4741,16 +4745,10 @@ int puts2(char* s)
// unlike puts(), fputs() doesn't append '\n', append it manually // unlike puts(), fputs() doesn't append '\n', append it manually
res = fputc('\n', OutFile); res = fputc('\n', OutFile);
} }
}
else
{
res = puts(s);
}
return res; return res;
} }
// Equivalent to printf() but outputs to OutFile // Equivalent to printf() but outputs to OutFile.
// if it's not NULL.
STATIC STATIC
int printf2(char* format, ...) int printf2(char* format, ...)
{ {
@@ -4763,31 +4761,24 @@ int printf2(char* format, ...)
void* vl = &format + 1; void* vl = &format + 1;
#endif #endif
if (!OutFile)
return 0;
#ifndef __SMALLER_C__ #ifndef __SMALLER_C__
if (OutFile)
res = vfprintf(OutFile, format, vl); res = vfprintf(OutFile, format, vl);
else
res = vprintf(format, vl);
#else #else
// TBD!!! This is not good. Really need the va_something macros. // TBD!!! This is not good. Really need the va_something macros.
#ifdef DETERMINE_VA_LIST #ifdef DETERMINE_VA_LIST
if (VaListType == 2) if (VaListType == 2)
{ {
// va_list is a one-element array containing a pointer // va_list is a one-element array containing a pointer
if (OutFile)
res = vfprintf(OutFile, format, &vl); res = vfprintf(OutFile, format, &vl);
else
res = vprintf(format, &vl);
} }
else // if (VaListType == 1) else // if (VaListType == 1)
// fallthrough // fallthrough
#endif // DETERMINE_VA_LIST #endif // DETERMINE_VA_LIST
{ {
// va_list is a pointer // va_list is a pointer
if (OutFile)
res = vfprintf(OutFile, format, vl); res = vfprintf(OutFile, format, vl);
else
res = vprintf(format, vl);
} }
#endif // __SMALLER_C__ #endif // __SMALLER_C__
@@ -4881,7 +4872,7 @@ void warning(char* format, ...)
warnCnt++; warnCnt++;
if (!(warnings && OutFile)) if (!warnings)
return; return;
printf("Warning in \"%s\" (%d:%d)\n", FileNames[fidx], LineNo, LinePos); printf("Warning in \"%s\" (%d:%d)\n", FileNames[fidx], LineNo, LinePos);
@@ -6928,7 +6919,6 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
// local variables to the symbol table and parse the body. // local variables to the symbol table and parse the body.
int undoSymbolsPtr = SyntaxStackCnt; int undoSymbolsPtr = SyntaxStackCnt;
int undoIdents = IdentTableLen; int undoIdents = IdentTableLen;
int locAllocLabel = (LabelCnt += 2) - 2;
int i; int i;
int Main; int Main;
@@ -6941,7 +6931,7 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
gotoLabCnt = 0; gotoLabCnt = 0;
if (verbose && OutFile) if (verbose)
printf("%s()\n", CurFxnName); printf("%s()\n", CurFxnName);
ParseLevel++; ParseLevel++;
@@ -6959,7 +6949,6 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
puts2(CurHeaderFooter[0]); puts2(CurHeaderFooter[0]);
GenLabel(CurFxnName, Static); GenLabel(CurFxnName, Static);
CurFxnEpilogLabel = LabelCnt++;
#ifndef MIPS #ifndef MIPS
#ifdef CAN_COMPILE_32BIT #ifdef CAN_COMPILE_32BIT
@@ -6969,9 +6958,7 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
#endif #endif
#endif #endif
GenFxnProlog(); GenFxnProlog();
CurFxnEpilogLabel = LabelCnt++;
GenJumpUncond(locAllocLabel + 1);
GenNumLabel(locAllocLabel);
AddFxnParamSymbols(lastSyntaxPtr); AddFxnParamSymbols(lastSyntaxPtr);
@@ -7013,10 +7000,6 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
#endif #endif
GenFxnEpilog(); GenFxnEpilog();
GenNumLabel(locAllocLabel + 1);
GenFxnProlog2();
GenJumpUncond(locAllocLabel);
puts2(CurHeaderFooter[1]); puts2(CurHeaderFooter[1]);
CurHeaderFooter = NULL; CurHeaderFooter = NULL;
@@ -8223,6 +8206,8 @@ int main(int argc, char** argv)
if (!FileCnt) if (!FileCnt)
error("Input file not specified\n"); error("Input file not specified\n");
if (!OutFile)
error("Output file not specified\n");
GenInitFinalize(); GenInitFinalize();
@@ -8272,7 +8257,7 @@ int main(int argc, char** argv)
GenStartCommentLine(); printf2("Next label number: %d\n", LabelCnt); GenStartCommentLine(); printf2("Next label number: %d\n", LabelCnt);
if (warnings && warnCnt && OutFile) if (warnings && warnCnt)
printf("%d warnings\n", warnCnt); printf("%d warnings\n", warnCnt);
GenStartCommentLine(); printf2("Compilation succeeded.\n"); GenStartCommentLine(); printf2("Compilation succeeded.\n");
@@ -8281,3 +8266,4 @@ int main(int argc, char** argv)
return 0; return 0;
} }