11package ordt .output .cheader ;
22
3+ import ordt .extract .RegNumber ;
34import ordt .output .FieldProperties ;
45import ordt .output .OutputBuilder ;
56import ordt .output .common .OutputLine ;
67import ordt .parameters .ExtParameters ;
78
89import java .io .BufferedWriter ;
910import java .util .ArrayList ;
11+ import java .util .Iterator ;
1012import java .util .List ;
1113
1214
1315public class CHeaderBuilder extends OutputBuilder {
14- private List <OutputLine > memoryMapOutputList = new ArrayList <OutputLine >();
1516 private List <OutputLine > bitfieldOutputList = new ArrayList <OutputLine >();
16- private List <OutputLine > commonOutputList = new ArrayList <OutputLine >();
17- private List <OutputLine > explicitFunctionOutputList = new ArrayList <OutputLine >();
18- private int indentLvl = 0 ;
1917 private final int noIndent = 0 ;
2018
21- /*******************************************************************************************************************
22- * User configurable parameters
23- ******************************************************************************************************************/
24-
25- /*******************************************************************************************************************
26- * Internal variables
27- ******************************************************************************************************************/
28-
2919 public CHeaderBuilder (ordt .extract .RegModelIntf model ) {
3020 setBaseBuilderID (); // set unique ID of this instance
3121 this .model = model ;
@@ -37,21 +27,72 @@ public CHeaderBuilder(ordt.extract.RegModelIntf model) {
3727 model .getRoot ().generateOutput (null , this ); // generate output structures recursively starting at model root
3828 }
3929
30+ public class MemoryMapEntry {
31+ public RegNumber address ;
32+ public String regName ;
33+ public MemoryMapEntry (RegNumber address , String regName ) {
34+ this .address = address ;
35+ this .regName = regName ;
36+ }
37+ }
38+ private List <MemoryMapEntry > memoryMapEntryList = new ArrayList <MemoryMapEntry >();
39+
40+ String explicitFunctionString =
41+ "/*\n " +
42+ " * bits.h\n " +
43+ " *\n " +
44+ " * Struct and function declarations for dealing with bit assignment.\n " +
45+ " */\n " +
46+ "\n " +
47+ "#ifndef _BITS_H\n " +
48+ "#define _BITS_H\n " +
49+ "\n " +
50+ "#define BITS_PER_LONG 32\n " +
51+ "\n " +
52+ "// ## allows token concatenation\n " +
53+ "//X = 1 and Y = 10 would return 110\n " +
54+ "#define __AC(X,Y)\t (X##Y)\n " +
55+ "#define _AC(X,Y)\t __AC(X,Y)\n " +
56+ "\n " +
57+ "#define _UL(x)\t \t (_AC(x, UL))\n " +
58+ "#define UL(x)\t \t (_UL(x))\n " +
59+ "\n " +
60+ "#define BIT(nr) (1UL << (nr))\n " +
61+ "// BIT defines a bit mask for the specified bit number from 0 to whatever fits into an unsigned long\n " +
62+ "// so BIT(10) should evaluate to decimal 1024 (which is binary 1 left shifted by 10 bits)\n " +
63+ "\n " +
64+ "#define GENMASK_INPUT_CHECK(h, l) 0\n " +
65+ "\n " +
66+ "// h is high index, l is low index in a bitfield\n " +
67+ "// __GENMASK returns 32 bit number with 1s in the h-to-l field\n " +
68+ "// if h = 4 and l = 1, __GENMASK would return 00000000000000000000000000011110\n " +
69+ "#define __GENMASK(h, l) \\ \n " +
70+ "\t (((~UL(0)) - (UL(1) << (l)) + 1) & \\ \n " +
71+ "\t (~UL(0) >> (BITS_PER_LONG - 1 - (h))))\n " +
72+ "\n " +
73+ "#define GENMASK(h, l) \\ \n " +
74+ "\t (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))\n " +
75+ "\n " +
76+ "#endif /* _BITS_H */\n " ;
77+
78+ /*******************************************************************************************************************
79+ * Builder override methods
80+ ******************************************************************************************************************/
81+
4082 @ Override
4183 public void addField () {
42- while (fieldList .size () > 0 ){
43- FieldProperties field = fieldList .remove ();
44- int lowIndex = field .getLowIndex ();
45- int highIndex = field .getLowIndex () + field .getFieldWidth () - 1 ;
46-
47- if (lowIndex == highIndex ) {
48- String bitIndices = String .format ("%d" , lowIndex );
49- bitfieldOutputList .add (new OutputLine (noIndent , String .format ("#define %s BIT(%s)" , field .getTextName (), bitIndices )));
50- }
51- if (lowIndex != highIndex ) {
52- String bitIndices = String .format ("%d, %d" , highIndex , lowIndex );
53- bitfieldOutputList .add (new OutputLine (noIndent , String .format ("#define %s GENMASK(%s)" , field .getTextName (), bitIndices )));
54- }
84+ int lowIndex = fieldProperties .getLowIndex ();
85+ int highIndex = fieldProperties .getLowIndex () + fieldProperties .getFieldWidth () - 1 ;
86+ String fieldName = fieldProperties .getBaseName ().toUpperCase ();
87+ String textNameComment = (fieldProperties .getTextName () == null ) ? "" : " /* " + fieldProperties .getTextName () + " */" ;
88+
89+ if (lowIndex == highIndex ) {
90+ String bitIndices = String .format ("%d" , lowIndex );
91+ bitfieldOutputList .add (new OutputLine (noIndent , String .format ("#define %s BIT(%s)%s" , fieldName , bitIndices , textNameComment )));
92+ }
93+ else {
94+ String bitIndices = String .format ("%d, %d" , highIndex , lowIndex );
95+ bitfieldOutputList .add (new OutputLine (noIndent , String .format ("#define %s GENMASK(%s)%s" , fieldName , bitIndices , textNameComment )));
5596 }
5697 }
5798 @ Override
@@ -60,14 +101,15 @@ public void addAliasField() {
60101
61102 @ Override
62103 public void addRegister () {
63- String regAddress = regProperties .getExtractInstance ().getAddress ().toString ();
64- String regName = regProperties .getTextName ();
65-
66- if (ExtParameters .cheaderAddMemoryMap ())
67- memoryMapOutputList .add (new OutputLine (indentLvl , String .format ("%s = %s," , regName , regAddress )));
68-
69- if (ExtParameters .cheaderAddBitfields ())
70- bitfieldOutputList .add (new OutputLine (noIndent , String .format ("\n /* %s registers */" , regName )));
104+ String regName = regProperties .getBaseName ().toUpperCase ();
105+
106+ if (ExtParameters .cheaderAddMemoryMap ())
107+ memoryMapEntryList .add (new MemoryMapEntry (regProperties .getBaseAddress (), regName ));
108+
109+ if (ExtParameters .cheaderAddBitfields ()) {
110+ String textName = (regProperties .getTextName () == null ) ? "" : " (" + regProperties .getTextName () + ")" ;
111+ bitfieldOutputList .add (new OutputLine (noIndent , "\n /* " + regName + textName + " register fields */" ));
112+ }
71113 }
72114
73115 @ Override
@@ -83,109 +125,43 @@ public void finishRegSet() {
83125
84126 @ Override
85127 public void addRegMap () {
86- if (ExtParameters .cheaderAddMemoryMap ())
87- addHeader ();
88128 }
89129 @ Override
90130 public void finishRegMap () {
91- if (ExtParameters .cheaderAddMemoryMap ())
92- endEnum ();
93131 }
94132
95133 @ Override
96134 public void write (BufferedWriter bw ) {
97135 bufferedWriter = bw ;
98136
99- // Comments about auto generated file with name and date
100- addComments ();
101- for (OutputLine jsLine : commonOutputList ){
102- writeStmt (jsLine .getIndent (), jsLine .getLine ());
103- }
137+ writeStmt (0 , String .format ("#ifndef __%s_REGISTER_MAP__" , getAddressMapName ().toUpperCase ()));
138+ writeStmt (0 , String .format ("#define __%s_REGISTER_MAP__\n " , getAddressMapName ().toUpperCase ()));
104139
105140 // Explicitly declare all functions in the same header file
106- if (ExtParameters .cheaderExplicitFunctions ()){
107- explicitFunctions ();
108- for (OutputLine jsLine : explicitFunctionOutputList ){
109- writeStmt (jsLine .getIndent (), jsLine .getLine ());
110- }
111- }
112- else writeStmt (noIndent ,"#include <bits.h>\n " );
141+ if (ExtParameters .cheaderExplicitFunctions ())
142+ writeStmt (noIndent , explicitFunctionString );
143+ else writeStmt (noIndent , "#include <bits.h>\n " );
113144
114145 // Write memory map (enum)
115- if (ExtParameters .cheaderAddMemoryMap ())
116- // sherlock: memoryMapOutputList is array, OutputLine is datatype for temp variable jsLine
117- // sherlock: loop iterates over array and jsline becomes each element
118- for (OutputLine jsLine : memoryMapOutputList ) {
119- writeStmt (jsLine .getIndent (), jsLine .getLine ());
146+ if (ExtParameters .cheaderAddMemoryMap ()) {
147+ writeStmt (0 , String .format ("/* %s_REGISTERS memory map */" , getAddressMapName ().toUpperCase ()));
148+ writeStmt (0 , String .format ("enum %s_REGS {" , getAddressMapName ().toUpperCase ()));
149+ Iterator <MemoryMapEntry > mapIter = memoryMapEntryList .iterator ();
150+ while (mapIter .hasNext ()) {
151+ MemoryMapEntry mapEntry = mapIter .next ();
152+ String suffix = (mapIter .hasNext ())? "," : "" ;
153+ writeStmt (1 , mapEntry .regName + " = " + mapEntry .address .toString () + suffix );
120154 }
155+ writeStmt (0 , "};" );
156+ }
121157
122158 // Write bitfields (#define)
123159 if (ExtParameters .cheaderAddBitfields ())
124160 for (OutputLine jsLine : bitfieldOutputList ) {
125161 writeStmt (jsLine .getIndent (), jsLine .getLine ());
126162 }
127163
128- endComments ();
129- }
130-
131- /*******************************************************************************************************************
132- * Builder specific methods
133- ******************************************************************************************************************/
134- void addComments () {
135- commonOutputList .add (new OutputLine (indentLvl , String .format ("#ifndef __%s_REGISTER_MAP__" , getAddressMapName ().toUpperCase ())));
136- commonOutputList .add (new OutputLine (indentLvl , String .format ("#define __%s_REGISTER_MAP__\n " , getAddressMapName ().toUpperCase ())));
137- }
138-
139- void addHeader () {
140- memoryMapOutputList .add (new OutputLine (indentLvl , String .format ("/* %s_REGISTERS memory map */" , getAddressMapName ().toUpperCase ())));
141- memoryMapOutputList .add (new OutputLine (indentLvl ++, String .format ("enum %s_REGS {" , getAddressMapName ().toUpperCase ())));
142- }
143-
144- void endEnum (){
145- memoryMapOutputList .add (new OutputLine (--indentLvl , "};" ));
146- }
147-
148- void endComments () {
149- commonOutputList .add (new OutputLine (indentLvl , "#endif" ));
150164 writeStmt (noIndent , "\n #endif" );
151165 }
152-
153- void explicitFunctions (){
154- explicitFunctionOutputList .add (new OutputLine (indentLvl , String .format ("/*\n " +
155- " * bits.h\n " +
156- " *\n " +
157- " * Struct and function declarations for dealing with bit assignment.\n " +
158- " */\n " +
159- "\n " +
160- "#ifndef _BITS_H\n " +
161- "#define _BITS_H\n " +
162- "\n " +
163- "#define BITS_PER_LONG 32\n " +
164- "\n " +
165- "// ## allows token concatenation\n " +
166- "//X = 1 and Y = 10 would return 110\n " +
167- "#define __AC(X,Y)\t (X##Y)\n " +
168- "#define _AC(X,Y)\t __AC(X,Y)\n " +
169- "\n " +
170- "#define _UL(x)\t \t (_AC(x, UL))\n " +
171- "#define UL(x)\t \t (_UL(x))\n " +
172- "\n " +
173- "#define BIT(nr) (1UL << (nr))\n " +
174- "// BIT defines a bit mask for the specified bit number from 0 to whatever fits into an unsigned long\n " +
175- "// so BIT(10) should evaluate to decimal 1024 (which is binary 1 left shifted by 10 bits)\n " +
176- "\n " +
177- "#define GENMASK_INPUT_CHECK(h, l) 0\n " +
178- "\n " +
179- "// h is high index, l is low index in a bitfield\n " +
180- "// __GENMASK returns 32 bit number with 1s in the h-to-l field\n " +
181- "// if h = 4 and l = 1, __GENMASK would return 00000000000000000000000000011110\n " +
182- "#define __GENMASK(h, l) \\ \n " +
183- "\t (((~UL(0)) - (UL(1) << (l)) + 1) & \\ \n " +
184- "\t (~UL(0) >> (BITS_PER_LONG - 1 - (h))))\n " +
185- "\n " +
186- "#define GENMASK(h, l) \\ \n " +
187- "\t (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))\n " +
188- "\n " +
189- "#endif /* _BITS_H */" )));
190- }
166+
191167}
0 commit comments