Smaller C improvements

- type specifiers may occur in any order
  (e.g. "unsigned short int" and "int short unsigned")

- use .rodata/.rdata section for string literals
- arbitrary length string literals (hooray!)
- better concatenation of adjacent string literals
  (now works even across preprocessor directives)

Support .bss section
- -nobss option in smlrc: use .data instead of .bss as before
- take advantage of .bss in smlrc (put a large array into it)

Remove dead/useless code

Remove useless/rarely used features/options:
-use-gp (MIPS)
-flat16/-flat32 (x86)
-seg16t (x86), -seg16 is now the default
-ctor-fxn

Add/change:
- use EXIT_FAILURE=1 instead of -1 in smlrc when aborting
  due to an error
This commit is contained in:
Alexey Frunze
2015-05-16 05:57:39 -07:00
parent 352d23a073
commit 4ea521eabf
3 changed files with 515 additions and 1180 deletions

View File

@@ -39,14 +39,6 @@ either expressed or implied, of the FreeBSD Project.
// Works around bugs in RetroBSD's as instruction reordering
#define REORDER_WORKAROUND
// Works around bugs in RetroBSD's as immediate operand truncation to 16 bits
//#define INSTR_IMM_WORKAROUND
// Allows the -use-gp option (generally unreliable since implemented simplistically)
//#define ALLOW_GP
#ifdef ALLOW_GP
int UseGp = 0;
#endif
STATIC
void GenInit(void)
@@ -54,8 +46,10 @@ void GenInit(void)
// initialization of target-specific code generator
SizeOfWord = 4;
OutputFormat = FormatSegmented;
CodeHeader = "\t.text";
DataHeader = "\t.data";
CodeHeaderFooter[0] = "\t.text";
DataHeaderFooter[0] = "\t.data";
RoDataHeaderFooter[0] = "\t.rdata";
BssHeaderFooter[0] = "\t.bss";
UseLeadingUnderscores = 0;
#ifdef REORDER_WORKAROUND
FileHeader = "\t.set\tnoreorder";
@@ -69,15 +63,6 @@ int GenInitParams(int argc, char** argv, int* idx)
{
(void)argc;
// initialization of target-specific code generator with parameters
#ifdef ALLOW_GP
if (!strcmp(argv[*idx], "-use-gp"))
{
UseGp = 1;
return 1;
}
else
// fallthrough
#endif
if (!strcmp(argv[*idx], "-v"))
{
// RetroBSD's cc may supply this parameter. Just need to consume it.
@@ -100,8 +85,9 @@ void GenStartCommentLine(void)
}
STATIC
void GenWordAlignment(void)
void GenWordAlignment(int bss)
{
(void)bss;
printf2("\t.align 2\n");
}
@@ -109,7 +95,7 @@ STATIC
void GenLabel(char* Label, int Static)
{
{
if (OutputFormat != FormatFlat && !Static && GenExterns)
if (!Static && GenExterns)
printf2("\t.globl\t%s\n", Label);
printf2("%s:\n", Label);
}
@@ -139,8 +125,9 @@ void GenPrintNumLabel(int label)
}
STATIC
void GenZeroData(unsigned Size)
void GenZeroData(unsigned Size, int bss)
{
(void)bss;
printf2("\t.space\t%u\n", truncUint(Size)); // or ".fill size"
}
@@ -318,7 +305,7 @@ void GenPrintInstr(int instr, int val)
#define MipsOpConst 0x80
#define MipsOpLabel 0x81
#define MipsOpNumLabel 0x82
#define MipsOpLabelGpOption 0x83
#define MipsOpLabelLo 0x83
#define MipsOpIndLocal MipsOpIndRegFp
#define MAX_TEMP_REGS 8 // this many temp registers used beginning with T0 to hold subexpression results
@@ -349,22 +336,10 @@ void GenPrintOperand(int op, int val)
switch (op)
{
case MipsOpConst: printf2("%d", truncInt(val)); break;
case MipsOpLabelGpOption:
#ifdef ALLOW_GP
if (UseGp)
{
printf2("%%gp_rel(");
GenPrintLabel(IdentTable + val);
printf2(")($28)");
}
else
// fallthrough
#endif
{
printf2("%%lo(");
GenPrintLabel(IdentTable + val);
printf2(")($1)");
}
case MipsOpLabelLo:
printf2("%%lo(");
GenPrintLabel(IdentTable + val);
printf2(")($1)");
break;
case MipsOpLabel: GenPrintLabel(IdentTable + val); break;
case MipsOpNumLabel: GenPrintNumLabel(val); break;
@@ -427,62 +402,11 @@ void GenPrintInstr3Operands(int instr, int instrval,
int operand2, int operand2val,
int operand3, int operand3val)
{
#ifdef INSTR_IMM_WORKAROUND
int useAt = 0;
#endif
if (operand3 == MipsOpConst && operand3val == 0 &&
(instr == MipsInstrAddU || instr == MipsInstrSubU) &&
operand1 == operand2)
return;
#ifdef INSTR_IMM_WORKAROUND
if (operand3 == MipsOpConst)
{
unsigned imm = truncUint(operand3val);
switch (instr)
{
// signed imm16:
// addi[u], subi[u], slti[u]
case MipsInstrAddU:
case MipsInstrSLT:
case MipsInstrSLTU:
if (imm > 0x7FFF && imm < 0xFFFF8000) // if not (-0x8000 <= imm <= 0x7FFF)
useAt = 1;
break;
case MipsInstrSubU:
// subi[u] will be transformed into addi[u] and the immediate will be negated,
// hence the immediate range is shifted by 1
if (imm > 0x8000 && imm < 0xFFFF8001) // if not (-0x7FFF <= imm <= 0x8000)
useAt = 1;
break;
// unsigned imm16:
// andi, ori, xori
case MipsInstrAnd:
case MipsInstrOr:
case MipsInstrXor:
if (imm > 0xFFFF)
useAt = 1;
break;
// also: various trap instructions
default:
break;
}
}
if (useAt)
{
puts2("\t.set\tnoat");
GenPrintInstr2Operands(MipsInstrLI, 0,
MipsOpRegAt, 0,
MipsOpConst, operand3val);
operand3 = MipsOpRegAt;
}
#endif
GenPrintInstr(instr, instrval);
GenPrintOperand(operand1, operand1val);
GenPrintOperandSeparator();
@@ -491,13 +415,6 @@ void GenPrintInstr3Operands(int instr, int instrval,
GenPrintOperand(operand3, operand3val);
GenPrintNewLine();
#ifdef INSTR_IMM_WORKAROUND
if (useAt)
{
puts2("\t.set\tat");
}
#endif
#ifdef REORDER_WORKAROUND
if (instr == MipsInstrBEQ || instr == MipsInstrBNE)
GenNop();
@@ -749,10 +666,6 @@ int GenGetBinaryOperatorInstr(int tok)
STATIC
void GenPreIdentAccess(int label)
{
#ifdef ALLOW_GP
if (UseGp)
return;
#endif
printf2("\t.set\tnoat\n\tlui\t$1, %%hi(");
GenPrintLabel(IdentTable + label);
puts2(")");
@@ -761,10 +674,6 @@ void GenPreIdentAccess(int label)
STATIC
void GenPostIdentAccess(void)
{
#ifdef ALLOW_GP
if (UseGp)
return;
#endif
puts2("\t.set\tat");
}
@@ -791,7 +700,7 @@ void GenReadIdent(int regDst, int opSz, int label)
}
GenPrintInstr2Operands(instr, 0,
regDst, 0,
MipsOpLabelGpOption, label);
MipsOpLabelLo, label);
GenPostIdentAccess();
}
@@ -860,7 +769,7 @@ void GenWriteIdent(int regSrc, int opSz, int label)
}
GenPrintInstr2Operands(instr, 0,
regSrc, 0,
MipsOpLabelGpOption, label);
MipsOpLabelLo, label);
GenPostIdentAccess();
}
@@ -1160,7 +1069,7 @@ void GenPrep(int* idx)
{
if (tok == tokUMod || tok == tokAssignUMod)
{
stack[oldIdxRight][1] = uint2int(m - 1);
stack[oldIdxRight][1] = (int)(m - 1);
tok = (tok == tokUMod) ? '&' : tokAssignAnd;
}
else
@@ -2215,103 +2124,36 @@ void GenExpr0(void)
}
STATIC
unsigned GenStrData(int generatingCode, unsigned requiredLen)
void GenDumpChar(int ch)
{
int i;
unsigned total = 0;
// insert string literals into the code
for (i = 0; i < sp; i++)
if (ch < 0)
{
int tok = stack[i][0];
char* p = IdentTable + stack[i][1];
if (tok == tokIdent && isdigit(*p))
{
int label = atoi(p);
unsigned len;
p = FindString(label);
len = *p++ & 0xFF;
// If this is a string literal initializing an array of char,
// truncate or pad it as necessary.
if (requiredLen)
{
if (len >= requiredLen)
{
len = requiredLen; // copy count
requiredLen = 0; // count to be zeroed out
}
else
{
requiredLen -= len; // count to be zeroed out
}
}
// Also, calculate its real size for incompletely typed arrays.
total = len + requiredLen;
if (generatingCode)
{
if (OutputFormat == FormatFlat)
{
GenJumpUncond(label + 1);
}
else
{
puts2(CodeFooter);
puts2(DataHeader);
}
}
GenNumLabel(label);
GenStartAsciiString();
printf2("\"");
while (len--)
{
// quote ASCII chars for better readability
if (*p >= 0x20 && *p <= 0x7E)
{
if (*p == '\"' || *p == '\\')
printf2("\\");
printf2("%c", *p);
}
else
{
printf2("\\%03o", *p & 0xFFu);
}
p++;
}
while (requiredLen)
{
printf2("\\000");
requiredLen--;
}
printf2("\"");
puts2("");
if (generatingCode)
{
if (OutputFormat == FormatFlat)
{
GenNumLabel(label + 1);
}
else
{
puts2(DataFooter);
puts2(CodeHeader);
}
}
}
if (TokenStringLen)
printf2("\"\n");
return;
}
return total;
if (TokenStringLen == 0)
{
GenStartAsciiString();
printf2("\"");
}
if (ch >= 0x20 && ch <= 0x7E)
{
if (ch == '"' || ch == '\\')
printf2("\\");
printf2("%c", ch);
}
else
{
printf2("\\%03o", ch);
}
}
STATIC
void GenExpr(void)
{
GenStrData(1, 0);
GenExpr0();
}
@@ -2320,19 +2162,11 @@ void GenFin(void)
{
if (StructCpyLabel)
{
char s[1 + 2 + (2 + CHAR_BIT * sizeof StructCpyLabel) / 3];
char *p = s + sizeof s;
int lbl = LabelCnt++;
*--p = '\0';
p = lab2str(p, StructCpyLabel);
*--p = '_';
*--p = '_';
puts2(CodeHeaderFooter[0]);
if (OutputFormat != FormatFlat)
puts2(CodeHeader);
GenLabel(p, 1);
GenNumLabel(StructCpyLabel);
puts2("\tmove\t$2, $6\n"
"\tmove\t$3, $6");
@@ -2352,64 +2186,6 @@ void GenFin(void)
GenNop();
#endif
if (OutputFormat != FormatFlat)
puts2(CodeFooter);
puts2(CodeHeaderFooter[1]);
}
#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
}

