lots of changes, created Disassembler class, removed a few globals etc.

This commit is contained in:
Artur K 2012-03-11 02:48:19 +01:00
parent 87e41f5a8a
commit bc395da6ab
60 changed files with 2058 additions and 151 deletions

View File

@ -7,7 +7,7 @@ if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W4) add_definitions(/W4)
else() else()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x") 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() endif()
FIND_PACKAGE(LLVM) FIND_PACKAGE(LLVM)

View File

@ -6,15 +6,11 @@
#include "locident.h" #include "locident.h"
#include "state.h" #include "state.h"
#include "icode.h" #include "icode.h"
//#include "types.h"
//#include "ast.h"
//#include "error.h"
//#include "graph.h"
//#include "bundle.h"
#include "StackFrame.h" #include "StackFrame.h"
/* PROCEDURE NODE */ /* PROCEDURE NODE */
struct CALL_GRAPH; struct CALL_GRAPH;
struct COND_EXPR; struct COND_EXPR;
struct Disassembler;
namespace llvm namespace llvm
{ {
// Traits for intrusive list of basic blocks... // Traits for intrusive list of basic blocks...
@ -144,7 +140,7 @@ public:
void mergeFallThrough(BB *pBB); void mergeFallThrough(BB *pBB);
void structIfs(); void structIfs();
void structLoops(derSeq *derivedG); void structLoops(derSeq *derivedG);
void buildCFG(); void buildCFG(Disassembler &ds);
void controlFlowAnalysis(); void controlFlowAnalysis();
void newRegArg(iICODE picode, iICODE ticode); void newRegArg(iICODE picode, iICODE ticode);
protected: protected:
@ -153,7 +149,7 @@ protected:
void propLongStk(int i, const ID &pLocId); void propLongStk(int i, const ID &pLocId);
void propLongGlb(int i, const ID &pLocId); void propLongGlb(int i, const ID &pLocId);
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong); 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 findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE iter);
int findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg); int findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg);

View File

@ -140,7 +140,7 @@ eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c *
void parse (CALL_GRAPH * *); /* parser.c */ void parse (CALL_GRAPH * *); /* parser.c */
int strSize (uint8_t *, char); /* 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 */ void interactDis(Function * initProc, int initIC); /* disassem.c */
bool JmpInst(llIcode opcode); /* idioms.c */ bool JmpInst(llIcode opcode); /* idioms.c */
queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */ queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */

View File

@ -4,10 +4,30 @@
****************************************************************************/ ****************************************************************************/
#pragma once #pragma once
#include <sstream> #include <sstream>
#include <fstream>
#include <vector> #include <vector>
#include "bundle.h" #include "bundle.h"
struct LLInst; struct LLInst;
struct Disassembler
{
protected:
int pass;
int g_lab;
//bundle &cCode;
std::ofstream m_fp;
std::vector<std::string> m_decls;
std::vector<std::string> 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) */ /* Definitions for extended keys (first key is zero) */
#define EXT 0x100 /* "Extended" flag */ #define EXT 0x100 /* "Extended" flag */

View File

@ -261,9 +261,11 @@ public:
bool isJmpInst(); bool isJmpInst();
HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func); HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func);
HLTYPE createCall(); 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; ICODE *m_link;
}; };
@ -331,7 +333,9 @@ public:
Use &u(idx[regIdx]); Use &u(idx[regIdx]);
u.removeUser(ic); u.removeUser(ic);
} }
DU1() : numRegsDef(0) {} DU1() : numRegsDef(0)
{
}
}; };
icodeType type; /* Icode type */ icodeType type; /* Icode type */
BB *inBB; /* BB to which this icode belongs */ BB *inBB; /* BB to which this icode belongs */

View File

@ -10,9 +10,9 @@
/* STATE TABLE */ /* STATE TABLE */
struct STATE 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 */ 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 struct
{ /* For case stmt indexed reg */ { /* For case stmt indexed reg */
uint8_t regi; /* Last conditional jump */ uint8_t regi; /* Last conditional jump */
@ -20,6 +20,8 @@ struct STATE
} JCond; } JCond;
void setState(uint16_t reg, int16_t value); void setState(uint16_t reg, int16_t value);
void checkStartup(); void checkStartup();
bool isKnown(eReg v) {return f[v];}
void kill(eReg v) { f[v]=false;}
STATE() : IP(0) STATE() : IP(0)
{ {
JCond.regi=0; JCond.regi=0;

View File

@ -106,12 +106,14 @@ void BB::displayDfs()
} }
} }
/* Display out edges information */ /* Display out edges information */
i=0;
for(TYPEADR_TYPE &edg : edges) for(TYPEADR_TYPE &edg : edges)
{ {
if (nodeType == INTERVAL_NODE) if (nodeType == INTERVAL_NODE)
printf(" outEdge[%ld] = %ld\n", i, edg.BBptr->correspInt->numInt); printf(" outEdge[%ld] = %ld\n", i, edg.BBptr->correspInt->numInt);
else else
printf(" outEdge[%d] = %ld\n", i, edg.BBptr->begin()->loc_ip); printf(" outEdge[%d] = %ld\n", i, edg.BBptr->begin()->loc_ip);
++i;
} }
printf("----\n"); printf("----\n");

