Skip to content

Commit 0771491

Browse files
author
Derek Hower
committed
WIP
1 parent 4f27109 commit 0771491

File tree

11 files changed

+88
-69
lines changed

11 files changed

+88
-69
lines changed

.devcontainer/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ RUN apt-get install -y --no-install-recommends ditaa
2121
RUN apt-get install -y --no-install-recommends libyaml-dev
2222
RUN apt-get install -y --no-install-recommends cmake
2323
RUN apt-get install -y --no-install-recommends g++
24+
RUN apt-get install -y --no-install-recommends clang-format
2425
RUN apt-get clean autoclean
2526
RUN apt-get autoremove -y
2627
RUN rm -rf /var/lib/{apt,dpkg,cache,log}/*

backends/cpp_hart_gen/cpp/include/udb/bits.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ namespace udb
881881
last_val = val;
882882
pow *= 10;
883883
}
884-
width = 64 - std::countl_zero(val);
884+
width = val == 0 ? 1 : 64 - std::countl_zero(val);
885885
}
886886
if (base == 16)
887887
{
@@ -901,6 +901,9 @@ namespace udb
901901

902902
// the lsbs need full bits
903903
width += (len - 1) * 4;
904+
905+
// special case: if zero, need one bit
906+
width = width == 0 ? 1 : width;
904907
}
905908
return width;
906909
}
@@ -977,6 +980,7 @@ namespace udb
977980
}
978981
}
979982

983+
static_assert((0x0_b).Width == 1);
980984
static_assert((0x1_b).Width == 1);
981985
static_assert((0x2_b).Width == 2);
982986
static_assert((0x7_b).Width == 3);

backends/cpp_hart_gen/cpp/include/udb/hart.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,6 @@ namespace udb {
166166
// xlen of M-mode, i.e., MXLEN
167167
virtual unsigned mxlen() = 0;
168168

169-
// the current effective XLEN, in the current mode
170-
virtual unsigned xlen() = 0;
171-
172169
virtual uint64_t xreg(unsigned num) const = 0;
173170
virtual void set_xreg(unsigned num, uint64_t value) = 0;
174171

backends/cpp_hart_gen/cpp/include/udb/types.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ namespace udb {
125125
template <unsigned N, bool Signed>
126126
bool operator==(const _Bits<N, Signed>& other) { return other == static_cast<Bits<Size>>(*this); }
127127

128+
template <unsigned N, bool Signed>
129+
bool operator>(const _Bits<N, Signed>& other) { return static_cast<Bits<Size>>(*this) > other; }
130+
131+
template <unsigned N, bool Signed>
132+
bool operator>=(const _Bits<N, Signed>& other) { return static_cast<Bits<Size>>(*this) >= other; }
133+
134+
template <unsigned N, bool Signed>
135+
Bits<Size> operator&(const _Bits<N, Signed>& other) { return static_cast<Bits<Size>>(*this) & other; }
136+
128137
Bits<Bits<Size>::InfinitePrecision> operator<<(const int& shamt) const { return static_cast<Bits<Size>>(*this) << shamt; }
129138

130139
template <unsigned Shamt>

backends/cpp_hart_gen/cpp/include/udb/util.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,23 @@ namespace udb {
9090
for (unsigned i=1; i<N; i++) {
9191
result |= value << (i*M);
9292
}
93-
return value;
93+
return result;
9494
}
9595

96+
template <unsigned M, typename T>
97+
constexpr Bits<BitsInfinitePrecision> replicate(const Bits<M>& value, const T& N)
98+
{
99+
udb_assert(N > 0, "Must replicate at least once");
100+
static_assert(M < BitsMaxNativePrecision, "Please don't replicate multiprecision numbers ;(");
101+
102+
Bits<BitsInfinitePrecision> result = value;
103+
for (unsigned i=1; i<N; i++) {
104+
result |= value << (i*M);
105+
}
106+
return result;
107+
}
108+
109+
96110
template <unsigned FirstExtendedBit, unsigned ResultWidth, unsigned InputWidth>
97111
constexpr Bits<ResultWidth> sign_extend(const Bits<InputWidth>& value) {
98112
bool zero = (value & (static_cast<Bits<InputWidth>>(1).template sll<FirstExtendedBit - 1>())) == 0;

backends/cpp_hart_gen/lib/gen_cpp.rb

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -269,13 +269,9 @@ class IntLiteralAst
269269
def gen_cpp(symtab, indent = 0, indent_spaces: 2)
270270
v = value(symtab)
271271
if v >= 0
272-
if v.bit_length <= 64
273-
"#{' ' * indent}#{value(symtab)}ULL"
274-
else
275-
"#{' ' * indent}#{value(symtab)}_b"
276-
end
272+
"#{' ' * indent}#{value(symtab)}_b"
277273
else
278-
if v.bit_length <= 63
274+
if v.bit_length <= 127
279275
"#{' ' * indent}#{value(symtab)}LL"
280276
else
281277
"#{' ' * indent}#{value(symtab)}_b"
@@ -289,10 +285,10 @@ def gen_cpp(symtab, indent = 0, indent_spaces: 2)
289285
var = symtab.get(text_value)
290286

291287
if !var.nil? && var.param?
292-
if var.value.nil?
288+
if symtab.cfg_arch.params_without_value.any? { |p| p.name == text_value }
293289
"#{' ' * indent}__UDB_RUNTIME_PARAM(#{text_value})"
294290
else
295-
"#{' ' * indent}__UDB_STATIC_PARAM(#{text_value})"
291+
"#{' ' * indent}__UDB_STATIC_PARAM(#{text_value}) /* #{var.value} */"
296292
end
297293
else
298294
"#{' ' * indent}#{text_value}"
@@ -341,7 +337,15 @@ def gen_cpp(symtab, indent = 0, indent_spaces: 2)
341337
class BuiltinTypeNameAst
342338
def gen_cpp(symtab, indent = 0, indent_spaces: 2)
343339
if @type_name == "Bits"
344-
"#{' '*indent}Bits<#{bits_expression.gen_cpp(symtab, 0, indent_spaces:)}>"
340+
result = ""
341+
value_result = value_try do
342+
bits_expression.value(symtab)
343+
result = "#{' '*indent}Bits<#{bits_expression.gen_cpp(symtab, 0, indent_spaces:)}>"
344+
end
345+
value_else(value_result) do
346+
result = "#{' '*indent}Bits<BitsInfinitePrecision>"
347+
end
348+
result
345349
elsif @type_name == "XReg"
346350
"#{' '*indent}Bits<#{symtab.cfg_arch.possible_xlens.max()}>"
347351
elsif @type_name == "Boolean"
@@ -407,7 +411,11 @@ def gen_cpp(symtab, indent = 0, indent_spaces: 2)
407411
#"#{' '*indent}#{var.gen_cpp(symtab, 0, indent_spaces:)}[#{index.gen_cpp(symtab, 0, indent_spaces:)}]"
408412
"#{' '*indent} __UDB__FUNC__OBJ xregRef(#{index.gen_cpp(symtab, 0, indent_spaces:)})"
409413
else
410-
"#{' '*indent}#{var.gen_cpp(symtab, 0, indent_spaces:)}[#{index.gen_cpp(symtab, 0, indent_spaces:)}]"
414+
if var.type(symtab).integral?
415+
"#{' '*indent}extract<#{index.gen_cpp(symtab, 0)}, 1, #{var.type(symtab).width}>(#{var.gen_cpp(symtab, 0, indent_spaces:)})"
416+
else
417+
"#{' '*indent}#{var.gen_cpp(symtab, 0, indent_spaces:)}[#{index.gen_cpp(symtab, 0, indent_spaces:)}]"
418+
end
411419
end
412420
end
413421
end
@@ -469,7 +477,14 @@ def gen_cpp(symtab, indent = 0, indent_spaces: 2)
469477

