94 lines
2.3 KiB
C++
94 lines
2.3 KiB
C++
#include <fxos/semantics.h>
|
|
|
|
namespace FxOS {
|
|
|
|
DataValue::DataValue():
|
|
type(nullptr), determined(false)
|
|
{
|
|
}
|
|
|
|
uint32_t DataValue::read(int offset, int size)
|
|
{
|
|
if(offset < 0 || size < 0 || (type->size && offset+size >= type->size))
|
|
throw std::logic_error("Invalid read into simulated data");
|
|
if(!size || size & (size - 1))
|
|
throw std::logic_error("Simulated read not a power of 2");
|
|
|
|
if(type->kind==DataType::Integral || type->kind==DataType::BitField)
|
|
{
|
|
int shift = (4 - size - offset) << 3;
|
|
uint32_t u = uinteger >> shift;
|
|
return (size == 4) ? u :
|
|
(size == 2) ? (uint16_t)u :
|
|
(uint8_t)u;
|
|
}
|
|
else if(type->kind == DataType::Array)
|
|
{
|
|
int elsize = type->arraytype->size;
|
|
int index = offset / elsize;
|
|
|
|
if(index >= (int)entries.size())
|
|
throw std::logic_error("Read out of array bounds");
|
|
|
|
/* Will throw if reading from two entries simultaneously */
|
|
return entries[index].read(offset % elsize, size);
|
|
}
|
|
else if(type->kind == DataType::Array)
|
|
{
|
|
int index = 0;
|
|
while(offset >= type->attributes[index].size)
|
|
{
|
|
index++;
|
|
offset -= type->attributes[index].size;
|
|
}
|
|
|
|
return entries[index].read(offset, size);
|
|
}
|
|
|
|
throw std::logic_error("Read into unknown DataValue kind");
|
|
}
|
|
|
|
void DataValue::write(int offset, int size, uint32_t contents)
|
|
{
|
|
if(offset < 0 || size < 0 || (type->size && offset+size >= type->size))
|
|
throw std::logic_error("Invalid write into simulated data");
|
|
if(!size || size & (size - 1))
|
|
throw std::logic_error("Simulated write not a power of 2");
|
|
|
|
if(type->kind==DataType::Integral || type->kind==DataType::BitField)
|
|
{
|
|
uint32_t mask = (size == 1) ? 0xff :
|
|
(size == 2) ? 0xffff :
|
|
0xffffffff;
|
|
|
|
int shift = (4 - size - offset) << 3;
|
|
|
|
uinteger = (uinteger & ~(mask << shift)) | (contents << shift);
|
|
}
|
|
else if(type->kind == DataType::Array)
|
|
{
|
|
int elsize = type->arraytype->size;
|
|
int index = offset / elsize;
|
|
|
|
if(index >= (int)entries.size())
|
|
throw std::logic_error("Write out of array bounds");
|
|
|
|
entries[index].write(offset % elsize, size, contents);
|
|
}
|
|
else if(type->kind == DataType::Array)
|
|
{
|
|
int index = 0;
|
|
while(offset >= type->attributes[index].size)
|
|
{
|
|
index++;
|
|
offset -= type->attributes[index].size;
|
|
}
|
|
|
|
entries[index].write(offset, size, contents);
|
|
}
|
|
|
|
throw std::logic_error("Write into unknown DataValue kind");
|
|
}
|
|
|
|
} /* namespace FxOS */
|