Skip to content

Commit

Permalink
[Literate] Generate enumeration bitfields
Browse files Browse the repository at this point in the history
  • Loading branch information
0x8000-0000 committed May 12, 2020
1 parent 910b00b commit 4f44c9a
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 9 deletions.
23 changes: 23 additions & 0 deletions src/main/java/net/signbit/samx/literate/CppVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ class BitField
final int width;
final String name;

final String enumType;

public BitField(RecordSetVisitor.RecordDataGroup rdg)
{
final String wordText = rdg.getValue(FieldIndices.Word.ordinal(), plainTextVisitor);
Expand All @@ -314,6 +316,15 @@ public BitField(RecordSetVisitor.RecordDataGroup rdg)
final String widthText = rdg.getValue(FieldIndices.Width.ordinal(), plainTextVisitor);
width = NumberUtils.createInteger(widthText);
name = rdg.getValue(FieldIndices.Name.ordinal(), plainTextVisitor);

if (rdg.getRows().size() > 1)
{
enumType = name;
}
else
{
enumType = null;
}
}

public BitField(RecordSetVisitor.RecordData rd)
Expand All @@ -325,6 +336,8 @@ public BitField(RecordSetVisitor.RecordData rd)
final String widthText = rd.getValue(FieldIndices.Width.ordinal(), plainTextVisitor);
width = NumberUtils.createInteger(widthText);
name = rd.getValue(FieldIndices.Name.ordinal(), plainTextVisitor);

enumType = null;
}

public int getWord()
Expand All @@ -347,6 +360,16 @@ public boolean isBoolean()
return width == 1;
}

public boolean isEnumeration()
{
return enumType != null && (width > 1);
}

public String getEnumType()
{
return enumType;
}

public String getName()
{
return name;
Expand Down
58 changes: 49 additions & 9 deletions src/main/resources/net/signbit/samx/literate/cpp_header.stg
Original file line number Diff line number Diff line change
Expand Up @@ -59,30 +59,70 @@ private:

bitFieldDecl(field, unitWidth) ::= <<

<if(field.enumeration)>enum class <field.enumType> : uint<unitWidth>_t
{
};<endif>


/** <field.name>
*
* <field.description>
*/
constexpr void set<field.name>(<if(field.boolean)>bool<else>uint<unitWidth>_t<endif> val)
<if(field.boolean)>
constexpr void set<field.name>(bool val)
{
<if(field.boolean)>const auto mask = uint<unitWidth>_t(1U);<else>const auto mask = static_cast\<uint<unitWidth>_t>((uint<unitWidth>_t(1U) \<\< <field.width>U) - uint<unitWidth>_t(1U));
assert(val \<= mask);
<endif>
const auto mask = uint<unitWidth>_t(1U);

const auto shiftedMask = mask \<\< <field.offset>U;

m_data = (m_data & (~shiftedMask)) | (uint<unitWidth>_t(val) \<\< <field.offset>U);
}

constexpr bool get<field.name>() const
{
const auto mask = uint<unitWidth>_t(1U);

return (m_data \>> <field.offset>U) & mask;
}
<elseif(field.enumeration)>
constexpr void set<field.name>(enum <field.enumType> enumVal)
{
const auto val = static_cast\<uint<unitWidth>_t>(enumVal);

const auto mask = static_cast\<uint<unitWidth>_t>((uint<unitWidth>_t(1U) \<\< <field.width>U) - uint<unitWidth>_t(1U));
assert(val \<= mask);

const auto shiftedMask = mask \<\< <field.offset>U;

m_data = (m_data & (~shiftedMask)) | (<if(field.boolean)>uint<unitWidth>_t(val)<else>val<endif> \<\< <field.offset>U);
m_data = (m_data & (~shiftedMask)) | (val \<\< <field.offset>U);
}

constexpr <if(field.boolean)>bool<else>uint<unitWidth>_t<endif> get<field.name>() const
constexpr enum <field.enumType> get<field.name>() const
{
const auto mask = static_cast\<uint<unitWidth>_t>((uint<unitWidth>_t(1U) \<\< <field.width>U) - uint<unitWidth>_t(1U));

const auto val = (m_data \>> <field.offset>U) & mask;

return static_cast\<enum <field.enumType>\>(val);
}
<else>
constexpr void set<field.name>(uint<unitWidth>_t val)
{
<if(field.boolean)>const auto mask = uint<unitWidth>_t(1U);<else>const auto mask = static_cast\<uint<unitWidth>_t>((uint<unitWidth>_t(1U) \<\< <field.width>U) - uint<unitWidth>_t(1U));
<endif>
const auto mask = static_cast\<uint<unitWidth>_t>((uint<unitWidth>_t(1U) \<\< <field.width>U) - uint<unitWidth>_t(1U));
assert(val \<= mask);

const auto shiftedMask = mask \<\< <field.offset>U;

m_data = (m_data & (~shiftedMask)) | (val \<\< <field.offset>U);
}

constexpr uint<unitWidth>_t get<field.name>() const
{
const auto mask = static_cast\<uint<unitWidth>_t>((uint<unitWidth>_t(1U) \<\< <field.width>U) - uint<unitWidth>_t(1U));

return ((m_data \>> <field.offset>U) & mask)<if(field.boolean)> != 0<endif>;
return (m_data \>> <field.offset>U) & mask;
}
<endif>

>>

Expand Down

0 comments on commit 4f44c9a

Please sign in to comment.