1 /*
2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package hat.codebuilders;
26
27 import hat.Config;
28 import hat.FFIConfigCreator;
29 import optkl.codebuilders.C99CodeBuilder;
30 import optkl.codebuilders.ScopedCodeBuilderContext;
31 import optkl.util.Mutable;
32
33 import java.lang.invoke.MethodHandles;
34 import java.text.SimpleDateFormat;
35 import java.util.Date;
36
37 public class C99HATConfigBuilder extends C99CodeBuilder<C99HATConfigBuilder> {
38
39 public C99HATConfigBuilder(ScopedCodeBuilderContext scopedCodeBuilderContext) {
40 super(scopedCodeBuilderContext);
41 }
42
43 public final C99HATConfigBuilder staticConstInt(String name, int padWidth, int value) {
44 staticKeyword().space().constexprKeyword().space().s32Type().space().identifier(name, padWidth).space().equals().space().intHexValue(value).semicolon().nl();
45 return this;
46 }
47
48 public final C99HATConfigBuilder staticConstIntShiftedOne(String name, int padWidth, int shift) {
49 staticKeyword().space().constexprKeyword().space().s32Type().space().identifier(name, padWidth).space().equals().space().intValue(1).leftShift().intHexValue(shift).semicolon().nl();
50 return this;
51 }
52
53 public final C99HATConfigBuilder className() {
54 return identifier("BasicConfig");
55 }
56
57 public final C99HATConfigBuilder bitNamesVar() {
58 return identifier("bitNames");
59 }
60
61 public final C99HATConfigBuilder bitDescriptionsVar() {
62 return identifier("bitDescriptions");
63 }
64
65 public final C99HATConfigBuilder configBitsVar() {
66 return identifier("configBits");
67 }
68
69 public final C99HATConfigBuilder configBitsAnd() {
70 return configBitsVar().space().ampersand().space();
71 }
72
73 public final C99HATConfigBuilder configBitsAndBitName(String bitName) {
74 return configBitsAnd().identifier(bitName + "_BIT");
75 }
76
77 public final C99HATConfigBuilder camelExceptFirst(String s) {
78 return identifier(toCamelExceptFirst(s));
79 }
80
81 public final C99HATConfigBuilder std(String s) {
82 return identifier("std").colon().colon().identifier(s);
83 }
84
85 public final C99HATConfigBuilder stdEndl() {
86 return std("endl");
87 }
88
89 public final C99HATConfigBuilder stdCout(String s) {
90 return std("cout").space().leftShift().space().dquote().literal(s).dquote();
91 }
92
93 public static String create(){
94 C99HATConfigBuilder cb = new C99HATConfigBuilder(new ScopedCodeBuilderContext(MethodHandles.lookup(),null));
95 cb.oracleCopyright();
96 cb.blockComment("""
97 You probably should not edit this this file!!!
98 It was auto generated""" + " " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()) + " by " + FFIConfigCreator.class.getName()
99 );
100 cb.pragma("once").nl();
101 cb.includeSys("iostream").nl();
102 final int START_BIT_INDEX = Config.bitList.stream().filter(bit -> bit.size() == 1).findFirst().get().index();
103
104 cb.structKeyword().space().className().braceNlIndented((_) -> {
105 var i = Mutable.of(START_BIT_INDEX);
106 Config.bitList.stream().filter(bit -> bit.size() == 1).forEach(bit -> {
107 cb.staticConstIntShiftedOne(bit.name() + "_BIT", 32, i.get());
108 i.set(i.get() + 1);
109 });
110 cb.constKeyword().space().staticKeyword().space().s08Type().space().asterisk().bitNamesVar().osbrace().csbrace().semicolon().space().lineComment("See below for initialization");
111 cb.constKeyword().space().staticKeyword().space().s08Type().space().asterisk().bitDescriptionsVar().osbrace().csbrace().semicolon().space().lineComment("See below for initialization");
112
113 cb.s32Type().space().identifier("configBits").semicolon().nl();
114
115 Config.bitList.stream().filter(bit -> bit.size() == 1).forEach(bit ->
116 cb.identifier("bool").space().camelExceptFirst(bit.name()).semicolon().nl()
117 );
118
119 cb.s32Type().space().identifier("platform").semicolon().nl();
120 cb.s32Type().space().identifier("device").semicolon().nl();
121 cb.identifier("bool").space().identifier("alwaysCopy").semicolon().nl();
122 //Constructor
123 cb.explicitKeyword().space().className().paren((_) -> cb.s32Type().space().configBitsVar()).colon().nl().indent((_) -> {
124 cb.configBitsVar().paren((_) -> cb.configBitsVar()).comma().nl();
125 Config.bitList.stream().filter(bit -> bit.size() == 1).forEach(bit ->
126 cb.camelExceptFirst(bit.name()).paren((_) -> cb.paren((_) -> cb.configBitsAndBitName(bit.name())).eq().identifier(bit.name() + "_BIT")).comma().nl()
127 );
128 cb.identifier("platform").paren((_) -> cb.configBitsAnd().intHexValue(0xf)).comma().nl();
129 cb.identifier("alwaysCopy").paren(_ -> cb.pling().camelExceptFirst("MINIMIZE_COPIES")).comma().nl();
130 cb.identifier("device").paren(_ ->
131 cb.paren(_ -> cb.configBitsAnd().intHexValue(0xf0)).space().rightShift().space().intValue(4)).braceNlIndented(_ ->
132 cb.ifKeyword().paren(_ -> cb.identifier("showDeviceInfo")).braceNlIndented(_ -> {
133 cb.nlSeparated(
134 Config.bitList.stream().filter(bit -> bit.size() == 1),
135 bit -> cb.stdCout("native " + cb.toCamelExceptFirst(bit.name()) + " ").space().leftShift().space().camelExceptFirst(bit.name()).space().leftShift().space().stdEndl().semicolon()
136 );
137 cb.nl().stdCout("native platform ").space().leftShift().space().identifier("platform").space().leftShift().space().stdEndl().semicolon();
138 cb.nl().stdCout("native device ").space().leftShift().space().identifier("device").space().leftShift().space().stdEndl().semicolon();
139 })
140 );
141 }).nl();
142
143 cb.virtualKeyword().space().tilde().className().ocparen().equals().space().defaultKeyword().semicolon();
144 }).semicolon().nl().nl();
145
146
147 cb.hashIfdef("shared_cpp", (_) -> {
148 cb.constKeyword().space().s08Type().space().asterisk().className().colon().colon().bitNamesVar().ocsbrace().equals().brace((_) -> {
149 cb.nl();
150 Config.bitList.stream().filter(bit -> bit.size() == 1).forEach(bit ->
151 cb.dquote().identifier(bit.name() + "_BIT").dquote().comma().nl()
152 );
153 }).semicolon().nl();
154 cb.constKeyword().space().s08Type().space().asterisk().className().colon().colon().bitDescriptionsVar().ocsbrace().equals().brace((_) -> {
155 cb.nl();
156 Config.bitList.stream().filter(bit -> bit.size() == 1).forEach(bit ->
157 cb.dquote().identifier(bit.description()).dquote().comma().nl()
158 );
159 }).semicolon().nl();
160 });
161 return cb.toString();
162
163 }
164
165 static public void main(){
166 var c = Config.fromSpec("INFO,SHOW_CODE,HEADLESS,SHOW_KERNEL_MODEL,SHOW_COMPUTE_MODEL,PLATFORM:0,DEVICE:0");
167 System.out.println(c);
168 System.out.println(create());
169 System.exit(1);
170 }
171 }