470478
class ReplicationExpressionAst
471479
def gen_cpp(symtab, indent = 0, indent_spaces: 2)
472-
"#{' '*indent}replicate<#{n.gen_cpp(symtab, 0, indent_spaces:)}>(#{v.gen_cpp(symtab, 0, indent_spaces:)})"
480+
result = ""
481+
value_result = value_try do
482+
result = "#{' '*indent}replicate<#{n.value(symtab)}>(#{v.gen_cpp(symtab, 0, indent_spaces:)})"
483+
end
484+
value_else(value_result) do
485+
result = "#{' '*indent}replicate(#{v.gen_cpp(symtab, 0, indent_spaces:)}, #{n.gen_cpp(symtab, 0, indent_spaces:)})"
486+
end
487+
result
473488
end
474489
end
475490

backends/cpp_hart_gen/tasks.rake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ rule %r{#{CPP_HART_GEN_DST}/.*/include/udb/cfgs/[^/]+/[^/]+\.hxx} => proc { |tna
9595

9696
FileUtils.mkdir_p File.dirname(t.name)
9797
File.write(t.name, erb.result(CppHartGen::TemplateEnv.new(cfg_arch).get_binding))
98+
sh "clang-format -i #{t.name}"
9899
end
99100

100101
rule %r{#{CPP_HART_GEN_DST}/.*/src/cfgs/[^/]+/[^/]+\.cxx} => proc { |tname|
@@ -120,6 +121,7 @@ rule %r{#{CPP_HART_GEN_DST}/.*/src/cfgs/[^/]+/[^/]+\.cxx} => proc { |tname|
120121

121122
FileUtils.mkdir_p File.dirname(t.name)
122123
File.write(t.name, erb.result(CppHartGen::TemplateEnv.new(cfg_arch).get_binding))
124+
sh "clang-format -i #{t.name}"
123125
end
124126

125127
rule %r{#{CPP_HART_GEN_DST}/[^/]+/CMakeLists\.txt} => [

backends/cpp_hart_gen/templates/csrs.cxx.erb

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ using namespace udb;
99
<%- fields = cfg_arch.fully_configured? ? csr.implemented_fields(cfg_arch) : csr.fields -%>
1010

1111
#define __UDB_RUNTIME_PARAM(param_name) m_hart->m_params.param_name
12+
#define __UDB_STATIC_PARAM(param_name) <%= name_of(:params, cfg_arch) %>::param_name
1213
#define __UDB_FUNC_CALL m_hart->
1314
#define __UDB_CONSTEXPR_FUNC_CALL <%= name_of(:hart, cfg_arch) %>::
1415

@@ -61,10 +62,12 @@ void <%= name_of(:csr_field, cfg_arch, csr.name, field.name) %>::reset() {
6162
<%- end -%>
6263

6364
#undef __UDB_RUNTIME_PARAM
65+
#undef __UDB_STATIC_PARAM
6466
#undef __UDB_CONSTEXPR_FUNC_CALL
6567
#undef __UDB_FUNC_CALL
6668

6769
#define __UDB_RUNTIME_PARAM(param_name) m_parent->m_params.param_name
70+
#define __UDB_STATIC_PARAM(param_name) <%= name_of(:params, cfg_arch) %>::param_name
6871
#define __UDB_CSR_BY_ADDR(addr) m_parent->csr(addr)
6972
#define __UDB_CSR_BY_NAME(csr_name) m_parent->m_csrs.csr_name
7073
#define __UDB_CSR_FIELD_READ(field_name) m_##field_name
@@ -159,18 +162,20 @@ bool <%= name_of(:csr, cfg_arch, csr.name) %>::_sw_write(const Bits<<%= csr.max_
159162
<%- fields.each do |field| -%>
160163
<%- next unless cfg_arch.possible_xlens.any? { |xlen| field.defined_in_base?(xlen) } -%>
161164
<%- if field.has_custom_sw_write? -%>
162-
auto wr_val_fn = [this, value]() -> PossiblyUndefinedBits {
163-
View<<%= cfg_arch.possible_xlens[0] %>> csr_value(value);
164-
<%- pruned_ast = field.pruned_sw_write_ast(cfg_arch.possible_xlens[0]) -%>
165-
<%- symtab = field.fill_symtab_for_sw_write(cfg_arch.possible_xlens[0], pruned_ast) -%>
166-
<%= pruned_ast.gen_cpp(symtab) %>
167-
<%- symtab.release -%>
168-
};
169-
auto wr_val = wr_val_fn();
170-
if (wr_val == UNDEFINED_LEGAL_DETERMINISTIC) {
171-
m_<%= field.name %>.makeUndefined();
172-
} else {
173-
m_<%= field.name %>._hw_write(wr_val);
165+
{
166+
auto wr_val_fn = [this, value]() -> PossiblyUndefinedBits {
167+
View<<%= cfg_arch.possible_xlens[0] %>> csr_value(value);
168+
<%- pruned_ast = field.pruned_sw_write_ast(cfg_arch.possible_xlens[0]) -%>
169+
<%- symtab = field.fill_symtab_for_sw_write(cfg_arch.possible_xlens[0], pruned_ast) -%>
170+
<%= pruned_ast.gen_cpp(symtab) %>
171+
<%- symtab.release -%>
172+
};
173+
auto wr_val = wr_val_fn();
174+
if (wr_val == UNDEFINED_LEGAL_DETERMINISTIC) {
175+
m_<%= field.name %>.makeUndefined();
176+
} else {
177+
m_<%= field.name %>._hw_write(wr_val);
178+
}
174179
}
175180
<%- end -%>
176181
<%- end -%>
@@ -179,6 +184,7 @@ bool <%= name_of(:csr, cfg_arch, csr.name) %>::_sw_write(const Bits<<%= csr.max_
179184
<%- end -%>
180185
181186
#undef __UDB_RUNTIME_PARAM
187+
#undef __UDB_STATIC_PARAM
182188
#undef __UDB_CSR_BY_ADDR
183189
#undef __UDB_CSR_BY_NAME
184190
#undef __UDB_CSR_FIELD_READ

backends/cpp_hart_gen/templates/func_prototypes.hxx.erb

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// IT IS NOT STANDALONE. IT IS A FUNCTION LIST FOR THE Hart CLASS
33

44
#define __UDB_CONSTEXPR_FUNC_CALL
5-
#define __UDB_RUNTIME_PARAM(param_name) m_params.param_name
65

76
<%# need to get symtab at function scope -%>
87
<%- symtab = cfg_arch.symtab.global_clone.push(nil) -%>
@@ -15,41 +14,5 @@
1514
<%- end -%>
1615

1716
#undef __UDB_CONSTEXPR_FUNC_CALL
18-
#undef __UDB_RUNTIME_PARAM
19-
20-
//
21-
// begin the builtin functions
22-
//
23-
24-
constexpr bool implemented_Q_(const ExtensionName& ext, const VersionRequirement& req) const {
25-
26-
<%- if cfg_arch.fully_configured? -%>
27-
<%- cfg_arch.implemented_extensions.each do |ext| -%>
28-
if (ext == ExtensionName::<%= ext.name %>) { return true; }
29-
<%- end -%>
30-
<%- elsif cfg_arch.partially_configured? -%>
31-
<%- cfg_arch.mandatory_extensions.each do |ext| -%>
32-
if (ext == ExtensionName::<%= ext.name %>) { return true; }
33-
<%- end -%>
34-
<%- end -%>
35-
return m_implemented_optional_extensions.find(ext) != m_implemented_optional_extensions.end();
36-
}
37-
38-
constexpr bool implemented_Q_(const ExtensionName& ext) const {
39-
40-
<%- if cfg_arch.fully_configured? -%>
41-
<%- cfg_arch.implemented_extensions.each do |ext| -%>
42-
if (ext == ExtensionName::<%= ext.name %>) { return true; }
43-
<%- end -%>
44-
<%- elsif cfg_arch.partially_configured? -%>
45-
<%- cfg_arch.mandatory_extensions.each do |ext| -%>
46-
if (ext == ExtensionName::<%= ext.name %>) { return true; }
47-
<%- end -%>
48-
<%- end -%>
49-
return m_implemented_optional_extensions.find(ext) != m_implemented_optional_extensions.end();
50-
}
51-
52-
// generated decode function
53-
InstBase<Hart>* decode(const XReg& pc, const Bits<INSTR_ENC_SIZE>& encoding);
5417

5518
<%- symtab.release -%>

backends/cpp_hart_gen/templates/hart.hxx.erb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ namespace udb {
3535
static <%= global.type(cfg_arch.symtab).to_cxx %> <%= global.id %>;
3636
<%- end -%>
3737
<%- end -%>
38+
39+
<%- cfg_arch.global_ast.structs.each do |struct| -%>
40+
#define __UDB_RUNTIME_PARAM(param_name) 64
41+
struct <%= struct.name %> {
42+
<%- struct.member_types.each_index do |idx| -%>
43+
<%= struct.member_types[idx].gen_cpp(cfg_arch.symtab, 0) %> <%= struct.member_names[idx] %>;
44+
<%- end -%>
45+
};
46+
#undef __UDB_RUNTIME_PARAM
47+
<%- end -%>
48+
3849
#include "udb/cfgs/<%= cfg_arch.name %>/func_prototypes.hxx"
3950

4051
static constexpr unsigned MXLEN = <%= cfg_arch.mxlen.nil? ? 64 : cfg_arch.mxlen %>;
@@ -48,10 +59,6 @@ namespace udb {
4859
m_xregs[0].makeZeroReg();
4960
}
5061

51-
unsigned xlen() {
52-
return MXLEN;
53-
}
54-
5562
bool implemented_Q_(const ExtensionName& ext, const VersionRequirement& req)
5663
{
5764
return false;

0 commit comments

Comments
 (0)