View File

@ -264,7 +264,10 @@ void Function::codeGen (std::ostream &fs)
} }
/* Write procedure's code */ /* Write procedure's code */
if (flg & PROC_ASM) /* generate assembler */ if (flg & PROC_ASM) /* generate assembler */
disassem (3, this); {
Disassembler ds(3);
ds.disassem(this);
}
else /* generate C */ else /* generate C */
{ {
m_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT); m_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT);

View File

@ -455,8 +455,8 @@ bool LibCheck(Function & pProc)
pProc.name = "main"; pProc.name = "main";
return false; return false;
} }
memcpy(pat, &prog.Image[fileOffset], PATLEN);
memmove(pat, &prog.Image[fileOffset], PATLEN); //memmove(pat, &prog.Image[fileOffset], PATLEN);
fixWildCards(pat); /* Fix wild cards in the copy */ fixWildCards(pat); /* Fix wild cards in the copy */
h = g_pattern_hasher.hash(pat); /* Hash the found proc */ h = g_pattern_hasher.hash(pat); /* Hash the found proc */
/* We always have to compare keys, because the hash function will /* 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 by dcc, rather than considered as known functions. When a prototype is
found (in searchPList()), the parameter info is written to the proc struct. found (in searchPList()), the parameter info is written to the proc struct.
*/ */
void void readProtoFile(void)
readProtoFile(void)
{ {
FILE *fProto; FILE *fProto;
char *pPath; /* Point to the environment string */ char *pPath; /* Point to the environment string */

View File

@ -333,7 +333,7 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
/* user/runtime routine */ /* user/runtime routine */
if (! (pcallee->flg & PROC_ISLIB)) 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); pcallee->dataFlow (pbb->liveOut);
pbb->liveOut = pcallee->liveIn; pbb->liveOut = pcallee->liveIn;
} }
@ -691,14 +691,13 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, int num
} }
else else
adjustActArgType (_exp, pp->args.sym[numArgs].type, pProc); adjustActArgType (_exp, pp->args.sym[numArgs].type, pProc);
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc);
} }
else /* user function */ else /* user function */
{ {
if (pp->args.numArgs > 0) if (pp->args.numArgs > 0)
pp->args.adjustForArgType (numArgs, expType (_exp, pProc)); 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 /* Do not update the size of k if the expression was a segment register
* in a near call */ * 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; Function * pp;
int cb, numArgs; int cb, numArgs;
@ -957,10 +956,12 @@ void Function::findExps()
/* Check for only one use of these registers */ /* Check for only one use of these registers */
if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1)) 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) { switch (picode->hl()->opcode) {
case HLI_ASSIGN: case HLI_ASSIGN:
/* Replace rhs of current icode into target /* Replace rhs of current icode into target
* icode expression */ * icode expression */
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0]) if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
{ {
ticode = picode->du1.idx[0].uses.front(); 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)) 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, /* If we could not substitute the result of a function,

View File

@ -109,7 +109,7 @@ static const char *szFlops3C[] =
static const char *szPtr[2] = { "word ptr ", "byte ptr " }; 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 void formatRM(ostringstream &p, uint32_t flg, const LLOperand &pm);
static ostringstream &strDst(ostringstream &os, uint32_t flg, 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); static void dispData(uint16_t dataSeg);
boolT callArg(uint16_t off, char *temp); /* Check for procedure name */ boolT callArg(uint16_t off, char *temp); /* Check for procedure name */
static FILE *fp; //static FILE *dis_g_fp;
static CIcodeRec pc; static CIcodeRec pc;
static int cb, j, numIcode, allocIcode; static int cb, j, numIcode, allocIcode;
static map<int,int> pl; static map<int,int> pl;
static uint32_t nextInst; static uint32_t nextInst;
static boolT fImpure; static boolT fImpure;
static int g_lab, prevPass; //static int g_lab;
static Function * pProc; /* Points to current proc struct */ static Function * pProc; /* Points to current proc struct */
struct POSSTACK_ENTRY struct POSSTACK_ENTRY
@ -173,16 +173,12 @@ void LLInst::findJumpTargets(CIcodeRec &_pc)
* pass == 2 generates output on file .a2 * pass == 2 generates output on file .a2
* pass == 3 generates output on file .b * pass == 3 generates output on file .b
****************************************************************************/ ****************************************************************************/
void disassem(int pass, Function * ppProc)
void Disassembler::disassem(Function * ppProc)
{ {
pProc = ppProc; /* Save the passes pProc */ pProc = ppProc; /* Save the passes pProc */
if (pass != prevPass)
{
prevPass = pass;
g_lab = 0; /* Restart label numbers */
}
createSymTables(); createSymTables();
allocIcode = numIcode = pProc->Icode.size(); allocIcode = numIcode = pProc->Icode.size();
cb = allocIcode * sizeof(ICODE); cb = allocIcode * sizeof(ICODE);
@ -195,8 +191,8 @@ void disassem(int pass, Function * ppProc)
if (pass != 3) if (pass != 3)
{ {
auto p = (pass == 1)? asm1_name: asm2_name; auto p = (pass == 1)? asm1_name: asm2_name;
fp = fopen(p, "a+"); m_fp.open(p,ios_base::app);
if (!fp) if (!m_fp.is_open())
{ {
fatalError(CANNOT_OPEN, p); fatalError(CANNOT_OPEN, p);
} }
@ -222,20 +218,23 @@ void disassem(int pass, Function * ppProc)
/* Write procedure header */ /* Write procedure header */
if (pass != 3) 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"<<pProc->name<<" PROC "<< near_far<<"\n";
}
/* Loop over array printing each record */ /* Loop over array printing each record */
nextInst = 0; nextInst = 0;
for( ICODE &icode : pc) for( ICODE &icode : pc)
{ {
icode.ll()->dis1Line(icode.loc_ip,pass); this->dis1Line(*icode.ll(),icode.loc_ip,pass);
} }
/* Write procedure epilogue */ /* Write procedure epilogue */
if (pass != 3) if (pass != 3)
{ {
fprintf(fp, "\n\t\t%s ENDP\n\n", pProc->name.c_str()); m_fp << "\n\t\t"<<pProc->name<<" ENDP\n\n";
fclose(fp); m_fp.close();
} }
pc.clear(); pc.clear();
@ -246,51 +245,50 @@ void disassem(int pass, Function * ppProc)
* i is index into Icode for this proc * * i is index into Icode for this proc *
* It is assumed that icode i is already scanned * * 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 oper_stream;
ostringstream hex_bytes; ostringstream hex_bytes;
ostringstream result_stream; ostringstream result_stream;
ostringstream opcode_with_mods; ostringstream opcode_with_mods;
ostringstream operands_s; ostringstream operands_s;
oper_stream << uppercase; oper_stream << uppercase;
hex_bytes << uppercase; hex_bytes << uppercase;
/* Disassembly stage 1 -- /* Disassembly stage 1 --
* Do not try to display NO_CODE entries or synthetic instructions, * Do not try to display NO_CODE entries or synthetic instructions,
* other than JMPs, that have been introduced for def/use analysis. */ * other than JMPs, that have been introduced for def/use analysis. */
if ((option.asm1) && if ((option.asm1) &&
( this->testFlags(NO_CODE) || ( inst.testFlags(NO_CODE) ||
(this->testFlags(SYNTHETIC) && (this->getOpcode() != iJMP)))) (inst.testFlags(SYNTHETIC) && (inst.getOpcode() != iJMP))))
{ {
return; return;
} }
else if (this->testFlags(NO_CODE)) else if (inst.testFlags(NO_CODE))
{ {
return; return;
} }
if (this->testFlags(TARGET | CASE)) if (inst.testFlags(TARGET | CASE))
{ {
if (pass == 3) if (pass == 3)
cCode.appendCode("\n"); /* Print to c code buffer */ cCode.appendCode("\n"); /* Print to c code buffer */
else 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 */ /* Find next instruction label and print hex bytes */
if (this->testFlags(SYNTHETIC)) if (inst.testFlags(SYNTHETIC))
nextInst = this->label; nextInst = inst.label;
else else
{ {
cb = (uint32_t) this->numBytes; cb = (uint32_t) inst.numBytes;
nextInst = this->label + cb; nextInst = inst.label + cb;
/* Output hexa code in program image */ /* Output hexa code in program image */
if (pass != 3) if (pass != 3)
{ {
for (j = 0; j < cb; j++) 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 << ' '; hex_bytes << ' ';
} }
@ -301,11 +299,11 @@ void LLInst::dis1Line(int loc_ip, int pass)
oper_stream << setw(5)<<left; // align for the labels oper_stream << setw(5)<<left; // align for the labels
{ {
ostringstream lab_contents; ostringstream lab_contents;
if (readVal(lab_contents, this->label, 0)) if (readVal(lab_contents, inst.label, 0))
{ {
lab_contents << ':'; /* Also removes the null */ 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 */ /* Print label */
if (pl.count(loc_ip)==0) if (pl.count(loc_ip)==0)
@ -316,62 +314,62 @@ void LLInst::dis1Line(int loc_ip, int pass)
} }
oper_stream<< lab_contents.str(); 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<<Machine_X86::opcodeName(this->getOpcode()); opcode_with_mods<<Machine_X86::opcodeName(inst.getOpcode());
switch ( this->getOpcode() ) switch ( inst.getOpcode() )
{ {
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR: case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG: case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
strDst(operands_s,getFlag(), dst); strDst(operands_s,inst.getFlag(), inst.dst);
strSrc(operands_s); inst.strSrc(operands_s);
break; break;
case iESC: case iESC:
flops(operands_s); inst.flops(operands_s);
break; break;
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL: case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
case iROR: case iROR:
strDst(operands_s,getFlag() | I, dst); strDst(operands_s,inst.getFlag() | I, inst.dst);
if(testFlags(I)) if(inst.testFlags(I))
strSrc(operands_s); inst.strSrc(operands_s);
else else
operands_s<<", cl"; operands_s<<", cl";
break; break;
case iINC: case iDEC: case iNEG: case iNOT: case iPOP: 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; break;
case iPUSH: case iPUSH:
if (testFlags(I)) if (inst.testFlags(I))
{ {
operands_s<<strHex(src.op()); operands_s<<strHex(inst.src.op());
} }
else else
{ {
strDst(operands_s,getFlag() | I, dst); strDst(operands_s,inst.getFlag() | I, inst.dst);
} }
break; break;
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD: case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
if (testFlags(I)) if (inst.testFlags(I))
{ {
strDst(operands_s,getFlag(), dst) <<", "; strDst(operands_s,inst.getFlag(), inst.dst) <<", ";
formatRM(operands_s, getFlag(), src); formatRM(operands_s, inst.getFlag(), inst.src);
strSrc(operands_s); inst.strSrc(operands_s);
} }
else else
strDst(operands_s,getFlag() | I, src); strDst(operands_s,inst.getFlag() | I, inst.src);
break; break;
case iLDS: case iLES: case iBOUND: case iLDS: case iLES: case iBOUND:
strDst(operands_s,getFlag(), dst)<<", dword ptr"; strDst(operands_s,inst.getFlag(), inst.dst)<<", dword ptr";
strSrc(operands_s,true); inst.strSrc(operands_s,true);
break; break;
case iJB: case iJBE: case iJAE: case iJA: case iJB: case iJBE: case iJAE: case iJA:
@ -383,71 +381,71 @@ void LLInst::dis1Line(int loc_ip, int pass)
/* Check if there is a symbol here */ /* Check if there is a symbol here */
{ {
ICODE *lab=pc.GetIcode(src.op()); ICODE *lab=pc.GetIcode(inst.src.op());
selectTable(Label); selectTable(Label);
if ((src.op() < (uint32_t)numIcode) && /* Ensure in range */ if ((inst.src.op() < (uint32_t)numIcode) && /* Ensure in range */
readVal(operands_s, lab->ll()->label, 0)) readVal(operands_s, lab->ll()->label, 0))
{ {
break; /* Symbolic label. Done */ break; /* Symbolic label. Done */
} }
} }
if (testFlags(NO_LABEL)) if (inst.testFlags(NO_LABEL))
{ {
//strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op)); //strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op));
operands_s<<strHex(src.op()); operands_s<<strHex(inst.src.op());
} }
else if (testFlags(I) ) else if (inst.testFlags(I) )
{ {
j = src.op(); j = inst.src.op();
if (pl.count(j)==0) /* Forward jump */ if (pl.count(j)==0) /* Forward jump */
{ {
pl[j] = ++g_lab; pl[j] = ++g_lab;
} }
if (getOpcode() == iJMPF) if (inst.getOpcode() == iJMPF)
{ {
operands_s<<" far ptr "; operands_s<<" far ptr ";
} }
operands_s<<"L"<<pl[j]; operands_s<<"L"<<pl[j];
} }
else if (getOpcode() == iJMPF) else if (inst.getOpcode() == iJMPF)
{ {
operands_s<<"dword ptr"; operands_s<<"dword ptr";
strSrc(operands_s,true); inst.strSrc(operands_s,true);
} }
else else
{ {
strDst(operands_s,I, src); strDst(operands_s,I, inst.src);
} }
break; break;
case iCALL: case iCALLF: case iCALL: case iCALLF:
if (testFlags(I)) if (inst.testFlags(I))
{ {
if((getOpcode() == iCALL)) if((inst.getOpcode() == iCALL))
operands_s<< "near"; operands_s<< "near";
else else
operands_s<< " far"; operands_s<< " far";
operands_s<<" ptr "<<(src.proc.proc)->name; operands_s<<" ptr "<<(inst.src.proc.proc)->name;
} }
else if (getOpcode() == iCALLF) else if (inst.getOpcode() == iCALLF)
{ {
operands_s<<"dword ptr "; operands_s<<"dword ptr ";
strSrc(operands_s,true); inst.strSrc(operands_s,true);
} }
else else
strDst(operands_s,I, src); strDst(operands_s,I, inst.src);
break; break;
case iENTER: case iENTER:
operands_s<<strHex(dst.off)<<", "; operands_s<<strHex(inst.dst.off)<<", ";
operands_s<<strHex(src.op()); operands_s<<strHex(inst.src.op());
break; break;
case iRET: case iRETF: case iINT: case iRET: case iRETF: case iINT:
if (testFlags(I)) if (inst.testFlags(I))
{ {
operands_s<<strHex(src.op()); operands_s<<strHex(inst.src.op());
} }
break; break;
@ -458,49 +456,49 @@ void LLInst::dis1Line(int loc_ip, int pass)
case iMOVS: case iREP_MOVS: case iMOVS: case iREP_MOVS:
case iINS: case iREP_INS: case iINS: case iREP_INS:
case iOUTS: case iREP_OUTS: case iOUTS: case iREP_OUTS:
if (src.segOver) if (inst.src.segOver)
{ {
bool is_dx_src=(getOpcode() == iOUTS || getOpcode() == iREP_OUTS); bool is_dx_src=(inst.getOpcode() == iOUTS || inst.getOpcode() == iREP_OUTS);
if(is_dx_src) if(is_dx_src)
operands_s<<"dx, "<<szPtr[getFlag() & B]; operands_s<<"dx, "<<szPtr[inst.getFlag() & B];
else else
operands_s<<szPtr[getFlag() & B]; operands_s<<szPtr[inst.getFlag() & B];
if (getOpcode() == iLODS || if (inst.getOpcode() == iLODS ||
getOpcode() == iREP_LODS || inst.getOpcode() == iREP_LODS ||
getOpcode() == iOUTS || inst.getOpcode() == iOUTS ||
getOpcode() == iREP_OUTS) inst.getOpcode() == iREP_OUTS)
{ {
operands_s<<Machine_X86::regName(src.segOver); // szWreg[src.segOver-rAX] operands_s<<Machine_X86::regName(inst.src.segOver); // szWreg[src.segOver-rAX]
} }
else else
{ {
operands_s<<"es:[di], "<<Machine_X86::regName(src.segOver); operands_s<<"es:[di], "<<Machine_X86::regName(inst.src.segOver);
} }
operands_s<<":[si]"; operands_s<<":[si]";
} }
else else
{ {
(getFlag() & B)? opcode_with_mods<< "B": opcode_with_mods<< "W"; (inst.getFlag() & B)? opcode_with_mods<< "B": opcode_with_mods<< "W";
} }
break; break;
case iXLAT: case iXLAT:
if (src.segOver) if (inst.src.segOver)
{ {
operands_s<<" "<<szPtr[1]; operands_s<<" "<<szPtr[1];
operands_s<<Machine_X86::regName(src.segOver)<<":[bx]"; operands_s<<Machine_X86::regName(inst.src.segOver)<<":[bx]";
} }
break; break;
case iIN: case iIN:
(getFlag() & B)? operands_s<<"al, " : operands_s<< "ax, "; (inst.getFlag() & B)? operands_s<<"al, " : operands_s<< "ax, ";
(testFlags(I))? operands_s << strHex(src.op()) : operands_s<< "dx"; (inst.testFlags(I))? operands_s << strHex(inst.src.op()) : operands_s<< "dx";
break; break;
case iOUT: case iOUT:
{ {
std::string d1=((testFlags(I))? strHex(src.op()): "dx"); std::string d1=((inst.testFlags(I))? strHex(inst.src.op()): "dx");
std::string d2=((getFlag() & B) ? ", al": ", ax"); std::string d2=((inst.getFlag() & B) ? ", al": ", ax");
operands_s<<d1 << d2; operands_s<<d1 << d2;
} }
break; break;
@ -511,13 +509,13 @@ void LLInst::dis1Line(int loc_ip, int pass)
oper_stream << setw(15) << left <<opcode_with_mods.str(); oper_stream << setw(15) << left <<opcode_with_mods.str();
oper_stream << operands_s.str(); oper_stream << operands_s.str();
/* Comments */ /* Comments */
if (testFlags(SYNTHETIC)) if (inst.testFlags(SYNTHETIC))
{ {
fImpure = FALSE; fImpure = FALSE;
} }
else else
{ {
for (j = label, fImpure = 0; j > 0 && j < (int)nextInst; j++) for (j = inst.label, fImpure = 0; j > 0 && j < (int)nextInst; j++)
{ {
fImpure |= BITMAP(j, BM_DATA); fImpure |= BITMAP(j, BM_DATA);
} }
@ -527,17 +525,17 @@ void LLInst::dis1Line(int loc_ip, int pass)
/* Check for user supplied comment */ /* Check for user supplied comment */
selectTable(Comment); selectTable(Comment);
ostringstream cbuf; ostringstream cbuf;
if (readVal(cbuf, label, 0)) if (readVal(cbuf, inst.label, 0))
{ {
result_stream <<"; "<<cbuf.str(); result_stream <<"; "<<cbuf.str();
} }
else if (fImpure || (testFlags(SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES))) else if (fImpure || (inst.testFlags(SWITCH | CASE | SEG_IMMED | IMPURE | SYNTHETIC | TERMINATES)))
{ {
if (testFlags(CASE)) if (inst.testFlags(CASE))
{ {
result_stream << ";Case l"<< caseTbl.numEntries; result_stream << ";Case l"<< inst.caseTbl.numEntries;
} }
if (testFlags(SWITCH)) if (inst.testFlags(SWITCH))
{ {
result_stream << ";Switch "; result_stream << ";Switch ";
} }
@ -545,29 +543,29 @@ void LLInst::dis1Line(int loc_ip, int pass)
{ {
result_stream << ";Accessed as data "; result_stream << ";Accessed as data ";
} }
if (testFlags(IMPURE)) if (inst.testFlags(IMPURE))
{ {
result_stream << ";Impure operand "; result_stream << ";Impure operand ";
} }
if (testFlags(SEG_IMMED)) if (inst.testFlags(SEG_IMMED))
{ {
result_stream << ";Segment constant"; result_stream << ";Segment constant";
} }
if (testFlags(TERMINATES)) if (inst.testFlags(TERMINATES))
{ {
result_stream << ";Exit to DOS"; result_stream << ";Exit to DOS";
} }
} }
/* Comment on iINT icodes */ /* Comment on iINT icodes */
if (getOpcode() == iINT) if (inst.getOpcode() == iINT)
writeIntComment(result_stream); inst.writeIntComment(result_stream);
/* Display output line */ /* Display output line */
if(pass==3) if(pass==3)
{ {
/* output to .b code buffer */ /* output to .b code buffer */
if (testFlags(SYNTHETIC)) if (inst.testFlags(SYNTHETIC))
result_stream<<";Synthetic inst"; result_stream<<";Synthetic inst";
if (pass == 3) /* output to .b code buffer */ if (pass == 3) /* output to .b code buffer */
cCode.appendCode("%s\n", result_stream.str().c_str()); cCode.appendCode("%s\n", result_stream.str().c_str());
@ -575,16 +573,18 @@ void LLInst::dis1Line(int loc_ip, int pass)
} }
else else
{ {
if (not testFlags(SYNTHETIC) ) char buf[12];
/* output to .a1 or .a2 file */
if (not inst.testFlags(SYNTHETIC) )
{ {
/* output to .a1 or .a2 file */ sprintf(buf,"%03ld %06lX",loc_ip, inst.label);
fprintf (fp, "%03ld %06lX %s\n", loc_ip, label, result_stream.str().c_str());
} }
else /* SYNTHETIC instruction */ else /* SYNTHETIC instruction */
{ {
sprintf(buf,"%03ld ",loc_ip);
result_stream<<";Synthetic inst"; result_stream<<";Synthetic inst";
fprintf (fp, "%03ld %s\n", loc_ip, result_stream.str().c_str());
} }
m_fp<<buf<< " " << result_stream.str() << "\n";
} }
} }

View File

@ -76,11 +76,14 @@ void FrontEnd (char *filename, CALL_GRAPH * *pcallGraph)
} }
/* Search through code looking for impure references and flag them */ /* Search through code looking for impure references and flag them */
Disassembler ds(1);
for(Function &f : pProcList) for(Function &f : pProcList)
{ {
f.markImpure(); f.markImpure();
if (option.asm1) if (option.asm1)
disassem(1, &f); {
ds.disassem(&f);
}
} }
if (option.Interact) if (option.Interact)
{ {

View File

@ -165,6 +165,7 @@ void Function::markImpure()
{ {
if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF)) if ( not icod.ll()->testFlags(SYM_USE | SYM_DEF))
continue; continue;
assert(icod.ll()->caseTbl.numEntries<symtab.size());
psym = &symtab[icod.ll()->caseTbl.numEntries]; psym = &symtab[icod.ll()->caseTbl.numEntries];
for (int c = (int)psym->label; c < (int)psym->label+psym->size; c++) for (int c = (int)psym->label; c < (int)psym->label+psym->size; c++)
{ {

View File

@ -70,17 +70,17 @@ void LOCAL_ID::flagByteWordId (int off)
int idx; int idx;
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool { 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.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)) (en.id.bwId.off == off) && (en.id.bwId.regOff == 0))
return true; return true;
return false; return false;
}); });
if(found==id_arr.end()) 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; return;
} }
found->illegal = TRUE; found->illegal = true;
} }
/* Creates a new stack identifier node of TYPE_BYTE_(UN)SIGN or /* Creates a new stack identifier node of TYPE_BYTE_(UN)SIGN or

View File

@ -294,6 +294,8 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
case iCALL: case iCALL:
case iCALLF: case iCALLF:
done = process_CALL (*pIcode, pcallGraph, pstate); done = process_CALL (*pIcode, pcallGraph, pstate);
pstate->kill(rBX);
pstate->kill(rCX);
break; break;
/*** Returns ***/ /*** Returns ***/
@ -483,6 +485,7 @@ boolT Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGr
pIcode.ll()->setFlags(SWITCH); pIcode.ll()->setFlags(SWITCH);
pIcode.ll()->caseTbl.numEntries = (endTable - offTable) / 2; pIcode.ll()->caseTbl.numEntries = (endTable - offTable) / 2;
assert(pIcode.ll()->caseTbl.numEntries<512);
psw = (uint32_t*)allocMem(pIcode.ll()->caseTbl.numEntries*sizeof(uint32_t)); psw = (uint32_t*)allocMem(pIcode.ll()->caseTbl.numEntries*sizeof(uint32_t));
pIcode.ll()->caseTbl.entries = psw; 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. So we just exit this function, and ignore the call.
We probably should not have parsed this deep, anyway. We probably should not have parsed this deep, anyway.
*/ */
return FALSE; return false;
} }
/* Offset into program image is seg:off of read input */ /* 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 es:0 where es:0 is the start of the image. This is
usually wrong! Consider also CALL [BP+0E] in which the usually wrong! Consider also CALL [BP+0E] in which the
segment for the pointer is in SS! - Mike */ 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 /* Address of function is given by 4 (CALLF) or 2 (CALL) bytes at
* previous offset into the program image */ * 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; tgtAddr= LH(&prog.Image[off]) + (uint32_t)(uint16_t)state.r[rCS] << 4;
pIcode.ll()->src.SetImmediateOp( tgtAddr ); pIcode.ll()->src.SetImmediateOp( tgtAddr );
pIcode.ll()->setFlags(I); pIcode.ll()->setFlags(I);
indirect = TRUE; indirect = true;
} }
/* Process CALL. Function address is located in pIcode.ll()->immed.op */ /* Process CALL. Function address is located in pIcode.ll()->immed.op */

