コード例 #1
0
/**
 * Transform an address to a smart string, that is,
 * if a source line is available, transform it to "source_file:source_line",
 * if the CFG has a label, it gives "label + 0xoffset", else return the
 * address.
 * @param base		Base address of the function containing the give address.
 * @param address	Address to display.
 * @return			Address transformed in string.
 */
string CFGProcessor::str(const Address& base, const Address& address) {
	Inst *first;
	if(base.isNull())
		first = _cfg->firstInst();
	else
		first = workspace()->findInstAt(base);
	String label;
	if(first)
		label = FUNCTION_LABEL(first);
	if(label) {
		int offset = address.offset() - first->address().offset();
		if(offset < 0)
			return _ << label << " - 0x" << io::hex(-offset) << " (" << address << ")";
		else
			return _ << label << " + 0x" << io::hex(offset) << " (" << address << ")";
	}
	else
		return _ << "0x" << address;
}
コード例 #2
0
/**
 * Fill-in the BSet structure by identifying each brbanch address class.
 * 
 * @param cfg	CFG to analyze.
 * @param bs	BSets structure to fill-in.
 */
void BPredProcessor::generateClasses(CFG *cfg, BSets& bs) {
	for(CFG::BBIterator bb(cfg); bb; bb++) {
		unsigned int nb_OE = 0;

		// Parcours des OutEdges
		for(BasicBlock::OutIterator edge(bb); edge ; edge++ ) {
			// on incremente que s'il s'agit d'un edge TAKEN ou NOT_TAKEN
			if(edge->kind() == Edge::TAKEN) nb_OE++;
			else if(edge->kind() == Edge::NOT_TAKEN) nb_OE++;
		}

		// Si un branchement a ete trouve ...
		if(nb_OE == 2 ) {
			Inst* inst = NULL;
			for(BasicBlock::InstIter i(bb); i; i++) {
				inst=i;
			}
			bs.add((inst->address() & (this->BHT)), bb->number());
		}
	}
}
コード例 #3
0
ファイル: test_hard.cpp プロジェクト: t-crest/patmos-otawa
int main(int argc, char **argv) {

    Manager manager;
    PropList props;
    PROCESSOR_PATH(props) = "../../data/procs/op1.xml";
    CACHE_CONFIG_PATH(props) = "../../data/caches/inst-64x16x1.xml";

    try {

        // Load program
        if(argc < 2) {
            cerr << "ERROR: no argument.\n"
                 << "Syntax is : test_ipet <executable>\n";
            return 2;
        }
        WorkSpace *fw = manager.load(argv[1], props);
        assert(fw);

        // Display information
        cout << "PLATFORM INFORMATION\n";
        Platform *pf = fw->platform();
        cout << "Platform : " << pf->identification().name() << '\n';
        cout << '\n';

        // Display registers
        cout << "REGISTERS\n";
        for(int i = 0; i < pf->banks().count(); i++) {
            const hard::RegBank *bank = pf->banks()[i];
            cout << "Bank " << bank->name() << ", "
                 << bank->size() << "bits, "
                 << bank->count() << " registers, "
                 << reg_kinds[bank->kind()];
            for(int j = 0; j < bank->registers().count(); j++) {
                if(j % 8 == 0)
                    cout << "\n\t";
                else
                    cout << ", ";
                cout << bank->registers()[j]->name();
            }
            cout << '\n';
        }
        cout << '\n';

        // Display cache
        cout << "CACHE CONFIGURATION\n";
        const CacheConfiguration& cconf(pf->cache());
        display_cache_level(1, cconf.instCache(), cconf.dataCache());
        cout << '\n';

        // Display some instructions
        fw->require(DECODED_TEXT);
        cout << "READ/WRITTEN REGS TEST\n";
        String label("main");
        Inst *inst = fw->process()->findInstAt("main");
        //fw->findLabel(label));
        if(!inst)
            throw new otawa::Exception(CString("no main in this file ?"));
        for(int i = 0; i < 10; i++, inst = inst->nextInst()) {
            cout << '\n' << inst->address() << ": "
                 << inst << " (" << io::hex(inst->kind()) << ")\n";
            const elm::genstruct::Table<hard::Register *>& reads = inst->readRegs();
            cout << "\tread registers : ";
            for(int i = 0; i < reads.count(); i++)
                cout << reads[i] << ' ';
            cout << '\n';
            const elm::genstruct::Table<hard::Register *>& writes = inst->writtenRegs();
            cout << "\twritten registers : ";
            for(int i = 0; i < writes.count(); i++)
                cout << writes[i] << ' ';
            cout << '\n';
        }
        cout << io::endl;


        // Processor load test
        cout << "Processor load test\n";
        //pf->loadProcessor("proc.xml");
        const hard::Processor *proc = pf->processor();
        if(!proc)
            cout << "NO PROCESSOR !\n";
        else {
            cout << "arch = " << proc->getArch() << io::endl;
            cout << "model = " << proc->getModel() << io::endl;
            cout << "builder = " << proc->getBuilder() << io::endl;
            cout <<"stages =\n";
            const elm::genstruct::Table<hard::Stage *>& stages = proc->getStages();
            for(int i = 0; i< stages.count(); i++) {
                cout << '\t'
                     << stages[i]->getName() << " "
                     << stages[i]->getType() << " "
                     << stages[i]->getWidth() << " "
                     << stages[i]->getLatency() << " "
                     << io::pointer(stages[i]) << io::endl;
                const elm::genstruct::Table<hard::FunctionalUnit *>& fus = stages[i]->getFUs();
                if(fus) {
                    cout << "\tfus=\n";
                    for(int i = 0; i < fus.count(); i++)
                        cout << "\t\t" << fus[i]->getName() << ' '
                             << fus[i]->getWidth() << ' '
                             << fus[i]->getLatency() << ' '
                             << fus[i]->isPipelined() << io::endl;
                }
                const elm::genstruct::Table<hard::Dispatch *>& dispatch = stages[i]->getDispatch();
                if(dispatch) {
                    cout << "\tdispatch=\n";
                    for(int i = 0; i < dispatch.count(); i++)
                        cout << "\t\t" << dispatch[i]->getType() << ' '
                             << dispatch[i]->getFU()->getName() << io::endl;
                }
            }
            cout << "queues =\n";
            const elm::genstruct::Table<hard::Queue *>& queues = proc->getQueues();
            for(int i = 0; i< queues.count(); i++) {
                cout << '\t'
                     << queues[i]->getName() << " "
                     << queues[i]->getSize() << " "
                     << queues[i]->getInput()->getName() << " ("
                     << io::pointer(queues[i]->getInput()) << ") "
                     << queues[i]->getOutput()->getName() << " ("
                     << io::pointer(queues[i]->getOutput()) << ")" << io::endl;
                const elm::genstruct::Table<hard::Stage *>& intern = queues[i]->getIntern();
                if(intern) {
                    cout << "\tintern=\n";
                    for(int i = 0; i < intern.count(); i++)
                        cout << "\t\t" << intern[i]->getName()
                             << " (" << io::pointer(intern[i]) << ')' << io::endl;
                }
            }
        }
    }
    catch(elm::Exception& e) {
        cerr << "ERROR: " << e.message() << '\n';
        return 1;
    }
    return 0;
}
コード例 #4
0
/**
 * Use fft_parser for editing flow facts:
 * 	<br>-to ETS::ID_LOOP_COUNT for loop.
 * <br>If the table contains the key put its value,
 * <br>else put -1.
 * @param ws	Container framework.
 * @param ast	AST to process.
 */		
