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 0000000..ae0173d Binary files /dev/null and b/tests/inputs_base/DHAMP.EXE differ diff --git a/tests/inputs_base/FIBOL.EXE b/tests/inputs_base/FIBOL.EXE new file mode 100644 index 0000000..a20a002 Binary files /dev/null and b/tests/inputs_base/FIBOL.EXE differ diff --git a/tests/inputs_base/FIBOS.EXE b/tests/inputs_base/FIBOS.EXE old mode 100755 new mode 100644 diff --git a/tests/inputs_base/INTOPS.EXE b/tests/inputs_base/INTOPS.EXE new file mode 100644 index 0000000..d09534f Binary files /dev/null and b/tests/inputs_base/INTOPS.EXE differ diff --git a/tests/inputs_base/LONGOPS.EXE b/tests/inputs_base/LONGOPS.EXE new file mode 100644 index 0000000..4bf563c Binary files /dev/null and b/tests/inputs_base/LONGOPS.EXE differ diff --git a/tests/inputs_base/MATRIXMU.EXE b/tests/inputs_base/MATRIXMU.EXE new file mode 100644 index 0000000..f018bfe Binary files /dev/null and b/tests/inputs_base/MATRIXMU.EXE differ diff --git a/tests/inputs_base/MAX.EXE b/tests/inputs_base/MAX.EXE new file mode 100644 index 0000000..ad93a42 Binary files /dev/null and b/tests/inputs_base/MAX.EXE differ diff --git a/tests/inputs_base/STRLEN.EXE b/tests/inputs_base/STRLEN.EXE new file mode 100644 index 0000000..aaf4b48 Binary files /dev/null and b/tests/inputs_base/STRLEN.EXE differ diff --git a/tests/inputs_base/TESTLONG.EXE b/tests/inputs_base/TESTLONG.EXE new file mode 100644 index 0000000..af9999f Binary files /dev/null and b/tests/inputs_base/TESTLONG.EXE differ