6#include "dawn/prog/expression.hxx"
12#include "dawn/debug.hxx"
13#include "dawn/io/common.hxx"
14#include "dawn/io/ddata.hxx"
18static constexpr uint32_t EXPRESSION_VALUE_BITS =
sizeof(uint32_t) * CHAR_BIT;
22 , opType(OP_SHIFT_LEFT)
29CProgExpression::~CProgExpression()
36 SExpressionBind *bind;
38 bind =
new (std::nothrow) SExpressionBind();
45 bind->sourceId = sourceId;
46 bind->outputId = outputId;
47 bind->source =
nullptr;
48 bind->output =
nullptr;
50 binds.push_back(bind);
56int CProgExpression::configureDesc(
const CDescObject &desc)
63 for (
size_t i = 0; i < desc.
getSize(); i++)
67 if (item->
cfgid.
s.
cls != CProgCommon::PROG_CLASS_EXPRESSION)
69 DAWNERR(
"expression: unsupported cfg class 0x%" PRIx32
"\n", item->
cfgid.
v);
75 case PROG_EXPRESSION_CFG_IOBIND:
77 size_t nitems =
static_cast<size_t>(item->
cfgid.
s.
size);
78 if (nitems == 0 || nitems % 2 != 0)
80 DAWNERR(
"expression: invalid IOBIND size %zu\n", nitems);
85 for (
size_t b = 0; b < nitems / 2; b++)
87 int ret = allocBind(ids[b * 2].v, ids[b * 2 + 1].v);
96 case PROG_EXPRESSION_CFG_OP:
100 DAWNERR(
"expression: OP config must have exactly 2 entries\n");
112 DAWNERR(
"expression: unsupported cfg id %u\n", item->
cfgid.
s.
id);
120 DAWNERR(
"expression: at least one IOBIND entry required\n");
126 DAWNERR(
"expression: invalid op type %" PRIu32
"\n", opType);
130 if ((opType == OP_SHIFT_LEFT || opType == OP_SHIFT_RIGHT) && constant >= EXPRESSION_VALUE_BITS)
132 DAWNERR(
"expression: invalid shift constant %" PRIu32
"\n", constant);
141 return configureDesc(
getDesc());
148 for (
auto bind : binds)
150 bind->source =
getIO(bind->sourceId);
151 bind->output =
getIO(bind->outputId);
152 if (!bind->source || !bind->output)
157 ret = prepareWritableTarget(bind->output, 1,
true);
164 bind->source->getDataDim() != 1 || !bind->output->isWrite() ||
167 DAWNERR(
"expression: only scalar uint32 source/output IO is supported\n");
179 for (
auto bind : binds)
188bool CProgExpression::compute(uint32_t input, uint32_t &result,
const char *phase)
193 result = input << constant;
196 result = input >> constant;
198 case OP_CONST_LEFT_SHIFT:
199 if (input >= EXPRESSION_VALUE_BITS)
201 DAWNERR(
"expression: invalid %s shift %" PRIu32
"\n", phase, input);
204 result = constant << input;
207 result = input + constant;
210 result = input - constant;
217void CProgExpression::refresh(SExpressionBind *bind,
io_ddata_t *data,
const char *phase)
226 bind->sourceData.getDataPtr(), data->
getDataPtr(), bind->sourceData.getDataSize());
228 else if (bind->source->getData(bind->sourceData, 1) != OK)
233 input = bind->sourceData(0);
234 if (!compute(input, result, phase))
239 bind->outputData(0) = result;
240 ret = bind->output->setData(bind->outputData);
243 DAWNERR(
"expression: setData failed %d\n", ret);
247int CProgExpression::ioNotifierCb(
void *priv,
io_ddata_t *data)
249 SExpressionBind *bind =
static_cast<SExpressionBind *
>(priv);
251 if (bind && bind->owner && bind->owner->active)
253 bind->owner->refresh(bind, data,
"runtime");
265 for (
auto bind : binds)
267 if (!bind->source->isNotify())
272 ret = bind->source->setNotifier(ioNotifierCb, 0, bind);
284 for (
auto bind : binds)
286 refresh(bind,
nullptr,
"initial");
296 for (
auto bind : binds)
298 if (bind->source && bind->source->isNotify())
300 bind->source->setNotifier(
nullptr, 0,
nullptr);
CIOCommon * getIO(SObjectId::ObjectId id)
Get an I/O object by ID.
void setObjectMapItem(SObjectId::ObjectId id, CObject *obj)
Set an item in the object map.
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemNext(size_t &offset) const
Get config item at current offset and advance past it.
CDescObject & getDesc()
Get descriptor object for this object.
Base class for all PROG (processing) objects.
int init()
One-time initialize object after bindings are resolved.
int configure()
Configure object from descriptor data.
int doStop()
Stop implementation hook.
int doStart()
Start implementation hook.
bool hasThread() const
Check if a background thread is active.
int deinit()
De-initialize object.
uint32_t ObjectCfgData_t
Configuration data element - single 32-bit word.
static uint32_t cfgToU32(ObjectCfgData_t x)
Convert ObjectCfgData_t to uint32_t.
Out-of-tree user-extension hooks for Dawn.
Single configuration item within object.
ObjectCfgData_t data[]
Configuration data array (flexible, size from cfgid.s.size).
UObjectCfgId cfgid
Configuration ID header (type, class, id, size, rw, dtype).
@ DTYPE_UINT32
Unsigned 32-bit integer (0 to 4294967295).
uint32_t ObjectId
ObjectID type - single 32-bit value.
Heap-allocated dynamic I/O data buffer.
void * getDataPtr(size_t batch=0)
Get pointer to data only (skips timestamp if present).
size_t getItems()
Get number of items per batch.
ObjectCfgId v
Raw 32-bit ConfigID value (for storage, comparison).
uint32_t cls
Object class (bits 21-29, max 511).
uint32_t id
Configuration identifier (bits 0-4, max 31).
uint32_t size
Configuration data size in 32-bit words (bits 5-14, max 1023).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.
32-bit encoded object identifier (union with bit field).