View File

@ -126,7 +126,8 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
{ {
regL = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l; regL = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l;
regH = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.h; 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 */ /* 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 */ /* Find stack offset for this argument */
off = m_minOff; off = m_minOff;
for (i = 0; i < numArg_; i++) for (i = 0; i < numArg_; i++)
{
if(i>=sym.size())
{
break; //TODO: verify
}
off += sym[i].size; off += sym[i].size;
}
/* Find formal argument */ /* Find formal argument */
if (numArg_ < sym.size()) if (numArg_ < sym.size())
{ {
psym = &sym[numArg_]; psym = &sym[numArg_];
i = numArg_; i = numArg_;
while ((i < sym.size()) && (psym->off != off)) //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;});
psym++; if(iter==sym.end()) // symbol not found
i++;
}
if (numArg_ == sym.size())
return; return;
psym = &(*iter);
} }
/* If formal argument does not exist, do not create new ones, just /* If formal argument does not exist, do not create new ones, just
* ignore actual argument * ignore actual argument

View File

@ -8,6 +8,7 @@
#include <cassert> #include <cassert>
#include <stdio.h> #include <stdio.h>
#include "dcc.h" #include "dcc.h"
#include "disassem.h"
static void displayCFG(Function * pProc); static void displayCFG(Function * pProc);
static void displayDfs(BB * pBB); static void displayDfs(BB * pBB);
@ -15,7 +16,7 @@ static void displayDfs(BB * pBB);
/**************************************************************************** /****************************************************************************
* udm * udm
****************************************************************************/ ****************************************************************************/
void Function::buildCFG() void Function::buildCFG(Disassembler &ds)
{ {
if(flg & PROC_ISLIB) if(flg & PROC_ISLIB)
return; // Ignore library functions return; // Ignore library functions
@ -26,7 +27,9 @@ void Function::buildCFG()
compressCFG(); // Remove redundancies and add in-edge information compressCFG(); // Remove redundancies and add in-edge information
if (option.asm2) 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 */ /* Idiom analysis and propagation of long type */
lowLevelAnalysis(); lowLevelAnalysis();
@ -67,11 +70,13 @@ void udm(void)
/* Build the control flow graph, find idioms, and convert low-level /* Build the control flow graph, find idioms, and convert low-level
* icodes to high-level ones */ * icodes to high-level ones */
Disassembler ds(2);
for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter) for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter)
{ {
iter->buildCFG(); iter->buildCFG(ds);
} }
/* Data flow analysis - eliminate condition codes, extraneous registers /* Data flow analysis - eliminate condition codes, extraneous registers
* and intermediate instructions. Find expressions by forward * and intermediate instructions. Find expressions by forward
* substitution algorithm */ * substitution algorithm */

View File

@ -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 <stdio.h>
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");
}