void FlowFactLoader::processAST(WorkSpace *ws, AST *ast){
	//int val;
	switch(ast->kind()) {
		case AST_Seq:
			processAST(ws, ast->toSeq()->child1());
			processAST(ws, ast->toSeq()->child2());
			break;
		case AST_If:
			processAST(ws, ast->toIf()->condition());
			processAST(ws, ast->toIf()->thenPart());
			processAST(ws, ast->toIf()->elsePart());
			break;
		case AST_While: {
				Inst *inst = ast->toWhile()->condition()->first();
				int count = MAX_ITERATION(inst);
				if(count < 0)
					warn(_ << "loop at " << inst->address() << " has no bound");
				else {
					FFL_OUT(cout << "|| " << ast->toWhile()->condition()->first()->get<String>(File::ID_Label, "unknown ")<< " a pour nb d'iter : "<< count << '\n');
					LOOP_COUNT(ast->toWhile()) = count;
				}
				processAST(ws, ast->toWhile()->condition());
				processAST(ws, ast->toWhile()->body());
			}
		 	break;
		case AST_DoWhile: {
				Inst *inst = ast->toDoWhile()->condition()->first();
				int count = MAX_ITERATION(inst);
				if(count < 0)
					warn(_ << "loop at " << inst->address() << " has no bound");
				else {
					FFL_OUT(cout << "|| "<< ast->toDoWhile()->condition()->first()->get<String>(File::ID_Label, "unknown ") << " a pour nb d'iter : "<< count << '\n');
					LOOP_COUNT(ast->toDoWhile()) = count;
				}
				processAST(ws, ast->toDoWhile()->condition());
				processAST(ws, ast->toDoWhile()->body());
			}
			break;
		case AST_For: {
				Inst *inst = ast->toFor()->condition()->first();
				int count = MAX_ITERATION(inst);
				if(count < 0)
					warn(_ << "loop at " << inst->address() << " has no bound");
				else {
					FFL_OUT(cout << "|| " << ast->toFor()->condition()->first()->address()<<" ~ "<<ast->toFor()->condition()->first()->get<String>(File::ID_Label, "unknown ") << " a pour nb d'iter : "<< count << '\n');
					LOOP_COUNT(ast->toFor()) = count;
				}
				processAST(ws, ast->toFor()->initialization());
				processAST(ws, ast->toFor()->condition());
				processAST(ws, ast->toFor()->body());
				processAST(ws, ast->toFor()->incrementation());
			}
			break;
		case AST_Call:{
			ASTInfo *ast_info = ws->getASTInfo();
			Option< FunAST *> fun_res = ast_info->get(ast->toCall()->function()->name());
			if(fun_res) {
				AST *fun_ast = (*fun_res)->ast();
				processAST(ws, fun_ast);
			}
			break;
		}
		default:
			break;
	}
}
コード例 #5
0
ファイル: odec.cpp プロジェクト: dllinxi/WCET
	virtual void work(PropList &props) throw (elm::Exception) {
		WorkSpace *ws = workspace();
		cerr << "DEBUG: verbose = " << isVerbose() << "\n";

		// put the symbols
		for(Process::FileIter file(workspace()->process()); file; file++)
			for(File::SymIter sym(file); sym; sym++) {
				if(sym->kind() == Symbol::FUNCTION || sym->kind() == Symbol::LABEL) {
					cerr << "DEBUG: code symbol: " << sym->name() << " (" << sym->address() << ")\n";
					Inst *inst = workspace()->findInstAt(sym->address());
					if(inst) {
						Symbol::ID(inst).add(*sym);
						switch(sym->kind()) {
						case Symbol::FUNCTION:
							FUNCTION_LABEL(inst).add(sym->name());
							break;
						case Symbol::LABEL:
							LABEL(inst).add(sym->name());
							break;
						default:
							break;
						}
					}
				}
			}
		cerr << "DEBUG: here\n";

		// Look the _start
		Inst *start = ws->start();
		if(start) {
			if(isVerbose())
				cerr << "ENTRY: processing entry at " << start->address() << io::endl;
			processEntry(ws, start->address());
		}
		else if(isVerbose())
			cerr << "no entry to process\n";

		// Look the function symbols
		for(Process::FileIter file(ws->process()); file; file++)
			for(File::SymIter sym(file); sym; sym++)
				if(sym->kind() == Symbol::FUNCTION) {
					if(IGNORE_ENTRY(sym))
						cerr << "\n\nINFO: ignoring function symbol \"" << sym->name() << "\"\n";
					else {
						cerr << "\n\nENTRY: processing function \"" << sym->name() << " at " << sym->address() << io::endl;
						Inst *inst = ws->findInstAt(sym->address());
						if(inst)
							processEntry(ws, sym->address());
						else
							cerr << "bad function symbol \"" << sym->name()
								   << "\" no code segment at " << sym->address() << io::endl;
					}
				}

		// dump the instructions
		for(Process::FileIter file(workspace()->process()); file; file++) {
			cout << "FILE: " << file->name() << io::endl;
			for(File::SegIter seg(file); seg; seg++) {
				cout << "SEGMENT: " << seg->name() << io::endl;
				for(Segment::ItemIter item(seg); item; item++) {
					Inst *inst = item->toInst();
					if(inst) {
						if(MARKER(inst))
							cout << io::endl;
						for(Identifier<Symbol *>::Getter sym(inst, Symbol::ID); sym; sym++)
							cout << "\t" << sym->name() << ":\n";
						cout << "\t\t" << inst->address() << "  ";
						if(inst->isUnknown()) {
							cout << "<unknown>:";
							writeBytes(cout, inst->address(), inst->size());
						}
						else
							cout << inst;
						if(MARKER(inst)) {
							bool fst = true;
							for(Identifier<Inst *>::Getter from(inst, FROM); from; from++) {
								cout << (fst ? "\tfrom " : ", ");
								fst = false;
								cout << from->address();
							}
						}
						cout << io::endl;
					}
				}
			}
			cout << "\n";
		}
	}
