mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-24 13:55:36 +03:00
Added Compact Encoding (-c)
Added second pass optimization (-h)
This commit is contained in:
parent
c9a0a3f9be
commit
81b3e662cf
@ -29,6 +29,8 @@ Compiler::Compiler()
|
||||
Output = 0;
|
||||
stacksize = cellsize * 4096;
|
||||
debug = false;
|
||||
pack = false;
|
||||
dopt = false;
|
||||
Init();
|
||||
}
|
||||
|
||||
@ -53,9 +55,20 @@ Compiler::Compiler(std::string &f)
|
||||
filename.assign(f);
|
||||
stacksize = cellsize * 4096;
|
||||
debug = false;
|
||||
pack = false;
|
||||
dopt = false;
|
||||
Init();
|
||||
}
|
||||
|
||||
bool Compiler::SetDOpt()
|
||||
{
|
||||
bool state = dopt;
|
||||
|
||||
dopt = dopt ? false : true;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
bool Compiler::SetDebug()
|
||||
{
|
||||
bool state = debug;
|
||||
@ -65,6 +78,15 @@ bool Compiler::SetDebug()
|
||||
return state;
|
||||
}
|
||||
|
||||
bool Compiler::SetPack()
|
||||
{
|
||||
bool state = pack;
|
||||
|
||||
pack = pack ? false : true;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void Compiler::Load(std::string &f)
|
||||
{
|
||||
filename.assign(f);
|
||||
@ -111,6 +133,49 @@ int Compiler::CipCount()
|
||||
return cipc;
|
||||
}
|
||||
|
||||
void Compiler::WriteCell(FILE *fp, ucell *c, int repeat)
|
||||
{
|
||||
unsigned char T[5] = {0,0,0,0,0};
|
||||
unsigned char code = 0;
|
||||
int index = 0;
|
||||
ucell p = (*c);
|
||||
int i = 0;
|
||||
|
||||
for (i=1; i<=repeat; i++)
|
||||
{
|
||||
if (pack)
|
||||
{
|
||||
for (index=0;index<5;index++)
|
||||
{
|
||||
T[index]=(unsigned char)(p & 0x7f);
|
||||
p>>=7;
|
||||
}
|
||||
while (index>1 && T[index-1]==0 && (T[index-2] & 0x40)==0)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
if (index==5 && T[index-1]==0x0f && (T[index-2] & 0x40)!=0)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
while (index>1 && T[index-1]==0x7f && (T[index-2] & 0x40)!=0)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
assert(index>0);
|
||||
while (index-->0)
|
||||
{
|
||||
code=(unsigned char)((index==0)?T[index]:(T[index]|0x80));
|
||||
fwrite((void*)&code, sizeof(unsigned char), 1, fp);
|
||||
bitsOut += sizeof(unsigned char);
|
||||
}
|
||||
} else {
|
||||
fwrite((void*)c, sizeof(ucell), 1, fp);
|
||||
bitsOut += sizeof(ucell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Compiler::Compile(std::string &out)
|
||||
{
|
||||
if (CodeList.size() < 1 || !CError || CError->GetStatus() >= Err_Error)
|
||||
@ -118,6 +183,7 @@ bool Compiler::Compile(std::string &out)
|
||||
return false;
|
||||
}
|
||||
|
||||
bitsOut = 0;
|
||||
int32_t fileSize = 0;
|
||||
int16_t magic = (int16_t)AMX_MAGIC;
|
||||
char file_version = CUR_FILE_VERSION;
|
||||
@ -127,6 +193,15 @@ bool Compiler::Compile(std::string &out)
|
||||
int32_t cod, dat, hea, stp, cip, publics, natives, libraries;
|
||||
int32_t pubvars, tags, names;
|
||||
int hdrEnd = sizeof(AMX_HEADER);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
flags |= AMX_FLAG_DEBUG;
|
||||
}
|
||||
if (pack)
|
||||
{
|
||||
flags |= AMX_FLAG_COMPACT;
|
||||
}
|
||||
|
||||
std::vector<ProcMngr::AsmProc *> ProcList;
|
||||
std::vector<ProcMngr::AsmProc *>::iterator pl;
|
||||
@ -195,6 +270,7 @@ bool Compiler::Compile(std::string &out)
|
||||
cOffset += (int)strlen(Nametbl.at(off).Name) + 1;
|
||||
}
|
||||
|
||||
bitsOut = cOffset;
|
||||
cod = cOffset;
|
||||
dat = cod + CipCount();
|
||||
hea = dat + DAT->GetSize();
|
||||
@ -267,15 +343,15 @@ bool Compiler::Compile(std::string &out)
|
||||
|
||||
std::vector<Asm *>::iterator ci;
|
||||
std::vector<int>::iterator di;
|
||||
int cop = 0;
|
||||
ucell cop = 0;
|
||||
for (ci = CodeList.begin(); ci != CodeList.end(); ci++)
|
||||
{
|
||||
cop = (*ci)->op;
|
||||
fwrite((void *)&cop, sizeof(int32_t), 1, fp);
|
||||
WriteCell(fp, &cop, 1);
|
||||
for (di = (*ci)->params.begin(); di != (*ci)->params.end(); di++)
|
||||
{
|
||||
cop = (*di);
|
||||
fwrite((void *)&cop, sizeof(int32_t), 1, fp);
|
||||
WriteCell(fp, &cop, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,7 +359,7 @@ bool Compiler::Compile(std::string &out)
|
||||
std::vector<DataMngr::Datum *>::iterator dmi;
|
||||
DAT->GetData(dm);
|
||||
|
||||
int val = 0;
|
||||
ucell val = 0;
|
||||
const char *s = 0;
|
||||
for (dmi = dm.begin(); dmi != dm.end(); dmi++)
|
||||
{
|
||||
@ -298,18 +374,25 @@ bool Compiler::Compile(std::string &out)
|
||||
for (int q = 0; q < (*dmi)->e.Size(); q++)
|
||||
{
|
||||
val = s[q];
|
||||
fwrite((void*)&val, sizeof(int32_t), 1, fp);
|
||||
WriteCell(fp, &val, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char c = (*dmi)->fill;
|
||||
for (int iter=0; iter<=(*dmi)->e.GetNumber(); iter++)
|
||||
{
|
||||
fwrite((void*)&c, sizeof(int32_t), 1, fp);
|
||||
}
|
||||
if (DAT->IsOptimized())
|
||||
break;
|
||||
ucell c = (*dmi)->fill;
|
||||
WriteCell(fp, &c, (*dmi)->e.GetNumber());
|
||||
}
|
||||
}
|
||||
|
||||
/* Was packing enabled? Re-output the actual size */
|
||||
if (pack)
|
||||
{
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fwrite((void *)&bitsOut, sizeof(int32_t), 1, fp);
|
||||
fseek(fp, 0, SEEK_END);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
@ -326,32 +409,44 @@ void Compiler::Clear()
|
||||
CSymbols->Clear();
|
||||
}
|
||||
|
||||
/* Two pass parser.
|
||||
* The first pass applies macros + defines + directives
|
||||
* natives, and data.
|
||||
* The second pass eats up everything else (code, publics)
|
||||
*/
|
||||
bool Compiler::Parse()
|
||||
{
|
||||
std::ifstream fp(filename.c_str());
|
||||
FILE *fp = 0;
|
||||
char buffer[256] = {0};
|
||||
std::stack<int> DefStack;
|
||||
std::stack<std::string> LabelStack;
|
||||
curLine = 0;
|
||||
AsmSection sec = Asm_None;
|
||||
lastCip = 0-cellsize;
|
||||
int pass = 0;
|
||||
|
||||
if (!fp.is_open())
|
||||
Start:
|
||||
fp = fopen(filename.c_str(), "rt");
|
||||
curLine = 0;
|
||||
sec = Asm_None;
|
||||
lastCip = 0-cellsize;
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
CError->ErrorMsg(Err_FileOpen, filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!fp.eof())
|
||||
while (!feof(fp))
|
||||
{
|
||||
fp.getline(buffer, 255);
|
||||
fgets(buffer, 255, fp);
|
||||
curLine+=1;
|
||||
|
||||
/* Check for preprocessor directives */
|
||||
if (buffer[0] == '#')
|
||||
{
|
||||
std::string procline(buffer);
|
||||
if (procline.substr(0, 3).compare("#if") == 0)
|
||||
if (procline.substr(0, 6).compare("#ifdef") == 0)
|
||||
{
|
||||
std::string def;
|
||||
std::string temp;
|
||||
@ -359,16 +454,37 @@ bool Compiler::Parse()
|
||||
StringBreak(procline, def, temp);
|
||||
StringBreak(temp, def, comp);
|
||||
DefineMngr::Define *D = 0;
|
||||
if ((D = CDefines->FindDefine(def)) == 0)
|
||||
if ( (D = CDefines->FindDefine(def)) == NULL)
|
||||
{
|
||||
DefStack.push(0);
|
||||
} else if (D->GetDefine()->compare(comp) == 0) {
|
||||
} else {
|
||||
if (D->GetDefine()->compare("0") == 0)
|
||||
{
|
||||
DefStack.push(0);
|
||||
} else {
|
||||
DefStack.push(1);
|
||||
}
|
||||
}
|
||||
} else if (procline.substr(0, 7).compare("#ifndef") == 0) {
|
||||
std::string def;
|
||||
std::string temp;
|
||||
std::string comp;
|
||||
StringBreak(procline, def, temp);
|
||||
StringBreak(temp, def, comp);
|
||||
DefineMngr::Define *D = 0;
|
||||
if ( (D = CDefines->FindDefine(def)) == NULL)
|
||||
{
|
||||
DefStack.push(1);
|
||||
} else {
|
||||
DefStack.push(0);
|
||||
if (D->GetDefine()->compare("0") == 0)
|
||||
{
|
||||
DefStack.push(1);
|
||||
} else {
|
||||
DefStack.push(0);
|
||||
}
|
||||
}
|
||||
} else if (procline.substr(0, 5).compare("#else") == 0) {
|
||||
if (DefStack.size())
|
||||
if (!DefStack.empty())
|
||||
{
|
||||
if (DefStack.top() == 1)
|
||||
{
|
||||
@ -383,7 +499,7 @@ bool Compiler::Parse()
|
||||
}
|
||||
continue;
|
||||
} else if (procline.substr(0, 6).compare("#endif") == 0) {
|
||||
if (DefStack.size())
|
||||
if (!DefStack.empty())
|
||||
{
|
||||
DefStack.pop();
|
||||
} else {
|
||||
@ -399,7 +515,11 @@ bool Compiler::Parse()
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ProcessDirective(procline);
|
||||
// only process directives on pass one
|
||||
if (pass == 0)
|
||||
{
|
||||
ProcessDirective(procline);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -428,7 +548,7 @@ bool Compiler::Parse()
|
||||
if (line.compare(".DATA") == 0)
|
||||
{
|
||||
sec = Asm_Data;
|
||||
} else if (line.compare(".CODE") == 0) {
|
||||
} else if (line.compare(".CODE") == 0) {;
|
||||
sec = Asm_Code;
|
||||
} else if (line.compare(".PUBLIC") == 0) {
|
||||
sec = Asm_Public;
|
||||
@ -438,13 +558,16 @@ bool Compiler::Parse()
|
||||
sec = Asm_Invalid;
|
||||
CError->ErrorMsg(Err_Invalid_Section, buffer);
|
||||
}
|
||||
/* Update the labels */
|
||||
CLabels->CompleteQueue(true);
|
||||
while (!LabelStack.empty())
|
||||
if (pass == 1)
|
||||
{
|
||||
CLabels->EraseLabel(LabelStack.top());
|
||||
CSymbols->EraseSymbol(LabelStack.top());
|
||||
LabelStack.pop();
|
||||
/* Update the labels */
|
||||
CLabels->CompleteQueue(true);
|
||||
while (!LabelStack.empty())
|
||||
{
|
||||
CLabels->EraseLabel(LabelStack.top());
|
||||
CSymbols->EraseSymbol(LabelStack.top());
|
||||
LabelStack.pop();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Do pre-processing */
|
||||
@ -461,6 +584,8 @@ bool Compiler::Parse()
|
||||
} else if (sec == Asm_Invalid) {
|
||||
/* Just ignore it */
|
||||
} else if (sec == Asm_Data) {
|
||||
if (pass == 1)
|
||||
continue;
|
||||
/* Format is Symbol, [db|stat], Data */
|
||||
std::string symbol;
|
||||
std::string data;
|
||||
@ -505,17 +630,17 @@ bool Compiler::Parse()
|
||||
CExpr t(CError);
|
||||
t.Set(fill);
|
||||
t.Evaluate();
|
||||
e.Set(amt);
|
||||
e.Evaluate();
|
||||
e = EvalE(amt, Sym_None);
|
||||
DAT->Add(symbol, e, false, t.GetNumber());
|
||||
} else {
|
||||
e.Set(data);
|
||||
e.Evaluate();
|
||||
e = EvalE(data, Sym_None);
|
||||
DAT->Add(symbol, e, false, 0);
|
||||
}
|
||||
}
|
||||
CSymbols->AddSymbol(symbol, Sym_Dat, CurLine());
|
||||
} else if (sec == Asm_Public) {
|
||||
if (pass == 0)
|
||||
continue;
|
||||
if (!IsValidSymbol(line))
|
||||
{
|
||||
CError->ErrorMsg(Err_Invalid_Symbol);
|
||||
@ -538,6 +663,8 @@ bool Compiler::Parse()
|
||||
continue;
|
||||
}
|
||||
} else if (sec == Asm_Native) {
|
||||
if (pass == 1)
|
||||
continue;
|
||||
if (!IsValidSymbol(line))
|
||||
{
|
||||
CError->ErrorMsg(Err_Invalid_Symbol);
|
||||
@ -552,6 +679,8 @@ bool Compiler::Parse()
|
||||
S = CSymbols->AddSymbol(line, Sym_Native, CurLine());
|
||||
CNatives->AddNative(S);
|
||||
} else if (sec == Asm_Code) {
|
||||
if (pass == 0)
|
||||
continue;
|
||||
std::string code;
|
||||
std::string params;
|
||||
SymbolList::Symbol *S;
|
||||
@ -1454,12 +1583,25 @@ bool Compiler::Parse()
|
||||
} /* Line processing */
|
||||
} /* While */
|
||||
|
||||
// go for second pass
|
||||
if (pass == 0)
|
||||
{
|
||||
pass = 1;
|
||||
fclose(fp);
|
||||
if (dopt)
|
||||
DAT->Optimize();
|
||||
goto Start;
|
||||
}
|
||||
|
||||
/* We're not done! Check the label Queue */
|
||||
CLabels->CompleteQueue();
|
||||
|
||||
CError->PrintReport();
|
||||
|
||||
if (CError->GetStatus() >= Err_Error)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1882,13 +2024,22 @@ void Compiler::ProcessDirective(std::string &text)
|
||||
}
|
||||
}
|
||||
|
||||
int Compiler::Eval(std::string &str, SymbolType sym)
|
||||
{
|
||||
CExpr e(CError);
|
||||
|
||||
e = EvalE(str, sym);
|
||||
|
||||
return e.GetNumber();
|
||||
}
|
||||
|
||||
/* The evaluator works by storing expressions on a stack.
|
||||
Each expression is an RPN-ordered pair of lists for ops and values
|
||||
Every time the stack is popped, the expression is evaluated by searching
|
||||
for the highest operators and evaluating them.
|
||||
Note that string literals are not allowed here yet.
|
||||
*/
|
||||
int Compiler::Eval(std::string &str, SymbolType sym)
|
||||
CExpr Compiler::EvalE(std::string &str, SymbolType sym)
|
||||
{
|
||||
std::stack<rpn *> Stack;
|
||||
std::string bpstr;
|
||||
@ -2025,7 +2176,7 @@ int Compiler::Eval(std::string &str, SymbolType sym)
|
||||
delete r;
|
||||
r = 0;
|
||||
|
||||
return final.GetNumber();
|
||||
return final;
|
||||
}
|
||||
|
||||
CExpr Compiler::EvalRpn(rpn *r, SymbolType sym)
|
||||
|
@ -68,16 +68,20 @@ public:
|
||||
int CurCip() { return lastCip; }
|
||||
Asm *CurAsm() { return curAsm; }
|
||||
bool SetDebug();
|
||||
public: //private
|
||||
bool SetPack();
|
||||
bool SetDOpt();
|
||||
int DerefSymbol(std::string &str, SymbolType sym = Sym_None);
|
||||
bool IsSymbol(std::string &str);
|
||||
private:
|
||||
void ProcessDirective(std::string &text);
|
||||
void Init();
|
||||
void InitOpcodes();
|
||||
int Eval(std::string &str, SymbolType sym = Sym_None);
|
||||
CExpr EvalE(std::string &str, SymbolType sym = Sym_None);
|
||||
CExpr EvalRpn(rpn *r, SymbolType sym);
|
||||
OpToken OperToken(char c);
|
||||
char OperChar(OpToken c);
|
||||
bool IsSymbol(std::string &str);
|
||||
void WriteCell(FILE *fp, ucell *c, int repeat);
|
||||
private:
|
||||
std::vector<Asm *> CodeList;
|
||||
std::map<std::string,int> OpCodes;
|
||||
@ -96,6 +100,9 @@ private:
|
||||
int cellsize;
|
||||
int stacksize;
|
||||
bool debug;
|
||||
bool pack;
|
||||
bool dopt;
|
||||
int bitsOut;
|
||||
Asm *curAsm;
|
||||
};
|
||||
|
||||
|
@ -45,6 +45,7 @@ DataMngr::Datum::Datum()
|
||||
db = false;
|
||||
offset = -1;
|
||||
fill = 0;
|
||||
zeroed = false;
|
||||
}
|
||||
|
||||
void DataMngr::Add(std::string &s, CExpr &expr, bool db, int fill)
|
||||
@ -128,3 +129,68 @@ void DataMngr::GetData(std::vector<DataMngr::Datum *> &dList)
|
||||
}
|
||||
}
|
||||
|
||||
void DataMngr::PrintTable()
|
||||
{
|
||||
std::vector<DataMngr::Datum *>::iterator i;
|
||||
DataMngr::Datum *p = 0;
|
||||
|
||||
printf("Symbol\tSize\n");
|
||||
for (i=List.begin(); i!=List.end(); i++)
|
||||
{
|
||||
p = (*i);
|
||||
printf("%s\t%d\n", p->symbol.c_str(), p->offset);
|
||||
}
|
||||
}
|
||||
|
||||
//Rewrite the DAT section so empties are at the end
|
||||
void DataMngr::Optimize()
|
||||
{
|
||||
std::vector<DataMngr::Datum *> DbList;
|
||||
std::vector<DataMngr::Datum *> MtList;
|
||||
std::vector<DataMngr::Datum *>::iterator i;
|
||||
|
||||
for (i=List.begin(); i!=List.end(); i++)
|
||||
{
|
||||
if ( (*i)->db )
|
||||
{
|
||||
DbList.push_back( (*i) );
|
||||
} else if ( (*i)->fill == 0 ) {
|
||||
MtList.push_back( (*i) );
|
||||
} else {
|
||||
DbList.push_back( (*i) );
|
||||
}
|
||||
}
|
||||
|
||||
List.clear();
|
||||
|
||||
lastOffset = 0;
|
||||
cursize = 0;
|
||||
int size = 0;
|
||||
|
||||
for (i=DbList.begin(); i!=DbList.end(); i++)
|
||||
{
|
||||
size = (( (*i)->e.GetType() == Val_Number
|
||||
|| (*i)->e.GetType() == Val_Float ) ?
|
||||
cellsize : (*i)->e.Size() * cellsize);
|
||||
(*i)->offset = lastOffset;
|
||||
lastOffset += size;
|
||||
(*i)->zeroed = false;
|
||||
List.push_back( (*i) );
|
||||
}
|
||||
|
||||
cursize = lastOffset;
|
||||
DbList.clear();
|
||||
|
||||
for (i=MtList.begin(); i!=MtList.end(); i++)
|
||||
{
|
||||
size = ( (*i)->e.GetNumber() * cellsize );
|
||||
(*i)->offset = lastOffset;
|
||||
lastOffset += size;
|
||||
(*i)->zeroed = true;
|
||||
List.push_back( (*i) );
|
||||
}
|
||||
|
||||
MtList.clear();
|
||||
|
||||
optimized = true;
|
||||
}
|
||||
|
@ -35,22 +35,27 @@ public:
|
||||
bool db;
|
||||
int offset;
|
||||
int fill;
|
||||
bool zeroed;
|
||||
};
|
||||
public:
|
||||
~DataMngr();
|
||||
DataMngr() { cellsize = 4; lastOffset = 0; cursize = 0; }
|
||||
DataMngr(int cell) { lastOffset = 0; cellsize = cell; cursize = 0; }
|
||||
DataMngr() { cellsize = 4; lastOffset = 0; cursize = 0; optimized = false; }
|
||||
DataMngr(int cell) { lastOffset = 0; cellsize = cell; cursize = 0; optimized = false; }
|
||||
void Add(std::string &s, CExpr &expr, bool db = false, int fill = 0);
|
||||
DataMngr::Datum *FindData(std::string &sym);
|
||||
void GetData(std::vector<DataMngr::Datum *> &dList);
|
||||
int GetOffset(std::string &sym);
|
||||
int GetSize();
|
||||
void Clear();
|
||||
void PrintTable();
|
||||
void Optimize();
|
||||
bool IsOptimized() { return optimized; }
|
||||
private:
|
||||
std::vector<DataMngr::Datum *> List;
|
||||
int lastOffset;
|
||||
int cellsize;
|
||||
int cursize;
|
||||
bool optimized;
|
||||
public:
|
||||
static const int nof = -1;
|
||||
};
|
||||
|
@ -24,11 +24,10 @@
|
||||
|
||||
std::string filename;
|
||||
std::string output_name;
|
||||
Compiler Program;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Compiler Program;
|
||||
|
||||
{
|
||||
get_options(argc, argv, Program);
|
||||
|
||||
if (filename.size() < 1)
|
||||
@ -76,6 +75,12 @@ void get_options(int argc, char **argv, Compiler &Prog)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'c':
|
||||
{
|
||||
Program.SetPack();
|
||||
opt_flag = 0;
|
||||
break;
|
||||
}
|
||||
case 'v':
|
||||
{
|
||||
opt_flag = 0; /* no options expected */
|
||||
@ -89,6 +94,18 @@ void get_options(int argc, char **argv, Compiler &Prog)
|
||||
Prog.SetDebug();
|
||||
break;
|
||||
}
|
||||
case 'h':
|
||||
{
|
||||
opt_flag = 0;
|
||||
Prog.SetDOpt();
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
{
|
||||
opt_flag = 0;
|
||||
Prog.SetDOpt();
|
||||
Prog.SetPack();
|
||||
}
|
||||
} /* switch */
|
||||
} else { /* - */
|
||||
if (!opt_flag)
|
||||
@ -110,7 +127,7 @@ void get_options(int argc, char **argv, Compiler &Prog)
|
||||
|
||||
void print_version()
|
||||
{
|
||||
printf("Small/AMX Assembler 1.00\n");
|
||||
printf("Small/AMX Assembler 1.01\n");
|
||||
printf("(C)2004 David 'BAILOPAN' Anderson\n");
|
||||
}
|
||||
|
||||
@ -120,5 +137,8 @@ void print_options()
|
||||
printf("\t-d\t\t- Add debug opcodes (will double file size)\n");
|
||||
printf("\t-v\t\t- Output version and exit\n");
|
||||
printf("\t-o\t\t- Specify file to write\n");
|
||||
printf("\t-c\t\t- Enable compact encoding\n");
|
||||
printf("\t-h\t\t- Optimize DAT section\n");
|
||||
printf("\t-f\t\t- Optimal Build\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user