View File

@ -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");
}

View File

@ -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 <stdio.h>
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);
}


View File

@ -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);
}

View File

@ -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 <stdio.h>
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);
}


View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 <stdio.h>
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);
}


View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

223
tests/initial_base/DHAMP.C Normal file
View File

@ -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);
}


391
tests/initial_base/DHAMP.b Normal file
View File

@ -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);
}

29
tests/initial_base/FIBO.C Normal file
View File

@ -0,0 +1,29 @@
/* Fibonacci */
#include <stdio.h>
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);
}


View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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<n; i++)
for (j=0; j<m; j++)
for (k=0; k<m; k++)
c[i][j] = a[i][k] * b[k][j] + c[i][j];
}
main()
{ int a[n][m], b[n][m], c[n][m];
multMatrix (a,b,c);
}


View File

@ -0,0 +1,46 @@
/*
* Input file : test\matrixmu.exe
* File type : EXE
*/
#include "dcc.h"
void proc_1 (int arg0, int arg1, int arg2)
/* Takes 6 bytes of parameters.
* High-level language prologue code.
* C calling convention.
*/
{
int loc1;
int loc2;
int loc3;
loc2 = 0;
while ((loc2 < 5)) {
loc3 = 0;
while ((loc3 < 4)) {
loc1 = 0;
while ((loc1 < 4)) {
*((((loc2 * 10) + arg2) + (loc3 << 1))) = ((*((((loc2 << 3) + arg0) + (loc1 << 1))) * *((((loc1 * 10) + arg1) + (loc3 << 1)))) + *((((loc2 * 10) + arg2) + (loc3 << 1))));
loc1 = (loc1 + 1);
}
loc3 = (loc3 + 1);
}
loc2 = (loc2 + 1);
}
}
void main ()
/* Takes no parameters.
* High-level language prologue code.
*/
{
int loc1;
int loc2;
int loc3;
proc_1 (&loc3, &loc2, &loc1);
}

