--- /dev/null
+#include <Python.h>
+#include <stdint.h>
+#include <stdio.h>
+
+static const char* PLUGIN_NAME = "pypowersim";
+
+typedef struct pypowersim_state {
+ PyObject *name;
+ PyObject *plugin_module;
+ PyObject *binary;
+ PyObject *bigendian;
+ PyObject *prog;
+ PyObject *qemu_cosim;
+ PyObject *initial_regs;
+ PyObject *initial_sprs;
+ PyObject *svstate;
+ PyObject *mmu;
+ PyObject *initial_cr;
+ PyObject *initial_mem;
+ PyObject *initial_fprs;
+ PyObject *initial_pc;
+ PyObject *args;
+ PyObject *simulator;
+ PyObject *result_obj;
+} pypowersim_state_t;
+
+pypowersim_state_t *pypowersim_prepare(void) {
+ // Initialize Python C API
+ Py_Initialize();
+ // Add pypowersim directory to Python path
+ PyObject* sysPath = PySys_GetObject((char*)"path");
+ PyObject* curDir = PyUnicode_FromString("../../../src/openpower/decoder/isa/");
+ PyList_Append(sysPath, curDir);
+ Py_DECREF(curDir);
+
+ // Allocate memory for state
+ pypowersim_state_t *state = malloc(sizeof(pypowersim_state_t));
+ if (!state) {
+ printf("Error creating pypowersim_state object\n");
+ exit(1);
+ }
+ // Set plugin name and module
+ state->name = PyUnicode_FromString(PLUGIN_NAME);
+ state->plugin_module = PyImport_Import(state->name);
+ Py_DECREF(state->name);
+ if (!state->plugin_module) {
+ PyErr_Print();
+ printf("Error importing module\n");
+ exit(1);
+ }
+ // Set simulator object
+ state->simulator = PyObject_GetAttrString(state->plugin_module, "run_a_simulation");
+ Py_DECREF(state->plugin_module);
+ if (!state->simulator) {
+ PyErr_Print();
+ printf("Error retrieving 'run_a_simulation'\n");
+ exit(1);
+ }
+
+ // Little Endian for now
+ state->bigendian = Py_False;
+ state->prog = Py_None;
+ state->qemu_cosim = Py_False;
+ // Set and clear 128 GPRs
+ state->initial_regs = PyList_New(128);
+ for (int i=0; i < 128; i++) {
+ PyList_SetItem(state->initial_regs, i, PyLong_FromLong(0));
+ }
+ // Create SPRs to all bits set
+ state->initial_sprs= PyDict_New();
+ PyDict_SetItemString(state->initial_sprs, "LR", PyLong_FromLong(0xffffff));
+ // Set empty SVSTATE
+ state->svstate = PyLong_FromLong(0);
+ // Set no MMU
+ state->mmu = Py_None;
+ // Set no initial CR
+ state->initial_cr = PyLong_FromLong(0);
+ // Set empty initial Memory
+ state->initial_mem = PyDict_New();
+ // Set and Clear 128 FPR
+ state->initial_fprs = PyList_New(128);
+ for (int i=0; i < 128; i++) {
+ PyList_SetItem(state->initial_fprs, i, PyLong_FromLong(0));
+ }
+ // Set initial Program Counter
+ state->initial_pc= PyLong_FromLong(0x0);
+
+ return state;
+}
+
+void pypowersim_prepareargs(pypowersim_state_t *state) {
+ // Set the tuple with the state objects
+ state->args = PyTuple_Pack(12, state->binary, state->bigendian, state->prog, state->qemu_cosim,
+ state->initial_regs, state->initial_sprs, state->svstate, state->mmu,
+ state->initial_cr, state->initial_mem, state->initial_fprs, state->initial_pc );
+ if (!state->args) {
+ PyErr_Print();
+ Py_DECREF(state->simulator);
+ printf("Error building args tuple\n");
+ exit(1);
+ }
+}
+
+void pypowersim_finalize(void) {
+ // Finalize Python C API
+ Py_Finalize();
+}
+
--- /dev/null
+#include <Python.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "pypowersim_wrapper_common.h"
+
+int test_function(int x) {
+ int result = 0;
+ for (int i=0; i < x; i++)
+ result += 2*i;
+ return result;
+}
+
+int test_function_wrapper(int x) {
+ // Create the pypowersim_state
+ pypowersim_state_t *state = pypowersim_prepare();
+
+ // Change the relevant elements, mandatory: body
+ //
+ state->binary = PyBytes_FromStringAndSize((const char *)&test_function, 1000);
+ // Set GPR #3 to the argument x
+ PyList_SetItem(state->initial_regs, 3, PyLong_FromLong(x));
+
+ // Prepare the args object
+ pypowersim_prepareargs(state);
+
+ // Call the function and get the resulting object
+ state->result_obj = PyObject_CallObject(state->simulator, state->args);
+ Py_DECREF(state->simulator);
+ Py_DECREF(state->args);
+ if (!state->result_obj) {
+ PyErr_Print();
+ printf("Error invoking 'run_a_simulation'\n");
+ }
+
+ // Get the GPRs from the result_obj
+ PyObject *final_regs = PyObject_GetAttrString(state->result_obj, "gpr");
+ if (!final_regs) {
+ PyErr_Print();
+ Py_DECREF(state->result_obj);
+ printf("Error getting final GPRs\n");
+ }
+
+ // GPR #3 holds the return value as an integer
+ PyObject *key = PyLong_FromLong(3);
+ PyObject *itm = PyDict_GetItem(final_regs, key);
+ PyObject *value = PyObject_GetAttrString(itm, "value");
+ uint64_t val = PyLong_AsLongLong(value);
+
+ Py_DECREF(state->result_obj);
+
+ // Return value
+ return val;
+}
+
+int main(int argc, char* argv[]) {
+ for (int i=0; i < 20; i++) {
+ int result = test_function_wrapper(i);
+ printf("i = %d, result = %d\n", i, result);
+ }
+ pypowersim_finalize();
+ return 0;
+}
+
+