From bc395da6aba83da8403b2123313f0f4b5a0347c0 Mon Sep 17 00:00:00 2001 From: Artur K Date: Sun, 11 Mar 2012 02:48:19 +0100 Subject: [PATCH] lots of changes, created Disassembler class, removed a few globals etc. --- CMakeLists.txt | 2 +- include/Procedure.h | 10 +- include/dcc.h | 2 +- include/disassem.h | 28 ++- include/icode.h | 10 +- include/state.h | 6 +- src/BasicBlock.cpp | 2 + src/backend.cpp | 5 +- src/chklib.cpp | 7 +- src/dataflow.cpp | 13 +- src/disassem.cpp | 208 +++++++++--------- src/frontend.cpp | 5 +- src/graph.cpp | 1 + src/locident.cpp | 6 +- src/parser.cpp | 28 ++- src/procs.cpp | 19 +- src/udm.cpp | 11 +- tests/initial_base/BENCHFN.C | 23 ++ tests/initial_base/BENCHFN.b | 88 ++++++++ tests/initial_base/BENCHLNG.C | 36 +++ tests/initial_base/BENCHLNG.b | 153 +++++++++++++ tests/initial_base/BENCHMUL.C | 30 +++ tests/initial_base/BENCHMUL.b | 36 +++ tests/initial_base/BENCHMUS.b | 36 +++ tests/initial_base/BENCHSHO.C | 37 ++++ tests/initial_base/BENCHSHO.b | 55 +++++ tests/initial_base/BYTEOPS.C | 16 ++ tests/initial_base/BYTEOPS.b | 28 +++ tests/initial_base/DHAMP.C | 223 +++++++++++++++++++ tests/initial_base/DHAMP.b | 391 +++++++++++++++++++++++++++++++++ tests/initial_base/FIBO.C | 29 +++ tests/initial_base/FIBOL.b | 52 +++++ tests/initial_base/FIBOS.b | 51 +++++ tests/initial_base/INTOPS.C | 16 ++ tests/initial_base/INTOPS.b | 33 +++ tests/initial_base/LONGOPS.C | 16 ++ tests/initial_base/LONGOPS.b | 295 +++++++++++++++++++++++++ tests/initial_base/MATRIXMU.C | 18 ++ tests/initial_base/MATRIXMU.b | 46 ++++ tests/initial_base/MAX.C | 15 ++ tests/initial_base/MAX.b | 41 ++++ tests/initial_base/STRLEN.C | 13 ++ tests/initial_base/STRLEN.b | 35 +++ tests/initial_base/TESTLONG.C | 10 + tests/initial_base/TESTLONG.b | 24 ++ tests/inputs_base/BENCHFN.EXE | Bin tests/inputs_base/BENCHLNG.EXE | Bin tests/inputs_base/BENCHMUL.EXE | Bin tests/inputs_base/BENCHMUS.EXE | Bin tests/inputs_base/BENCHSHO.EXE | Bin tests/inputs_base/BYTEOPS.EXE | Bin tests/inputs_base/DHAMP.EXE | Bin 0 -> 32173 bytes tests/inputs_base/FIBOL.EXE | Bin 0 -> 15616 bytes tests/inputs_base/FIBOS.EXE | Bin tests/inputs_base/INTOPS.EXE | Bin 0 -> 8459 bytes tests/inputs_base/LONGOPS.EXE | Bin 0 -> 9017 bytes tests/inputs_base/MATRIXMU.EXE | Bin 0 -> 4677 bytes tests/inputs_base/MAX.EXE | Bin 0 -> 9482 bytes tests/inputs_base/STRLEN.EXE | Bin 0 -> 2348 bytes tests/inputs_base/TESTLONG.EXE | Bin 0 -> 12935 bytes 60 files changed, 2058 insertions(+), 151 deletions(-) create mode 100644 tests/initial_base/BENCHFN.C create mode 100644 tests/initial_base/BENCHFN.b create mode 100644 tests/initial_base/BENCHLNG.C create mode 100644 tests/initial_base/BENCHLNG.b create mode 100644 tests/initial_base/BENCHMUL.C create mode 100644 tests/initial_base/BENCHMUL.b create mode 100644 tests/initial_base/BENCHMUS.b create mode 100644 tests/initial_base/BENCHSHO.C create mode 100644 tests/initial_base/BENCHSHO.b create mode 100644 tests/initial_base/BYTEOPS.C create mode 100644 tests/initial_base/BYTEOPS.b create mode 100644 tests/initial_base/DHAMP.C create mode 100644 tests/initial_base/DHAMP.b create mode 100644 tests/initial_base/FIBO.C create mode 100644 tests/initial_base/FIBOL.b create mode 100644 tests/initial_base/FIBOS.b create mode 100644 tests/initial_base/INTOPS.C create mode 100644 tests/initial_base/INTOPS.b create mode 100644 tests/initial_base/LONGOPS.C create mode 100644 tests/initial_base/LONGOPS.b create mode 100644 tests/initial_base/MATRIXMU.C create mode 100644 tests/initial_base/MATRIXMU.b create mode 100644 tests/initial_base/MAX.C create mode 100644 tests/initial_base/MAX.b create mode 100644 tests/initial_base/STRLEN.C create mode 100644 tests/initial_base/STRLEN.b create mode 100644 tests/initial_base/TESTLONG.C create mode 100644 tests/initial_base/TESTLONG.b mode change 100755 => 100644 tests/inputs_base/BENCHFN.EXE mode change 100755 => 100644 tests/inputs_base/BENCHLNG.EXE mode change 100755 => 100644 tests/inputs_base/BENCHMUL.EXE mode change 100755 => 100644 tests/inputs_base/BENCHMUS.EXE mode change 100755 => 100644 tests/inputs_base/BENCHSHO.EXE mode change 100755 => 100644 tests/inputs_base/BYTEOPS.EXE create mode 100644 tests/inputs_base/DHAMP.EXE create mode 100644 tests/inputs_base/FIBOL.EXE mode change 100755 => 100644 tests/inputs_base/FIBOS.EXE create mode 100644 tests/inputs_base/INTOPS.EXE create mode 100644 tests/inputs_base/LONGOPS.EXE create mode 100644 tests/inputs_base/MATRIXMU.EXE create mode 100644 tests/inputs_base/MAX.EXE create mode 100644 tests/inputs_base/STRLEN.EXE create mode 100644 tests/inputs_base/TESTLONG.EXE diff --git a/CMakeLists.txt b/CMakeLists.txt index 495546d..2ec9b5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)") add_definitions(/W4) else() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x") - SET(CMAKE_CXX_FLAGS_DEBUG "-D_GLIBCXX_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}" ) + #SET(CMAKE_CXX_FLAGS_DEBUG "-D_GLIBCXX_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}" ) endif() FIND_PACKAGE(LLVM) diff --git a/include/Procedure.h b/include/Procedure.h index 8c50cf9..ddc25c7 100644 --- a/include/Procedure.h +++ b/include/Procedure.h @@ -6,15 +6,11 @@ #include "locident.h" #include "state.h" #include "icode.h" -//#include "types.h" -//#include "ast.h" -//#include "error.h" -//#include "graph.h" -//#include "bundle.h" #include "StackFrame.h" /* PROCEDURE NODE */ struct CALL_GRAPH; struct COND_EXPR; +struct Disassembler; namespace llvm { // Traits for intrusive list of basic blocks... @@ -144,7 +140,7 @@ public: void mergeFallThrough(BB *pBB); void structIfs(); void structLoops(derSeq *derivedG); - void buildCFG(); + void buildCFG(Disassembler &ds); void controlFlowAnalysis(); void newRegArg(iICODE picode, iICODE ticode); protected: @@ -153,7 +149,7 @@ protected: void propLongStk(int i, const ID &pLocId); void propLongGlb(int i, const ID &pLocId); void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong); - void processHliCall1(COND_EXPR *exp, iICODE picode); + void processHliCall(COND_EXPR *exp, iICODE picode); int findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE iter); int findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg); diff --git a/include/dcc.h b/include/dcc.h index ffaf4ee..f2c8407 100644 --- a/include/dcc.h +++ b/include/dcc.h @@ -140,7 +140,7 @@ eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c * void parse (CALL_GRAPH * *); /* parser.c */ int strSize (uint8_t *, char); /* parser.c */ -void disassem(int pass, Function * pProc); /* disassem.c */ +//void disassem(int pass, Function * pProc); /* disassem.c */ void interactDis(Function * initProc, int initIC); /* disassem.c */ bool JmpInst(llIcode opcode); /* idioms.c */ queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */ diff --git a/include/disassem.h b/include/disassem.h index 85949da..5bcc7bc 100644 --- a/include/disassem.h +++ b/include/disassem.h @@ -4,10 +4,30 @@ ****************************************************************************/ #pragma once #include +#include #include #include "bundle.h" struct LLInst; +struct Disassembler +{ +protected: + int pass; + int g_lab; + //bundle &cCode; + std::ofstream m_fp; + std::vector m_decls; + std::vector m_code; +public: + Disassembler(int _p) : pass(_p) + { + g_lab=0; + } +public: + void disassem(Function *ppProc); + void disassem(Function *ppProc, int i); + void dis1Line(LLInst &inst, int loc_ip, int pass); +}; /* Definitions for extended keys (first key is zero) */ #define EXT 0x100 /* "Extended" flag */ @@ -24,10 +44,10 @@ struct LLInst; #ifdef _CONSOLE #define KEY_DOWN 0x50 /* Same as keypad scancodes */ #define KEY_LEFT 0x4B -#define KEY_UP 0x48 -#define KEY_RIGHT 0x4D -#define KEY_NPAGE 0x51 -#define KEY_PPAGE 0x49 +#define KEY_UP 0x48 +#define KEY_RIGHT 0x4D +#define KEY_NPAGE 0x51 +#define KEY_PPAGE 0x49 #endif #ifdef __UNIX__ diff --git a/include/icode.h b/include/icode.h index c2dc8d9..c67287d 100644 --- a/include/icode.h +++ b/include/icode.h @@ -261,9 +261,11 @@ public: bool isJmpInst(); HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func); HLTYPE createCall(); - LLInst(ICODE *container) : m_link(container),flg(0) + LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container) { - + caseTbl.entries=0; + caseTbl.numEntries=0; + setOpcode(0); } ICODE *m_link; }; @@ -331,7 +333,9 @@ public: Use &u(idx[regIdx]); u.removeUser(ic); } - DU1() : numRegsDef(0) {} + DU1() : numRegsDef(0) + { + } }; icodeType type; /* Icode type */ BB *inBB; /* BB to which this icode belongs */ diff --git a/include/state.h b/include/state.h index 6377374..003720d 100644 --- a/include/state.h +++ b/include/state.h @@ -10,9 +10,9 @@ /* STATE TABLE */ struct STATE { - uint32_t IP; /* Offset into Image */ + uint32_t IP; /* Offset into Image */ int16_t r[INDEX_BX_SI]; /* Value of segs and AX */ - uint8_t f[INDEX_BX_SI]; /* True if r[.] has a value */ + bool f[INDEX_BX_SI]; /* True if r[.] has a value */ struct { /* For case stmt indexed reg */ uint8_t regi; /* Last conditional jump */ @@ -20,6 +20,8 @@ struct STATE } JCond; void setState(uint16_t reg, int16_t value); void checkStartup(); + bool isKnown(eReg v) {return f[v];} + void kill(eReg v) { f[v]=false;} STATE() : IP(0) { JCond.regi=0; diff --git a/src/BasicBlock.cpp b/src/BasicBlock.cpp index 779820b..032ba2e 100644 --- a/src/BasicBlock.cpp +++ b/src/BasicBlock.cpp @@ -106,12 +106,14 @@ void BB::displayDfs() } } /* Display out edges information */ + i=0; for(TYPEADR_TYPE &edg : edges) { if (nodeType == INTERVAL_NODE) printf(" outEdge[%ld] = %ld\n", i, edg.BBptr->correspInt->numInt); else printf(" outEdge[%d] = %ld\n", i, edg.BBptr->begin()->loc_ip); + ++i; } printf("----\n"); diff --git a/src/backend.cpp b/src/backend.cpp index 792d2a3..37dc9c9 100644 --- a/src/backend.cpp +++ b/src/backend.cpp @@ -264,7 +264,10 @@ void Function::codeGen (std::ostream &fs) } /* Write procedure's code */ if (flg & PROC_ASM) /* generate assembler */ - disassem (3, this); + { + Disassembler ds(3); + ds.disassem(this); + } else /* generate C */ { m_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT); diff --git a/src/chklib.cpp b/src/chklib.cpp index b7cbd45..123755a 100644 --- a/src/chklib.cpp +++ b/src/chklib.cpp @@ -455,8 +455,8 @@ bool LibCheck(Function & pProc) pProc.name = "main"; return false; } - - memmove(pat, &prog.Image[fileOffset], PATLEN); + memcpy(pat, &prog.Image[fileOffset], PATLEN); + //memmove(pat, &prog.Image[fileOffset], PATLEN); fixWildCards(pat); /* Fix wild cards in the copy */ h = g_pattern_hasher.hash(pat); /* Hash the found proc */ /* We always have to compare keys, because the hash function will @@ -856,8 +856,7 @@ gotVendor: by dcc, rather than considered as known functions. When a prototype is found (in searchPList()), the parameter info is written to the proc struct. */ -void -readProtoFile(void) +void readProtoFile(void) { FILE *fProto; char *pPath; /* Point to the environment string */ diff --git a/src/dataflow.cpp b/src/dataflow.cpp index 411d9f4..6b49e8e 100644 --- a/src/dataflow.cpp +++ b/src/dataflow.cpp @@ -333,7 +333,7 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) /* user/runtime routine */ if (! (pcallee->flg & PROC_ISLIB)) { - if (pcallee->liveAnal == FALSE) /* hasn't been processed */ + if (pcallee->liveAnal == false) /* hasn't been processed */ pcallee->dataFlow (pbb->liveOut); pbb->liveOut = pcallee->liveIn; } @@ -691,14 +691,13 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, int num } else adjustActArgType (_exp, pp->args.sym[numArgs].type, pProc); - res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc); } else /* user function */ { if (pp->args.numArgs > 0) pp->args.adjustForArgType (numArgs, expType (_exp, pProc)); - res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc); } + res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc); /* Do not update the size of k if the expression was a segment register * in a near call */ @@ -757,7 +756,7 @@ void Function::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode } } -void Function::processHliCall1(COND_EXPR *_exp, iICODE picode) +void Function::processHliCall(COND_EXPR *_exp, iICODE picode) { Function * pp; int cb, numArgs; @@ -957,10 +956,12 @@ void Function::findExps() /* Check for only one use of these registers */ if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1)) { + regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this + switch (picode->hl()->opcode) { case HLI_ASSIGN: /* Replace rhs of current icode into target - * icode expression */ + * icode expression */ if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) { ticode = picode->du1.idx[0].uses.front(); @@ -1061,7 +1062,7 @@ void Function::findExps() if ((picode->hl()->opcode == HLI_CALL) && ! (picode->hl()->call.proc->flg & REG_ARGS)) { - processHliCall1(_exp, picode); + processHliCall(_exp, picode); } /* If we could not substitute the result of a function, diff --git a/src/disassem.cpp b/src/disassem.cpp index aefb9d4..f4e8e38 100644 --- a/src/disassem.cpp +++ b/src/disassem.cpp @@ -109,7 +109,7 @@ static const char *szFlops3C[] = static const char *szPtr[2] = { "word ptr ", "byte ptr " }; -void dis1LineOp(int i, boolT fWin, char attr, uint16_t *len, Function * pProc); +//void dis1LineOp(int i, boolT fWin, char attr, uint16_t *len, Function * pProc); static void formatRM(ostringstream &p, uint32_t flg, const LLOperand &pm); static ostringstream &strDst(ostringstream &os, uint32_t flg, LLOperand &pm); @@ -119,13 +119,13 @@ static void setProc(Function * proc); static void dispData(uint16_t dataSeg); boolT callArg(uint16_t off, char *temp); /* Check for procedure name */ -static FILE *fp; +//static FILE *dis_g_fp; static CIcodeRec pc; static int cb, j, numIcode, allocIcode; static map pl; static uint32_t nextInst; static boolT fImpure; -static int g_lab, prevPass; +//static int g_lab; static Function * pProc; /* Points to current proc struct */ struct POSSTACK_ENTRY @@ -173,16 +173,12 @@ void LLInst::findJumpTargets(CIcodeRec &_pc) * pass == 2 generates output on file .a2 * pass == 3 generates output on file .b ****************************************************************************/ -void disassem(int pass, Function * ppProc) + +void Disassembler::disassem(Function * ppProc) { pProc = ppProc; /* Save the passes pProc */ - if (pass != prevPass) - { - prevPass = pass; - g_lab = 0; /* Restart label numbers */ - } createSymTables(); allocIcode = numIcode = pProc->Icode.size(); cb = allocIcode * sizeof(ICODE); @@ -195,8 +191,8 @@ void disassem(int pass, Function * ppProc) if (pass != 3) { auto p = (pass == 1)? asm1_name: asm2_name; - fp = fopen(p, "a+"); - if (!fp) + m_fp.open(p,ios_base::app); + if (!m_fp.is_open()) { fatalError(CANNOT_OPEN, p); } @@ -222,20 +218,23 @@ void disassem(int pass, Function * ppProc) /* Write procedure header */ if (pass != 3) - fprintf(fp, "\t\t%s PROC %s\n", pProc->name.c_str(), (pProc->flg & PROC_FAR)? "FAR": "NEAR"); + { + std::string near_far=(pProc->flg & PROC_FAR)? "FAR": "NEAR"; + m_fp << "\t\t"<name<<" PROC "<< near_far<<"\n"; + } /* Loop over array printing each record */ nextInst = 0; for( ICODE &icode : pc) { - icode.ll()->dis1Line(icode.loc_ip,pass); + this->dis1Line(*icode.ll(),icode.loc_ip,pass); } /* Write procedure epilogue */ if (pass != 3) { - fprintf(fp, "\n\t\t%s ENDP\n\n", pProc->name.c_str()); - fclose(fp); + m_fp << "\n\t\t"<name<<" ENDP\n\n"; + m_fp.close(); } pc.clear(); @@ -246,51 +245,50 @@ void disassem(int pass, Function * ppProc) * i is index into Icode for this proc * * It is assumed that icode i is already scanned * ****************************************************************************/ -void LLInst::dis1Line(int loc_ip, int pass) +void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass) { ostringstream oper_stream; ostringstream hex_bytes; ostringstream result_stream; ostringstream opcode_with_mods; ostringstream operands_s; - oper_stream << uppercase; hex_bytes << uppercase; /* Disassembly stage 1 -- * Do not try to display NO_CODE entries or synthetic instructions, * other than JMPs, that have been introduced for def/use analysis. */ if ((option.asm1) && - ( this->testFlags(NO_CODE) || - (this->testFlags(SYNTHETIC) && (this->getOpcode() != iJMP)))) + ( inst.testFlags(NO_CODE) || + (inst.testFlags(SYNTHETIC) && (inst.getOpcode() != iJMP)))) { return; } - else if (this->testFlags(NO_CODE)) + else if (inst.testFlags(NO_CODE)) { return; } - if (this->testFlags(TARGET | CASE)) + if (inst.testFlags(TARGET | CASE)) { if (pass == 3) cCode.appendCode("\n"); /* Print to c code buffer */ else - fprintf(fp, "\n"); /* No, print to the stream */ + m_fp<< "\n"; /* No, print to the stream */ } /* Find next instruction label and print hex bytes */ - if (this->testFlags(SYNTHETIC)) - nextInst = this->label; + if (inst.testFlags(SYNTHETIC)) + nextInst = inst.label; else { - cb = (uint32_t) this->numBytes; - nextInst = this->label + cb; + cb = (uint32_t) inst.numBytes; + nextInst = inst.label + cb; /* Output hexa code in program image */ if (pass != 3) { for (j = 0; j < cb; j++) { - hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[this->label + j]); + hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[inst.label + j]); } hex_bytes << ' '; } @@ -301,11 +299,11 @@ void LLInst::dis1Line(int loc_ip, int pass) oper_stream << setw(5)<label, 0)) + if (readVal(lab_contents, inst.label, 0)) { lab_contents << ':'; /* Also removes the null */ } - else if (this->testFlags(TARGET)) /* Symbols override Lnn labels */ + else if (inst.testFlags(TARGET)) /* Symbols override Lnn labels */ { /* Print label */ if (pl.count(loc_ip)==0) @@ -316,62 +314,62 @@ void LLInst::dis1Line(int loc_ip, int pass) } oper_stream<< lab_contents.str(); } - if ((this->getOpcode()==iSIGNEX )&& this->testFlags(B)) + if ((inst.getOpcode()==iSIGNEX )&& inst.testFlags(B)) { - setOpcode(iCBW); + inst.setOpcode(iCBW); } - opcode_with_mods<getOpcode()); + opcode_with_mods<getOpcode() ) + switch ( inst.getOpcode() ) { case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR: case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG: - strDst(operands_s,getFlag(), dst); - strSrc(operands_s); + strDst(operands_s,inst.getFlag(), inst.dst); + inst.strSrc(operands_s); break; case iESC: - flops(operands_s); + inst.flops(operands_s); break; case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL: case iROR: - strDst(operands_s,getFlag() | I, dst); - if(testFlags(I)) - strSrc(operands_s); + strDst(operands_s,inst.getFlag() | I, inst.dst); + if(inst.testFlags(I)) + inst.strSrc(operands_s); else operands_s<<", cl"; break; case iINC: case iDEC: case iNEG: case iNOT: case iPOP: - strDst(operands_s,getFlag() | I, dst); + strDst(operands_s,inst.getFlag() | I, inst.dst); break; case iPUSH: - if (testFlags(I)) + if (inst.testFlags(I)) { - operands_s<ll()->label, 0)) { break; /* Symbolic label. Done */ } } - if (testFlags(NO_LABEL)) + if (inst.testFlags(NO_LABEL)) { //strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op)); - operands_s<name; + operands_s<<" ptr "<<(inst.src.proc.proc)->name; } - else if (getOpcode() == iCALLF) + else if (inst.getOpcode() == iCALLF) { operands_s<<"dword ptr "; - strSrc(operands_s,true); + inst.strSrc(operands_s,true); } else - strDst(operands_s,I, src); + strDst(operands_s,I, inst.src); break; case iENTER: - operands_s< 0 && j < (int)nextInst; j++) + for (j = inst.label, fImpure = 0; j > 0 && j < (int)nextInst; j++) { fImpure |= BITMAP(j, BM_DATA); } @@ -527,17 +525,17 @@ void LLInst::dis1Line(int loc_ip, int pass) /* Check for user supplied comment */ selectTable(Comment); ostringstream cbuf; - if (readVal(cbuf, label, 0)) + if (readVal(cbuf, inst.label, 0)) { result_stream <<"; "<testFlags(SYM_USE | SYM_DEF)) continue; + assert(icod.ll()->caseTbl.numEntriescaseTbl.numEntries]; for (int c = (int)psym->label; c < (int)psym->label+psym->size; c++) { diff --git a/src/locident.cpp b/src/locident.cpp index d964acd..bc4fbd8 100644 --- a/src/locident.cpp +++ b/src/locident.cpp @@ -70,17 +70,17 @@ void LOCAL_ID::flagByteWordId (int off) int idx; auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool { //if (((en.type == TYPE_WORD_SIGN) || (en.type == TYPE_BYTE_SIGN)) && - if ((en.isSigned()) && + if ((en.typeBitsize()<=16) && (en.id.bwId.off == off) && (en.id.bwId.regOff == 0)) return true; return false; }); if(found==id_arr.end()) { - printf("Entry not found in LOCAL_ID::flagByteWordId \n"); + printf("No entry to flag as invalid in LOCAL_ID::flagByteWordId \n"); return; } - found->illegal = TRUE; + found->illegal = true; } /* Creates a new stack identifier node of TYPE_BYTE_(UN)SIGN or diff --git a/src/parser.cpp b/src/parser.cpp index f4e754b..e7fe00a 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -294,6 +294,8 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) case iCALL: case iCALLF: done = process_CALL (*pIcode, pcallGraph, pstate); + pstate->kill(rBX); + pstate->kill(rCX); break; /*** Returns ***/ @@ -483,6 +485,7 @@ boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGr pIcode.ll()->setFlags(SWITCH); pIcode.ll()->caseTbl.numEntries = (endTable - offTable) / 2; + assert(pIcode.ll()->caseTbl.numEntries<512); psw = (uint32_t*)allocMem(pIcode.ll()->caseTbl.numEntries*sizeof(uint32_t)); pIcode.ll()->caseTbl.entries = psw; @@ -543,7 +546,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps So we just exit this function, and ignore the call. We probably should not have parsed this deep, anyway. */ - return FALSE; + return false; } /* Offset into program image is seg:off of read input */ @@ -551,9 +554,26 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps es:0 where es:0 is the start of the image. This is usually wrong! Consider also CALL [BP+0E] in which the segment for the pointer is in SS! - Mike */ + if(pIcode.ll()->dst.isReg()) + { + if( not pstate->isKnown(pIcode.ll()->dst.regi) + or + not pstate->isKnown(pIcode.ll()->dst.seg) + ) + { + fprintf(stderr,"Indirect call with unkown register values\n"); + return false; + } + off = pstate->r[pIcode.ll()->dst.seg]; + off <<=4; + off += pstate->r[pIcode.ll()->dst.regi]; - off = (uint32_t)(uint16_t)pIcode.ll()->dst.off + - ((uint32_t)(uint16_t)pIcode.ll()->dst.segValue << 4); + } + else + { + off = (uint32_t)(uint16_t)pIcode.ll()->dst.off + + ((uint32_t)(uint16_t)pIcode.ll()->dst.segValue << 4); + } /* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at * previous offset into the program image */ @@ -564,7 +584,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps tgtAddr= LH(&prog.Image[off]) + (uint32_t)(uint16_t)state.r[rCS] << 4; pIcode.ll()->src.SetImmediateOp( tgtAddr ); pIcode.ll()->setFlags(I); - indirect = TRUE; + indirect = true; } /* Process CALL. Function address is located in pIcode.ll()->immed.op */ diff --git a/src/procs.cpp b/src/procs.cpp index 26110fa..4087d10 100644 --- a/src/procs.cpp +++ b/src/procs.cpp @@ -126,7 +126,8 @@ void Function::newRegArg(iICODE picode, iICODE ticode) { regL = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l; regH = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.h; - tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, Icode.begin() /*0*/); + tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/); + //tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, Icode.begin() /*0*/); } /* Check if register argument already on the formal argument list */ @@ -320,20 +321,24 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_) /* Find stack offset for this argument */ off = m_minOff; for (i = 0; i < numArg_; i++) + { + if(i>=sym.size()) + { + break; //TODO: verify + } off += sym[i].size; + } /* Find formal argument */ if (numArg_ < sym.size()) { psym = &sym[numArg_]; i = numArg_; - while ((i < sym.size()) && (psym->off != off)) - { - psym++; - i++; - } - if (numArg_ == sym.size()) + //auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;}); + auto iter=std::find_if(sym.begin()+numArg_,sym.end(),[off](STKSYM &s)->bool {s.off==off;}); + if(iter==sym.end()) // symbol not found return; + psym = &(*iter); } /* If formal argument does not exist, do not create new ones, just * ignore actual argument diff --git a/src/udm.cpp b/src/udm.cpp index 9334b2d..a30c75f 100644 --- a/src/udm.cpp +++ b/src/udm.cpp @@ -8,6 +8,7 @@ #include #include #include "dcc.h" +#include "disassem.h" static void displayCFG(Function * pProc); static void displayDfs(BB * pBB); @@ -15,7 +16,7 @@ static void displayDfs(BB * pBB); /**************************************************************************** * udm ****************************************************************************/ -void Function::buildCFG() +void Function::buildCFG(Disassembler &ds) { if(flg & PROC_ISLIB) return; // Ignore library functions @@ -26,7 +27,9 @@ void Function::buildCFG() compressCFG(); // Remove redundancies and add in-edge information if (option.asm2) - disassem(2, this); // Print 2nd pass assembler listing + { + ds.disassem(this); // Print 2nd pass assembler listing + } /* Idiom analysis and propagation of long type */ lowLevelAnalysis(); @@ -67,11 +70,13 @@ void udm(void) /* Build the control flow graph, find idioms, and convert low-level * icodes to high-level ones */ + Disassembler ds(2); for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter) { - iter->buildCFG(); + iter->buildCFG(ds); } + /* Data flow analysis - eliminate condition codes, extraneous registers * and intermediate instructions. Find expressions by forward * substitution algorithm */ diff --git a/tests/initial_base/BENCHFN.C b/tests/initial_base/BENCHFN.C new file mode 100644 index 0000000..a649395 --- /dev/null +++ b/tests/initial_base/BENCHFN.C @@ -0,0 +1,23 @@ +/* benchfn - benchmark for function calls + * Thomas Plum, Plum Hall Inc, 609-927-3770 + * Let T be the execution time in milliseconds + * Then average time per operator = T/major usec + * (Because the inner loop has exactly 1000 operations) + */ +#include + +f3() { ;} +f2() { f3();f3();f3();f3();f3();f3();f3();f3();f3();f3();} /* 10 */ +f1() { f2();f2();f2();f2();f2();f2();f2();f2();f2();f2();} /* 10 */ +f0() { f1();f1();f1();f1();f1();f1();f1();f1();f1();} /* 9 */ + +main(int ac, char *av[]) +{ long d, major; + + printf ("enter number of iterations "); + scanf ("%ld", &major); + printf("executing %ld iterations\n", major); + for (d = 1; d <= major; ++d) + f0(); /* executes 1000 calls */ + printf ("finished\n"); +} \ No newline at end of file diff --git a/tests/initial_base/BENCHFN.b b/tests/initial_base/BENCHFN.b new file mode 100644 index 0000000..c357a04 --- /dev/null +++ b/tests/initial_base/BENCHFN.b @@ -0,0 +1,88 @@ +/* + * Input file : test\benchfn.exe + * File type : EXE + */ + +#include "dcc.h" + + +void proc_4 () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +} + + +void proc_3 () +/* Takes no parameters. + * High-level language prologue code. + */ +{ + proc_4 (); + proc_4 (); + proc_4 (); + proc_4 (); + proc_4 (); + proc_4 (); + proc_4 (); + proc_4 (); + proc_4 (); + proc_4 (); +} + + +void proc_2 () +/* Takes no parameters. + * High-level language prologue code. + */ +{ + proc_3 (); + proc_3 (); + proc_3 (); + proc_3 (); + proc_3 (); + proc_3 (); + proc_3 (); + proc_3 (); + proc_3 (); + proc_3 (); +} + + +void proc_1 () +/* Takes no parameters. + * High-level language prologue code. + */ +{ + proc_2 (); + proc_2 (); + proc_2 (); + proc_2 (); + proc_2 (); + proc_2 (); + proc_2 (); + proc_2 (); + proc_2 (); +} + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +long loc1; +long loc2; + + printf ("enter number of iterations "); + scanf ("%ld", &loc0); + printf ("executing %ld iterations\n", loc2); + loc1 = 1; + while ((loc1 <= loc2)) { + proc_1 (); + loc1 = (loc1 + 1); + } + printf ("finished\n"); +} + diff --git a/tests/initial_base/BENCHLNG.C b/tests/initial_base/BENCHLNG.C new file mode 100644 index 0000000..2d33f1c --- /dev/null +++ b/tests/initial_base/BENCHLNG.C @@ -0,0 +1,36 @@ +/* benchlng - benchmark for long integers + * Thomas Plum, Plum Hall Inc, 609-927-3770 + * If machine traps overflow, use an unsigned type + * Let T be the execution time in milliseconds + * Then average time per operator = T/major usec + * (Because the inner loop has exactly 1000 operations) + */ +#define STOR_CL auto +#define TYPE long +#include +main(int ac, char *av[]) +{ TYPE a, b, c; + long d, major; + + scanf ("%ld", &major); + printf("executing %ld iterations\n", major); + scanf ("%ld", &a); + scanf ("%ld", &b); + for (d = 1; d <= major; ++d) + { + /* inner loop executes 1000 selected operations */ + for (c = 1; c <= 40; ++c) + { + a = a + b + c; + b = a >> 1; + a = b % 10; + a = b == c; + b = a | c; + a = !b; + b = a + c; + a = b > c; + } + } + printf("a=%d\n", a); +} + \ No newline at end of file diff --git a/tests/initial_base/BENCHLNG.b b/tests/initial_base/BENCHLNG.b new file mode 100644 index 0000000..ddd3de1 --- /dev/null +++ b/tests/initial_base/BENCHLNG.b @@ -0,0 +1,153 @@ +/* + * Input file : test\benchlng.exe + * File type : EXE + */ + +#include "dcc.h" + + +long LMOD@ (long arg0, int arg2int arg3) +/* Takes 8 bytes of parameters. + * Runtime support routine of the compiler. + * Untranslatable routine. Assembler provided. + * Return value in registers dx:ax. + * Pascal calling convention. + */ +{ + MOV cx, 2 + PUSH bp + PUSH si + PUSH di + MOV bp, sp + MOV di, cx + MOV ax, [bp+0Ah] + MOV dx, [bp+0Ch] + MOV bx, [bp+0Eh] + MOV cx, [bp+10h] + CMP cx, 0 + JNE L1 + OR dx, dx + JE L2 + OR bx, bx + JE L2 + +L1: TEST di, 1 + JNE L3 + OR dx, dx + JNS L4 + NEG dx + NEG ax + SBB dx, 0 + OR di, 0Ch + +L4: OR cx, cx + JNS L3 + NEG cx + NEG bx + SBB cx, 0 + XOR di, 4 + +L3: MOV bp, cx + MOV cx, 20h + PUSH di + XOR di, 0 + XOR si, 0 + +L5: SHL ax, 1 + RCL dx, 1 + RCL si, 1 + RCL di, 1 + CMP di, bp + JB L6 + JA L7 + CMP si, bx + JB L6 + +L7: SUB si, bx + SBB di, bp + INC ax + +L6: LOOP L5 + POP bx + TEST bx, 2 + JE L8 + MOV ax, si + MOV dx, di + SHR bx, 1 + +L8: TEST bx, 4 + JE L9 + NEG dx + NEG ax + SBB dx, 0 + +L9: POP di + POP si + POP bp + RETF 8 + +L2: MOV tmp, dx:ax ;Synthetic inst + DIV bx + MOD bx ;Synthetic inst + TEST di, 2 + JE L10 + MOV ax, dx + +L10: XOR dx, dx + JMP L9 +} + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +long loc1; +long loc2; +long loc3; +long loc4; +long loc5; +int loc6; /* ax */ + + scanf ("%ld", &loc0); + printf ("executing %ld iterations\n", loc5); + scanf ("%ld", &loc2); + scanf ("%ld", &loc3); + loc3 = 1; + while ((loc3 <= loc5)) { + loc2 = 1; + while ((loc2 <= 40)) { + loc4 = ((loc4 + loc1) + loc2); + loc1 = (loc4 >> 1); + loc4 = LMOD@ (loc1, 10); + if (loc1 == loc2) { + loc6 = 1; + } + else { + loc6 = 0; + } + loc4 = loc6; + loc1 = (loc4 | loc2); + if ((loc3 | loc9) == 0) { + loc6 = 1; + } + else { + loc6 = 0; + } + loc4 = loc6; + loc1 = (loc4 + loc2); + if (loc1 > loc2) { + loc6 = 1; + } + else { + loc6 = 0; + } + loc4 = loc6; + loc2 = (loc2 + 1); + } + loc3 = (loc3 + 1); + } + printf ("a=%d\n", loc4); +} + diff --git a/tests/initial_base/BENCHMUL.C b/tests/initial_base/BENCHMUL.C new file mode 100644 index 0000000..e769612 --- /dev/null +++ b/tests/initial_base/BENCHMUL.C @@ -0,0 +1,30 @@ +/* benchmul - benchmark for int multiply + * Thomas Plum, Plum Hall Inc, 609-927-3770 + * If machine traps overflow, use an unsigned type + * Let T be the execution time in milliseconds + * Then average time per operator = T/major usec + * (Because the inner loop has exactly 1000 operations) + */ +#define STOR_CL auto +#define TYPE int +#include +main(int ac, char *av[]) +{ STOR_CL TYPE a, b, c; + long d, major; + + printf ("enter number of iterations\n"); + scanf ("%ld", &major); + printf("executing %ld iterations\n", major); + scanf ("%d", &a); + scanf ("%d", &b); + for (d = 1; d <= major; ++d) + { + /* inner loop executes 1000 selected operations */ + for (c = 1; c <= 40; ++c) + { + a = 3 *a*a*a*a*a*a*a*a * a*a*a*a*a*a*a*a * a*a*a*a*a*a*a*a * a; /* 25 * */ + } + } + printf("a=%d\n", a); + } + \ No newline at end of file diff --git a/tests/initial_base/BENCHMUL.b b/tests/initial_base/BENCHMUL.b new file mode 100644 index 0000000..0418ca3 --- /dev/null +++ b/tests/initial_base/BENCHMUL.b @@ -0,0 +1,36 @@ +/* + * Input file : test\benchmul.exe + * File type : EXE + */ + +#include "dcc.h" + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +int loc1; +int loc2; +long loc3; +long loc4; +int loc5; + + printf ("enter number of iterations\n"); + scanf ("%ld", &loc0); + printf ("executing %ld iterations\n", loc4); + scanf ("%d", &loc1); + scanf ("%d", &loc2); + loc3 = 1; + while ((loc3 <= loc4)) { + loc5 = 1; + while ((loc5 <= 40)) { + loc1 = (((((((((((((((((((((((((loc1 * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * loc1) * 3); + loc5 = (loc5 + 1); + } + loc3 = (loc3 + 1); + } + printf ("a=%d\n", loc1); +} + diff --git a/tests/initial_base/BENCHMUS.b b/tests/initial_base/BENCHMUS.b new file mode 100644 index 0000000..8f271ea --- /dev/null +++ b/tests/initial_base/BENCHMUS.b @@ -0,0 +1,36 @@ +/* + * Input file : test\benchmus.exe + * File type : EXE + */ + +#include "dcc.h" + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +int loc1; +long loc2; +long loc3; +int loc4; +int loc5; + + printf ("enter number of iterations\n"); + scanf ("%ld", &loc0); + printf ("executing %ld iterations\n", loc3); + loc4 = 20; + loc1 = loc4; + loc2 = 1; + while ((loc2 <= loc3)) { + loc5 = 1; + while ((loc5 <= 40)) { + loc4 = (((((((((((((((((((((((((loc4 * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * loc4) * 3); + loc5 = (loc5 + 1); + } + loc2 = (loc2 + 1); + } + printf ("a=%d\n", loc4); +} + diff --git a/tests/initial_base/BENCHSHO.C b/tests/initial_base/BENCHSHO.C new file mode 100644 index 0000000..778674f --- /dev/null +++ b/tests/initial_base/BENCHSHO.C @@ -0,0 +1,37 @@ +/* benchsho - benchmark for short integers + * Thomas Plum, Plum Hall Inc, 609-927-3770 + * If machine traps overflow, use an unsigned type + * Let T be the execution time in milliseconds + * Then average time per operator = T/major usec + * (Because the inner loop has exactly 1000 operations) + */ +#define STOR_CL auto +#define TYPE short +#include + +main(int ac, char *av[]) +{ STOR_CL TYPE a, b, c; + long d, major; + + scanf ("%ld", &major); + printf("executing %ld iterations\n", major); + scanf ("%ld", &a); + scanf ("%ld", &b); + for (d = 1; d <= major; ++d) + { + /* inner loop executes 1000 selected operations */ + for (c = 1; c <= 40; ++c) + { + a = a + b + c; + b = a >> 1; + a = b % 10; + a = b == c; + b = a | c; + a = !b; + b = a + c; + a = b > c; + } + } + printf("a=%d\n", a); + } + \ No newline at end of file diff --git a/tests/initial_base/BENCHSHO.b b/tests/initial_base/BENCHSHO.b new file mode 100644 index 0000000..7ef9eb3 --- /dev/null +++ b/tests/initial_base/BENCHSHO.b @@ -0,0 +1,55 @@ +/* + * Input file : test\benchsho.exe + * File type : EXE + */ + +#include "dcc.h" + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +int loc1; +int loc2; +int loc3; +long loc4; +long loc5; +int loc6; /* ax */ + + scanf ("%ld", &loc0); + printf ("executing %ld iterations\n", loc5); + scanf ("%ld", &loc1); + scanf ("%ld", &loc2); + loc4 = 1; + while ((loc4 <= loc5)) { + loc3 = 1; + while ((loc3 <= 40)) { + loc1 = ((loc1 + loc2) + loc3); + loc2 = (loc1 >> 1); + loc1 = (loc2 % 10); + if (loc2 == loc3) { + loc6 = 1; + } + else { + loc6 = 0; + } + loc1 = loc6; + loc2 = (loc1 | loc3); + loc1 = !loc2; + loc2 = (loc1 + loc3); + if (loc2 > loc3) { + loc6 = 1; + } + else { + loc6 = 0; + } + loc1 = loc6; + loc3 = (loc3 + 1); + } + loc4 = (loc4 + 1); + } + printf ("a=%d\n", loc1); +} + diff --git a/tests/initial_base/BYTEOPS.C b/tests/initial_base/BYTEOPS.C new file mode 100644 index 0000000..a414118 --- /dev/null +++ b/tests/initial_base/BYTEOPS.C @@ -0,0 +1,16 @@ +#define TYPE unsigned char + +main() +{ TYPE a, b; + + a = 255; + b = 143; + b = a + b; + a = a - b; + a = a * b; + b = b / a; + b = b % a; + a = a << 5; + b = b >> a; + printf ("a = %d, b = %d\n", a, b); +} \ No newline at end of file diff --git a/tests/initial_base/BYTEOPS.b b/tests/initial_base/BYTEOPS.b new file mode 100644 index 0000000..890c393 --- /dev/null +++ b/tests/initial_base/BYTEOPS.b @@ -0,0 +1,28 @@ +/* + * Input file : test\byteops.exe + * File type : EXE + */ + +#include "dcc.h" + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +int loc1; +int loc2; + + loc1 = 255; + loc2 = 143; + loc2 = (loc1 + loc2); + loc1 = (loc1 - loc2); + loc1 = (loc1 * loc2); + loc2 = (loc2 / loc1); + loc2 = (loc2 % loc1); + loc1 = (loc1 << 5); + loc2 = (loc2 >> loc1); + printf ("a = %d, b = %d\n", loc1, loc2); +} + diff --git a/tests/initial_base/DHAMP.C b/tests/initial_base/DHAMP.C new file mode 100644 index 0000000..634b67a --- /dev/null +++ b/tests/initial_base/DHAMP.C @@ -0,0 +1,223 @@ +/* The dhampstone benchmark. Written by Jack purdum. */ +/* version 1.0, August 1,1985 */ + +#include "stdio.h" + +#define BELL 7 /* ASCII BELL code */ +#define FIB 24 +#define TINY 100 +#define MAXINT 179 +#define LITTLE 1000 +#define SMALL 9000 +#define PRECISION .000001 +#define FILENAME "zyxw.vut" +#define NUMTEST 6 + +#ifndef ERR + #define ERR -1 +#endif + +struct + { + int cresult; + int iresult; + int cprsult; + unsigned uresult; + long lresult; + double dresult; + } results; + +main() +{ +char buf1[TINY], buf2[TINY]; +int i = 0; +unsigned fib (); +long square, sq (); +double dmath, sroot (), dply (); + +printf("Start...%c\n\n",BELL); +while (i < NUMTEST) + { + switch (i) + { + case (0): /* Character test */ + results.cresult = stest (buf1,buf2); + printf ("\ncresult = %d\n",results.cresult); + break; + case (1): /* Integer test */ + results.iresult = intest (); + printf ("\niresult = %d\n",results.iresult); + break; + case (2): /* Unsigned test */ + results.uresult = fib (FIB); + printf ("\nuresult = %u\n",results.uresult); + break; + case (3): /* Long test */ + square = 0L; + results.lresult = sq (square); + square = sq (results.lresult); /* Check the value */ + printf ("\nlresult = %ld",results.lresult); + printf ("\n square = %ld\n",square); + break; + case (4): /* Double test */ + results.dresult = sroot ((double) results.lresult); + printf ("\ndresult = %f\n",results.dresult); + dmath = dply (results.dresult); + printf (" dmath = %f\n",dmath); + break; + case (5): /* Disk copy */ + results.cprsult = mcopy (); + printf ("\b copy = %d",results.cprsult); + break; + default: + break; + } + ++i; + } /* End while i */ +printf ("\n\n...End%c",BELL); +} + +long sq (big) /* Function to square a number by iteration */ +long big; +{ +int i; +static long j = 1L; + +if (!big) + for (i = 0; i < SMALL; ++i) + { + big += j; + j += 2; + } +else + for (i = 0; i < SMALL; ++i) + { + j -= 2; + big -= j; + } +return (big); +} + +double sroot (num) /* Find square root of number */ +double num; +{ +double temp1, temp2, abs (); + +temp2 = num / 2.0; +temp1 = num; +while (temp1 > PRECISION * temp2) + { + temp1 = (num / temp2) - temp2; + temp1 = abs (temp1); + temp2 = ((num / temp2) + temp2) / 2.0; + } +return (temp2); +} + +double abs (x) /* Absolute value of a double */ +double x; +{ + +return (x < 0 ? -x : x); +} + +double dply (x) /* Exercise some doubles */ +double x; +{ +int i = TINY; +double y; + +while (i--) + { + y = x * x * x * x * x * x * x; + y = y / x / x / x / x / x / x; + + y = y + x + x + x + x + x + x; + y = y - x - x - x - x - x - x; + } +return (y); +} + +unsigned fib (x) /* Common Fibonacci function */ +int x; +{ + +if (x > 2) + return (fib (x-1) + fib (x-2)); +else + return (1); +} + +int stest (b1,b2) /* String test using strcpy() and strcmp() */ +char *b1, *b2; +{ +int i,j; +void mstrcpy (); + +for (i = 0, j = 0; i < SMALL; ++i) + { + mstrcpy (b1, "0123456789abcdef"); + mstrcpy (b2, "0123456789abcdee"); /* Note it's a different string. */ + j += mstrcmp (b1,b2); + } +return (j); +} + +int mstrcmp (c,d) /* External string compare */ +char *c, *d; +{ + +while (*c == *d) + { + if (!*c) + return (0); + ++c; + ++d; + } +return (*c - *d); +} + +void mstrcpy (c,d) /* External string copy */ +char *c, *d; +{ + +while (*c++ = *d++) + ; +} + +int mcopy () /* Disk copy. Test assumes file doesn't exist */ +{ +FILE *fp, *fopen (); +char buf[TINY]; +int i, j; + +mstrcpy (buf, "Disk I/O test"); +if ((fp = fopen(FILENAME,"w")) == NULL) + { + printf ("Cannot open file"); + exit (ERR); + } +i = 0; +while (++i < LITTLE) + for (j = 0; buf[j]; ++j) + putc (buf[j], fp); +fclose (fp); +return (i); +} + +int intest () /* Square an integer by iteration */ +{ +int i, j, k, sum; + +for (i = 0; i < LITTLE; ++i) + { + sum = 0; + for (j = 0, k = 1; j < MAXINT; ++j) + { + sum += k; + k += 2; + } + } +return (sum); +} + \ No newline at end of file diff --git a/tests/initial_base/DHAMP.b b/tests/initial_base/DHAMP.b new file mode 100644 index 0000000..45e349d --- /dev/null +++ b/tests/initial_base/DHAMP.b @@ -0,0 +1,391 @@ +/* + * Input file : test\dhamp.exe + * File type : EXE + */ + +#include "dcc.h" + + +int proc_2 (long arg0, long arg1) +/* Takes 8 bytes of parameters. + * High-level language prologue code. + * C calling convention. + */ +{ +char loc1; /* al */ +int loc2; /* bx */ + + do { + arg0 = (arg0 + 1); + loc1 = es[bx]; + arg1 = (arg1 + 1); + es[bx] = loc1; + } while ((loc1 != 0)); + return (loc2); +} + + +int proc_3 (long arg0, long arg1) +/* Takes 8 bytes of parameters. + * High-level language prologue code. + * C calling convention. + */ +{ +int loc1; /* ax */ + + while ((es[bx] == es[bx])) { + if (es[bx] == 0) { + loc1 = 0; + return (loc1); + } + else { + arg0 = (arg0 + 1); + arg1 = (arg1 + 1); + } + } + loc1 = (es[bx] - es[bx]); +} + + +int proc_1 (int arg0, int arg1, int arg2, int arg3) +/* Takes 8 bytes of parameters. + * High-level language prologue code. + * C calling convention. + */ +{ +int loc1; +int loc2; + + loc1 = 0; + loc2 = 0; + while ((loc1 < 0x2328)) { + proc_2 (arg1, arg0, 311); + proc_2 (arg3, arg2, 328); + loc2 = (loc2 + proc_3 (arg1, arg0, arg3, arg2)); + loc1 = (loc1 + 1); + } + return (loc2); +} + + +int proc_4 () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +int loc1; +int loc2; +int loc3; +int loc4; + + loc3 = 0; + while ((loc3 < 0x3E8)) { + loc1 = 0; + loc4 = 0; + loc2 = 1; + while ((loc4 < 179)) { + loc1 = (loc1 + loc2); + loc2 = (loc2 + 2); + loc4 = (loc4 + 1); + } + loc3 = (loc3 + 1); + } + return (loc1); +} + + +int proc_5 (int arg0) +/* Takes 2 bytes of parameters. + * High-level language prologue code. + * C calling convention. + */ +{ +int loc1; +int loc2; /* ax */ + + loc1 = arg0; + if (loc1 > 2) { + loc2 = (proc_5 ((loc1 - 1)) + proc_5 ((loc1 + 0xFFFE))); + } + else { + loc2 = 1; + } + return (loc2); +} + + +long proc_6 (int arg0, int arg1) +/* Takes 4 bytes of parameters. + * High-level language prologue code. + * C calling convention. + */ +{ +int loc1; +long loc2; + + if ((arg0 | arg1) == 0) { + loc1 = 0; + while ((loc1 < 0x2328)) { + loc2 = (loc2 + [-862954250]); + [-862954250] = ([-862954250] + 2); + loc1 = (loc1 + 1); + } + } + else { + loc1 = 0; + while ((loc1 < 0x2328)) { + [-862954250] = ([-862954250] - 2); + loc2 = (loc2 - [-862954250]); + loc1 = (loc1 + 1); + } + } + return (loc2); +} + + +void proc_8 (int arg0) +/* Takes 8 bytes of parameters. + * High-level language prologue code. + * Untranslatable routine. Assembler provided. + * C calling convention. + * Contains instructions not normally used by compilers. + * Contains coprocessor instructions. + */ +{ + PUSH bp + MOV bp, sp + ESC qword ptr [126h] + ESC qword ptr [bp+6] + ESC FCOMPP + ESC qword ptr [62Ch] + INT 3Dh + + MOV ah, [62Dh] + SAHF + JAE L1 + ESC qword ptr [bp+6] + ESC FCHS + +L2: POP bp + RETF + +L1: ESC qword ptr [bp+6] + JMP L2 ;Synthetic inst +} + + + proc_7 (int arg0, int arg1, int arg2, int arg3) +/* Takes 8 bytes of parameters. + * High-level language prologue code. + * Untranslatable routine. Assembler provided. + * C calling convention. + * Contains instructions not normally used by compilers. + * Contains coprocessor instructions. + */ +{ + PUSH bp + MOV bp, sp + SUB sp, 10h + ESC qword ptr [bp+6] + ESC qword ptr [127h] + ESC qword ptr [bp-8] + INT 3Dh + + MOV ax, [bp+0Ch] + MOV [bp-0Ah], ax + MOV ax, [bp+0Ah] + MOV [bp-0Ch], ax + MOV ax, [bp+8] + MOV [bp-0Eh], ax + MOV ax, [bp+6] + MOV [bp-10h], ax + +L3: ESC qword ptr [12Fh] + ESC qword ptr [bp-8] + ESC qword ptr [bp-10h] + ESC qword ptr [62Ch] + INT 3Dh + + MOV ah, [62Dh] + SAHF + JB L4 + ESC qword ptr [bp-8] + MOV sp, bp + POP bp + RETF + +L4: ESC qword ptr [bp+6] + ESC qword ptr [bp-8] + ESC qword ptr [bp-8] + ESC qword ptr [bp-10h] + INT 3Dh + + PUSH word ptr [bp-0Ah] + PUSH word ptr [bp-0Ch] + PUSH word ptr [bp-0Eh] + PUSH word ptr [bp-10h] + CALL far ptr proc_8 + ADD sp, 8 + ESC qword ptr [bp-10h] + INT 3Dh + + ESC qword ptr [bp+6] + ESC qword ptr [bp-8] + ESC qword ptr [bp-8] + ESC qword ptr [127h] + ESC qword ptr [bp-8] + INT 3Dh + + JMP L3 ;Synthetic inst +} + + + proc_9 (int arg0) +/* Takes 8 bytes of parameters. + * High-level language prologue code. + * C calling convention. + * Contains instructions not normally used by compilers. + * Contains coprocessor instructions. + */ +{ +int loc1; +int loc2; +int loc3; /* ax */ + + loc2 = 100; + loc3 = loc2; + loc2 = (loc2 - 1); + while (((loc3 | loc3) != 0)) { + loc3 = loc2; + loc2 = (loc2 - 1); + } + return (var06278); +} + + +int proc_10 () +/* Takes no parameters. + * High-level language prologue code. + * Untranslatable routine. Assembler provided. + * Return value in register ax. + * Contains instructions not normally used by compilers. + */ +{ + PUSH bp + MOV bp, sp + SUB sp, 68h + PUSH si + PUSH di + PUSH ds + MOV ax, 159h + PUSH ax + PUSH ss + LEA ax, [bp-64h] + PUSH ax + PUSH cs + CALL near ptr proc_2 + ADD sp, 8 + PUSH ds + MOV ax, 170h + PUSH ax + PUSH ds + MOV ax, 167h + PUSH ax + CALL far ptr fopen + ADD sp, 8 + MOV [bp-66h], dx + MOV [bp-68h], ax + OR dx, ax + JNE L5 + PUSH ds + MOV ax, 172h + PUSH ax + CALL far ptr printf + POP cx + POP cx + MOV ax, 0FFFFh + PUSH ax + CALL far ptr exit + POP cx + +L5: XOR di, 0 + +L6: INC di + MOV ax, di + CMP ax, 3E8h + JL L7 + PUSH word ptr [bp-66h] + PUSH word ptr [bp-68h] + CALL far ptr fclose + POP cx + POP cx + MOV ax, di + POP di + POP si + MOV sp, bp + POP bp + RETF + +L7: XOR si, 0 + +L8: CMP byte ptr ss:[bp+si-64h], 0 + JNE L9 + +L9: LES bx, dword ptr [bp-68h] + INC word ptr es:[bx] + JGE L10 + MOV al, ss:[bp+si-64h] + LES bx, dword ptr [bp-68h] + INC word ptr es:[bx+0Ch] + LES bx, dword ptr es:[bx+0Ch] + DEC bx + MOV es:[bx], al + MOV ah, 0 + +L11: INC si + JMP L8 ;Synthetic inst + +L10: PUSH word ptr [bp-66h] + PUSH word ptr [bp-68h] + PUSH word ptr ss:[bp+si-64h] + CALL far ptr _fputc + ADD sp, 6 + JMP L11 ;Synthetic inst +} + + +void main () +/* Takes no parameters. + * High-level language prologue code. + * Contains instructions not normally used by compilers. + * Contains coprocessor instructions. + */ +{ +int loc1; +int loc2; +int loc3; +int loc4; +int loc5; +int loc6; +int loc7; +int loc8; +int loc9; +int loc10; +int loc11; +int loc12; /* ax */ +int loc13; /* bx */ + + loc11 = 0; + printf ("Start...%c\n\n", 7); + while ((loc11 < 6)) { + loc12 = loc11; + if (loc12 <= 5) { + loc13 = (loc12 << 1); + var06278 = proc_1 (&loc2, &loc1, , ); + printf ("\ncresult = %d\n", var06278); + } + loc11 = (loc11 + 1); + } + printf ("\n\n...End%c", 7); +} + diff --git a/tests/initial_base/FIBO.C b/tests/initial_base/FIBO.C new file mode 100644 index 0000000..7671933 --- /dev/null +++ b/tests/initial_base/FIBO.C @@ -0,0 +1,29 @@ +/* Fibonacci */ + +#include + +int main() +{ int i, numtimes, number; + unsigned value, fib(); + + printf("Input number of iterations: "); + scanf ("%d", &numtimes); + for (i = 1; i <= numtimes; i++) + { + printf ("Input number: "); + scanf ("%d", &number); + value = fib(number); + printf("fibonacci(%d) = %u\n", number, value); + } + exit(0); +} + +unsigned fib(x) /* compute fibonacci number recursively */ +int x; +{ + if (x > 2) + return (fib(x - 1) + fib(x - 2)); + else + return (1); +} + \ No newline at end of file diff --git a/tests/initial_base/FIBOL.b b/tests/initial_base/FIBOL.b new file mode 100644 index 0000000..45bb8ae --- /dev/null +++ b/tests/initial_base/FIBOL.b @@ -0,0 +1,52 @@ +/* + * Input file : test\fibol.exe + * File type : EXE + */ + +#include "dcc.h" + + +int proc_1 (int arg0) +/* Takes 2 bytes of parameters. + * High-level language prologue code. + * C calling convention. + */ +{ +int loc1; +int loc2; /* ax */ + + loc1 = arg0; + if (loc1 > 2) { + loc2 = (proc_1 ((loc1 - 1)) + proc_1 ((loc1 + 0xFFFE))); + } + else { + loc2 = 1; + } + return (loc2); +} + + +void main () +/* Takes no parameters. + * High-level language prologue code. + * Contains instructions not normally used by compilers. + */ +{ +int loc1; +int loc2; +int loc3; +int loc4; + + printf ("Input number of iterations: "); + scanf ("%d", &loc1, ); + loc3 = 1; + while ((loc3 <= loc1)) { + printf ("Input number: "); + scanf ("%d", &loc2, ); + loc4 = proc_1 (loc2); + printf ("fibonacci(%d) = %u\n", loc2, loc4); + loc3 = (loc3 + 1); + } + exit (0); +} + diff --git a/tests/initial_base/FIBOS.b b/tests/initial_base/FIBOS.b new file mode 100644 index 0000000..77182f6 --- /dev/null +++ b/tests/initial_base/FIBOS.b @@ -0,0 +1,51 @@ +/* + * Input file : test\fibos.exe + * File type : EXE + */ + +#include "dcc.h" + + +int proc_1 (int arg0) +/* Takes 2 bytes of parameters. + * High-level language prologue code. + * C calling convention. + */ +{ +int loc1; +int loc2; /* ax */ + + loc1 = arg0; + if (loc1 > 2) { + loc2 = (proc_1 ((loc1 - 1)) + proc_1 ((loc1 + 0xFFFE))); + } + else { + loc2 = 1; + } + return (loc2); +} + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +int loc1; +int loc2; +int loc3; +int loc4; + + printf ("Input number of iterations: "); + scanf ("%d", &loc1); + loc3 = 1; + while ((loc3 <= loc1)) { + printf ("Input number: "); + scanf ("%d", &loc2); + loc4 = proc_1 (loc2); + printf ("fibonacci(%d) = %u\n", loc2, loc4); + loc3 = (loc3 + 1); + } + exit (0); +} + diff --git a/tests/initial_base/INTOPS.C b/tests/initial_base/INTOPS.C new file mode 100644 index 0000000..afc33eb --- /dev/null +++ b/tests/initial_base/INTOPS.C @@ -0,0 +1,16 @@ +#define TYPE int + +main() +{ TYPE a, b; + + a = 255; + b = 143; + b = a + b; + a = a - b; + a = a * b; + b = b / a; + b = b % a; + a = a << 5; + b = b >> a; + printf ("a = %d, b = %d\n", a, b); +} \ No newline at end of file diff --git a/tests/initial_base/INTOPS.b b/tests/initial_base/INTOPS.b new file mode 100644 index 0000000..98198ff --- /dev/null +++ b/tests/initial_base/INTOPS.b @@ -0,0 +1,33 @@ +/* + * Input file : test\intops.exe + * File type : EXE + */ + +#include "dcc.h" + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +int loc1; +int loc2; +long loc3; /* dx:ax */ +int loc4; /* tmp */ + + loc1 = 255; + loc2 = 143; + loc2 = (loc1 + loc2); + loc1 = (loc1 - loc2); + loc1 = (loc1 * loc2); + loc3 = loc2; + loc2 = (loc4 / loc1); + loc3 = loc2; + LO(loc3) = (loc4 / loc1); + loc2 = (loc4 % loc1); + loc1 = (loc1 << 5); + loc2 = (loc2 >> loc1); + printf ("a = %d, b = %d\n", loc1, loc2); +} + diff --git a/tests/initial_base/LONGOPS.C b/tests/initial_base/LONGOPS.C new file mode 100644 index 0000000..52fd685 --- /dev/null +++ b/tests/initial_base/LONGOPS.C @@ -0,0 +1,16 @@ +#define TYPE long + +main() +{ TYPE a, b; + + a = 255; + b = 143; + b = a + b; + a = a - b; + a = a * b; + b = b / a; + b = b % a; + a = a << 5; + b = b >> a; + printf ("a = %ld, b = %ld\n", a, b); +} \ No newline at end of file diff --git a/tests/initial_base/LONGOPS.b b/tests/initial_base/LONGOPS.b new file mode 100644 index 0000000..c49115f --- /dev/null +++ b/tests/initial_base/LONGOPS.b @@ -0,0 +1,295 @@ +/* + * Input file : test\longops.exe + * File type : EXE + */ + +#include "dcc.h" + + +long LXMUL@ (long arg0, long arg1) +/* Uses register arguments: + * arg0 = dx:ax. + * arg1 = cx:bx. + * Runtime support routine of the compiler. + */ +{ +int loc1; +int loc2; /* tmp */ + + loc2 = LO(arg0); + LO(arg0) = loc1; + loc1 = loc2; + loc2 = LO(arg0); + LO(arg0) = HI(arg0); + if ((LO(arg0) & LO(arg0)) != 0) { + LO(arg0) = (LO(arg0) * LO(arg1)); + } + loc2 = LO(arg0); + LO(arg0) = HI(arg1); + HI(arg1) = loc2; + if ((LO(arg0) & LO(arg0)) != 0) { + LO(arg0) = (LO(arg0) * loc1); + HI(arg1) = (HI(arg1) + LO(arg0)); + } + loc2 = LO(arg0); + LO(arg0) = loc1; + loc1 = loc2; + arg0 = (LO(arg0) * LO(arg1)); + HI(arg0) = (HI(arg0) + HI(arg1)); + return (arg0); +} + + +long LDIV@ (long arg0, long arg2) +/* Takes 8 bytes of parameters. + * Runtime support routine of the compiler. + * Untranslatable routine. Assembler provided. + * Return value in registers dx:ax. + * Pascal calling convention. + */ +{ + XOR cx, 0 + PUSH bp + PUSH si + PUSH di + MOV bp, sp + MOV di, cx + MOV ax, [bp+0Ah] + MOV dx, [bp+0Ch] + MOV bx, [bp+0Eh] + MOV cx, [bp+10h] + CMP cx, 0 + JNE L1 + OR dx, dx + JE L2 + OR bx, bx + JE L2 + +L1: TEST di, 1 + JNE L3 + OR dx, dx + JNS L4 + NEG dx + NEG ax + SBB dx, 0 + OR di, 0Ch + +L4: OR cx, cx + JNS L3 + NEG cx + NEG bx + SBB cx, 0 + XOR di, 4 + +L3: MOV bp, cx + MOV cx, 20h + PUSH di + XOR di, 0 + XOR si, 0 + +L5: SHL ax, 1 + RCL dx, 1 + RCL si, 1 + RCL di, 1 + CMP di, bp + JB L6 + JA L7 + CMP si, bx + JB L6 + +L7: SUB si, bx + SBB di, bp + INC ax + +L6: LOOP L5 + POP bx + TEST bx, 2 + JE L8 + MOV ax, si + MOV dx, di + SHR bx, 1 + +L8: TEST bx, 4 + JE L9 + NEG dx + NEG ax + SBB dx, 0 + +L9: POP di + POP si + POP bp + RETF 8 + +L2: MOV tmp, dx:ax ;Synthetic inst + DIV bx + MOD bx ;Synthetic inst + TEST di, 2 + JE L10 + MOV ax, dx + +L10: XOR dx, dx + JMP L9 +} + + +long LMOD@ (long arg0, long arg2) +/* Takes 8 bytes of parameters. + * Runtime support routine of the compiler. + * Untranslatable routine. Assembler provided. + * Return value in registers dx:ax. + * Pascal calling convention. + */ +{ + MOV cx, 2 + PUSH bp + PUSH si + PUSH di + MOV bp, sp + MOV di, cx + MOV ax, [bp+0Ah] + MOV dx, [bp+0Ch] + MOV bx, [bp+0Eh] + MOV cx, [bp+10h] + CMP cx, 0 + JNE L11 + OR dx, dx + JE L12 + OR bx, bx + JE L12 + +L11: TEST di, 1 + JNE L13 + OR dx, dx + JNS L14 + NEG dx + NEG ax + SBB dx, 0 + OR di, 0Ch + +L14: OR cx, cx + JNS L13 + NEG cx + NEG bx + SBB cx, 0 + XOR di, 4 + +L13: MOV bp, cx + MOV cx, 20h + PUSH di + XOR di, 0 + XOR si, 0 + +L15: SHL ax, 1 + RCL dx, 1 + RCL si, 1 + RCL di, 1 + CMP di, bp + JB L16 + JA L17 + CMP si, bx + JB L16 + +L17: SUB si, bx + SBB di, bp + INC ax + +L16: LOOP L15 + POP bx + TEST bx, 2 + JE L18 + MOV ax, si + MOV dx, di + SHR bx, 1 + +L18: TEST bx, 4 + JE L19 + NEG dx + NEG ax + SBB dx, 0 + +L19: POP di + POP si + POP bp + RETF 8 + +L12: MOV tmp, dx:ax ;Synthetic inst + DIV bx + MOD bx ;Synthetic inst + TEST di, 2 + JE L20 + MOV ax, dx + +L20: XOR dx, dx + JMP L19 +} + + +long LXLSH@ (long arg0, char arg1) +/* Uses register arguments: + * arg0 = dx:ax. + * arg1 = cl. + * Runtime support routine of the compiler. + */ +{ +int loc1; /* bx */ + + if (arg1 < 16) { + loc1 = LO(arg0); + LO(arg0) = (LO(arg0) << arg1); + HI(arg0) = (HI(arg0) << arg1); + HI(arg0) = (HI(arg0) | (loc1 >> (!arg1 + 16))); + return (arg0); + } + else { + HI(arg0) = LO(arg0); + LO(arg0) = 0; + HI(arg0) = (HI(arg0) << (arg1 - 16)); + return (arg0); + } +} + + +long LXRSH@ (long arg0, char arg1) +/* Uses register arguments: + * arg0 = dx:ax. + * arg1 = cl. + * Runtime support routine of the compiler. + */ +{ +int loc1; /* bx */ + + if (arg1 < 16) { + loc1 = HI(arg0); + LO(arg0) = (LO(arg0) >> arg1); + HI(arg0) = (HI(arg0) >> arg1); + LO(arg0) = (LO(arg0) | (loc1 << (!arg1 + 16))); + return (arg0); + } + else { + arg0 = HI(arg0); + LO(arg0) = (LO(arg0) >> (arg1 - 16)); + return (arg0); + } +} + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +long loc1; +long loc2; + + loc2 = 255; + loc1 = 143; + loc1 = (loc2 + loc1); + loc2 = (loc2 - loc1); + loc2 = LXMUL@ (loc2, loc1); + loc1 = LDIV@ (loc1, loc2); + loc1 = LMOD@ (loc1, loc2); + loc2 = LXLSH@ (loc2, 5); + loc1 = LXRSH@ (loc1, loc1); + printf ("a = %ld, b = %ld\n", loc2, loc1); +} + diff --git a/tests/initial_base/MATRIXMU.C b/tests/initial_base/MATRIXMU.C new file mode 100644 index 0000000..a6211e4 --- /dev/null +++ b/tests/initial_base/MATRIXMU.C @@ -0,0 +1,18 @@ +#define n 5 +#define m 4 + +static void multMatrix (int a[n][m], int b[m][n], int c[n][n]) +{ int i,j,k; + + for (i=0; i y) + return (x); + return (y); +} \ No newline at end of file diff --git a/tests/initial_base/MAX.b b/tests/initial_base/MAX.b new file mode 100644 index 0000000..93d8608 --- /dev/null +++ b/tests/initial_base/MAX.b @@ -0,0 +1,41 @@ +/* + * Input file : test\max.exe + * File type : EXE + */ + +#include "dcc.h" + + +int proc_1 (int arg0, int arg1) +/* Takes 4 bytes of parameters. + * High-level language prologue code. + * C calling convention. + */ +{ +int loc1; /* ax */ + + if (arg0 > arg1) { + loc1 = arg0; + } + else { + loc1 = arg1; + } + return (loc1); +} + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +int loc1; +int loc2; + + printf ("Enter 2 numbers: "); + scanf ("%d %d", &loc2, &loc1); + if (loc2 != loc1) { + printf ("Maximum: %d\n", proc_1 (loc2, loc1)); + } +} + diff --git a/tests/initial_base/STRLEN.C b/tests/initial_base/STRLEN.C new file mode 100644 index 0000000..0d59721 --- /dev/null +++ b/tests/initial_base/STRLEN.C @@ -0,0 +1,13 @@ +main() +{ char *s = "test"; + + strlen(s); +} + +strlen(char *s) +{ int n = 0; + + while (*s++) + n++; + return (n); +} \ No newline at end of file diff --git a/tests/initial_base/STRLEN.b b/tests/initial_base/STRLEN.b new file mode 100644 index 0000000..89496e4 --- /dev/null +++ b/tests/initial_base/STRLEN.b @@ -0,0 +1,35 @@ +/* + * Input file : test\strlen.exe + * File type : EXE + */ + +#include "dcc.h" + + +void proc_1 (int arg0) +/* Takes 2 bytes of parameters. + * High-level language prologue code. + * C calling convention. + */ +{ +int loc1; + + loc1 = 0; + arg0 = (arg0 + 1); + while ((*arg0 != 0)) { + loc1 = (loc1 + 1); + arg0 = (arg0 + 1); + } +} + + +void main () +/* Takes no parameters. + */ +{ +int loc1; + + loc1 = 404; + proc_1 (loc1); +} + diff --git a/tests/initial_base/TESTLONG.C b/tests/initial_base/TESTLONG.C new file mode 100644 index 0000000..a9bd14d --- /dev/null +++ b/tests/initial_base/TESTLONG.C @@ -0,0 +1,10 @@ +#include + +main() +{ long a, d; + + scanf ("%d", &d); + scanf ("%d", &a); + scanf ("%d %d", &a, &d); + printf ("%ld %ld", a, d); +} \ No newline at end of file diff --git a/tests/initial_base/TESTLONG.b b/tests/initial_base/TESTLONG.b new file mode 100644 index 0000000..be833ab --- /dev/null +++ b/tests/initial_base/TESTLONG.b @@ -0,0 +1,24 @@ +/* + * Input file : test\testlong.exe + * File type : EXE + */ + +#include "dcc.h" + + +void main () +/* Takes no parameters. + * High-level language prologue code. + */ +{ +int loc1; +int loc2; +int loc3; +int loc4; + + scanf ("%d", &loc1); + scanf ("%d", &loc2); + scanf ("%d %d", &loc2, &loc1); + printf ("%ld %ld", loc2, loc4, loc1, loc3); +} + diff --git a/tests/inputs_base/BENCHFN.EXE b/tests/inputs_base/BENCHFN.EXE old mode 100755 new mode 100644 diff --git a/tests/inputs_base/BENCHLNG.EXE b/tests/inputs_base/BENCHLNG.EXE old mode 100755 new mode 100644 diff --git a/tests/inputs_base/BENCHMUL.EXE b/tests/inputs_base/BENCHMUL.EXE old mode 100755 new mode 100644 diff --git a/tests/inputs_base/BENCHMUS.EXE b/tests/inputs_base/BENCHMUS.EXE old mode 100755 new mode 100644 diff --git a/tests/inputs_base/BENCHSHO.EXE b/tests/inputs_base/BENCHSHO.EXE old mode 100755 new mode 100644 diff --git a/tests/inputs_base/BYTEOPS.EXE b/tests/inputs_base/BYTEOPS.EXE old mode 100755 new mode 100644 diff --git a/tests/inputs_base/DHAMP.EXE b/tests/inputs_base/DHAMP.EXE new file mode 100644 index 0000000000000000000000000000000000000000..ae0173d0e5ab260d6da1a17e8aaf117c23b16c5c GIT binary patch literal 32173 zcmeFadt6l2`aiz*W%i5%0tzCgA|lXbl+0^|D0vwx74ZgI3YC{G$6GK1S_s3LQirXc z%yX=yPbZJ3j%oG5(hlm$P!Q6hK+8Z&&FhTY3@-r+&i=ihy=Q>P&-eBFet-Y`{`l^B zt-YW1tY_Vxwbrwqb)891gmXjK`z(nurmFp<3;5C#4a2eKsLU6-aRf1T4CVxk0hR!m zgD|}KGP@$Y%uc|($iK|?a4)mBVPu#Bm}g)fhlzvnvX_|xQvxZoo`1FjmQZX1Is{%n%LJ3nm;U z1jY>WZ)O)hhIt>R3v&o-*;+wj;Zh^pDsBXa5otx$WX{wp|s�wwq^1&pOLOoM-D@k;~bdBbH0@$ZVlNWqg+L3&y)(*&!bNb$r6F zS%N2&lTQi9U6C#%V=deKGPBgKE8Y2cT2&(4kSyO` z-xj2XdkveuMcvp`g(ka`Ro&$ZcQRMds|-%Oqz=ns>aZ7KmcT56`4ihDLg1uq;?dmW z*F{!xn=&ETK+Poi^3I8cRXG%GP^ zmbtLZXC;zmc@~!ESqY0>b9mkHJ+WL>-#%psBKBbTlMHZVi3l)52Mqw{>YxPhSpvTz z&NKGaS38sT@<5dBjzmflnU+wuM=cSM^3F&vV>9H-&ddDtnF;0g!Bt&id1jk8xb#B( ziL*s@?xMOYMJI0-)s+_2oh~|ASM*b!SGIcJu^UQwrX(T|{eHCnx2l-Pw5j>+fel>P74!jwTsSaH;acP~WEtm3~-lQ#Vw zB~~(I=WS;U)nGHYmvTzj zRvthSQwD8~uo+X_uW~aL7MsXy(NhN>k!wfSC|S*}@PBZX(my$lMeh3tm%7P_{?A!1 zKJlb+R{G37L2iz{_ALb~tjKgV5l~~HzrYD}`Y?Bj1 znC+eB_(l)T)H|H@VI4 za&mRS8RpP%gAY_C3evmWfRRaq4{Ujts~QfHC(5Rz>^3oXk*YJ*P&Ksi%+;B*5X_mB zLa}fjAD9$<+Ho#_^*p|6Xw1y2#4^1U4pAAc^tgg}-o00K_hXR0QZdO?dkIKJBTFJR0U*XmSUE}r?b0vIiRo|wsA`gbY;)DBqK*_pF~-_0?{$Q4Y;?6OYEVX}8e{-9Dw>};(Y9bQdc<0&VTq=KttK3|Aq*gB^-uW`^w;o{1Y1^oDfdPH{{C}CG(7Y-W9)ytqEVk&USHS zvo)!_^Po8FLv!irTee>Ym%6OXW#!}5_(}uiWv~hZY!`jIQx~pRWQAt?1l%w6Vrn#yM-4GT=3#EK4jn zz(NW=JH#XB`QHlNN8Lho;lbEoM#O>bh`+NC?IqCO1ntE^CoD(XQ%@;$qkGdl7oI(; z%o4sT{1Krz&ju&d*!hIAul7teD8imJ!)^n6%_s49-wlC3+psgKs;`!EHC~h;^$IS3 z$5ID3lo(k`WXYRa_vICx<&x(WPOeBaux!DT!^yQZXXDj>4P}q8Ke1J8E0eg@T=-h+ zYboJtSN2y^HXVT4?kqQLi2%zYq{x!@+6DA5wD^(UbDSwc8i*QOU-UVx6P53Kx__FdT+|YkYr0Q zgxCuq2DLg#3a>D$(<`kIJT|XhKE2vp)6rvmh4M?4tx|y1WRDr#phU>w8` zNi{j8zcStl46_z^@9CF&Mu{dGXFQ=Jf%Z|~Yn6JWntU{JstExqEL{uSc{!x&A*)pN z;IO;7s)r~evNh0UZIG>Iuvxa6T-IwKcUkL|F*;#(Q`LhDnm}7mnWpkmv#+Vy^_xms z*#Va}S}W*V1Fw2Wx}U3hFc~=be`sWXFugEtfb>r0Kj5QDAsvD847xa^2MK$)u02^+ zCk;9Dv?3CqFkdE2sr%+J&uXT*KA4RB+`(ws0|g?_2E`prI||~-9ZWll1)#Wt(V1A0 z41p$i7ONB=nB7{I*^<-C=S9jDkER5#0k1Rqb6Pomr|6HzAScYEgN@#hy z6z3Sl?Bd{3$JA; z;|tVJS?;gk9|AfKC6^dTp0z%7)fpBT5i@Yaqtl;Sxa^hJ-rl;?*R?uG%P#54lzHC5 zo>dc;ZTb##53HmgQ>N{$?>_t9gl#Bb(qfr1dgy`Y`u^j1@F9(298(^6tMS|BS2jg$ zQdLl-G9~K6<=@sccF){FftNhXlwbnr;Yxv6#v<1oT35HRWw*qxzvuilaATjcv=mEe z%XU07w-@f;$+l;d?c&^%dZ+2wou%7LxFi^INKKPR)-rf=;Uh&F^A!b@&^8A3 z@j3R9N$=b38G)Eup;KGPHs7BHPRpEMue5f~lx z19RLAv<-6HWVXKiM6=_jXp42+>|~2-JkgD@<-HuaX3qXzB6HZ^Rf0d^qN~lv3(C}d zDgx2B$I27}WRF0vydIn`Aj6A5iYH96{Xz(vGrhJffJ9vg*6`Fo&ho^AVG0^X6XW z*_=F9l&4D$Pe@LPxy)R-;dRRqWH|4-d^y7OOIZVzv=ho;Qjrs4L%l7 zVLoN9E4-cFR(2^=cA>tq8$)F`vhhS_pkm&^MSp3oqtZf2I*+jB_iB6$D!7HxG$mq; zDk$NvdFHEy-&F4(G|}9!pR-AxRJBR@RwFcmOSRw3~FPo8yiW-Nc$H^1%oi2S& z%*+kVj|(_tj}ACtj|?ca-?b0bcQAa`K+UWD&3TkTDMaL-b8KG{G1|PUX4O|4oL54W zYs&(Xh0@Ryp@%|`EdR~5$n3J4Tr;#9K8JT1P?|IJ+A%8sAu!x}2ZnbdhKrV8lqkzD z^7lH!<)7>kVEIv`;d>}F2<7wB%?~yJ)XO1xE_bg-khV8F!|J!!wuO{R;HEq=u zIT=kmX+?izdYqnVJzhQ;?bBcjblf!AjFuC`=`Q;?%ndt~PPT|$QSK!XN*9Yyzjs+h zSGwfNHhGHKz6V*qtAoF(xkA6jlg* zz*j5nCgDiJ57`$LiN2YqoL7vworKEOqm2zeD#1dfYqZg7&6gZgjV!Y<%XqUU9X+Ym zlJ%w`&o&iKG&@Hyd$2Q?XZB88^X-O)a?TdampZOitaUM zsy)>wYK|9{7oI6RR(KuUb^a=r737*AC_14+JlfrI#8SFfWy*JiEX^}OSPbqCHXN19 zl+x5RsYR>l5Eu;*n#U|B_>;DQ4zFs9aw>T@tB)66EBp>a6BcQ-ly2X?9uaKVzHvK= za=F%gyz#_d2%uW|aKM+gAb6<0gj#-N+2ILFBgysyY4TW3&K2Z|hQjGaWbiW~y52m* zE^am1x)?;}{DGQ`1343_kB=!R^9p&Rkul?n$77nR&(tW@$IX?6*X2_+zt+?u>vgD` zt&n-Fxy_Q%f@D$RP_xR=z36!j-4&t)>b&T-=d=oTJQQx8Zmv0OIV9J~`;|j`RipB^ zv^BMB%GRA&SBhqCDFqX%Z?9cp-oC?d^pfqVf?KN5Hulqyf=gcE_3iR>gX2Q5`MNw& zkY{s+F~zLrG&-7^nj;;*uOl^7*ZpBhX^lkmep!8vqJiwVk+PEw@Cw^!7Bi&?9npJuK9U2eUkEmMN96`1A?Qc9qkO1i zxr)y67iedamX6YOCvKy|Lhe4=fSjJKsoq|r*g^^v@2CyiDWn!7b@k{;wo_qm->zJl znhLHIoKf?&o-|;(Xz%N6R&5al`KV#JUF0;~v3o!oACM;6$2FxtQAPwKb%Nm?2y7%v z6Vjxd$jrMSniA5)oUqIgbXN&!e2zI&lEV_Z=kW6NH0UpD!=O*JTz~IohO%u3r|>&y z8guP}Tj)o#O>&-8xPQ<%^PsWj)z(|`Sd%=*L`-<7pc(I!gt8T;L6giIRy8UD8rACL zW|~M#Zh>oQp3zd4n8fmC$eL)JNZpd>K5kl?d`iv}-GOSxlbORPnB3ll)>}|>`zc|2 zRkaY2?Ux&g#N*BEhHxqBW>O)Ol%0ewZ16O&)mBwD$a8pkk|@uRDxhaN7OSS*9;>Zh zG}5z$rwVTtRux_ z=~C9Sz9v9Ksm88`8bMg;s{13jH?p2Xsf~hGlmr z+qzXR@YYoO>QcS)N)ngdq6DL>x=8sbt*|yj{{)TSBS{=YRgi~Fu85{jXau*H?xU%_yeT$zBv6 z3Xw|i9<2n2CzR!K8%XB~70MnZ{Fo%z@>3wbY+X@9l>}dT&Ay$H`C!2cl5G)6zf_cz zUPxnar)NfKav;AmmCofG%3Mf*;qaUUdttKIU3o)ENrA(vM)$=V?upDP)v}0;fFsKS zCf8ih*@TvTfm8~A-<~DZ9LFF5m4jDyXc751u@QXmlIl&v1#klWd3-IisPeaRV}mu= zVUy%!CTH^vR>5Hl7Lo%)vx7oa&4rr`acm82Tp$WxhF*hAl&v8cOm=Tvz}gUv3wWVE z^cE7LkxH$WAoAyT=?Z^l@~0y#hf?LMvK1tf&=h(cvbHs7u?<14wV{Wd$KXl<#86y1 zxsIb4S_z06$&`=1k)DB0oSI~loNiKcBsE7=b9i;Qr8I>K7%gU80 zUKHa z&6(GA0dvG1c3rtBU#DUR&E)3Hy5?+ELL}|TAkeD zvffJ3+UVIX@(l4_YkiOOYdunL^vG^Fb1l8`g3Eg4^$m>|D97?R5x|$|dSBnzIA0Pf z09n%OdnRA&X}!@C6I1E+uHQte7@>XCfQk>0|77uA&> z>GeHQul2~jp+)t-j^|3xXLdZB(-HD7TaEz z=ZI$m?zQ@&IrCfNg|;XpWM#jWfh#?&^*vLsQK;5>*)9siDHL@UMg~e3>KAH`G&XE# zY`~DJw)!NdL*=W5q~umNocs-~AvC=qG`T4>`&QS~mg-Acooi0|gx5(GoLBh7bNq~`hb_@%M1zS zDNo{SnzM{!AaHAI>YTT{S-q!Ckq<*YUAtLxvaumKp+38-Rj98yDc3+lx^k0LE~UFQ zp+1Y-IO|ERjD@SnaV-k^Sc~P*dcRhLl`!gd8J{$o6CN3ZmZ93sdVkf{AwVi(mTrZ~ zl51KKp-g>kyplLM_g2k<7F~e|J(AgT`IUs}61v5U2@}Pf&Y7nZX7f2xW?h1q`8`B& zJ9!_V=9fWOb+(P2?DxI=HzC)QCg(Nyq!Q)>tll@bJL0})|M|j*_TA#h^Ky0!WcxM6 z7yd0a#1sy#oJ3ZcK34fP1f9V)f}OvHtg68a_Dx@KrBEXeSx!Km*o^M7y+U9c0+#vnmw=A?;YsG) z$MO>){DOH#se zFl1nMGv;Cy6G06qk=4jKD#!tm$-OMSF%;^Fu6efDbB>tP3FG3k4qLf$h(4byUlRpk z9T!_{A1j~I=U>Wa2->Gj>Y8L1giqre8!dfO@MRqtauN)w4gf=x(|7PJYJ(%8GvhVS zCCu;#|CEC|43DS>k*!Ql=jCKkPL(Q+>VU?v$K5RMStO&8@2l|zW znp4Wvnu}kcq5ArNS_VnyUCE*=Rf3kIbxG)k%yK%DlX*1w8bsrh@}Z3+`9d2J@HZAr z3-cZEM5%Qce#)A&&@o!+#m3XV0IU*qBwAqYFj^-Us{nRjK2t~_W> zW-Jew7?m9LFr>g12R1B_1_ZK=Lbm9h_KOTPNy^L9CbJ61g%2EOcCTr28C)1mW7cSf zlz|zp8N|PMxpzF;d^{w5JfvJa)VPPOX4?=;I_sIt_e>RgW=mONjmI>#>BMjP2p+O< z2ypfONfoJjTUtT zXYbM)AgN!WjY?Mt7hQeRHL}pg@tbSe8~UJSBU&p-57NG=sv_s@p3k;v&waGhN{ET3 zhvp91r{`GbYStML#}=C=R3^mho+^^U-@?8c4Ien}^b=Y%ZB`<`fxQBaHum^&>*27Hui@ImTjrjpxXriSA1Llas{5Q; z=AS2}DE$#=VY9Ru+5-nnvhs#_R_7BBsoj)4dbo z3;)ieoqG$)?hlun;k!TirfxHB?YJ9TYFUc=vuhO5@*D0c9_mE5U-K2p@CHrybw@Kf z&s$I#5Dwp0JgfX==Dg^(|ICD*>^Nr|dFL;z_ZAN*VNpL^jj3Qm$t>ooy zDQ;^E#SnDE=d+9|YTKii7)v6|2YLn9s@$^HvSlo;pH|s5PrWR)e;!b))qB=*b8wO{ zL_@Q%slt#XUtp07TiXDeSbS)*PR-c*pbK~D)QnBZ#?~|6bFhDaA7nmhyEado%yzGG zQ{tywcaa3nH96JO5H)SX#qpSV@eSC<=aNR$IzDj1LtqOr#McAUKpL_Ld`awHGOBxu zJH8nWKLw#*_cImhOS?q^tpc~E>p7ht+J?40L#VC~*4+M8_UP*|kLfv_G$*>!U)f_) zmDx654j=mH@{UknNVktUg8doa_0qWze*~JAVnSEbrlJ(wGVIC;@lR;%!y;|6SLx;( zR<@hw#B`iRg?7+m!}`~uCpgv8{Ht2_DfjNwi^>2RM``mTH0ha|Hg(Fh6#0f5n+|40 zxL>+5=P5(%hZu)3jCA7I*not%~Z(imp^Nx(8~Z zxbM+|Ow=r?Yi)tx?%%GaYAdu}xBLf>sJx|l*0$KjUQow@2Wjr2U+I0{b$7puawJws z#+!I|b`#2OeniQ$5h?D>o77&=f`(sJ$7Kl+HYuGhu3}O{3@?=AtK%XTa0nF zwWToK>uAO%8a}faYvn(41dCzp9bKCO`k}^W%2i!t#w=q50)kHNKIWlIFHt(>y!Qa?lldn=mL{ zT|LLFMRL9j*#ifBYd-FP^S(j*gQT*@?_l!DM{|vC^}Kv)2e*r@Twu{uS0|aMT@Ac4YxP1i<+)78OrzP|aPBW-&Cur+<@e#U^GfvZF>jqyLVl0=>YV#8 z=N&6BPUs?sr>@VV8)JB=adU2*cKJk8jjMd2P_k>$Gj~b&6JH{MwKd|c#EG>yL zxF?=RZr0`oLaw_<|1z_tDQiHb`0BjMvHZ!Km1D)h*DJ?L;x5G^dod;PPYy{#!X7-Q zAcgMF&MFU8qGtjzy);N-jwIJuQ^i;_R@Kln+{w+9z~U?PK7UzL>P0AYoR(lJrnPwy zyO``LHaGk%H0>*8&MSe=U(N2Xlu7wFpx6bWc3Y{MUUDy;iA z(>fEaiFz%~m<;ohpC4{}zR5ndTJmT7Bq0#lt8fl64bP3c4d zq^_MEIBi{}`?u?qxYY~7%ZO<$ih({}u-)(3eN^M5fI$3|dZD;qxcqjyuWv%)$isoF`{K z@hxhOfhm{1RxYMYi45=a?su#(2&Mk>D96=N=7WW&qkkTBx}n@;;{&5!*>4LDbo}Ex z7QKH&l)ZDGSu@LG@?j-F+p0Cp6tNNTu5soaB5bCkr;oV5 zH-8awcjLtkYi$ztn+auIkIBbjl@B*w6u#_w48`tV4>UC0uE$czX}x?6?yGJ!o)J!l zHl-86QdQU=dOY;jK7@3Eyk6L-xqlPdgc$@m+v`qNg<4XUF@t}Ep*f)==sW=X|N5`` zVb#r5Un##X3wV?U7BxSR@Rze&T)kWqc~`FJnl7Ox>td6pdd{UxDW11Oe7yk+4d0oM zoHL((UHg<5Uf2%KX_CH$MvlGYi9Ci%vQ2~%l>6X-5iGY){@{XJ0VgxN=U5875C17M zIHzC1%~9Ez#+;tc=K7rQovgnohUAA7UZl~Ce9dx1saKv=7WWTX5rht0o3^O_(Oa5( zjX&q>!jDmYHd4N6J_mCk?sV01LOE#dD=Ccgi6@mos$@V<}qozQni-;BNs`o7Y4QD1Xxe(d?!i?K(f_xNMR zFB&}K8pTV^w@qi(Vs>C3}}D!RlK|Q+uHA? ze!KeR_bcj$$~yD5XOST%rlCB_esy$V`I=KPrM93Ejx|4IV#-|15#+qExDQvJjxj2O zuo16QT;1qqZ!eX;z4~f&7)k$T3+((KK_u-ppWdCN`4zr{v!5S!7O>0gnk7|$vXry2@6YiKY zM1v$i_vu9a1S?VW0xdq>sI^wF!|rZcvK_2+2l<*~8y&YeJNL%AQgR}PyBxPmu`T>9 z)^IS&E_jCXdnFcKhy86SQ6&$u=z}%x8u#Cb<~~hV)ptMmXx^9^wWem>{(XT=KDCy~ z)w@ID;??(`it@=oXlnxE5antcW-2TV4g1k2g4j=%GHvP<&odXbPm~9;D`nagPp4lu zXb9^?{rkhE&n4E+L#Z3xa4^JvSHnS*eLAJ3RHL+qXVc=KfI| z1josX8Vagr%us^eFPsMpoR#L9^EKyfU6%i<1YjqEfnDED2>bQ2FG`W1g`%@!I(fi? z^DkKe&MW4CU+mYF;F@2cD!Y@<15xu!=2hx;oE0se!RqE?YVn8X|5!i4u#<)W` za#{}hjycX(n%(QSmr+OK-g8+iL2;UE~&aL{PGABFYLo60>@60%{HxE=d%&op>G;AAgl z3Guws3R0)&`3ood9-j&?iYCb2>`HQ<}Rt54%~`J9c{P zz}Qi-vtyUU?(M^(e~K?$wKC?-H>j1r=Z*2zCG@86$56p}&NE$o&};F(-jC6(+F-~} zvtL_t3H0pNW_O|3=-w%#@B2}${vGH0IBpB}$5DkS0-f8!iM4jK^H=`1^YT->2ZCXh z(sztKQVB(DltAqUIut5zDc+~q{6&@08D?KqDV@WZU+IDwM7yzqJSYYfM9(JWf!CCV zhJ$_VSO3S#=1LAy0$v*?4?E6=Q9=7Phv46L>fe5?T=7p~ct`mmbrc(2s?LwsjjB5 zMSlM-7GvDX*$hP|J&I8DQ(aNrHQFh4?^fX@K?`SpQSFxm;C*s`QQfU-ceQ)aK^q)# ze&nX|K;h}?%Z_v0pz|6E-g;@?&S?=hSk)w3fG?f#3^AO%Ns|hH%Xh0|p;B(_UnSnNJyWnlz5v_tfA1`2c6NvumfNSkcTms}}^8p=K5?=#0_`EGo2ic3FX`ty3bor)OE>{mukC>j zzG(BVY1R+bA>&5kpt9Jj3YfX3Rq5ZZ$lqI3!<&DS<@ zcY=dWOj4~OYIc~K-4#QXJOTTNu{S!sWm@>!>}uNGpRy?s2a7k9=LKR%ikgo-q|M%Z zTQ?=P#PS%5nc4Ux?AJ}UZui_`C6?q?RPiI*J#OY83ZZzwHZ3U`6l1XC);QZDXY=jc z=MvIG^5;66@5xUOIFTP*GBAES&hywh6%X7t#@>Q$dUQC(X5Kcz-cTIB?GdFO85EMe z3H!4x|ty)z<_lLJ?sa)0ez)trzQXcrKaGWWG%A8jj+ zH=nch-d0$?jRLjb?BJmY9*U!)t>(aS+e$10Cae%wmN%Z*wqf_cfr)cjc8|o1Lbmy> zy>6lLI=_G0>z~eRpzq4^H$OEuTo?9l$5|o_!%_7PhiLWAc{wOGtE_|*O$XOwW19+hCnhTF)N)TGblkgHfEqQjjgX5abm#W6E#2A90kwgT)nlUV|h2| z@WTzqx$%ycBwM(nh4vewjq%FBJ>GmJb`LgCMeX5O@jy8_1bcRc#=1wGH}A<7cHhHV z%JWRuw;_c%UgjCdRShkz8lKlc;duwBqxOVMYP_^z=OnCdSD$V;hr#v{hW(`&In&OL ze5tWkIFS2ZVpr4+>>8JAEeGU!TQs$o6r4>e5N1-FlJt{n0S);E9DGx#3QyBrtA^l= z1f{;g`r9~L*yu6N=B_!A4t!__pbu)pIsPU$(UP_!1FK5{uG*f4P5HnV$z&4d!i z*M9y<$N6A;!05ON%##JxnWN4%xqy_8gmT`5(-}l5#HRWbjBV|Z@-*Nl~Ry^MgEE{`3y$}=&;0L zUaJ*Kpd7hOz*NIo_3!c0=4FB!v`l~)@~Dw72x{bFm`s5VQP5G?S^9~Ek;{ZAEE+=v zjMPuZ_=9l0F;H@?ikDPrnSgT=`e_q1*uh7prff3caKC)M^$3cnNz}BUIC*@aEBqB< z%bx}8W<{Ocv=ArZ?Ln2&D_EGQl>Usj@&FN+XPDMly{_~YY>I#!FOU4Q5a&uW$GOIv zWCXDJ&q8^63ot>z1d_2N&14ok> zdRTm%%czs-b_rpNdOGEBhp;(M(39I4&TAxx;EK!>FdWemh;}chn|;CKV36cXH&WtC z(*x4z3?`gjX-lu~G|CCwYk)&tT6cyXOtl9>j^TLj;3MGdC|~656Q!L~>X`O+$?|#m zKZtF(7D_HM_Y$$#pHH1H9b?op*&!Cx0XmXpq{L&FpU-D^;&W`hiv19(E0s7j_|V`J za(J$=`6VA;gLQ5MVd7}kEYE*%LQ5-Xoh?MIvtRIR&aE#6zQwMmb+TU)%X$kveVE(c$9hU@1B-Njy{#2=AK=YA`ncRr4Nb?a~@t#77* z5@Mc~f+J5A0*-O}MFX8?(zX;0R?E`^RcjzlXkiEHh)lZ)%X43#2rP~~HOJn0ACKei zEe`et4)sR>^)#V6wW18D)f-U(ef|*;Xe_pFgmH|r*ayIBvq^YAWA95&_D-$Daz$*5 z+8G;c>M1zx3jqp>YO_lP-(XWtKh297u%qBxEV_hlPBO%@(tvuo;sfTeiG-|_mI_$d^Xf5Qrdc0^ZUD2Juit!?GEe_}DaTtuG(h{;3ju+pgzB5;x zg&?(j7GN!zFJXKNxi^9wC+n$x^U%Uc5m&Q=a1alLvw{wQ!WY`AhSATUX<>&dUG&JX z_9~|aVHc-X(5)F;lkNroRtt1Sl-i~P*~ksms|1dwh3$c&nZ8+fO6WrzL)RT2hum;(55gnsuLx~O2&e6%| zb&FpF(Gf)VB6#*!L~1d)o!x`mqSXWGQ)rba!C<={z0NKw759L)$Rn}AY3GQ8si^CH zGI_V+0sd=FCbR% zHZc{Nx;A3yr6o0-h{*gd-zKPAy+JRaBC`;x$np>9#hL;R$R}&gx>iLXH~zDaq@WdZ zaTH6n) zkR@y^C~<|)0W2134VHTF5IHZ1B1fCY*207X_5i2K=Su}%H6Np0@Gy*XjJq)_f z-nRu3K6X>3WQD$@^l*+G3#YE+v|4wPDy6Y-^5w^-RXe@0Yju1oZlrRSYkWj;i_F%Q zDAgP@j0w^<-$0s*Rw&mYl~E|;alF^3XBo6$eX24!`iciBw!IM0kiDQ%S}6PrUC0Xp zZE`gSSOe{SQxR&l05;=zyE&lR7N7+`8FAyhHM-NGZF;pYI6Y)dAJ;&PsZ(J&vaA1+}e(u?*^?$18K3`(C5#)$+T@l`~IuK!@M)<$vgC_pbWB99`2{&}jlIsbf z^;bFo7HNR50_!~*BF@K3Y&3D7T-BTqOzZq8Vh9s}ySj8fSB|HC2yI+%lfDs{!RZal z4JeU(B2NjWR$K{bpsIes*3QGuk@86>CxLzvw1U=}*Vfec1v9;GyDTWZs4qai1!jXX zMi(gfj%ia5mu&x;M*F@|PwGC==MQ~i??3vZ20v?7GI)lM;Cx zn1f#P7>C+lbG8w=fB;1=NS&9jRE)US45HH$tJ4(x3pu?F9c0bQT-Ei?ODe)~t;|-} z99>to_MJR+%}N{4nW|?qQ`cpy<)BbkzNC`UwQ{*S!fX#Lhbun%xQmclj~E%*RIS{Ar2(;1zIYx-M2EK!WJH&W@!}| z=hg!)NS#n=sZi#1OrvvOwu)&Y&x}7ttamio{r|@(y85FqA_^^d1Aun@K^sR+IE}+I zpB5z1Nq$Jj$el@=YzjP>Y9iSboT7Os_zQ|4WM*3>(S;G}sjoPEeX?Bd#Bh=NgI++2h@4_h5( zJ!@9#$x1M~qZ@0JPhz^`o0eqElk_)diQ>bGz+0tlXRZ{pZ5Vp%nw~z{5u_vCrOh8p$eG9Rg!LVxAko<>-nAaFN|*1WSnhmsgd9VU3z0^e zgEkH1AGaHDXU|A)qlG@O?dA@0(fDPf5usTdN_MtG7;E)T zm*sxt?NJDKMq*iG^J{JzHQ=)$#NpoVH#e||8pLM}8+;|Oq47YybD8pUi-#P1M` z3wMbSg*;xuK;KeLu&cW#LG>)50j$}6A7PN@BxdhJ`g3H-D+X}cYOcJiPoDLMwI%X z|4lS48~M?6QuKP5Y0}i?A3PsxwN}fBO{+Z`cP47}XuOnAk@X0H#Hc^&DhMbGlQr64 zmZsLYPGHWadQg_n>4{z3Z!@o=CHIBQ#b*7f_Lfq z{hY&QZRD3K?iPdht~In2RvdBvu&uBn`XJs1H246)sG|CSu;B8W==m$HTN$gcZcown z(ks?9$OO8+tg+^?jIv>?4dcDZ+w<)RNiBd}`(99GnDT6M94(@B9T98m;tMkW7Yw--x2H&SeU`1peF&%XL_heD zYn@H4T=|?D#a6G&0<;)sEh<+o#arRyJ{)vTu9j;ZN|dAdsjTsZfB!FoT$b3KuINe- zeOGjuxM^Gh);h;?|KTb)6W^7O=3nAw@`Lzc{KNbizDRgbctQv;Jgof|a7#IlDmZSl zoF?bG=TuJFMDS&Td1W2JrycvUFu5bH-k7C&URIs&Kc}ABW$?VH5=|7KXH_B_--uMB zrNt21ggqcBs^@(HohQVd!D*FvBeqXub#fs`y9DgfaoiT|Ctb*y_n;@1Y+2R2L{Crk z_5K6j1Z7UoUHmH0;^r5emY1usGyJr0fCI+U=q11ZSOvdu-PzuCsp_foQUXGdu5Y~s zfEY(9{uTBwyc$GE2ZQ~;z5m82_}^wF;NKyididiNE3;Hqv2u~hR&QL0{(%xc_=wW= z-)2H`ZOFH<{WaT6`GwwWh?Bd)o+qu{x11&l2V-mF{my+$Rc0SR#V@a0te)-Zys6s4 zW%!7N#vpz&P~ks`Dm>tR`}Uceo}X@0ilJ|ZrxjMdnNou`O>@QsG9*3oiO|8L$|LojGk3dR+F-adIM2Mj8WDB_OVx zEaIBdfJ(a|()h(ngZs0Vgmp_X^Csi%`DeQT2m#eez#b_nZA$pscb2Qurb1r!Lncy) zK{SD3h9ZC|4-CD!(*=!YtV_d+4IOk|+=LrZG2kf1AO<5~+;pZVmr@4a-X(8Dr8$z< z)jb#!0f__b++&uSJkhn$1_e7yMLP^5G_Ifc*rsw$pxNZO)dshr1!sk+xZYW;mKe0; z;O;wnc;WjCRY%Jbdx&!%Nb{vi==2!T_Ib_Gvdm_1w9K@JQRyX3m_PyYD>MSe1Tf%213lhQobn}_|fD?J0vG^4;! ze|?1&&{|lE(N|QMrMl0$U9fIN5qoAe%Me2ApbI1a#j$Q@6d z&A-N_&2Ui1;9uhMFM1J18+I!L;JgM4XD)3qf-bJp>Gef2Ux;l1w2l_(5;J`ngy=bA zT$eN)nj|&9<0=<|_pNgE*F5l6+pqcbSBK>a>M$$;;o?3FQY#T7tpw)bJ@~}BvcV_TNcv(FcC41eH>SKqeO-Xq zrRO7-W4NP~VFGuyZ=~#tI|%owU>&R7QjNXW{~Ut?MTr)Au%@DC+ZULgGUYCHm;*`0 zDxi)4v7fND?6nCo=lxhg%HTC!LjL38Bdv!J=l_=(87H@JC7No~Kt z=`T*LrfCVZBdV_6wrCZvFEGF2tVg8R52zDCztfyaanxtQ{9|KMsj>0T|4g@MKC@)N zn5Y3!W0ovkp85Q<&)K5xnR{>40}nm;VASX(nG2s@JTL08#kPg2;Xn#6$KKWfpp69hW zFEF#HsCkQ?wmnC#u$iKwqUM4JT13ojMgqnyo)AXB+JHLTD~kNKHF|%Ic&_+ix)4kMJ-u6e{s}; z=NHcRhyDNV`*vhXY6+`fSL+z*Rd3s+bI-(Z_V|*1(z@DrkFmnI?^sYD?Y`iBt2vvg zZb(rf-QL?!?yz-gsE#hb^eozcI$f)5z;@#JSGaGBu%U_-u={X5@SoWOcstp{c)!A| zc)!Xf$KXbvtB{^)y;(0zO1?BfVs>Z@4 zSy@p_7NCmEpZk0kDh9JIT!I?1_}QqXOP*hB)9cd1QL$OrD~bK5*n=AN2xDK4X6&W0 zEUA~3rId|lF}BAX8zUw}{b%1q<~TikdD$al-r2R(vh|~b|Mh&*_wRqJKGtX1ful*M z*LWO<#_!p%^^tWaZ~j-alDBQjn9B7*?|=MmkF#5>-2?3fEA82b9-VZ4PU68i3GzFy zKT-5XR3Sh0sq$Dm?R`Z8LU~>^NG6jhteYWJ4L5Y*^^?iIw*k|Tzkh<&emn-IctTZ` z=MBN+0igc$qfbBBvDx>q;5V%G@MBx4cftx_`)4&u%8XmK+dppu$Me4@ECy~2W;5GA z<*<&%EOYy(RwJPezirRuJK&h+?e}zHcfj3q2i%A|;8N~@n|BA?vOD0`+yVFQ9dJAE zfcx?exF7F;tG@$IG;mQoe&W0QyS{?_A3iLJj#D!>eNqaGkBNz4Y-uLd>a4j>FJ2J! za1>fa`^vt6S|R%UBWsBmQM)&};zO-3JZ;oq$RF2LP>eF9kry*9Un4 z(5(yFKRt8?Kz~ue5GbRI(~&}Go&=E8`<#-{1%`Se))j{ST!GOcar&PE76wCqkil@I zozb6UAY1T&%(CtX@I`lwNAv|iHy1}lvwn@svl#Kv@(}20zmsnPzn0r-i!4j zE@-Cp#p7uk3KG_%eg1wgAZ>@ff| z2f-c(uz`RH0BBa9O$2b7fJp#osgNZD$RuF0hPf!R6ach7fRjX&j9)}#h5qp8SCLI) zy%B|1WYbw+Bp&>n0VkB1fu#aih(G&bX#id&U?u>XT4u8V(7G>s0ssv*8QnBO`_CEb zJs$jx&m4T7WS<#WI)DrUG62ja;3)vl67V#DKN0W@fJFq%1@IyP^8nZhm=7R_fCT`S z6Ywm6mkD?dzzPDM_X95g$Ro_30OS*}5I_L|ivTzYSPWnl0ZRbL1S|#c7Xn@c5QP7T z0{_tJ2*?8P0s%GviwS_j!!ilT29Qla4uE9@ECcWo0m}j85%3a#KNIjWfYk)#0*EjG zSOFl3fII-B3CIU9mH-C;D**)nL2_23k1A{n%acEo!^A|bc28*Bo$SQ;jgSB*lUFOF97`scn1#TWNxKt#rz!( zf2Bfs7XfNCoBbjG13*1_Z*|(@r}-oBPrt9$DB98J2{Ui;r7-Y4hz~QR=Y0TLq<@E# zkrLnP{f{*N^84EA_w|2=!%O z-5u`Djwab@Uf;ofwS)ay2mAF7_8T4Szjd%Tbg+NHUMQZ{ zD-vzFFSL?4C_nc?SL_eXVF3Ewcyw_C(U(1derOOx{t(Fap^%Eh*n3b`wn9(&1S(1e zw38E1OzNSN2;3Ecc(qb2M~aSwY@{15ce z1MFq7jI9w5vaMnT+bMp@_KAnt0r4wnS%;V^e$9-ADi&t=23>PC)K;9lHymU48Gc~* z8|v7DhU09c;U|`2ILT%h`~@hoQtoe1iZ~!}z@OWsLDj0rm$ikJ_7#~`3c});CqS*`13rSK2_|^J_FnZ_*vpzc$m&Gl9G`Nz;{sVkBVB!oz;qztK(y(tZ9I5gD{?tk@l3EKY2W9~BfknO% zF|a;_q*?IxVN4o5-gwZhQNBTsj*RR;0D|X0pIudvPuNK>*6)}L@ev1+5{~B{Ej-N! z(h*81EnM(fiv;}Bz80T9a9|!q8Loxv|MtWnfyP#pON!5gfexNmMEwiCX?D?X@9;JF z?f92AEgZ9tKG^rg)e;mQ`smi@1Bz!G<##)A;6qC0M}+&B^}@)IUd3>A>>%7{^!hiw zsLa@I^0o&IaO?$RGBW07+ZH_iCjd5@s~(eWW7fxT>BSU$#^|4M+UM~{blX_n<|Dzi zU!Z*4N2!ryWXxaoybS?jHrTc#bN);7GncT8r=MApX=7u@Pn|p?B?*q>Ce4^SZrZr% z0IezGmd%~Nl;QgTCUo&x_%yy58Cml&RsC$X4$WVjy_BUqGIned!?i!7@g6ft3u)@O zM<$L*ML^mlYDU(JEF&v($r1$c^fOs3W8Tt*%UQ;P=br&un=sB;lx54DyJ#sq5U>=k zi)dz=WngxRW|Zd-d~jICwC9lCxtLbgY~vQ&GM5uLJfj`hN|TYXU@0cR5wj);N`*Jqp~7@kwt_%?5s(lv%tiU zYP-p!tsrH`^Q1?tPF$$txGat4fH$XcKEj-Em#g=|Ja~1r@X|dwX?Ax~?qm+SFRL_{ z0{&$mV$@4ut~$H}6nZV+_H6@P;uM76?}b0^g+FfsFvubDPy`J71*LYNe7a=QyJt)r zn7aR$y>m8zmqO{@mF1P1&8R=zo#1+u`2mDwnebky?*J8u>&nP}bW6u6^*{M;Rd&N z8vA?ESZ!D1Pc}1N?0N8lENai_>D0J|MRV$10vjIucO!%k3(;#uDc`BJAPkQoKh#+Vw-eOTQttyN@$Ct%VB*SZ> zb}8|i5XBpG;X4pjFMFmU-m;PDSpMx5h4F45sdVTT%JPXZ71WKKW@n@Nh$$T Q!=5^Qd5$EMi!7u604mYq8vpX3h+gkc1F|sEq?i{1J&rYNR9}zcK-dVN60oP?H8oFc6YBbIyPk zlcD1UCMQIcK16O?_1Ta00?(osYtVNgB_XN!s1RD^heZmaGaXuOwFF3*bH8h!Gx;Tb zpU=C0+`ry|J?FdjS$prb*V;eUUgzZDrC#ACwu(6zW19AX_yz8CO+XS@ufx4+j6jI7 zkCDzGSwO@f9Y*r7Y_<&P5hN$l{YVp$5|L&JtHo@jX_VMQtVv|-k4Tr1OePnr7hP-t z(ys*2J)%-bR{(G!AKouz}r)6pwV6ZD4zmmLh$R?SKqB*;i~Q>q06+x-7iO z&LO>nv;is1-ei8H45Z8K_v}2^`aTP?Y3vdUAiaq+iCtm2!Zr3eyT)cB-3DoL zkuumAVXuiXi5(Q}NO4GsNVSmaFuPZ{2NEVCC5y9!%fc*SI?^pjN74J0NaK(`6;}#< zrj7Z~~JSfy6Wgztm2ZcW)y^ZuUBp1?br13}^J1Cq%N=1rAn#}$tOhmc`={4b7 z!6SYv>_+-E(gCDowhUVRuUzk~7SjXCUBbR8N5`w_B2!cDVJ)X$dxkYjKVpHDwJebS zJnND+U~mKlp<|}P)GqbpeyuTe!;EPUDC1Jq#iH-p3?;$$#b+AWe34ScOyKWtUdW!C zI?bYd>^th~ITeUg*nW|nxZrP3@L%{kkn$93?oRu&I&+S&L1UuFdXR|$5O0}Je3hH^ zmB$nsEvTQFP6tu~5Mv8_^+zo2WJ}w=hf0o)FF*0+wU%!6%ifH(^cJa0I9O!a|9eZ? zN8jv<(~@Ueb{@yb-1!j{vX33TIgspUfw+HRcr?eNWqO#F`6N;u(i)`IY^R99>e^|? z5KV7M=@NFjQ5@W}Eb66wc}-69(eeA^*w**%WuZ+hrIp=(bbKJ?QRwG!)@tTNIfx3@ zYT?9k5S6S|;>1c2)vT3GYCh6(`n^fQ(ebynql!s~lOJWkDXnI}avfR#m+MdhTuJal z(mZ1yezgskk)E~b*2HrUMT`&*;`lGrLRQ@iOmlOmeh zmv+VdL-ot%ww9C4$6DGRS@6v-rnc>B`QxU)Z#t#6tH`-rZeid>ZP=>`@DKFkiLdBC)cqHqXJ&mTrBzzn=|*=+s<8+ z|B}%baI%0?OxMys5U4L1nxthu#dgMG0r7W;>PhQsPqIL=ho!Wfjya@Qcv~55`!y}_ zU~{hMZ#Vz_O&X|w3s?iW;%y(seDKW3o)bOC{q2JPI15kSYHIhGHymOKO`*5U-514w zGzCutO~;xJPl{*696N~l_i4oYXYgJH@0U~0q@5Vd{YX;~1DqFbx^N;~YWlG0Q`F+W z5TA8i5wqGqd@s=)HoZ62yx+pM8aCg52TXpedEcy~nd zQUaXP+G#MOxHHS!*U*;Hrq7eo@-p?};~%2sV%018BVt2}+Bx497rdmEy3|ffL<2sj zm8!>Df=&j_u)*J!k!qiEIDdC7s4{ zqjtX5$XYdx3LX&|wHA(5Q|1ZBFC4$1y=Itf7u0;4S|;tR#qOZQbxAIa-!3U1zv26cxue|H?2H7;`qbix>g?-C z$rn-sCHB-nu1!S+ujUIKWqrtrLr$!rOthmG$Er>{RdAOzbzF(a+g&84s<-LF?;MTx z0>zPl6BQGyMPUAJrq?B=2CO=pPD`lUtjnn;=LxSqBHQdqh6%hA4++GS-J#Iz{du_)RI8jG3cjnllbnwPI)O}XYBSWV$Zs~7#(G{rsx z_UAnm2N}aWNTAYE2ozP*JgQf(!vYuASYarWB*cPFYiohako4ooOX^AW$daXL?YA5c z8!K49ifNNPki?qHB3;hDVlnLC(aIQL69L9jB7Lyisu|4ecZZ!&o0MAr{^l`keV^#+jK? zgjMtXVzK#DR=YBvD${#!V<#94s*K?EuN1ZGtxSY=c)L&~-($5L+=iubhQQ=$1C2^Jot07^?;!70nCoGXerZb+X{O!o zYtTk2aYj?Km|_ZT;tg{nH956?#)g;DS}ek?d4(^JC4lM6^aPpJz#ee`W$SmP8s`rEARAB_)`#h>p{hnK($9QkN8m zMRr?%FPWZTJbcBEZ_Puy>Kx4LpAW~`JJ3$NC2 zONh&u!jM>A6?55J)g?_6g79lHaSDaA5#x+i#uszP8dEVgfShCfN;Wh2c~I#613rvV zonABdeK=ez`8B~95{pDzbcH9K@=0nQn55sMNs5k{m^^fX=F<#~xvYE^^+c&;iRz4< zHA7_Xkuc2h3q6~@Fwq#pHvUtluSv#aF~$vfQO>^MC491k-0-TcYJOjb*QQ3)vwf+1 zvTv5B;ACUjb^e?1ZRfv|3ds-{jma3c(oUnoN3DGrF}t#Q6*1fro>15-GFQ*3TiRTY zaIX~0AVw>fZNqaU+oNh%TD!3{Q}%J^|fpH9(17q^$`&olnXb2u1w{VYaHKCj9aWySpE zx-urML_THF*614Ro_+a{Pnp&#%z+=>4c*;W;A#~O0@D~i_R>=Kt*vYho{h;Wj<{pj z!aeSTH-&m)vDfxbB;)W>OiNL8k=8e~qtR7%eI-4_vSVY)t(;Fk`bB+p3r_1ZvC&PZ zX9J!PKOPR|xfwjz*l*+|L85a0gnS4o)%1XqZg)MPi}f9+iad(wo*IJyC8jkd3-{F^ zCKL4yEV_Z~p00l0Zk;8#S~mzd>aP-w9TuCY-L>-pwo)+6h&3Tq!|8?0+~kztv5iOI za9Hkep~bDwsMaA0gG zOAFO85>dIEav(Fd{M%?PPidWJhL&xH=VB~Na3l1`P?~hZ$7BUwk!}SprtYU%2YC;e zSrjYbRw#}Oz7g?vNc|xZxD9r4>y0rdr-vu#GpnO4R&&N;1>S*KCsP^jKV#j;>5{wl zpM>7zqn39>=A(yeCy#1F-?KVBvk7wFL9cYc9JGOWa6sc8`@jG*x{jiBVk!(j9OiyF zERV@x2t?f4fc@bl!PpcF=;wgMui@OvC8l~}bb;T|&mxZ>vGem>v3b8a{{4r|eNCO+ z!B2KIbxt^p-$NW9B8(w=NF>$`mv&(9>vF!qSf_KhtIHWdti@S^FdhXidyX$CZ_nIp z$&KXiZn(GbkpgLpb5Gh8SZ$9B(X0gOV_70rL<HDZI}9h0tZ%U zDpH5no{HF_oR~dH9%WS7_?O@=EgTH}t2yv%uLf^ml6;Z)Gd>8k$XeINCo~7!+~NVM z)inIp<2Nj(?wR_zdQ3g(3p;$hKlJ1_z5KXYZJ#lgc}<}#vwHIQg>>zgNkX}hE4(5U z3cnS)g(NXWOcyr_E5w=N9MLKMRs5xCo~g<-*5c&<+`@Vxq?vrz+1e}qmM1hJyp!-H z!tgl=pYt8?Xlb%}^LCFG`jO^;{R!=}cPybNHR5pqt<;Duw+B*Vrrl22ws(Y(OAEbj z!tR4{WAQsB(dxS{dPW4$qjyZ943se|X9MV2@{YI( zyfJO-yN{n!j~zdE{G92KfSgcIgv$QUO(=_}`vyO)*FvWvBtQb>`Y5sihzTU|SD+6@ zIHF7+1O2PWySA|XU3)m@-GqM+iKja^dNkI#agD|{Z?DmG!85wUiSODeQy9p6DK|IZ zwNrl+m~2T^$AE5-wj6khf&&>b-O9cG1N9nHCX@NqmRjw?E&i*ToUEe6By73nx2J@~ zw;fG~fVeOTFebtN0E5Vo(K?0pG*4Ut&_pBgtES{*+c&fc0`BI^iM({hN=;c6doRRpSUS z_TQKQ(nh46g>AUm@HPaICVI5R9bM>oA*qxt&klm!0) zur^9v@M_@#+_u%%w@$YB`j#k3WW8An7gB}dGn@f$Br%OiB20+bu(a0^e7kpH)~UwJ zl!rh|?A|HCS9+T^)@Z?(dQ}JkiSI}|l6E?^$(%hI?>roM=aHsZQ}+a)>RqsK(~%2S zl&I}Je-$t>?NsWX=t5!&R`j0#I_6Bn2=zlWvk)wy=3bZ-M@SE_Szb zx5@biOdKlhRj~-Qz?sBw-8(60?WOff>G3t}c0FSX3cXguV42LLUI@Oc&NmF__DBLP zq{c3A8t)(n0=arHlLw~tkYF(nS@*}4jJUEM#@2(@Jcdi>vuIpy0SRju%@qSDa*oO0XlYUHj%!oW0ZO6?=i_XE} zS>@J$-a;6T5(Re=N7cJ+RHjQ7zFEu6gQ$r7>lt8f>k%6^oj#FKRkts9cGvpX74dur`Ka267|ff>k`8eZ?p{psvw+ zJT=O8mSW>ZU(hH;?#1v-eYnCmc>jtv_@zeFoP6wZ0Tncr7#V0b95E_`>tHt=W*+)! zT`sy>q!%sJaBl37wEWZISF^h0pXs@-{@l=SO`*f4F6UVdt4C5Nq)XkiBj8PZF-BWI zzv*WO%u_YECu7Jx*=RD{lM5_Spnvhg7<}4rmub1MTv#JKEZ!?*3HJ+S!eMc>$t64? z{7#r7ED%EXYoX;PU;ZaT_!s`Krfh0Bi>i0F+F8$+g7a*6E1uZGP53p3pT(~jdPehA zeezkztATQa>JXDSoz@M#3G!p13he;iHjO+$`^bR=7B(GVtf$Mt6f;!-`+Q3Az|$_( zd3KW4h!>AA7kBjdTsD@u`&f?X@3_g|@F{D!i7Hm&HRs9T4rJ8m zC5B!QgN%iCi^J8nq3W#GNRQqV3$mxn;}FJ0Gt|<6YL_;j3ExIM+r>xmJgJ~?ILD() zdFu(mi`OB*3)H+r7PsvV{rx(cPZvX@#epuhYK;?}XK&P>Ut=5fcO>)v%%B=&6JAjV zw^F6NN0wG>!y^H0h^|6^bkvqgcD~2UNug)2?>qn)TCd;NZw~!CLVPT=PoT;aDd?n{ zc$ekLJWJSxAtxECEyLiXICi4FZQY1%d`NCpE(Fp+e**hvH?~@goUgLW z6bYjtA$89_)^tq0@|NkuSNpBPgd^P-ZL810QD^d9*^kS2W=~emrA|*;dnVNf@(-zd z?mi^{Nj!G!u>TVV#>j7#Z^Oq!Z@}?MgAcSyp)6-{~MF`C;3Wg_}#Sb{bmL`tzS^^$k0-yOJUFZ zBOk24uPNyJ%M|zBzUy}PSl?epxgEailH2b4i^H7^%Due#fL8dOuq0PloLDsl*fjTGOoPK!sbV>hOg0^ z75^ovxTMqBOFkp5pE#dM2Nw%?i#2G_LF2VMwq0)bDVEEEpq$^P)=i$KdZCF0A^=c3(p;9KxQ{2pXPd*qKx~4Z`<28g5q0BB_DzS;NT~V()2{>jwm7^lu=HGMjTPU>+IPD~P8T3J5h0eBMN;NO3Q#n>^Ps*)g}S z{wa6$$|q#Uoy+fX-1mcN(;Rc^+%*-oD;x`I<(hOhui9I^qS8_6cGtN_+Gj7Tt#hxb zsBzT0>sGoe);Q!!_nPY33c0$jcBFl1BmWQ7g4%jTcGN0smQ}hPbybdPRLkr1On0zJ zE7;)YdQMgKvbx%e<;$z@oV4OD#|+0Lg||Lh6wMaNX0s)Yv5eM|Eu%z)5e6=cWdQ3a zUYjT)aEEKOrir2@o(cf!*F?Ha1kFa^wiWbY#koxRgjG=icH^`fMgFNRA@|NBpkG^*r-tLcY zkhlE?dAn|qN507L`npYmL&QJxE8;80Q2r-3DqHWau9Y30N)nRB z&{!5(lF6Jj!VIXc_M5LMLMVq%+`dLJ)eT+SJgeb;{NpU>aCW?uon1FwDNmjd^KOZTM zio=2uFY3?v!J(I?OhpXf0944T=H=vyZ20gTNe zK-&$U$}s>GnPag?bhg0kV2ln6EDniJ&v<-`PajF&l)!Fb^o8h6qxfSd!-xLkP}f7K z9yue~!;B>X(3iJt3;=~RSTa4r_mpfb0EHpgO#t-CAPQ3lb})7`0Da1U1{ga>fE05I z-?ZRcf5zzJ7M23=kO*)a0DV}(902sS2-=}Wag3P&KwsS8uMiMh!Pg<|b`GvFeB;lc z*--*Z1)w*%><$2m+Oj(VS_qI8-Y0N3z!?H*0Q5ZxyN82&1vVMt(^s}E9XTT2ld*dN z=!F@Z0`LSr|7Z6BY#=ZdfL^rWuMp@uDBw>I7^Bb|{#N2-fRpq%*tjRY0|Y#;!OS0H+B&0q`k-YJjr@RsozNuo~cV0yO|%5O@+}&I-cp#?X&ow-!AB zeFS6xi5@8iut!0x7p0il&hULZI0)2&aqv~ogjf#-q`ra(u7gWyKJ;2Yl*AAi zdNm9sF(8IszM&*d?;+QZhfp+phF;GOCE33Wqc;wtHw~jV52FLa=%!(`I*e`}MsFEL zw+y478%A#(Mn6A{eqk8BZ5aKNVf6nPMsFWRzc`G>DmvtPX$XbCh#5xz>oEGK!|0z4 zqkle(et8(Zj{V~ot8TSm1dhO1wPV?j!NNKc>t!6)v3RT$37E=>SeZsMFLsCZSV#TX z0XAdJe;v#H?*95j_B6Q67|FCgyD?)3F_f4J3V)db?8nMXi=fE%AcuIP|Kd3>{g`RN z2Zs;dBaK!I5tM6W&_vR=OFhTN`SFVj(~)*d@MGQ)jSQNB`bJ5#reUW9&CoZ#!_vWu zGshW~-pT9ZB_PLWV&(N>_VY$!jC-0i zW!&7A9=Xn4`E;ebj+Iv|t8>e2UT(pn#jaU+=&6(|+$+60s;u?aGuP~S^JXzu;o>>? zo%=B7D#)3gH@CQmxZq05bt??y_S8@dlv!U_&&t)~aWSGg-I%aW&Q@mqhm%uOBe@Eb&oa(F5$iBYbsslnr_m6bAT z8hm@A!p+L7Jr%P26r;X*mnl`?Tvt_9qj;WR&_xBwuHV+WaTo_>+-vmO%kviH=N2uR zje6v|3RbSv@SFZyS%>PPmGQ#`RbPc8J_$1D#sw*Nx)vAZgQ3_}upqxE2g;xh*aZZg(w4Qu(wg(;mRB z5Ccdqs$N5-pQx;;UsmBE2-DSg$x4(b)8HsyQRj)41}c`XgQs%p1~?ll$s=B|U-AeYNe)sqAs8D?JN0isH(_?VSfRM&EW zD-E(vkq794%8Ht~Ub$a?g|JFd-HLu%ZyckMRjyg3R=^VY7Z9!z@V3R&^!C70LL%I-R&&Z0$ydTzyvRSLSr3s+UID}%dD!t z&V!p#COUz0mMkb@g*ipD3v!F;o|9kfVueKu^K$ap>>~cu`S9$#yhUhcPQgOHfbf-r znCBpSA)8xN>dHaAc{zpp?^Nb2%*k2Ea&wC2vIT{+i;7B#yLirG{8@w3nYXxbKEt9j zkN?bOB?SwLa`fNXERUDWqbZ6t$vJx=%UR@PMj<}YoDB1BE|ul0R{!jCIty}gSmE5+ c`A+_uj~Pi+(V}_AJ&zUTY$X0MO)B4S_HVtnR7V92Q6@fah?|Nr`BTHv^n zN%tp@FkKmE=8EYo5mT0sj*BnvC2jm3;!kNK{`5}L&+mi95nRr^w>m(?e)0SE6Mxy7Zi$lBQ-7#;rrKz%=xJ+m99^`XS~A~{0RYaj3MWSe7$Pl z(1<^!gS1^t`&L}7W}7HsovM?B^`p=)aE?Wa)jaE%_Xc=(u=%19N8X zoL*>R;pt?70H<_wfIDSW0yfIX19}mAak2>cYj0QXJ1ivh9!r6dR1sN^5baigT8k+m z>%}X+D{NK2AwtQCr-^8YDEh=}5T*6`4H1Zkzs9)lxnWNP(&hMjNPk0l?vj)fD2<#O z5wBHIcclAS#u)76eedy`#IGLdg|@3iHy8I)qs|xE;8vWdCjP90OknpRX8*o${P5?# z$ow7O_VWiBO2xjHpC#RthRLQ!PO${*hBab}h8-B9|D4Xfq+w}-hK=iSg=sQjX)+6e zW2u`9Zi&=9(kpMv^r!iE+4Q!QUUsYl7VZfzS@vaWXKvf+mQQ{!W(A0^kA>CeUA>nm z98){^HX=se*tM(&7OC6&-7c_0H$xP?igy=As5q83;&@d2rmd&reB0TMo^{1P99-6O zq~o)e?^`a2z2e#Y;4HF3<;V?ABRj6==mm97yujs5aRrz4gujgI5malAXnI^se)FYe zJ=ce3bQUj}CnR$7ayGhD-kfXCpC1@X> zAsRT@?EaQ?*uok%vnNdCxvUmFoLI=e+`wh`yVU)B14l?WNpwMl2F|~OdkNkJylK;< z(guF9QoKhoEE@P+Kj&{`U$S9k-k)XT!fG+1@bG>YEA}Zl5+>s{VF;On3n^{7Oh~yg zc%9VLh}V1(>VlmYo(V1Z3s@+F4MH;@OSPlj##H{x-&LOB&vHnWv?iYFbkh zULb;kj)bb)^I{0s9$m;W;qln^gQNn$mP7 zK&q-mgF1H=OPtEgp3qN3+{6tG4Y!mih*y|K-D>LQv6&$PyE*i!oZa+liGtpQx%4+T zQmF24-bvg4?4jX$+Od<02O24bjDV`O`L{Gjqs<8g`1uRTP1A>^Tyze(Q#9w5oIfNtqB-3ldG{|l`$B;@m#d1@5;QYYF_kcQdHt5 zwQqF6jt$;X)=?oEv|?#O-1|>W^?G|OFtjJp!mF9l3nCXo+g6+0Ry(h!$O#tI~EQ$Om8(% z$~~18fCz@UQPWyPrC|%Ry&kF&czDOV603rZMd7Qh0qg^*Mg{4|0s$mW5Qv4B5LY1&!8E(F_eJ$B}r1I^?T*GzEZ z#_mIks0rqw305)D^mYRmP1i)z|Is!oX?$=HPddZVK2<>lIyg9>r85I=4brrM2lqr| zrBlPVSHWVY26aFM7W+6-Q?rUv7dn_0xG|Q&D*Ym~lStzfR!ZtE15L8~ooT3Ld{ywf zo2VtuPIWb`Ie8XMW6~@-F*!GUZ#V-?K4ZL}3A=ZZa6+_qx*~Xgv~R4VmAif)ZY|?` zfG0FHm4l@xR&mF;#CQIv7z^|b20uL#=$m&M-lrr!g$#2J7ZNDibY(wy&3?mSLi!A^ z8R5zV$6sDGoTzw(7#=7#^|mUDBBif+(kj-K^X-Ptv=Mk2Q4w0D0p*oYhmk5Xp2O{) zPSry-5BKt8K>ibtQ4xcihofGYnzK+yk{jD~HF%VUzYR5V{y)2ECuDqsg)`sxcL>zq zv7NSdIB9>gjZ%0wz&p%zF8fkEE1vg;_1@7(okf8cPAbISRksnhBD8=L&kqcx(^r3t zyI*^!)~n6bzM}o3_B-vUHZHzan;Snneop-S_|x$_5@sf>Ot_qwn1r8l?M7`VsPNt- zJ4SraClmfxmt^dR zk~?O<#kN4%xSqzrflK1qflC9I6sH(S35`au?kg=&7jnBM=QhyLXA$f@2?lj8(gXxs z4TgIaFV9U@)#sIJ@uiooJxMwN#q&4jUbs?YmBeWDzPXR6~t7 zGs5hf`oO8+zu&xkJruf$!{y42)q(!~#sKtWtO&kyJy|901N8=XDMC61z5`+J&}%!K zj&SbK75Vx8O&pFvPlUv%n5+s;xq0-yBM>t;`;@XOsPbq#oZxBKTRy@zvj=vu;y~yG zf#xQ3!s$s?p%Tl!^ef>W9r|KYzT6LZ>s44TMHNTGn)i^oww}0tmoi0l@~|Q}FqYlX z0De}4cj(1Q)iD9iJjF4dRIh74@C2r7os8ZNS6%_X#ur(+S&6 zhsi>M?{$GPK1e2IsjbT3f-!MenxF$V+O3oZvr0)^$$>+4)H`N(CHYQ3(OrChGgKqt zIeWZgI|Ze8Y=cXO^Od`HEjGwLB^4k<0s9q41dCrA=8x)w1EXuRFYNjW({hQRJ(>|b zIT~oLqrvV`5e5MxzBBEEw2P?$E@vrxz0kwgi!_%iwKKSXw0LdH2SX~T(LQ?lI^fi_ z3#pw^f1wC^M=yUD_czZJ@vqR!<4_{>>L|=4tk&o(X~t(M%*%7sZ6v=oyrwW5PW3B8 z?okmu4QhULVQ|SP_#@Yd*Yle3DMc`KRORzT;7d4O%~W`EI6UrA)v>>fRJt6S?Mw6Z zOZEBoh9?}>ZQBL?qAiQ{ci+2mrGAawQD?So)fd}@x^zsE{2;&9j<@tVBNHoK$V3`HIGZ4Pt29*WmnZDzr0x5aB>`~Nvv;PCTv zxxd_WvwoF+;npSk%~C9xYdXtvN?xs2>t-mY(`4mT7S4}bk5YMyWlE&;S-29xGo4bF zRVHEuK>3-E(R`4}Gc1079WA1EINcQG_=9QDC-JsKHK0nD zJf5P9pCDb5CNVKltFcITwnTrxGgI5r6>0d@rLKs2d$xLzsV5SO$Dy)IN zcQ3*e2>l4Sz2C$(;vkG6Xd%qQ#^NC`*jNGt0U;5>egxdDA0kYJa1mh|gewTsAy6J( zItYc>^9%?L2&l_d1k`aRj%6l<>j?J(*cgEO0G>q12Jj%{0Q?SN6~JzU)d0;1_XD&dNMF>WK zbcA&P@Ut94$^jY>DgYb^8(>A_I^t>o;74b|t_NxIQ%x9L7tyW4kcTH{0&k3wABmAS z#mJ@@`Oz5J93yXzk+;OiTVrHPj9eQdZ;O$)$H>+g`LP)J@ff)-My`*MZ85SvMt+Dq zS=pgifDhpb!>VAy)o?^lAxW%;%w*$;p4E~?Y&^+e6UcpRA{@s_WF0yc>AAsdB$eRG z7?2p4JIuf|MoN?28zXrexjcsx33*;Pwst|15(V^X(F9lvAmECSQ@}|;d3eJEs{>sc zlt*uXe@#jR<N3RRSL-6$bAnHM&S@PpSd!q8pRj1&1Y-2lpby;0UC8 z=vbmnN@Ox^aSOHP$BD^g*=ZFZa#);#-C=ps;;<8wd9&Rikb+~Kea7RZUlbxw-~3zn3X7FCwz5tCK0n~BL)Cq?qRwzkgY+)hl=HK7&?*EYBW z=wx!V-Ryu2gK>RjDa7T4c_sN(l|WU-^5W9ULeR$q7xs)Q%N8(zEG(Za+%s9onh-#B z)JC=dXm54c(MUigwrw&vEm5ejK8cDoIKf0Fx5eRvyFHNIS#N$!>J!KcUjx9j4u=gU zz_c=B# zpu5!28l%%(YmpgRsgI83mKCq7UH*}N_#~WD1>WivkRvcsn*_Lkt_@xMbxfN zN^}a3%OJ17EjC=!PQhU@*E@l*eC<|%a*Mex-z`kcVg=kREA3k+WVyPqSu$;%859D; zJM1u8gj%ZuQt~q@qyVd@%vh10Ph=pQi8+dx7Tqj`8;UE*1BH3UlEP9_QCOK*UQ~r~ zVQH0-R8+3Tg%kG1fVmozA+WIKqR7Q0shUYrRE-kdpd%xdvl2Ws~ ze_+o&>3iPK_xt|-zVG{e&pEyK{-clz8ZZI?V_Q^yjOm((K?UPR_k${=XE=Zk3||g5a)Vi8s$+Sl=SsO8NZE^_>-_Wkpi{FKg4vxA%sm1Fn*F#q!pl^r z)`UPBkk0n7T{*i~uUz4sog;1F{MS}{GyH$~lwmf1tj;SC{Oy$yTT#wRwf6)6Y5(ZC zU|I-zR4_ae=+gy8#)8>h(0ShUrL;!R?PkDvv~K_xBw@fOxEJzkbewzMtHSVCr3GKP zX9q9=L~Q`I;7xl2G77%hp_L}1d}OXl`jkH(%zgp;dI+A|3#PMOy~n;+dwOpD@E6y* zhNLgX^LultB4pa#)T*hiBE@NVC+!ryVI=)N{ zM}&3rIIKksV1slia7i~{z6LO09%Fcm5luV+lJ%No9^=guH(Fys{4-A|8k2cq4r#6h z&0~s2s)$LOCZ6uo0VrzbyT*KD%ok(6iKqKBNKNIxp?+^ltyJ==`swzWi3%iZOfpY| zD#o66$U3DoRj1U^{iMngKBWnq(o3KJpby7jm3)HXN=s%Sw$aC*sD#X{^y^BZpNap=?5n{pt4cDl%2v2j^+gO_;{qKa{@c?Cm<+d8VuP zzOu_NEbTqq^>O>(+RsUS(wU<0Y}lc77lvH)9TziOVBJ5px2(idTqb^JRx`6fP?{WuiyA4z|g zE}5e4zet}4bK77fE$D;5Tio&^`rZrI#J}eE2F;Mmau)Ft?%4anrK&n<3>%xDovrOc zcaVQ&;_?f(N@E(fybHpMRDn~RbXNO(2cY5j$iB(^-X6w+-wpI}e|v>?|KEdJvUFfg z3TO1HarDtyl37s99&FD;SCPWy_eMdP%UY>bkV-VqyM=-QuWmr&7676dk{1iOh2Re1 zIlLEZ>NicxZPqMOOLy|4l37z26oM_>bInv(6I|XbM0HY(Z`B07oYb!tAPR|+*oFL| z1&r;!2vB7SUxm6l>92tp^WqMV-i$Q_i#g0g6=F3g%cbMZCKdj#Zxo&tTrSFml;ZJr zr*+uCM0J4u-A66mFAb;-uwaZyV}UiI0A6iv_!(9gT_-Jf3sOIt{SHZxJ`9{(Sa8xk zqt+VMvAVkGdHXbbf~w%8NBjIi zz(x%NnkPZ0>;&14l*g*!H3uOu1k&$!zX>V?!;n{B@CT2k9rgcMhPK7esGUR&PoWuq z&7{xcn%$Q|V6BzRy28~Qc+~m5kt-l=5(Y;`+bekRi#ITzj`=iH%?JceX(Asg$-7^w z;MpY3Ww5PX8Nvy}sP*wJn)e+fCDIn}M~(Yf>Z9M8qA{_2KKpjBXAr`MnmoV+%q0{8%9- zOBFhth|_c3=@vQj?kCVz85^S-OL*3J!qj9$#Y)H4h0OZt#ki=}5{_PbDxNiPX`Z!K zBem+YwbCYCV0`|Ljs9`YT`ieYq>41d+mFrkw`xE%^sASYj-DGm8#o7he4mV@|JXD% zdilqrmpd}eBQv63lZ1%-`+xRSd@_2D|KmhONLZ}*2*TY_o-+%FFMf3t4r?W|K0ex$ zDe~dcs?&QlxVWB*q9t&@RpDrH#&t(kmZLUH_yP39^6F96fxIB}M?p?2{J+uyt$MxU zLeOK#*=Ebxto!%3Fh zA1gdPH}d%y9UrxLen`b>1^uGD8X5wtpk>KuF{cA>id3wZJ_wvt7o7BF4WKKUCTpZ( zU9eb>`)QffqTyGSE?QNqs4Ssk;Q;!S30!Wt)MjE`z3;`%*iA+G-FVwnCPiubZOI%+VYj(47vL4*~R>U$)4PYSFc|c+}Ff#pqyJeP4&V zG*-krh}#@cuc7qlSwxa&_%$JNE8Dj??*Qi9G3Pa|9rGG`TZRTNNM{Bw z3|`<*s!$Udk5SoQv}0LJJvKeHnMFR1QR^Also~geB;0D)-LFvYi^)VvKcM`Z*z3Be z{&juS@Os8?BHa1@HV=dTwk8H0`x}|u?fjwW%-8j#Q%&ifDlHBAG&Ix<5Cv%#imk$) z6Axo&y!m*j-yS&8%)q-up7Jgy8<`Wh%ET-Q3oOuKiC^bMxnCPYC&Ry*ym&PdnWXLt zRhHV&zyV7LTe4J#e||MfEA7YO4ejD1nJRnz2J$P*5fy7o66$Lj5)CVJo>2Wbj z8=f(F^zOqLt0w!^%1~&?<9qOEH(hOikLoNK+{HzPaNYq0VU!NxMQA$IvR1^5#qB09g zKdDb>&0D1XxJHIrZwOaSvAv2D9(T)1VC@s7Jzt~9Q5xf^ZHt;RB^ z*q93y-o{2_v&-QW?QWyZ<8f?rHrbtGs=nCab8NL6?QXZrovL5E+39jO*)Xfywasm7 zGGg{7htnoHT+USeH(USbl24%DKTrQxO|cnQ8y7TgU2NQ}fNZcEIZjY(bUIz;EcJ~n zOFfgr1M>Q%R$pg@(%EesKJ(#qBV!z=PNxEh%5@t>x1kJIIr^b3@iPj*jA>tD(~$KX zeXmunY?L{Cyh~j8c@K&>J|V&yl-F_BC#*uwil2t!7k%l)ufhotoJn$PlH8RfA54;8 zNs><_$$w0eKS`4RJ4ucu$!YS?uJ<=PNzP4@*YGMMhd<$2?%BAR|4G#B#vNqzY_T~T zjCUIw8eO z&df~7oJxlw)sX6(>QA~q%fG3~`xk-nDjl~1m+T{O3y$akxF6=yg9vj}un1u%!FLc^2uuimg2f1r z6D&b!BgjSQAh;bNM39HjNpJ^37r|15y#)CP`v{gL;7){}kY+i;lLRXe_7ki`I6!b0 z!ZQSSBOD|sKzNp56~fO6RwKMfum<5U!FLf}At*#}su0#9JVLMzp_QNr;YS3;2#*t# zAhZ#f5jqG;5kds_AaoLxA#@RZ4`Cm{dW07V$`K9`+>5|*2o(qdK_!BQz=EJ7xDP>3 zP=$~}P>qmAP=ipxBWyreC?Hr7zC%!pkVmi)p_!l#!A)>Kf=E!03v~jWC-*}H{C@y& z4`9;tYZItwHOc#o_S)v@iO5@$pzCAd{N` zIh-C=at5g6QlNoLg~vGj=Mze8md>=ijiX`p?61qOrsbrnvT~)HP zle3fi#H<|n@yy(XDm4kDjVrJZDBwM=K_7+r@s1a+F7l|DpPUi>=UFDqPtKHN#?YIh zEc;No5IP_^Gdfqf(uHz;atW-Lyr@zyI!-x1IyE^)KO~nUzeZKcF@7^oT=n%^d}4#` zA*ipn?{tV5x$Pd&<+eX!ce|k8w%O$tp}4fFa)YH1>YHp1CuS+DEUBuhtb#-lk6pC6 zxA`yy$?o(uV?i-qU41h?2-G*Y?e_Z3jjk=&5I$)mVCMSGZfdvQBggVh!5wagXvdUz z+~~2}DPwtMMQKgtTBvu3E*sQ)8|6s8mv6jxLpgS^p`p?1*$(ycBTEC8X=wI}*w*xD zyUmRWX3K_}3XH2t)|MApYmls#sHNx;%+dBbLy+T#c*R ziUXphx7kb6Pt@RQw#ybqjw6k(QC51yhZIm2>=q|&0gvdm+nPK`l)qssLY3XtSmYC@ zX0aNdhHG3~r(~tLxLG!BqYVdyhIhNLw*(CiH)@LVs^viIxYAOcTLf{!v&5EQ)F!r9 z$;Pr8xTj>TrM#p9s!M9tR+U;QE~&6upt@!~sn^!Xx$a$CUS3%Q>#Ej+xvadTTDdQU z+N!de66L-Y%BxFC)t4 zB?}@`XNWa&^xDIbiP1|R8Ze8d>mv%o7cUQbD`u2rMc$A0N3VXM=k1{$iQXNI^=8Kg zhjmAsIxft?-Ej!iIb16?Jw}W`{}j#dGYDDMTx?=by#|> zOX?YtW}p4?c%G4eSV~@ylBea9)PI|ve~|RN=gG)FCK<)M$td25wu6#Qk~_IgDvUdZ zrDQw7>qV(3AwKW9pY~ptmFRoqx;Q*%LGE77-ZPc6!{Qd&np&_NM)UB988-y*?on;E`5Vlgc)fA!-o}q4<-tkua!l`vqf5Bb72r>Q5 ze2u`4ZUxwu!7N~V2Ccv-V=r$O(O-K{F8ZSkMQ@J-GpVD@IxZXC7IG(N8ANNuP;5x9 zTU+#XN-Z){PxZOdM5)Kczs?QvWm&HXSNhyXmH}aNgHGA$>P0bNS#K46tX+5YUbi@N zLz_LKwZQm)wYtr4rDI#uO8eoZF+*v8&J{~%wdl$!B>v{!kw>#Nj z#NM!SA9tqg!qF+68#I2?B^~LMjJ!@MClN^*`THd!{{Y%S$!JxQYtr>k^k#~*@YmL} za$$$#oP0fwWBlhR&HH%9iA5c6?t1?@QM`v@XJnkkXxTopsFUK>4if2Cx6Mo7$hJoR zy$xCEmdMg;d3}1?5Z7l9t51qgI}-7Mj(6gT$Ev5^unDqn5VZ=>`l4&ggx=m zHSP1Fgzln3W5!uopspTEE|u!VFb2EF;jqO~v_)TE|MJ*fV%TaF$0<2WioGF=0o&2t zgv41c4}DjZ=rIiakyx+%#miiyU+Fe;8_GH*XCw=&PfZpsC6ji2SC?d1J8||?WNud7 zTCr6TmDZz4skASW-DgeW6_J`KB5+7b`ex+_?n|tm^<%7E)>&C%zU8WLSr_Sw-Yy@x z#LiZ|_>z>$7HP{?s~(ZXnJk4;H0p^d6rG=L7~3xrRlAelP<_4lJeD>h3g$8e5%eW8 zY&amoKsLQch8^epr~h)EtQTLA*eT;aGVYiO=NMX6%=oI6M|xcJW#!QHVM7eZ%C6uW z$hJ0l$f!@1i{hjt&LHg%2u1uoc6w&%X?4Qdx@5LdU!S^1D5ZUBUS0C-biJWuMwlox zYbl%}XV)h0M1;|mViw}P?N>-DJsq|k?IaAE(`VgJ+0<LJD3<}yX zLl)ghG4xNdLO9HZHnhJnWTPe6gTva{gNK{Tkb`zh7H&U6dxjwwt&1TK?E=FsXh{a_ z1Zngn(Ih|{!>xdJh93i>3_k(vV3-Wp$&e4&&G1ve9)>A^4u+|KIKyp#y$rVl_A%Ts z3U>mYV~qo_pMi6BfWZkk$WQ<{#4rue$#6H|FvC577a67lx)^2vjx*c~c$r})ASeN5 z0k$yw46v19HsBeC`v5x_<^Xmw6ascL+z;5pFc;9l@BkprFb}Ygp$M>_;X%LwhWUVl z48?%w85RHzF_Zv086E<3G5mZKN=IQK;1YK|3`jDR0j@AqAi=!l_9Xy54faYT*xYs( z9%=mSk(UDad??ERY@>XSR|R%sfW4LgUSX&N>}IIKwp_#Uo3aQo#(v64ny`H2IP;NS zKDHCQVw}8koV;qByn3AM9w$FGPOcs&KT7?zai@aG+DMkO$tq7EyKJXPat{4U&PC}= zBwe0Fzmp#^i;G~XQ@Q!K5bKn;--s8J@1SL{u|T8C`DRUClU~9al`-obsbJV3@ko$N zQG@?la-p&dv?B^+9|G?|MuV+`J#QfXjG`eD>@)8R0}2rAxnB9ts$rmDA)94tI-yEU zW7Mx1bfy{4^gvuL)J$A#ziE%J0P~5XZu+5cWm2YcO`1bxox)FqyxlA@mhUzr zBJ{||_NLNY!Y`((2V~+>6N5?DYp})G+MRyz0hQxPW}Y z))ts+BSAbZc-eZIRG-h&5C}Cs&8`6ej6Dr1L^zpG^OivmUej~ye2o|#{SY1;E6g7& z6yFdq0}h&*2qxiILztllv?91M17Y6?)cCjfplS(Yrk+r^*}KUcsnw^3@ovxP{CN3e zg{m6F>OCcMOBUc!gN16f{$}>}JmvGYG-R{5xG=Dm;ghQUxlV(ZjISiF0QSvTDNjd zVFisMHBtk4>1ocw3S{>^|#&VhiT=ys#;oBx!Ap;auwB7)-JAITF1}IRdsHv Xsa?+M#kHo@%Ec>ItgfK)>gDtwU87R7 literal 0 HcmV?d00001 diff --git a/tests/inputs_base/MAX.EXE b/tests/inputs_base/MAX.EXE new file mode 100644 index 0000000000000000000000000000000000000000..ad93a42c942aad77aef206f204640b65cf4c2d2e GIT binary patch literal 9482 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 Yr^0bhW6g16u#4$pPBCvMA2&Y#17k`Nv;Y7A literal 0 HcmV?d00001 diff --git a/tests/inputs_base/STRLEN.EXE b/tests/inputs_base/STRLEN.EXE new file mode 100644 index 0000000000000000000000000000000000000000..aaf4b48a950031e8cf8a0d6b9c0e626f520a5503 GIT binary patch literal 2348 zcmeHIe@qj16o23A^@=5QY>CZSvU(6960}a3m8FPGTpi1{pqXIZ)ZrwK4O(;Dfm?`{ zoe__3(-AfMVT>E2Sqy1RT==7Pi=I~L;v_mW4q1#w{Bc-<42f1{{qB1d&3^ph|7N}1 z-RHgU`@HwQ@4fH!tu=Fz5fJcT0YbKb4^qDz`aK`9ZOVAjW+`heLZAohWSw9K!<4LA%ckiNNX@>}cb3<}8O&&@pwgC7C3vS`k?@%iN zrqOg17)2Li<4BleDE$@*IfvMDx0gF_3t2K<0MR5_?JlM-J7S@#*I~E~Y++c~m#x@DTGA#6vs1zrDtroI zr|d_DDxwh^&7=xa`xqu+1Kn0W0jN5%2UTeXaIcH5!Xs5hcjL%~*RjOK`j&t+fqUby zZf#Uwi<_}6h<+U+UxrX;5D`ldrK?h$Sob1g-AC{Jh%~X<`J{VoG<8PopL3Or-EUjT zOa|y29q~cowY*T7|76>R-Pq9%axX)N!B@Hq48pSk&JQ?wXj`F5XQs*b$2NI{2_rB> z4aahm1Wy(ug!l1HzZw|upAD!hD((ae)$YKhw(+)$IEv4fYgy2263Vpap!t3YFQ%1b zh-}FWNh?(2*V0wdw6xo-N~nCtl|uFY(9BT9+#K;4HmBr0$>b}^k(f|L`rYX8K+$&S~$b-$H^i!LWr_Njxys1^+PhD znDk1^r9s3?M!Ng>OzdJ)Wmnolh;TtVd~sMi)vIc}mBp`dU8BeulhR_`DE&sqGqFSo zqey9HJLz*7x1P37@9dPdi_16Sg@$|B#g!?n(!z9(=wwcDjG%ZLP8zmyip1bvBMWhO z#H1+{_2&}OdKF-0rFI|OZagL@iNw-eo~Is^Wel~^9a1+`o?=gj{TKPCe~@P?jxnT@ zQuOJ#e@i%>h(?)AH0hDn;FvKTauWn6KVfPZd128e?6e#z`S-N?03{eL<7vG_)hGt~*|;cHsP z9|*p#Yaaidydw!4yz|QWd3?Ed^Cv>xrVmAa&IkGYf>(-*`K4Z=zQ(hWukeWVc6eK= zuje;=>pWtuz}GZ3)@|}M)Oy4W^Rl|8x{bAbtsr=X4D+iSJYJ!phMEfAO+rlrPt69QX-f9O>5+jGn?}v9?hJ;2Hg*+sg##NB!s``U@I+jW_@R literal 0 HcmV?d00001 diff --git a/tests/inputs_base/TESTLONG.EXE b/tests/inputs_base/TESTLONG.EXE new file mode 100644 index 0000000000000000000000000000000000000000..af9999fa63a9176257d63e492e07a691ede6a8be GIT binary patch literal 12935 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 TVrfzATLO_wO4zbejj#U=O68$o literal 0 HcmV?d00001