Smaller C fixes and improvements:
- move va_list type detection under #ifdef as it's rarely needed anyway - allow up to 254 characters in a string literal - generate a warning when an integer is passed instead of a pointer (and vice versa) as a function parameter (pass -Wall for this) - when printing an unexpected token, print identifier tokens instead of '<tokIdent>' - fix: allow most control characters inside '' and "" - fix handling of -I<path> and -SI<path> - switch() now supports Duff's device - for() now supports declarations in its first clause as in C99/C++
This commit is contained in:
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
||||
|
||||
CFLAGS = -Os -Wall -DMIPS -DNO_ANNOTATIONS -DNO_PREPROCESSOR \
|
||||
-DNO_PPACK -D_RETROBSD -D__SMALLER_C_SCHAR__ \
|
||||
-D__SMALLER_C__ -D__SMALLER_C_32__
|
||||
-D__SMALLER_C__ -D__SMALLER_C_32__ -DSTATIC
|
||||
|
||||
# For cross compile
|
||||
#include $(TOPSRC)/cross.mk
|
||||
|
||||
@@ -44,6 +44,7 @@ either expressed or implied, of the FreeBSD Project.
|
||||
|
||||
int UseGp = 0;
|
||||
|
||||
STATIC
|
||||
void GenInit(void)
|
||||
{
|
||||
// initialization of target-specific code generator
|
||||
@@ -59,6 +60,7 @@ void GenInit(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
int GenInitParams(int argc, char** argv, int* idx)
|
||||
{
|
||||
(void)argc;
|
||||
@@ -77,21 +79,25 @@ int GenInitParams(int argc, char** argv, int* idx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenInitFinalize(void)
|
||||
{
|
||||
// finalization of initialization of target-specific code generator
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenStartCommentLine(void)
|
||||
{
|
||||
printf2(" # ");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenWordAlignment(void)
|
||||
{
|
||||
printf2("\t.align 2\n");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenLabel(char* Label, int Static)
|
||||
{
|
||||
{
|
||||
@@ -101,6 +107,7 @@ void GenLabel(char* Label, int Static)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintLabel(char* Label)
|
||||
{
|
||||
{
|
||||
@@ -111,21 +118,25 @@ void GenPrintLabel(char* Label)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenNumLabel(int Label)
|
||||
{
|
||||
printf2("$L%d:\n", Label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintNumLabel(int label)
|
||||
{
|
||||
printf2("$L%d", label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenZeroData(unsigned Size)
|
||||
{
|
||||
printf2("\t.space\t%u\n", truncUint(Size)); // or ".fill size"
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenIntData(int Size, int Val)
|
||||
{
|
||||
Val = truncInt(Val);
|
||||
@@ -137,11 +148,13 @@ void GenIntData(int Size, int Val)
|
||||
printf2("\t.word\t%d\n", Val);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenStartAsciiString(void)
|
||||
{
|
||||
printf2("\t.ascii\t");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenAddrData(int Size, char* Label, int ofs)
|
||||
{
|
||||
ofs = truncInt(ofs);
|
||||
@@ -198,6 +211,7 @@ void GenAddrData(int Size, char* Label, int ofs)
|
||||
//#define MipsInstrBGTZ 0x26
|
||||
//#define MipsInstrBreak 0x27
|
||||
|
||||
STATIC
|
||||
void GenPrintInstr(int instr, int val)
|
||||
{
|
||||
char* p = "";
|
||||
@@ -302,12 +316,14 @@ void GenPrintInstr(int instr, int val)
|
||||
#define MipsOpIndLocal MipsOpIndRegFp
|
||||
|
||||
#ifdef REORDER_WORKAROUND
|
||||
STATIC
|
||||
void GenNop(void)
|
||||
{
|
||||
puts2("\tnop");
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC
|
||||
void GenPrintOperand(int op, int val)
|
||||
{
|
||||
if (op >= MipsOpRegZero && op <= MipsOpRegRa)
|
||||
@@ -348,22 +364,19 @@ void GenPrintOperand(int op, int val)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintOperandSeparator(void)
|
||||
{
|
||||
printf2(", ");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintNewLine(void)
|
||||
{
|
||||
puts2("");
|
||||
}
|
||||
|
||||
void GenPrintInstrNoOperand(int instr)
|
||||
{
|
||||
GenPrintInstr(instr, 0);
|
||||
GenPrintNewLine();
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintInstr1Operand(int instr, int instrval, int operand, int operandval)
|
||||
{
|
||||
GenPrintInstr(instr, instrval);
|
||||
@@ -376,6 +389,7 @@ void GenPrintInstr1Operand(int instr, int instrval, int operand, int operandval)
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintInstr2Operands(int instr, int instrval, int operand1, int operand1val, int operand2, int operand2val)
|
||||
{
|
||||
if (operand2 == MipsOpConst && operand2val == 0 &&
|
||||
@@ -389,6 +403,7 @@ void GenPrintInstr2Operands(int instr, int instrval, int operand1, int operand1v
|
||||
GenPrintNewLine();
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintInstr3Operands(int instr, int instrval,
|
||||
int operand1, int operand1val,
|
||||
int operand2, int operand2val,
|
||||
@@ -470,6 +485,7 @@ void GenPrintInstr3Operands(int instr, int instrval,
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenExtendRegIfNeeded(int reg, int opSz)
|
||||
{
|
||||
if (opSz == -1)
|
||||
@@ -510,23 +526,28 @@ void GenExtendRegIfNeeded(int reg, int opSz)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenJumpUncond(int label)
|
||||
{
|
||||
GenPrintInstr1Operand(MipsInstrJ, 0,
|
||||
MipsOpNumLabel, label);
|
||||
}
|
||||
|
||||
void GenJumpIfNotEqual(int val, int label)
|
||||
#ifndef USE_SWITCH_TAB
|
||||
STATIC
|
||||
void GenJumpIfEqual(int val, int label)
|
||||
{
|
||||
GenPrintInstr2Operands(MipsInstrLI, 0,
|
||||
MipsOpRegT1, 0,
|
||||
MipsOpConst, val);
|
||||
GenPrintInstr3Operands(MipsInstrBNE, 0,
|
||||
GenPrintInstr3Operands(MipsInstrBEQ, 0,
|
||||
MipsOpRegV0, 0,
|
||||
MipsOpRegT1, 0,
|
||||
MipsOpNumLabel, label);
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC
|
||||
void GenJumpIfZero(int label)
|
||||
{
|
||||
#ifndef NO_ANNOTATIONS
|
||||
@@ -538,6 +559,7 @@ void GenJumpIfZero(int label)
|
||||
MipsOpNumLabel, label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenJumpIfNotZero(int label)
|
||||
{
|
||||
#ifndef NO_ANNOTATIONS
|
||||
@@ -549,6 +571,7 @@ void GenJumpIfNotZero(int label)
|
||||
MipsOpNumLabel, label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnProlog(void)
|
||||
{
|
||||
GenPrintInstr3Operands(MipsInstrSubU, 0,
|
||||
@@ -580,6 +603,7 @@ void GenFxnProlog(void)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenLocalAlloc(int size)
|
||||
{
|
||||
GenPrintInstr3Operands(MipsInstrSubU, 0,
|
||||
@@ -588,6 +612,7 @@ void GenLocalAlloc(int size)
|
||||
MipsOpConst, size);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnEpilog(void)
|
||||
{
|
||||
GenPrintInstr2Operands(MipsInstrMov, 0,
|
||||
@@ -611,6 +636,7 @@ void GenFxnEpilog(void)
|
||||
MipsOpRegRa, 0);
|
||||
}
|
||||
|
||||
STATIC
|
||||
int GenGetBinaryOperatorInstr(int tok)
|
||||
{
|
||||
switch (tok)
|
||||
@@ -673,6 +699,7 @@ int GenGetBinaryOperatorInstr(int tok)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPreIdentAccess(int label)
|
||||
{
|
||||
if (UseGp)
|
||||
@@ -682,6 +709,7 @@ void GenPreIdentAccess(int label)
|
||||
puts2(")");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostIdentAccess(void)
|
||||
{
|
||||
if (UseGp)
|
||||
@@ -689,6 +717,7 @@ void GenPostIdentAccess(void)
|
||||
puts2("\t.set\tat");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenReadIdent(int regDst, int opSz, int label)
|
||||
{
|
||||
int instr = MipsInstrLW;
|
||||
@@ -715,6 +744,7 @@ void GenReadIdent(int regDst, int opSz, int label)
|
||||
GenPostIdentAccess();
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenReadLocal(int regDst, int opSz, int ofs)
|
||||
{
|
||||
int instr = MipsInstrLW;
|
||||
@@ -739,6 +769,7 @@ void GenReadLocal(int regDst, int opSz, int ofs)
|
||||
MipsOpIndRegFp, ofs);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenReadIndirect(int regDst, int regSrc, int opSz)
|
||||
{
|
||||
int instr = MipsInstrLW;
|
||||
@@ -763,6 +794,7 @@ void GenReadIndirect(int regDst, int regSrc, int opSz)
|
||||
regSrc + MipsOpIndRegZero, 0);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenWriteIdent(int regSrc, int opSz, int label)
|
||||
{
|
||||
int instr = MipsInstrSW;
|
||||
@@ -781,6 +813,7 @@ void GenWriteIdent(int regSrc, int opSz, int label)
|
||||
GenPostIdentAccess();
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenWriteLocal(int regSrc, int opSz, int ofs)
|
||||
{
|
||||
int instr = MipsInstrSW;
|
||||
@@ -797,6 +830,7 @@ void GenWriteLocal(int regSrc, int opSz, int ofs)
|
||||
MipsOpIndRegFp, ofs);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenWriteIndirect(int regDst, int regSrc, int opSz)
|
||||
{
|
||||
int instr = MipsInstrSW;
|
||||
@@ -813,6 +847,7 @@ void GenWriteIndirect(int regDst, int regSrc, int opSz)
|
||||
regDst + MipsOpIndRegZero, 0);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenIncDecIdent(int regDst, int opSz, int label, int tok)
|
||||
{
|
||||
int instr = MipsInstrAddU;
|
||||
@@ -829,6 +864,7 @@ void GenIncDecIdent(int regDst, int opSz, int label, int tok)
|
||||
GenExtendRegIfNeeded(regDst, opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenIncDecLocal(int regDst, int opSz, int ofs, int tok)
|
||||
{
|
||||
int instr = MipsInstrAddU;
|
||||
@@ -845,6 +881,7 @@ void GenIncDecLocal(int regDst, int opSz, int ofs, int tok)
|
||||
GenExtendRegIfNeeded(regDst, opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenIncDecIndirect(int regDst, int regSrc, int opSz, int tok)
|
||||
{
|
||||
int instr = MipsInstrAddU;
|
||||
@@ -861,6 +898,7 @@ void GenIncDecIndirect(int regDst, int regSrc, int opSz, int tok)
|
||||
GenExtendRegIfNeeded(regDst, opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostIncDecIdent(int regDst, int opSz, int label, int tok)
|
||||
{
|
||||
int instr = MipsInstrAddU;
|
||||
@@ -881,6 +919,7 @@ void GenPostIncDecIdent(int regDst, int opSz, int label, int tok)
|
||||
GenExtendRegIfNeeded(regDst, opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostIncDecLocal(int regDst, int opSz, int ofs, int tok)
|
||||
{
|
||||
int instr = MipsInstrAddU;
|
||||
@@ -901,6 +940,7 @@ void GenPostIncDecLocal(int regDst, int opSz, int ofs, int tok)
|
||||
GenExtendRegIfNeeded(regDst, opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostIncDecIndirect(int regDst, int regSrc, int opSz, int tok)
|
||||
{
|
||||
int instr = MipsInstrAddU;
|
||||
@@ -924,6 +964,7 @@ void GenPostIncDecIndirect(int regDst, int regSrc, int opSz, int tok)
|
||||
int CanUseTempRegs;
|
||||
int TempsUsed;
|
||||
|
||||
STATIC
|
||||
void GenPushReg(int reg)
|
||||
{
|
||||
if (CanUseTempRegs && TempsUsed < 6)
|
||||
@@ -947,6 +988,7 @@ void GenPushReg(int reg)
|
||||
TempsUsed++;
|
||||
}
|
||||
|
||||
STATIC
|
||||
int GenPopReg(int reg)
|
||||
{
|
||||
TempsUsed--;
|
||||
@@ -969,6 +1011,7 @@ int GenPopReg(int reg)
|
||||
|
||||
// Original, primitive stack-based code generator
|
||||
// DONE: test 32-bit code generation
|
||||
STATIC
|
||||
void GenExpr0(void)
|
||||
{
|
||||
int i;
|
||||
@@ -1546,6 +1589,7 @@ void GenExpr0(void)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
unsigned GenStrData(int generatingCode, unsigned requiredLen)
|
||||
{
|
||||
int i;
|
||||
@@ -1562,7 +1606,7 @@ unsigned GenStrData(int generatingCode, unsigned requiredLen)
|
||||
unsigned len;
|
||||
|
||||
p = FindString(label);
|
||||
len = *p++;
|
||||
len = *p++ & 0xFF;
|
||||
|
||||
// If this is a string literal initializing an array of char,
|
||||
// truncate or pad it as necessary.
|
||||
@@ -1639,12 +1683,14 @@ unsigned GenStrData(int generatingCode, unsigned requiredLen)
|
||||
return total;
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenExpr(void)
|
||||
{
|
||||
GenStrData(1, 0);
|
||||
GenExpr0();
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFin(void)
|
||||
{
|
||||
if (StructCpyLabel)
|
||||
@@ -1684,4 +1730,62 @@ void GenFin(void)
|
||||
if (OutputFormat != FormatFlat)
|
||||
puts2(CodeFooter);
|
||||
}
|
||||
|
||||
#ifdef USE_SWITCH_TAB
|
||||
if (SwitchJmpLabel)
|
||||
{
|
||||
char s[1 + 2 + (2 + CHAR_BIT * sizeof SwitchJmpLabel) / 3];
|
||||
char *p = s + sizeof s;
|
||||
int lbl = (LabelCnt += 3) - 3;
|
||||
|
||||
*--p = '\0';
|
||||
p = lab2str(p, SwitchJmpLabel);
|
||||
*--p = '_';
|
||||
*--p = '_';
|
||||
|
||||
if (OutputFormat != FormatFlat)
|
||||
puts2(CodeHeader);
|
||||
|
||||
GenLabel(p, 1);
|
||||
|
||||
puts2("\tlw\t$2, 0($4)\n"
|
||||
"\tlw\t$31, 4($4)");
|
||||
printf2("\tbeq\t$2, $0, "); GenPrintNumLabel(lbl + 2); // beq $2, $0, L3
|
||||
puts2("");
|
||||
#ifdef REORDER_WORKAROUND
|
||||
GenNop();
|
||||
#endif
|
||||
GenNumLabel(lbl); // L1:
|
||||
puts2("\taddiu\t$4, $4, 8\n"
|
||||
"\tlw\t$6, 0($4)");
|
||||
printf2("\tbne\t$6, $5, "); GenPrintNumLabel(lbl + 1); // bne $6, $6, L2
|
||||
puts2("");
|
||||
#ifdef REORDER_WORKAROUND
|
||||
GenNop();
|
||||
#endif
|
||||
puts2("\tlw\t$31, 4($4)");
|
||||
printf2("\tj "); GenPrintNumLabel(lbl + 2); // j L3
|
||||
puts2("");
|
||||
#ifdef REORDER_WORKAROUND
|
||||
GenNop();
|
||||
#endif
|
||||
GenNumLabel(lbl + 1); // L2:
|
||||
puts2("\taddiu\t$2, $2, -1");
|
||||
printf2("\tbne\t$2, $0, "); GenPrintNumLabel(lbl); // bne $2, $0, L1
|
||||
puts2("");
|
||||
#ifdef REORDER_WORKAROUND
|
||||
GenNop();
|
||||
#endif
|
||||
GenNumLabel(lbl + 2); // L3:
|
||||
puts2("\taddiu\t$29, $29, 16\n"
|
||||
"\tj\t$31");
|
||||
#ifdef REORDER_WORKAROUND
|
||||
GenNop();
|
||||
#endif
|
||||
|
||||
if (OutputFormat != FormatFlat)
|
||||
puts2(CodeFooter);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,11 @@ either expressed or implied, of the FreeBSD Project.
|
||||
|
||||
// TBD!!! compress/clean up
|
||||
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
int WindowsStack = 0;
|
||||
int WinChkStkLabel = 0;
|
||||
#endif
|
||||
|
||||
#define MAX_GLOBALS_TABLE_LEN MAX_IDENT_TABLE_LEN
|
||||
|
||||
/*
|
||||
@@ -50,6 +55,7 @@ either expressed or implied, of the FreeBSD Project.
|
||||
char GlobalsTable[MAX_GLOBALS_TABLE_LEN];
|
||||
int GlobalsTableLen = 0;
|
||||
|
||||
STATIC
|
||||
void GenAddGlobal(char* s, int use)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -75,6 +81,7 @@ void GenAddGlobal(char* s, int use)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenInit(void)
|
||||
{
|
||||
// initialization of target-specific code generator
|
||||
@@ -83,6 +90,7 @@ void GenInit(void)
|
||||
UseLeadingUnderscores = 1;
|
||||
}
|
||||
|
||||
STATIC
|
||||
int GenInitParams(int argc, char** argv, int* idx)
|
||||
{
|
||||
(void)argc;
|
||||
@@ -120,11 +128,17 @@ int GenInitParams(int argc, char** argv, int* idx)
|
||||
OutputFormat = FormatSegHuge; SizeOfWord = 4;
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(argv[*idx], "-winstack"))
|
||||
{
|
||||
WindowsStack = 1;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenInitFinalize(void)
|
||||
{
|
||||
// finalization of initialization of target-specific code generator
|
||||
@@ -153,16 +167,19 @@ void GenInitFinalize(void)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenStartCommentLine(void)
|
||||
{
|
||||
printf2("; ");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenWordAlignment(void)
|
||||
{
|
||||
printf2("\talign %d\n", SizeOfWord);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenLabel(char* Label, int Static)
|
||||
{
|
||||
if (UseLeadingUnderscores)
|
||||
@@ -180,6 +197,7 @@ void GenLabel(char* Label, int Static)
|
||||
GenAddGlobal(Label, 1);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintLabel(char* Label)
|
||||
{
|
||||
if (UseLeadingUnderscores)
|
||||
@@ -198,6 +216,7 @@ void GenPrintLabel(char* Label)
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenNumLabel(int Label)
|
||||
{
|
||||
if (UseLeadingUnderscores)
|
||||
@@ -206,6 +225,7 @@ void GenNumLabel(int Label)
|
||||
printf2("..@L%d:\n", Label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintNumLabel(int label)
|
||||
{
|
||||
if (UseLeadingUnderscores)
|
||||
@@ -214,11 +234,13 @@ void GenPrintNumLabel(int label)
|
||||
printf2("..@L%d", label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenZeroData(unsigned Size)
|
||||
{
|
||||
printf2("\ttimes\t%u db 0\n", truncUint(Size));
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenIntData(int Size, int Val)
|
||||
{
|
||||
Val = truncInt(Val);
|
||||
@@ -232,11 +254,13 @@ void GenIntData(int Size, int Val)
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenStartAsciiString(void)
|
||||
{
|
||||
printf2("\tdb\t");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenAddrData(int Size, char* Label, int ofs)
|
||||
{
|
||||
ofs = truncInt(ofs);
|
||||
@@ -340,6 +364,7 @@ char* winstrs[] =
|
||||
"jmp",
|
||||
};
|
||||
|
||||
STATIC
|
||||
void GenPrintInstr(int instr, int val)
|
||||
{
|
||||
char* p = "";
|
||||
@@ -451,6 +476,7 @@ void GenPrintInstr(int instr, int val)
|
||||
#define X86OpIndRegBExplicitHalfWord 0x1D
|
||||
#define X86OpIndRegBExplicitByteOrWord 0x1E
|
||||
|
||||
STATIC
|
||||
int GenSelectByteOrWord(int op, int opSz)
|
||||
{
|
||||
switch (op)
|
||||
@@ -504,6 +530,7 @@ int GenSelectByteOrWord(int op, int opSz)
|
||||
return op;
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintOperand(int op, int val)
|
||||
{
|
||||
if (SizeOfWord == 2)
|
||||
@@ -537,7 +564,7 @@ void GenPrintOperand(int op, int val)
|
||||
else
|
||||
{
|
||||
char* frame = (OutputFormat == FormatSegHuge) ? "bp" : "ebp";
|
||||
char* base = (OutputFormat == FormatSegHuge) ? "bx" : "ebx";
|
||||
char* base = (OutputFormat == FormatSegHuge) ? "si" : "ebx";
|
||||
switch (op)
|
||||
{
|
||||
case X86OpRegAByte: printf2("al"); break;
|
||||
@@ -571,16 +598,19 @@ void GenPrintOperand(int op, int val)
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintOperandSeparator(void)
|
||||
{
|
||||
printf2(", ");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintNewLine(void)
|
||||
{
|
||||
puts2("");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintInstrNoOperand(int instr)
|
||||
{
|
||||
GenPrintInstr(instr, 0);
|
||||
@@ -588,19 +618,15 @@ void GenPrintInstrNoOperand(int instr)
|
||||
}
|
||||
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
void GenSaveRestoreRegB(int restore)
|
||||
{
|
||||
if (OutputFormat == FormatSegHuge)
|
||||
puts2(restore ? "\tpop\tebx" : "\tpush\tebx");
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenRegB2Seg(void)
|
||||
{
|
||||
if (OutputFormat == FormatSegHuge)
|
||||
puts2("\tror\tebx, 4\n\tmov\tds, bx\n\tshr\tebx, 28");
|
||||
puts2("\tmov\tesi, ebx\n\tror\tesi, 4\n\tmov\tds, si\n\tshr\tesi, 28");
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC
|
||||
void GenPrintInstr1Operand(int instr, int instrval, int operand, int operandval)
|
||||
{
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
@@ -629,6 +655,7 @@ void GenPrintInstr1Operand(int instr, int instrval, int operand, int operandval)
|
||||
GenPrintNewLine();
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintInstr2Operands(int instr, int instrval, int operand1, int operand1val, int operand2, int operand2val)
|
||||
{
|
||||
if (operand2 == X86OpConst && truncUint(operand2val) == 0 &&
|
||||
@@ -694,6 +721,7 @@ void GenPrintInstr2Operands(int instr, int instrval, int operand1, int operand1v
|
||||
GenPrintNewLine();
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPrintInstr3Operands(int instr, int instrval,
|
||||
int operand1, int operand1val,
|
||||
int operand2, int operand2val,
|
||||
@@ -708,6 +736,7 @@ void GenPrintInstr3Operands(int instr, int instrval,
|
||||
GenPrintNewLine();
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenExtendRegAIfNeeded(int opSz)
|
||||
{
|
||||
if (SizeOfWord == 2)
|
||||
@@ -742,21 +771,26 @@ void GenExtendRegAIfNeeded(int opSz)
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenJumpUncond(int label)
|
||||
{
|
||||
GenPrintInstr1Operand(X86InstrJmp, 0,
|
||||
X86OpNumLabel, label);
|
||||
}
|
||||
|
||||
void GenJumpIfNotEqual(int val, int label)
|
||||
#ifndef USE_SWITCH_TAB
|
||||
STATIC
|
||||
void GenJumpIfEqual(int val, int label)
|
||||
{
|
||||
GenPrintInstr2Operands(X86InstrCmp, 0,
|
||||
X86OpRegAWord, 0,
|
||||
X86OpConst, val);
|
||||
GenPrintInstr1Operand(X86InstrJcc, tokNEQ,
|
||||
GenPrintInstr1Operand(X86InstrJcc, tokEQ,
|
||||
X86OpNumLabel, label);
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC
|
||||
void GenJumpIfZero(int label)
|
||||
{
|
||||
#ifndef NO_ANNOTATIONS
|
||||
@@ -769,6 +803,7 @@ void GenJumpIfZero(int label)
|
||||
X86OpNumLabel, label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenJumpIfNotZero(int label)
|
||||
{
|
||||
#ifndef NO_ANNOTATIONS
|
||||
@@ -781,6 +816,7 @@ void GenJumpIfNotZero(int label)
|
||||
X86OpNumLabel, label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnProlog(void)
|
||||
{
|
||||
GenPrintInstr1Operand(X86InstrPush, 0,
|
||||
@@ -790,13 +826,41 @@ void GenFxnProlog(void)
|
||||
X86OpRegSpWord, 0);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenLocalAlloc(int size)
|
||||
{
|
||||
#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
|
||||
char s[1 + 2 + (2 + CHAR_BIT * sizeof WinChkStkLabel) / 3];
|
||||
char *p = s + sizeof s;
|
||||
|
||||
if (!WinChkStkLabel)
|
||||
WinChkStkLabel = LabelCnt++;
|
||||
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
X86OpRegAWord, 0,
|
||||
X86OpConst, size);
|
||||
*--p = '\0';
|
||||
p = lab2str(p, WinChkStkLabel);
|
||||
*--p = '_';
|
||||
*--p = '_';
|
||||
printf2("\tcall\t");
|
||||
GenPrintLabel(p);
|
||||
puts2("");
|
||||
}
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrSub, 0,
|
||||
X86OpRegSpWord, 0,
|
||||
X86OpConst, size);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFxnEpilog(void)
|
||||
{
|
||||
GenPrintInstrNoOperand(X86InstrLeave);
|
||||
@@ -876,6 +940,7 @@ void GenIsrEpilog(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC
|
||||
void GenReadIdent(int opSz, int label)
|
||||
{
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
@@ -884,6 +949,7 @@ void GenReadIdent(int opSz, int label)
|
||||
GenExtendRegAIfNeeded(opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenReadLocal(int opSz, int ofs)
|
||||
{
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
@@ -892,24 +958,22 @@ void GenReadLocal(int opSz, int ofs)
|
||||
GenExtendRegAIfNeeded(opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenReadIndirect(int opSz)
|
||||
{
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
X86OpRegBWord, 0,
|
||||
X86OpRegAWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
GenSelectByteOrWord(X86OpRegAByteOrWord, opSz), 0,
|
||||
X86OpIndRegB, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
GenExtendRegAIfNeeded(opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenReadCRegIdent(int opSz, int label)
|
||||
{
|
||||
if (opSz == -1)
|
||||
@@ -939,6 +1003,7 @@ void GenReadCRegIdent(int opSz, int label)
|
||||
X86OpIndLabel, label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenReadCRegLocal(int opSz, int ofs)
|
||||
{
|
||||
if (opSz == -1)
|
||||
@@ -968,13 +1033,13 @@ void GenReadCRegLocal(int opSz, int ofs)
|
||||
X86OpIndLocal, ofs);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenReadCRegIndirect(int opSz)
|
||||
{
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
X86OpRegBWord, 0,
|
||||
X86OpRegAWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
if (opSz == -1)
|
||||
@@ -1002,11 +1067,9 @@ void GenReadCRegIndirect(int opSz)
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
X86OpRegCWord, 0,
|
||||
X86OpIndRegB, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenIncDecIdent(int opSz, int label, int tok)
|
||||
{
|
||||
int instr = X86InstrInc;
|
||||
@@ -1022,6 +1085,7 @@ void GenIncDecIdent(int opSz, int label, int tok)
|
||||
GenExtendRegAIfNeeded(opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenIncDecLocal(int opSz, int ofs, int tok)
|
||||
{
|
||||
int instr = X86InstrInc;
|
||||
@@ -1037,6 +1101,7 @@ void GenIncDecLocal(int opSz, int ofs, int tok)
|
||||
GenExtendRegAIfNeeded(opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenIncDecIndirect(int opSz, int tok)
|
||||
{
|
||||
int instr = X86InstrInc;
|
||||
@@ -1048,7 +1113,6 @@ void GenIncDecIndirect(int opSz, int tok)
|
||||
X86OpRegBWord, 0,
|
||||
X86OpRegAWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr1Operand(instr, 0,
|
||||
@@ -1056,12 +1120,10 @@ void GenIncDecIndirect(int opSz, int tok)
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
GenSelectByteOrWord(X86OpRegAByteOrWord, opSz), 0,
|
||||
X86OpIndRegB, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
GenExtendRegAIfNeeded(opSz);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostIncDecIdent(int opSz, int label, int tok)
|
||||
{
|
||||
int instr = X86InstrInc;
|
||||
@@ -1077,6 +1139,7 @@ void GenPostIncDecIdent(int opSz, int label, int tok)
|
||||
GenSelectByteOrWord(X86OpIndLabelExplicitByteOrWord, opSz), label);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostIncDecLocal(int opSz, int ofs, int tok)
|
||||
{
|
||||
int instr = X86InstrInc;
|
||||
@@ -1092,6 +1155,7 @@ void GenPostIncDecLocal(int opSz, int ofs, int tok)
|
||||
GenSelectByteOrWord(X86OpIndLocalExplicitByteOrWord, opSz), ofs);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostIncDecIndirect(int opSz, int tok)
|
||||
{
|
||||
int instr = X86InstrInc;
|
||||
@@ -1103,7 +1167,6 @@ void GenPostIncDecIndirect(int opSz, int tok)
|
||||
X86OpRegBWord, 0,
|
||||
X86OpRegAWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
@@ -1112,11 +1175,9 @@ void GenPostIncDecIndirect(int opSz, int tok)
|
||||
GenExtendRegAIfNeeded(opSz);
|
||||
GenPrintInstr1Operand(instr, 0,
|
||||
GenSelectByteOrWord(X86OpIndRegBExplicitByteOrWord, opSz), 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostAddSubIdent(int opSz, int val, int label, int tok)
|
||||
{
|
||||
int instr = X86InstrAdd;
|
||||
@@ -1133,6 +1194,7 @@ void GenPostAddSubIdent(int opSz, int val, int label, int tok)
|
||||
X86OpConst, val);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostAddSubLocal(int opSz, int val, int ofs, int tok)
|
||||
{
|
||||
int instr = X86InstrAdd;
|
||||
@@ -1149,6 +1211,7 @@ void GenPostAddSubLocal(int opSz, int val, int ofs, int tok)
|
||||
X86OpConst, val);
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenPostAddSubIndirect(int opSz, int val, int tok)
|
||||
{
|
||||
int instr = X86InstrAdd;
|
||||
@@ -1160,7 +1223,6 @@ void GenPostAddSubIndirect(int opSz, int val, int tok)
|
||||
X86OpRegBWord, 0,
|
||||
X86OpRegAWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
@@ -1170,9 +1232,6 @@ void GenPostAddSubIndirect(int opSz, int val, int tok)
|
||||
GenPrintInstr2Operands(instr, 0,
|
||||
GenSelectByteOrWord(X86OpIndRegBExplicitByteOrWord, opSz), 0,
|
||||
X86OpConst, val);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define tokOpNumInt 0x100
|
||||
@@ -1188,6 +1247,7 @@ void GenPostAddSubIndirect(int opSz, int val, int tok)
|
||||
|
||||
#define tokPushAcc 0x200
|
||||
|
||||
STATIC
|
||||
int GetOperandInfo(int idx, int lvalSize, int* val, int* size, int* delDeref)
|
||||
{
|
||||
int idx0 = idx;
|
||||
@@ -1272,6 +1332,7 @@ l2:
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFuse(int* idx)
|
||||
{
|
||||
int tok;
|
||||
@@ -1643,6 +1704,7 @@ l3:
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
int GenGetBinaryOperatorInstr(int tok)
|
||||
{
|
||||
switch (tok)
|
||||
@@ -1708,6 +1770,7 @@ int GenGetBinaryOperatorInstr(int tok)
|
||||
// Newer, less stack-dependent code generator,
|
||||
// generates more compact code (~30% less) than the stack-based generator
|
||||
#ifndef CG_STACK_BASED
|
||||
STATIC
|
||||
void GenExpr1(void)
|
||||
{
|
||||
int s = sp - 1;
|
||||
@@ -2129,15 +2192,11 @@ void GenExpr1(void)
|
||||
GenPrintInstr1Operand(X86InstrPop, 0,
|
||||
X86OpRegBWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
GenSelectByteOrWord(X86OpRegAByteOrWord, v / 16 - 8), 0,
|
||||
X86OpIndRegB, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
GenExtendRegAIfNeeded(v / 16 - 8);
|
||||
break;
|
||||
}
|
||||
@@ -2541,15 +2600,11 @@ void GenExpr1(void)
|
||||
case tokOpIndAcc:
|
||||
case tokOpIndStack:
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
X86OpIndRegB, 0,
|
||||
GenSelectByteOrWord(X86OpRegAByteOrWord, v / 16 - 8), 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
// the result of the expression is of type of the
|
||||
@@ -2622,6 +2677,7 @@ void GenExpr1(void)
|
||||
#else // #ifndef CG_STACK_BASED
|
||||
// Original, primitive stack-based code generator
|
||||
// DONE: test 32-bit code generation
|
||||
STATIC
|
||||
void GenExpr0(void)
|
||||
{
|
||||
int i;
|
||||
@@ -2816,7 +2872,6 @@ void GenExpr0(void)
|
||||
GenPrintInstr1Operand(X86InstrPop, 0,
|
||||
X86OpRegBWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
@@ -2828,9 +2883,6 @@ void GenExpr0(void)
|
||||
GenPrintInstr2Operands(instr, 0,
|
||||
X86OpIndRegB, 0,
|
||||
GenSelectByteOrWord(X86OpRegCByteOrWord, v), 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
GenExtendRegAIfNeeded(v);
|
||||
}
|
||||
break;
|
||||
@@ -2846,7 +2898,6 @@ void GenExpr0(void)
|
||||
GenPrintInstr1Operand(X86InstrPop, 0,
|
||||
X86OpRegBWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
if (tok != tokAssignMul)
|
||||
@@ -2866,9 +2917,6 @@ void GenExpr0(void)
|
||||
X86OpIndRegB, 0,
|
||||
GenSelectByteOrWord(X86OpRegAByteOrWord, v), 0);
|
||||
}
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
GenExtendRegAIfNeeded(v);
|
||||
}
|
||||
break;
|
||||
@@ -2880,7 +2928,6 @@ void GenExpr0(void)
|
||||
GenPrintInstr1Operand(X86InstrPop, 0,
|
||||
X86OpRegBWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
@@ -2916,9 +2963,6 @@ void GenExpr0(void)
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
X86OpIndRegB, 0,
|
||||
GenSelectByteOrWord(X86OpRegAByteOrWord, v), 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
GenExtendRegAIfNeeded(v);
|
||||
break;
|
||||
|
||||
@@ -2930,7 +2974,6 @@ void GenExpr0(void)
|
||||
GenPrintInstr1Operand(X86InstrPop, 0,
|
||||
X86OpRegBWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
@@ -2942,9 +2985,6 @@ void GenExpr0(void)
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
GenSelectByteOrWord(X86OpRegAByteOrWord, v), 0,
|
||||
X86OpIndRegB, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
GenExtendRegAIfNeeded(v);
|
||||
}
|
||||
break;
|
||||
@@ -2953,15 +2993,11 @@ void GenExpr0(void)
|
||||
GenPrintInstr1Operand(X86InstrPop, 0,
|
||||
X86OpRegBWord, 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(0);
|
||||
GenRegB2Seg();
|
||||
#endif
|
||||
GenPrintInstr2Operands(X86InstrMov, 0,
|
||||
X86OpIndRegB, 0,
|
||||
GenSelectByteOrWord(X86OpRegAByteOrWord, v), 0);
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
GenSaveRestoreRegB(1);
|
||||
#endif
|
||||
GenExtendRegAIfNeeded(v);
|
||||
break;
|
||||
|
||||
@@ -3065,6 +3101,7 @@ void GenExpr0(void)
|
||||
}
|
||||
#endif // #ifndef CG_STACK_BASED
|
||||
|
||||
STATIC
|
||||
unsigned GenStrData(int generatingCode, unsigned requiredLen)
|
||||
{
|
||||
int i;
|
||||
@@ -3082,7 +3119,7 @@ unsigned GenStrData(int generatingCode, unsigned requiredLen)
|
||||
unsigned len;
|
||||
|
||||
p = FindString(label);
|
||||
len = *p++;
|
||||
len = *p++ & 0xFF;
|
||||
|
||||
// If this is a string literal initializing an array of char,
|
||||
// truncate or pad it as necessary.
|
||||
@@ -3174,6 +3211,7 @@ unsigned GenStrData(int generatingCode, unsigned requiredLen)
|
||||
return total;
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenExpr(void)
|
||||
{
|
||||
if (OutputFormat != FormatFlat && GenExterns)
|
||||
@@ -3191,6 +3229,7 @@ void GenExpr(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC
|
||||
void GenFin(void)
|
||||
{
|
||||
if (StructCpyLabel)
|
||||
@@ -3279,6 +3318,148 @@ void GenFin(void)
|
||||
puts2(CodeFooter);
|
||||
}
|
||||
|
||||
#ifdef USE_SWITCH_TAB
|
||||
if (SwitchJmpLabel)
|
||||
{
|
||||
char s[1 + 2 + (2 + CHAR_BIT * sizeof SwitchJmpLabel) / 3];
|
||||
char *p = s + sizeof s;
|
||||
|
||||
*--p = '\0';
|
||||
p = lab2str(p, SwitchJmpLabel);
|
||||
*--p = '_';
|
||||
*--p = '_';
|
||||
|
||||
if (OutputFormat != FormatFlat)
|
||||
puts2(CodeHeader);
|
||||
|
||||
GenLabel(p, 1);
|
||||
GenFxnProlog();
|
||||
|
||||
if (SizeOfWord == 2)
|
||||
{
|
||||
int lbl = (LabelCnt += 3) - 3;
|
||||
puts2("\tmov\tbx, [bp + 4]\n"
|
||||
"\tmov\tsi, [bx + 2]\n"
|
||||
"\tmov\tcx, [bx]");
|
||||
printf2("\tjcxz\t"); GenPrintNumLabel(lbl + 2); // jcxz L3
|
||||
puts2("\n\tmov\tax, [bp + 6]");
|
||||
GenNumLabel(lbl); // L1:
|
||||
puts2("\tadd\tbx, 4\n"
|
||||
"\tcmp\tax, [bx]");
|
||||
printf2("\tjne\t"); GenPrintNumLabel(lbl + 1); // jne L2
|
||||
puts2("\n\tmov\tsi, [bx + 2]");
|
||||
printf2("\tjmp\t"); GenPrintNumLabel(lbl + 2); // jmp L3
|
||||
puts2("");
|
||||
GenNumLabel(lbl + 1); // L2:
|
||||
printf2("\tloop\t"); GenPrintNumLabel(lbl); // loop L1
|
||||
puts2("");
|
||||
GenNumLabel(lbl + 2); // L3:
|
||||
puts2("\tmov\t[bp + 2], si\n"
|
||||
"\tleave\n"
|
||||
"\tret\t4");
|
||||
}
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
else if (OutputFormat != FormatSegHuge)
|
||||
{
|
||||
int lbl = (LabelCnt += 3) - 3;
|
||||
puts2("\tmov\tebx, [ebp + 8]\n"
|
||||
"\tmov\tesi, [ebx + 4]\n"
|
||||
"\tmov\tecx, [ebx]");
|
||||
printf2("\tjecxz\t"); GenPrintNumLabel(lbl + 2); // jecxz L3
|
||||
puts2("\n\tmov\teax, [ebp + 12]");
|
||||
GenNumLabel(lbl); // L1:
|
||||
puts2("\tadd\tebx, 8\n"
|
||||
"\tcmp\teax, [ebx]");
|
||||
printf2("\tjne\t"); GenPrintNumLabel(lbl + 1); // jne L2
|
||||
puts2("\n\tmov\tesi, [ebx + 4]");
|
||||
printf2("\tjmp\t"); GenPrintNumLabel(lbl + 2); // jmp L3
|
||||
puts2("");
|
||||
GenNumLabel(lbl + 1); // L2:
|
||||
printf2("\tloop\t"); GenPrintNumLabel(lbl); // loop L1
|
||||
puts2("");
|
||||
GenNumLabel(lbl + 2); // L3:
|
||||
puts2("\tmov\t[ebp + 4], esi\n"
|
||||
"\tleave\n"
|
||||
"\tret\t8");
|
||||
}
|
||||
else
|
||||
{
|
||||
int lbl = (LabelCnt += 3) - 3;
|
||||
puts2("\tmov\tebx, [bp + 8]\n"
|
||||
"\tror\tebx, 4\n"
|
||||
"\tmov\tds, ebx\n"
|
||||
"\tshr\tebx, 28\n"
|
||||
"\tmov\tsi, [bx + 4]\n"
|
||||
"\tmov\tcx, [bx]"); // use only 16 bits of case counter
|
||||
printf2("\tjcxz\t"); GenPrintNumLabel(lbl + 2); // jcxz L3
|
||||
puts2("\n\tmov\teax, [bp + 12]");
|
||||
GenNumLabel(lbl); // L1:
|
||||
// No segment reload inside the loop, hence the number of cases is limited to ~8190
|
||||
puts2("\tadd\tbx, 8\n"
|
||||
"\tcmp\teax, [bx]");
|
||||
printf2("\tjne\t"); GenPrintNumLabel(lbl + 1); // jne L2
|
||||
puts2("\n\tmov\tsi, [bx + 4]");
|
||||
printf2("\tjmp\t"); GenPrintNumLabel(lbl + 2); // jmp L3
|
||||
puts2("");
|
||||
GenNumLabel(lbl + 1); // L2:
|
||||
printf2("\tloop\t"); GenPrintNumLabel(lbl); // loop L1
|
||||
puts2("");
|
||||
GenNumLabel(lbl + 2); // L3:
|
||||
// Preserve CS on return
|
||||
puts2("\tmov\tax, [bp + 6]\n"
|
||||
"\tshl\tax, 4\n"
|
||||
"\tsub\tsi, ax\n"
|
||||
"\tmov\t[bp + 4], si\n"
|
||||
"\tdb\t0x66\n"
|
||||
"\tleave\n"
|
||||
"\tretf\t8");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Not using GenFxnEpilog() here because we need to remove the parameters
|
||||
// from the stack
|
||||
// GenFxnEpilog();
|
||||
|
||||
if (OutputFormat != FormatFlat)
|
||||
puts2(CodeFooter);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CAN_COMPILE_32BIT
|
||||
if (WinChkStkLabel)
|
||||
{
|
||||
// When targeting Windows, simulate _chkstk() to
|
||||
// correctly grow the stack page by page by probing it
|
||||
char s[1 + 2 + (2 + CHAR_BIT * sizeof WinChkStkLabel) / 3];
|
||||
char *p = s + sizeof s;
|
||||
int lbl = LabelCnt++;
|
||||
|
||||
*--p = '\0';
|
||||
p = lab2str(p, WinChkStkLabel);
|
||||
*--p = '_';
|
||||
*--p = '_';
|
||||
|
||||
if (OutputFormat != FormatFlat)
|
||||
puts2(CodeHeader);
|
||||
|
||||
GenLabel(p, 1);
|
||||
puts2("\tlea\tebx, [esp+4]\n"
|
||||
"\tmov\tecx, ebx\n"
|
||||
"\tsub\tecx, eax\n"
|
||||
"\tand\tebx, -4096\n"
|
||||
"\tand\tecx, -4096");
|
||||
GenNumLabel(lbl); // L1:
|
||||
puts2("\tsub\tebx, 4096\n"
|
||||
"\tmov\tal, [ebx]\n"
|
||||
"\tcmp\tebx, ecx");
|
||||
printf2("\tjne\t"); GenPrintNumLabel(lbl); // jne L1
|
||||
puts2("\n\tret");
|
||||
|
||||
if (OutputFormat != FormatFlat)
|
||||
puts2(CodeFooter);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (OutputFormat != FormatFlat && GenExterns)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -3296,3 +3477,4 @@ void GenFin(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user