View File

@@ -60,7 +60,7 @@ void GenAddGlobal(char* s, int use)
{
int i = 0;
int l;
if (OutputFormat != FormatFlat && GenExterns)
if (GenExterns)
{
while (i < GlobalsTableLen)
{
@@ -86,7 +86,7 @@ void GenInit(void)
{
// initialization of target-specific code generator
SizeOfWord = 2;
OutputFormat = FormatSegTurbo;
OutputFormat = FormatSegmented;
UseLeadingUnderscores = 1;
}
@@ -96,33 +96,23 @@ int GenInitParams(int argc, char** argv, int* idx)
(void)argc;
// initialization of target-specific code generator with parameters
if (!strcmp(argv[*idx], "-seg16t"))
if (!strcmp(argv[*idx], "-nobss"))
{
// this is the default option for x86
OutputFormat = FormatSegTurbo; SizeOfWord = 2;
UseBss = 0;
return 1;
}
else if (!strcmp(argv[*idx], "-seg16"))
{
// this is the default option for x86
OutputFormat = FormatSegmented; SizeOfWord = 2;
return 1;
}
else if (!strcmp(argv[*idx], "-flat16"))
{
OutputFormat = FormatFlat; SizeOfWord = 2;
return 1;
}
#ifdef CAN_COMPILE_32BIT
else if (!strcmp(argv[*idx], "-seg32"))
{
OutputFormat = FormatSegmented; SizeOfWord = 4;
return 1;
}
else if (!strcmp(argv[*idx], "-flat32"))
{
OutputFormat = FormatFlat; SizeOfWord = 4;
return 1;
}
else if (!strcmp(argv[*idx], "-huge"))
{
OutputFormat = FormatSegHuge; SizeOfWord = 4;
@@ -144,27 +134,14 @@ void GenInitFinalize(void)
// finalization of initialization of target-specific code generator
// Change the output assembly format/content according to the options
if (OutputFormat == FormatSegTurbo)
{
FileHeader = "SEGMENT _TEXT PUBLIC CLASS=CODE USE16\n"
"SEGMENT _DATA PUBLIC CLASS=DATA\n";
CodeHeader = "SEGMENT _TEXT";
CodeFooter = "; SEGMENT _TEXT";
DataHeader = "SEGMENT _DATA";
DataFooter = "; SEGMENT _DATA";
}
CodeHeaderFooter[0] = "section .text";
DataHeaderFooter[0] = "section .data";
RoDataHeaderFooter[0] = "section .rodata";
BssHeaderFooter[0] = "section .bss";
if (SizeOfWord == 2 || OutputFormat == FormatSegHuge)
FileHeader = "bits 16\n";
else
{
if (OutputFormat == FormatSegmented || OutputFormat == FormatSegHuge)
{
CodeHeader = "section .text";
DataHeader = "section .data";
}
if (SizeOfWord == 2 || OutputFormat == FormatSegHuge)
FileHeader = "bits 16\n";
else
FileHeader = "bits 32\n";
}
FileHeader = "bits 32\n";
}
STATIC
@@ -174,9 +151,9 @@ void GenStartCommentLine(void)
}
STATIC
void GenWordAlignment(void)
void GenWordAlignment(int bss)
{
printf2("\talign %d\n", SizeOfWord);
printf2(bss ? "\talignb %d\n" : "\talign %d\n", SizeOfWord);
}
STATIC
@@ -184,13 +161,13 @@ void GenLabel(char* Label, int Static)
{
if (UseLeadingUnderscores)
{
if (OutputFormat != FormatFlat && !Static && GenExterns)
if (!Static && GenExterns)
printf2("\tglobal\t_%s\n", Label);
printf2("_%s:\n", Label);
}
else
{
if (OutputFormat != FormatFlat && !Static && GenExterns)
if (!Static && GenExterns)
printf2("\tglobal\t$%s\n", Label);
printf2("$%s:\n", Label);
}
@@ -235,9 +212,9 @@ void GenPrintNumLabel(int label)
}
STATIC
void GenZeroData(unsigned Size)
void GenZeroData(unsigned Size, int bss)
{
printf2("\ttimes\t%u db 0\n", truncUint(Size));
printf2(bss ? "\tresb\t%u\n" : "\ttimes\t%u db 0\n", truncUint(Size));
}
STATIC
@@ -269,7 +246,7 @@ void GenAddrData(int Size, char* Label, int ofs)
{
int lab = LabelCnt++;
printf2("section .relod\n\tdd\t"); GenPrintNumLabel(lab); puts2("");
puts2(DataHeader);
puts2(DataHeaderFooter[0]);
GenNumLabel(lab);
}
#endif
@@ -641,7 +618,7 @@ void GenPrintInstr1Operand(int instr, int instrval, int operand, int operandval)
{
int lab = LabelCnt++;
printf2("section .relod\n\tdd\t"); GenPrintNumLabel(lab); puts2("");
puts2(CodeHeader);
puts2(CodeHeaderFooter[0]);
puts2("\tdb\t0x66, 0x68"); // push dword const
GenNumLabel(lab);
printf2("\tdd\t"); GenPrintLabel(IdentTable + operandval); puts2("");
@@ -690,7 +667,7 @@ void GenPrintInstr2Operands(int instr, int instrval, int operand1, int operand1v
{
int lab = LabelCnt++;
printf2("section .relod\n\tdd\t"); GenPrintNumLabel(lab); puts2("");
puts2(CodeHeader);
puts2(CodeHeaderFooter[0]);
puts2("\tdb\t0x66, 0xB8"); // mov eax, const
GenNumLabel(lab);
printf2("\tdd\t"); GenPrintLabel(IdentTable + operand2val); puts2("");
@@ -778,7 +755,6 @@ void GenJumpUncond(int label)
X86OpNumLabel, label);
}
#ifndef USE_SWITCH_TAB
STATIC
void GenJumpIfEqual(int val, int label)
{
@@ -788,7 +764,6 @@ void GenJumpIfEqual(int val, int label)
GenPrintInstr1Operand(X86InstrJcc, tokEQ,
X86OpNumLabel, label);
}
#endif
STATIC
void GenJumpIfZero(int label)
@@ -839,21 +814,14 @@ void GenGrowStack(int size)
{
// 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);
GenPrintNumLabel(WinChkStkLabel); // TBD??? use dedicated instr/op fxn???
puts2("");
}
#endif
@@ -2642,7 +2610,7 @@ void GenExpr1(void)
int lab = LabelCnt++;
puts2("\tdb\t0x9A"); // call far seg:ofs
printf2("section .relot\n\tdd\t"); GenPrintNumLabel(lab); puts2("");
puts2(CodeHeader);
puts2(CodeHeaderFooter[0]);
GenNumLabel(lab);
printf2("\tdd\t"); GenPrintLabel(IdentTable + stack[i - 1][1]); puts2("");
}
@@ -2659,7 +2627,7 @@ void GenExpr1(void)
int lab = (LabelCnt += 3) - 3;
puts2("\tdb\t0x9A"); // call far seg:ofs (only to generate return address)
printf2("section .relot\n\tdd\t"); GenPrintNumLabel(lab); puts2("");
puts2(CodeHeader);
puts2(CodeHeaderFooter[0]);
GenNumLabel(lab);
printf2("\tdd\t"); GenPrintNumLabel(lab + 1); puts2("");
GenNumLabel(lab + 1);
@@ -2764,7 +2732,7 @@ void GenExpr0(void)
int lab = (LabelCnt += 3) - 3;
puts2("\tdb\t0x9A"); // call far seg:ofs (only to generate return address)
printf2("section .relot\n\tdd\t"); GenPrintNumLabel(lab); puts2("");
puts2(CodeHeader);
puts2(CodeHeaderFooter[0]);
GenNumLabel(lab);
printf2("\tdd\t"); GenPrintNumLabel(lab + 1); puts2("");
GenNumLabel(lab + 1);
@@ -2995,13 +2963,17 @@ void GenExpr0(void)
GenPrintInstr2Operands(X86InstrMov, 0,
X86OpRegCWord, 0,
X86OpRegAWord, 0);
GenPrintInstr2Operands(instr, 0,
GenSelectByteOrWord(X86OpIndRegBExplicitByteOrWord, v), 0,
X86OpRegCByte, 0);
GenPrintInstr2Operands(X86InstrMov, 0,
GenSelectByteOrWord(X86OpRegAByteOrWord, v), 0,
X86OpIndRegB, 0);
GenExtendRegAIfNeeded(v);
GenPrintInstr2Operands(instr, 0,
X86OpRegAWord, 0,
X86OpRegCByte, 0);
GenPrintInstr2Operands(X86InstrMov, 0,
X86OpIndRegB, 0,
GenSelectByteOrWord(X86OpRegAByteOrWord, v), 0);
GenExtendRegAIfNeeded(v);
}
break;
@@ -3066,6 +3038,18 @@ void GenExpr0(void)
X86OpRegAWord, 0,
X86OpConst, 0xFF);
break;
#ifdef CAN_COMPILE_32BIT
case tokShort:
GenPrintInstr2Operands(X86InstrMovSx, 0,
X86OpRegAWord, 0,
X86OpRegAHalfWord, 0);
break;
case tokUShort:
GenPrintInstr2Operands(X86InstrMovZx, 0,
X86OpRegAWord, 0,
X86OpRegAHalfWord, 0);
break;
#endif
case tokShortCirc:
#ifndef NO_ANNOTATIONS
@@ -3118,126 +3102,60 @@ void GenExpr0(void)
#endif // #ifndef CG_STACK_BASED
STATIC
unsigned GenStrData(int generatingCode, unsigned requiredLen)
void GenDumpChar(int ch)
{
int i;
unsigned total = 0;
static int quot = 0;
// insert string literals into the code
for (i = 0; i < sp; i++)
if (ch < 0)
{
int tok = stack[i][0];
char* p = IdentTable + stack[i][1];
if (tok == tokIdent && isdigit(*p))
if (quot)
{
int label = atoi(p);
int quot = 0;
unsigned len;
p = FindString(label);
len = *p++ & 0xFF;
// If this is a string literal initializing an array of char,
// truncate or pad it as necessary.
if (requiredLen)
{
if (len >= requiredLen)
{
len = requiredLen; // copy count
requiredLen = 0; // count to be zeroed out
}
else
{
requiredLen -= len; // count to be zeroed out
}
}
// Also, calculate its real size for incompletely typed arrays.
total = len + requiredLen;
if (generatingCode)
{
if (OutputFormat == FormatFlat)
{
GenJumpUncond(label + 1);
}
else
{
puts2(CodeFooter);
puts2(DataHeader);
}
}
GenNumLabel(label);
GenStartAsciiString();
while (len--)
{
// quote ASCII chars for better readability
if (*p >= 0x20 && *p <= 0x7E && *p != '\"')
{
if (!quot)
{
quot = 1;
printf2("\"");
}
printf2("%c", *p);
}
else
{
if (quot)
{
quot = 0;
printf2("\",");
}
printf2("%u", *p & 0xFFu);
if (len || requiredLen)
printf2(",");
}
p++;
}
if (quot)
{
printf2("\"");
if (requiredLen)
printf2(",");
}
while (requiredLen)
{
printf2("0");
if (--requiredLen)
printf2(",");
}
puts2("");
if (generatingCode)
{
if (OutputFormat == FormatFlat)
{
GenNumLabel(label + 1);
}
else
{
puts2(DataFooter);
puts2(CodeHeader);
}
}
printf2("\"");
quot = 0;
}
if (TokenStringLen)
printf2("\n");
return;
}
return total;
if (TokenStringLen == 0)
GenStartAsciiString();
// quote ASCII chars for better readability
if (ch >= 0x20 && ch <= 0x7E && ch != '"')
{
if (!quot)
{
quot = 1;
if (TokenStringLen)
printf2(",");
printf2("\"");
}
printf2("%c", ch);
}
else
{
if (quot)
{
quot = 0;
printf2("\"");
}
if (TokenStringLen)
printf2(",");
printf2("%u", ch & 0xFFu);
}
}
STATIC
void GenExpr(void)
{
if (OutputFormat != FormatFlat && GenExterns)
if (GenExterns)
{
int i;
for (i = 0; i < sp; i++)
if (stack[i][0] == tokIdent && !isdigit(IdentTable[stack[i][1]]))
GenAddGlobal(IdentTable + stack[i][1], 2);
}
GenStrData(1, 0);
#ifndef CG_STACK_BASED
GenExpr1();
#else
@@ -3250,18 +3168,9 @@ void GenFin(void)
{
if (StructCpyLabel)
{
char s[1 + 2 + (2 + CHAR_BIT * sizeof StructCpyLabel) / 3];
char *p = s + sizeof s;
puts2(CodeHeaderFooter[0]);
*--p = '\0';
p = lab2str(p, StructCpyLabel);
*--p = '_';
*--p = '_';
if (OutputFormat != FormatFlat)
puts2(CodeHeader);
GenLabel(p, 1);
GenNumLabel(StructCpyLabel);
GenFxnProlog();
if (SizeOfWord == 2)
@@ -3330,25 +3239,15 @@ void GenFin(void)
GenFxnEpilog();
if (OutputFormat != FormatFlat)
puts2(CodeFooter);
puts2(CodeHeaderFooter[1]);
}
#ifndef NO_STRUCT_BY_VAL
if (StructPushLabel)
{
char s[1 + 2 + (2 + CHAR_BIT * sizeof StructPushLabel) / 3];
char *p = s + sizeof s;
puts2(CodeHeaderFooter[0]);
*--p = '\0';
p = lab2str(p, StructPushLabel);
*--p = '_';
*--p = '_';
if (OutputFormat != FormatFlat)
puts2(CodeHeader);
GenLabel(p, 1);
GenNumLabel(StructPushLabel);
GenFxnProlog();
if (SizeOfWord == 2)
@@ -3432,115 +3331,7 @@ void GenFin(void)
// GenFxnEpilog();
if (OutputFormat != FormatFlat)
puts2(CodeFooter);
}
#endif
#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);
puts2(CodeHeaderFooter[1]);
}
#endif
@@ -3549,19 +3340,11 @@ void GenFin(void)
{
// 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 = '_';
puts2(CodeHeaderFooter[0]);
if (OutputFormat != FormatFlat)
puts2(CodeHeader);
GenLabel(p, 1);
GenNumLabel(WinChkStkLabel);
puts2("\tlea\tebx, [esp+4]\n"
"\tmov\tecx, ebx\n"
"\tsub\tecx, eax\n"
@@ -3574,12 +3357,11 @@ void GenFin(void)
printf2("\tjne\t"); GenPrintNumLabel(lbl); // jne L1
puts2("\n\tret");
if (OutputFormat != FormatFlat)
puts2(CodeFooter);
puts2(CodeHeaderFooter[1]);
}
#endif
if (OutputFormat != FormatFlat && GenExterns)
if (GenExterns)
{
int i = 0;

File diff suppressed because it is too large Load Diff