You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
289 lines
9.8 KiB
289 lines
9.8 KiB
/***************************************************************************
|
|
* Copyright (C) 2007 Nicolas Hadacek <hadacek@kde.org> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
***************************************************************************/
|
|
#include "generator_check.h"
|
|
|
|
#include "devices/base/device_group.h"
|
|
#include "devices/pic/pic/pic_memory.h"
|
|
#include "tools/gputils/gputils.h"
|
|
#include "tools/gputils/gputils_generator.h"
|
|
#include "tools/sdcc/sdcc.h"
|
|
#include "tools/sdcc/sdcc_generator.h"
|
|
#include "devices/list/device_list.h"
|
|
|
|
//----------------------------------------------------------------------------
|
|
GeneratorCheckHelper::GeneratorCheckHelper()
|
|
: _cprocess(0), _lprocess(0), _generator(0)
|
|
{}
|
|
|
|
GeneratorCheckHelper::~GeneratorCheckHelper()
|
|
{
|
|
delete _generator;
|
|
}
|
|
|
|
void GeneratorCheckHelper::cleanup()
|
|
{
|
|
delete _lprocess;
|
|
_lprocess = 0;
|
|
delete _cprocess;
|
|
_cprocess = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GeneratorCheck::GeneratorCheck(GeneratorCheckHelper *helper)
|
|
: _helper(helper), _fdest(0), _fhex(0), _memory1(0)
|
|
{
|
|
_view = new CLI::View;
|
|
}
|
|
|
|
GeneratorCheck::~GeneratorCheck()
|
|
{
|
|
delete _view;
|
|
delete _helper;
|
|
}
|
|
|
|
void GeneratorCheck::runTest()
|
|
{
|
|
_helper->initSupported();
|
|
DeviceTest::runTest();
|
|
}
|
|
|
|
bool GeneratorCheck::init(const Device::Data &data)
|
|
{
|
|
PURL::Url dest(PURL::Directory::current(), "test.xxx");
|
|
dest = dest.toFileType(_helper->sourceFileType());
|
|
_fdest = new PURL::File(dest, *_view);
|
|
_helper->init(data);
|
|
PURL::Url hex(PURL::Directory::current(), "test.hex");
|
|
_fhex = new PURL::File(hex, *_view);
|
|
_memory1 = static_cast<Pic::Memory *>(data.group().createMemory(data));
|
|
return true;
|
|
}
|
|
|
|
bool GeneratorCheck::skip(const Device::Data &data) const
|
|
{
|
|
return !_helper->isSupported(data);
|
|
}
|
|
|
|
void GeneratorCheck::cleanup(const Device::Data &)
|
|
{
|
|
delete _memory1;
|
|
_memory1 = 0;
|
|
delete _fhex;
|
|
_fhex = 0;
|
|
// _fdest->remove();
|
|
delete _fdest;
|
|
_fdest = 0;
|
|
_helper->cleanup();
|
|
}
|
|
|
|
bool GeneratorCheck::execute(const Device::Data &data)
|
|
{
|
|
// create asm file from template source code
|
|
if ( !_fdest->openForWrite() ) TEST_FAILED_RETURN("");
|
|
_fdest->appendText(_source);
|
|
_fdest->close();
|
|
|
|
// run compiler
|
|
Process::State state = Process::runSynchronously(*_helper->_cprocess, Process::Start, 2000); // 2s timeout
|
|
if ( state!=Process::Exited ) TEST_FAILED_RETURN("Error while running compilation")
|
|
if ( _helper->_cprocess->exitCode()!=0 ) TEST_FAILED_RETURN(TQString("Error in compilation for %1:\n%2%3").tqarg(data.name()).tqarg(_helper->_cprocess->sout()+_helper->_cprocess->serr()).tqarg(TQString()))
|
|
|
|
// run linker
|
|
if (_helper->_lprocess) {
|
|
state = Process::runSynchronously(*_helper->_lprocess, Process::Start, 2000); // 2s timeout
|
|
if ( state!=Process::Exited ) TEST_FAILED_RETURN("Error while running linking")
|
|
if ( _helper->_lprocess->exitCode()!=0 ) TEST_FAILED_RETURN(TQString("Error in linking for %1:\n%2%3").tqarg(data.name()).tqarg(_helper->_lprocess->sout()+_helper->_lprocess->serr()).tqarg(TQString()))
|
|
}
|
|
|
|
// load hex file
|
|
if ( !_fhex->openForRead() ) TEST_FAILED_RETURN("")
|
|
TQStringList errors, warnings;
|
|
Device::Memory::WarningTypes warningTypes;
|
|
if ( !_memory1->load(_fhex->stream(), errors, warningTypes, warnings) ) TEST_FAILED_RETURN(TQString("Error loading hex into memory: %1").tqarg(errors.join(" ")))
|
|
//if ( warningTypes!=Device::Memory::NoWarning ) TEST_FAILED(TQString("Warning loading hex into memory: %1").tqarg(warnings.join(" ")))
|
|
|
|
TEST_PASSED
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool ConfigGeneratorCheck::init(const Device::Data &data)
|
|
{
|
|
if ( !GeneratorCheck::init(data) ) return false;
|
|
_memory2 = static_cast<Pic::Memory *>(data.group().createMemory(data));
|
|
return true;
|
|
}
|
|
|
|
bool ConfigGeneratorCheck::execute(const Device::Data &data)
|
|
{
|
|
// create configuration
|
|
const Pic::Config &config = static_cast<const Pic::Data &>(data).config();
|
|
for (uint l=0; ; l++) {
|
|
// set config bits
|
|
bool ok = false;
|
|
for (uint i=0; i<config._words.count(); i++) {
|
|
const Pic::Config::Word &cword = config._words[i];
|
|
for (uint k=0; k<cword.masks.count(); k++) {
|
|
const Pic::Config::Mask &cmask = cword.masks[k];
|
|
if ( l<cmask.values.count() ) {
|
|
ok = true;
|
|
if ( !cmask.values[l].name.isEmpty() ) _memory2->setConfigValue(cmask.name, cmask.values[l].name);
|
|
}
|
|
}
|
|
}
|
|
if ( !ok ) break;
|
|
|
|
// create source code
|
|
PURL::SourceFamily sfamily = _helper->sourceFileType().data().sourceFamily;
|
|
PURL::ToolType ttype = sfamily.data().toolType;
|
|
SourceLine::List lines = _helper->generator()->includeLines(ttype, data);
|
|
lines += _helper->generator()->configLines(ttype, *_memory2, ok);
|
|
lines += _helper->configEndLines();
|
|
_source = SourceLine::text(sfamily, lines, 2);
|
|
if (!ok) TEST_FAILED_RETURN("Config lines generation incomplete")
|
|
|
|
if ( !GeneratorCheck::execute(data) ) return false;
|
|
|
|
// check that config bits are the same
|
|
uint nbChars = static_cast<const Pic::Data &>(data).nbCharsWord(Pic::MemoryRangeType::Config);
|
|
for (uint i=0; i<config._words.count(); i++) {
|
|
const Pic::Config::Word &cword = config._words[i];
|
|
BitValue word1 = _memory1->word(Pic::MemoryRangeType::Config, i);
|
|
BitValue word2 = _memory2->word(Pic::MemoryRangeType::Config, i);
|
|
if ( word1==word2 ) continue;
|
|
for (uint k=0; k<cword.masks.count(); k++) {
|
|
const Pic::Config::Mask &cmask = cword.masks[k];
|
|
if ( cmask.value.isInside(cword.pmask) ) continue;
|
|
BitValue value1 = word1.maskWith(cmask.value);
|
|
BitValue value2 = word2.maskWith(cmask.value);
|
|
if ( value1==value2 ) continue;
|
|
TQString name1, name2;
|
|
uint l1, l2;
|
|
for (uint l=0; l<cmask.values.count(); l++) {
|
|
const Pic::Config::Value &value = cmask.values[l];
|
|
if ( value.value==value1 ) { name1 = value.name; l1 = l; }
|
|
if ( value.value==value2 ) { name2 = value.name; l2 = l; }
|
|
}
|
|
if ( name1==name2 ) continue;
|
|
TEST_FAILED_RETURN(TQString("Config bits are different in %1: set\"%2\"=(%3) != compiled=%4)")
|
|
.tqarg(cmask.name).tqarg(cmask.values[l2].name)
|
|
.tqarg(toHexLabel(word2.maskWith(cmask.value), nbChars)).tqarg(toHexLabel(word1.maskWith(cmask.value), nbChars)))
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_PASSED
|
|
return true;
|
|
}
|
|
|
|
void ConfigGeneratorCheck::cleanup(const Device::Data &data)
|
|
{
|
|
GeneratorCheck::cleanup(data);
|
|
delete _memory2;
|
|
_memory2 = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool TemplateGeneratorCheck::init(const Device::Data &data)
|
|
{
|
|
if ( !GeneratorCheck::init(data) ) return false;
|
|
bool ok;
|
|
PURL::SourceFamily sfamily = _helper->sourceFileType().data().sourceFamily;
|
|
PURL::ToolType ttype = sfamily.data().toolType;
|
|
SourceLine::List lines = _helper->generator()->templateSourceFile(ttype, data, ok);
|
|
_source = SourceLine::text(sfamily, lines, 2);
|
|
if (!ok) TEST_FAILED_RETURN(TQString("Incomplete template generator for %1").tqarg(data.name()))
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GPUtilsGeneratorCheckHelper::GPUtilsGeneratorCheckHelper()
|
|
{
|
|
_generator = new GPUtils::SourceGenerator;
|
|
}
|
|
|
|
void GPUtilsGeneratorCheckHelper::initSupported()
|
|
{
|
|
Process::StringOutput p;
|
|
TQStringList options;
|
|
options += "-l";
|
|
p.setup("gpasm", options, false);
|
|
Process::runSynchronously(p, Process::Start, 2000); // 2s timeout
|
|
_supported = GPUtils::getSupportedDevices(p.sout());
|
|
}
|
|
|
|
bool GPUtilsGeneratorCheckHelper::init(const Device::Data &data)
|
|
{
|
|
_cprocess = new Process::StringOutput;
|
|
TQStringList options;
|
|
options = "-c";
|
|
options += "-p" + GPUtils::toDeviceName(data.name());
|
|
options += "test.asm";
|
|
_cprocess->setup("gpasm", options, false);
|
|
_lprocess = new Process::StringOutput;
|
|
options = "-o";
|
|
options += "test.hex";
|
|
options += "test.o";
|
|
_lprocess->setup("gplink", options, false);
|
|
return true;
|
|
}
|
|
|
|
SourceLine::List GPUtilsGeneratorCheckHelper::configEndLines() const
|
|
{
|
|
SourceLine::List lines;
|
|
lines.appendIndentedCode("end");
|
|
return lines;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
SDCCGeneratorCheckHelper::SDCCGeneratorCheckHelper()
|
|
{
|
|
_generator = new SDCC::SourceGenerator;
|
|
}
|
|
|
|
void SDCCGeneratorCheckHelper::initSupported()
|
|
{
|
|
PURL::Url url(PURL::Directory::current(), "test.c");
|
|
Log::StringView view;
|
|
PURL::File file(url, view);
|
|
if ( file.openForWrite() ) file.appendText("void main(void) {}\n");
|
|
file.close();
|
|
_supported.clear();
|
|
for (uint i=0; i<SDCC::Nb_Families; i++) {
|
|
Process::StringOutput p;
|
|
TQStringList options;
|
|
options += TQString("-m") + SDCC::FAMILY_DATA[i].name;
|
|
options += "-phelp";
|
|
options += "test.c";
|
|
p.setup("sdcc", options, false);
|
|
Process::runSynchronously(p, Process::Start, 2000); // 2s timeout
|
|
_supported += SDCC::getSupportedDevices(p.serr());
|
|
}
|
|
}
|
|
|
|
bool SDCCGeneratorCheckHelper::init(const Device::Data &data)
|
|
{
|
|
_cprocess = new Process::StringOutput;
|
|
TQStringList options;
|
|
options += TQString("-m") + SDCC::FAMILY_DATA[SDCC::family(data.name())].name;
|
|
options += "-" + SDCC::toDeviceName(data.name());
|
|
options += "test.c";
|
|
options += "-I/usr/share/gputils/header";
|
|
options += "-Wl-otext.hex";
|
|
_cprocess->setup("sdcc", options, false);
|
|
return true;
|
|
}
|
|
|
|
SourceLine::List SDCCGeneratorCheckHelper::configEndLines() const
|
|
{
|
|
SourceLine::List lines;
|
|
lines.appendIndentedCode("void main() {}");
|
|
return lines;
|
|
}
|