1 ///////////////////////////////////////////////////////////////////////////////
3 // Bitfields and opcode encoding/decoding
5 ///////////////////////////////////////////////////////////////////////////////
6 #include <AD/contain/bitset.h>
12 ///////////////////////////////////////////////////////////////////////////////
14 // Instantiate the datatype FieldDef
16 ///////////////////////////////////////////////////////////////////////////////
17 instantiate datatype FieldDef, FieldLaw, List<FieldDef>, List<FieldLaw>;
19 ///////////////////////////////////////////////////////////////////////////////
21 // Constructor and destructor
23 ///////////////////////////////////////////////////////////////////////////////
24 BitfieldCompiler:: BitfieldCompiler() {}
25 BitfieldCompiler::~BitfieldCompiler() {}
27 ///////////////////////////////////////////////////////////////////////////////
29 // Environment for storing bitfields.
31 ///////////////////////////////////////////////////////////////////////////////
32 static HashTable bitfield_env(string_hash, string_equal);
34 ///////////////////////////////////////////////////////////////////////////////
36 // Method to insert bitfield definition into environment.
38 ///////////////////////////////////////////////////////////////////////////////
39 void insert_bitfield (Id name, FieldDef field_def)
40 { HashTable::Entry * e = bitfield_env.lookup(name);
42 { error ("%!redefinition of bitfield '%s'.\n"
43 "%!this is where it is last defined.\n",
44 ((FieldDef)e->v)->loc(), name, field_def->loc());
46 { bitfield_env.insert(name,field_def);
50 ///////////////////////////////////////////////////////////////////////////////
52 // Check the bitfield patterns for consistency
54 ///////////////////////////////////////////////////////////////////////////////
55 void check_bitfield_consistency (Id name, int width, FieldDefs field_defs)
56 { if (width < 0 || width >= 4096)
57 { error ("%Lillegal width in bitfield '%s (%i)'\n", name, width);
60 BitSet * referred = new (mem_pool, width) BitSet;
61 for_each (FieldDef, f, field_defs)
63 { // check that the field ranges are correct
64 FIELDdef { field_name, from_bit, to_bit ... }
65 | from_bit < 0 || to_bit < 0 || from_bit > to_bit ||
66 from_bit >= width || to_bit >= width:
67 { error ("%Lillegal bit range in bitfield '%s(%i)::%s (%i:%i)'\n",
68 name, width, field_name, from_bit, to_bit);
70 | FIELDdef { from_bit, to_bit ... }:
71 { for (int i = from_bit; i <= to_bit; i++)
74 | _: // skip field constructor definitions
78 // Check that all the bits are covered by the bitfield declaration
79 for (int i = 0; i < width; )
80 { if (! referred->contains(i))
82 for (j = i+1; j < width && ! referred->contains(j); j++);
83 msg ("%L%wrange (%i:%i) missing in bitfield '%s (%i)'\n",
92 ///////////////////////////////////////////////////////////////////////////////
94 // Method to compile a bitfield declaration
96 ///////////////////////////////////////////////////////////////////////////////
97 void BitfieldCompiler::define_bitfield
98 (Id name, int width, FieldDefs field_defs, FieldLaws field_laws)
100 // make sure that the bitfields are range consistent.
101 check_bitfield_consistency(name, width, field_defs);
103 // insert into environment
104 for_each (FieldDef, f, field_defs)
106 { FIELDdef { field_name ... }: { insert_bitfield(field_name, f); }
107 | FIELDCONdef { field_name ... }: { insert_bitfield(field_name, f); }
112 ///////////////////////////////////////////////////////////////////////////////
114 // Method to generate code for a bitfield declaration
116 ///////////////////////////////////////////////////////////////////////////////
117 void BitfieldCompiler::gen_bitfield
118 (Id name, int width, FieldDefs field_defs, FieldLaws laws)
121 "%^// Definitions for bitfield '%s (%i)'"
125 for_each (FieldLaw, l, laws)
127 { FIELDlaw { id, args, guard, exp }:
128 { (*output) << "#define " << id << "(" << args << ") |"
129 << guard << " = " << exp << '\n';