Bundle ranpi.c as an example
ADD
examples/C/ranpi.c
+/*--- pi.c PROGRAM RANPI
+ *
+ * Program to compute PI by probability.
+ * By Mark Riordan 24-DEC-1986;
+ * Original version apparently by Don Shull.
+ * To be used as a CPU benchmark.
+ *
+ * Translated to C from FORTRAN 20 Nov 1993
+ */
+
+/** Modified for Ripes:
+ * - No printing
+ * - Moves computation result to register x27
+ */
+
+void printFloat(float value) {
+ asm("mv a0, %[v]\n"
+ "li a7, 2\n"
+ "ecall"
+ :
+ : [v]"r"(value)
+ :
+ );
+}
+
+void printInt(int value) {
+ asm("mv a0, %[v]\n"
+ "li a7, 1\n"
+ "ecall"
+ :
+ : [v]"r"(value)
+ :
+ );
+}
+
+void printString(void* str) {
+ asm("mv a0, %[v]\n"
+ "li a7, 4\n"
+ "ecall"
+ :
+ : [v]"r"(str)
+ :
+ );
+}
+
+void printStringFloat(void* str, float f){
+ printString(str);
+ printFloat(f);
+ printString("\n");
+}
+
+void printStringInt(void* str, int i){
+ printString(str);
+ printInt(i);
+ printString("\n");
+}
+
+void myadd(float* sum, float* addend) {
+ /*
+ c Simple adding subroutine thrown in to allow subroutine
+ c calls/returns to be factored in as part of the benchmark.
+ */
+ *sum = *sum + *addend;
+}
+
+int main(int argc, char* argv[]) {
+ float ztot, yran, ymult, ymod, x, y, z, pi, prod;
+ long int low, ixran, itot, j, iprod;
+
+ printString("Running RanPI...\n");
+
+ ztot = 0.0;
+ low = 1;
+ ixran = 1907;
+ yran = 5813.0;
+ ymult = 1307.0;
+ ymod = 5471.0;
+ itot = 100; // 1200000;
+
+ for (j = 1; j <= itot; j++) {
+ /*
+ c X and Y are two uniform random numbers between 0 and 1.
+ c They are computed using two linear congruential generators.
+ c A mix of integer and real arithmetic is used to simulate a
+ c real program. Magnitudes are kept small to prevent 32-bit
+ c integer overflow and to allow full precision even with a 23-bit
+ c mantissa.
+ */
+ printString("\tIteration: ");
+ printInt(j);
+ printString("\n");
+ iprod = 27611 * ixran;
+ ixran = iprod - 74383 * (long int)(iprod / 74383);
+ x = (float)ixran / 74383.0;
+ prod = ymult * yran;
+ yran = (prod - ymod * (long int)(prod / ymod));
+ y = yran / ymod;
+ z = x * x + y * y;
+ myadd(&ztot, &z);
+ if (z <= 1.0) {
+ low = low + 1;
+ }
+ }
+
+ pi = 4.0 * (float)low / (float)itot;
+
+ // Print result
+ printString("Result: ");
+ printFloat(pi);
+
+ // Move result to some pre-determined register
+ asm("mv x27, %[v]"
+ : /* Output registers */
+ : [v] "r"(pi) /* Input registers */
+ : /* Clobber registers */
+ );
+
+ return 0;
+}

MODIFY
examples/examples.qrc
examples/examples.qrc
<file>assembly/Factorial function</file>
<file>assembly/Console printing</file>
<file>ELF/RanPi</file>
+ <file>C/ranpi.c</file>
</qresource>
</RCC>

MODIFY
src/editor/codeeditor.cpp
src/editor/codeeditor.cpp
#include <QPainter>
#include <QSyntaxHighlighter>
#include <QTextBlock>
+#include <QTimer>
#include <QToolTip>
#include <QWheelEvent>
#include <iterator>
+#include "csyntaxhighlighter.h"
#include "processorhandler.h"
#include "rvassemblyhighlighter.h"
@@ -44,14 +46,15 @@ CodeEditor::CodeEditor(QWidget* parent) : QPlainTextEdit(parent) {
}
void CodeEditor::setupChangedTimer() {
+ m_changeTimer = new QTimer(this);
// configures the change-timer and assembler connectivity with Parser
- m_changeTimer.setInterval(500);
- m_changeTimer.setSingleShot(true);
+ m_changeTimer->setInterval(500);
+ m_changeTimer->setSingleShot(true);
// A change in the document will start the timer - when the timer elapses, the contents will be assembled if there
// is no syntax error. By doing this, the timer is restartet each time a change occurs (ie. a user is continuously
// typing)
- connect(this, &QPlainTextEdit::textChanged, [=] { m_changeTimer.start(); });
- connect(&m_changeTimer, &QTimer::timeout, this, &CodeEditor::textChanged);
+ connect(this, &QPlainTextEdit::textChanged, m_changeTimer, QOverload<>::of(&QTimer::start));
+ connect(m_changeTimer, &QTimer::timeout, this, &CodeEditor::textChanged);
}
int CodeEditor::lineNumberAreaWidth() {
@@ -142,6 +145,9 @@ void CodeEditor::setSourceType(SourceType type) {
case SourceType::Assembly:
m_highlighter = std::make_unique<RVAssemblyHighlighter>(document());
break;
+ case SourceType::C:
+ m_highlighter = std::make_unique<CSyntaxHighlighter>(document());
+ break;
default:
break;
}

MODIFY
src/editor/codeeditor.h
src/editor/codeeditor.h
@@ -60,7 +60,7 @@ private:
// A timer is needed for only catching one of the multiple wheel events that
// occur on a regular mouse scroll
QTimer m_fontTimer;
- QTimer m_changeTimer;
+ QTimer* m_changeTimer;
bool eventFilter(QObject* observed, QEvent* event) override;
};