15
tests/initial_base/MAX.C Normal file
View File

@ -0,0 +1,15 @@
main()
{ int a, b;
printf ("Enter 2 numbers: ");
scanf ("%d %d", &a, &b);
if (a != b)
printf ("Maximum: %d\n", max (a,b));
}
max (int x, int y)
{
if (x > y)
return (x);
return (y);
}

41
tests/initial_base/MAX.b Normal file
View File

@ -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));
}
}

View File

@ -0,0 +1,13 @@
main()
{ char *s = "test";
strlen(s);
}
strlen(char *s)
{ int n = 0;
while (*s++)
n++;
return (n);
}

View File

@ -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);
}

View File

@ -0,0 +1,10 @@
#include <stdio.h>
main()
{ long a, d;
scanf ("%d", &d);
scanf ("%d", &a);
scanf ("%d %d", &a, &d);
printf ("%ld %ld", a, d);
}

View File

@ -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);
}

0
tests/inputs_base/BENCHFN.EXE Executable file → Normal file
View File

0
tests/inputs_base/BENCHLNG.EXE Executable file → Normal file
View File

0
tests/inputs_base/BENCHMUL.EXE Executable file → Normal file
View File

0
tests/inputs_base/BENCHMUS.EXE Executable file → Normal file
View File

0
tests/inputs_base/BENCHSHO.EXE Executable file → Normal file
View File

0
tests/inputs_base/BYTEOPS.EXE Executable file → Normal file
View File

BIN
tests/inputs_base/DHAMP.EXE Normal file

Binary file not shown.

BIN
tests/inputs_base/FIBOL.EXE Normal file

Binary file not shown.

0
tests/inputs_base/FIBOS.EXE Executable file → Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
tests/inputs_base/MAX.EXE Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.