コード例 #6
0
ファイル: odec.cpp プロジェクト: dllinxi/WCET
	void processEntry(WorkSpace *ws, address_t address) {
		ASSERT(ws);
		ASSERT(address);

		// Initialize the queue
		VectorQueue<Inst *> todo(1024);
		Inst *inst = getInst(workspace(), address);
		if(!inst) {
			cerr << "ERROR: bad function entry at " << address << io::endl;
			return;
		}
		todo.put(inst);

		// Repeat until there is no more address to explore
		while(!todo.isEmpty()) {

			// Get the next instruction
			Inst *first_inst = todo.get();
			if(!first_inst)
				continue;
			if(isVerbose())
				cerr << "starting from " << first_inst->address() << io::endl;
			inst = first_inst;

			// Follow the instruction until a branch
			address_t next;
			while(inst && !MARKER(inst)) {
				if(isVerbose()) {
					cerr << "process " << inst->address() << " : ";
					writeBytes(cerr, inst->address(), inst->size());
					cerr << ": " << inst << io::endl;
				}
				if(inst->isControl())
					break;
				next = inst->topAddress();
				inst = getInst(ws, next, inst);
			}

			// mark the block
			if(isVerbose())
				cerr << "end found\n";
			if(!inst) {
				cerr << "WARNING: unknown instruction at " << next << io::endl;
				continue;
			}
			bool marker_found = MARKER(inst);
			MARKER(first_inst) = true;
			if(marker_found)
				continue;

			// Record target and next
			if(inst->isConditional()) {
				if(isVerbose())
					cerr << "put(" << inst->topAddress() << ")" << io::endl;
				Inst *ti = getInst(ws, inst->topAddress(), inst);
				if(!ti)
					cerr << "ERROR: broken sequence from " << inst->address() << " to " <<  inst->topAddress() << io::endl;
				else {
					FROM(ti).add(first_inst);
					todo.put(ti);
				}
			}
			if(!inst->isReturn() && !IS_RETURN(inst)) {
				Inst *target = 0;
				try {
					target = inst->target();
					if(!target)
						continue;
				}
				catch(ProcessException& e) {
					cerr << "WARNING: " << e.message() << ": the branched code will not be decoded\n";
				}
				if(target && !NO_CALL(target)) {
					if(isVerbose())
						cerr << "put(" << target->address() << ")\n";
					FROM(target).add(first_inst);
					todo.put(target);
				}
				else if(!target) {
					bool one = false;
					for(Identifier<Address>::Getter target(inst, BRANCH_TARGET); target; target++) {
						one = true;
						Inst *ti = getInst(ws, target, inst);
						if(!ti) {
							cerr << "ERROR: broken target from " << inst->address() << " to " << *target << io::endl;
							continue;
						}
						FROM(ti).add(first_inst);
						todo.put(ti);
						if(isVerbose())
							cerr << "put(" << target << ")\n";
					}
					if(!one)
						cerr << "WARNING: no target for branch at " << inst->address() << io::endl;
				}
				if(inst->isCall() && (!target || !NO_RETURN(target))) {
					if(isVerbose())
						cerr << "put(" << inst->topAddress() << ")\n";
					Inst *ti = getInst(ws, inst->topAddress(), inst);
					if(!ti) {
						cerr << "ERROR: broken target from " << inst->address() << " to " << *target << io::endl;
						continue;
					}
					FROM(ti).add(first_inst);
					todo.put(ti);
				}
			}
		}
	}