MODIFY
src/edittab.cpp
src/edittab.cpp
@@ -26,7 +26,7 @@ EditTab::EditTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, parent)
m_assembler = std::make_unique<Assembler>();
- connect(m_ui->codeEditor, &CodeEditor::textChanged, this, &EditTab::assemble);
+ connect(m_ui->codeEditor, &CodeEditor::textChanged, this, &EditTab::sourceCodeChanged);
connect(m_ui->setAssemblyInput, &QRadioButton::toggled, this, &EditTab::sourceTypeChanged);
connect(m_ui->setCInput, &QRadioButton::toggled, this, &EditTab::sourceTypeChanged);
@@ -39,6 +39,7 @@ EditTab::EditTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, parent)
});
enableEditor();
+ sourceTypeChanged();
}
void EditTab::loadFile(const LoadFileParams& fileParams) {
@@ -51,6 +52,7 @@ void EditTab::loadFile(const LoadFileParams& fileParams) {
bool success = true;
Program loadedProgram;
switch (fileParams.type) {
+ case SourceType::C:
case SourceType::Assembly:
success &= loadAssemblyFile(loadedProgram, file);
break;
@@ -93,7 +95,7 @@ void EditTab::updateProgramViewerHighlighting() {
void EditTab::sourceTypeChanged() {
// Validate source type selection
if (m_ui->setAssemblyInput->isChecked()) {
- m_currentFileType = SourceType::Assembly;
+ m_currentSourceType = SourceType::Assembly;
} else if (m_ui->setCInput->isChecked()) {
// Ensure that we have a validated C compiler available
if (!CCManager::get().hasValidCC()) {
@@ -104,12 +106,12 @@ void EditTab::sourceTypeChanged() {
m_ui->setAssemblyInput->setChecked(true);
return;
} else {
- m_currentFileType = SourceType::C;
+ m_currentSourceType = SourceType::C;
}
}
// Notify the source type change to the code editor
- m_ui->codeEditor->setSourceType(m_currentFileType);
+ m_ui->codeEditor->setSourceType(m_currentSourceType);
}
void EditTab::emitProgramChanged() {
@@ -117,6 +119,19 @@ void EditTab::emitProgramChanged() {
updateProgramViewer();
}
+void EditTab::sourceCodeChanged() {
+ switch (m_currentSourceType) {
+ case SourceType::Assembly:
+ assemble();
+ break;
+ case SourceType::C:
+ break;
+ default:
+ // Do nothing, some external program is loaded
+ break;
+ }
+}
+
void EditTab::assemble() {
if (m_ui->codeEditor->syntaxAccepted()) {
m_assembler->assemble(*m_ui->codeEditor->document());
@@ -160,12 +175,12 @@ void EditTab::updateProgramViewer() {
}
void EditTab::enableEditor() {
- connect(m_ui->codeEditor, &CodeEditor::textChanged, this, &EditTab::assemble);
+ connect(m_ui->codeEditor, &CodeEditor::textChanged, this, &EditTab::sourceCodeChanged);
m_ui->editorStackedWidget->setCurrentIndex(0);
}
void EditTab::disableEditor() {
- disconnect(m_ui->codeEditor, &CodeEditor::textChanged, this, &EditTab::assemble);
+ disconnect(m_ui->codeEditor, &CodeEditor::textChanged, this, &EditTab::sourceCodeChanged);
m_ui->editorStackedWidget->setCurrentIndex(1);
clearAssemblyEditor();
m_editorEnabled = false;

MODIFY
src/edittab.h
src/edittab.h
@@ -59,10 +59,11 @@ public slots:
void enableAssemblyInput();
private slots:
- void assemble();
+ void sourceCodeChanged();
void on_disassembledViewButton_toggled();
private:
+ void assemble();
void updateProgramViewer();
bool loadFlatBinaryFile(Program& program, QFile& file, unsigned long entryPoint, unsigned long loadAt);
bool loadAssemblyFile(Program& program, QFile& file);
@@ -77,7 +78,7 @@ private:
Program m_activeProgram;
- SourceType m_currentFileType;
+ SourceType m_currentSourceType;
bool m_editorEnabled = true;
};

MODIFY
src/mainwindow.cpp
src/mainwindow.cpp
@@ -162,6 +162,19 @@ void MainWindow::setupExamplesMenu(QMenu* parent) {
}
}
+ const auto cExamples = QDir(":/examples/C/").entryList(QDir::Files);
+ if (!cExamples.isEmpty()) {
+ for (const auto& fileName : cExamples) {
+ parent->addAction(fileName, [=] {
+ LoadFileParams parms;
+ parms.filepath = QString(":/examples/C/") + fileName;
+ parms.type = SourceType::C;
+ m_editTab->loadFile(parms);
+ m_hasSavedFile = false;
+ });
+ }
+ }
+
const auto ELFExamples = QDir(":/examples/ELF/").entryList(QDir::Files);
if (!ELFExamples.isEmpty()) {
for (const auto& fileName : ELFExamples) {

Bundle ranpi.c as an example