Skip to content

Commit a98ef57

Browse files
author
Derek Hower
committed
WIP
1 parent 0771491 commit a98ef57

File tree

14 files changed

+166
-38
lines changed

14 files changed

+166
-38
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,20 @@ namespace udb
980980
}
981981
}
982982

983+
// signed bits
984+
template <char... Str>
985+
constexpr _Bits<BitsStr<Str..., '\0'>::width + 1, false> operator""_sb()
986+
{
987+
if constexpr ((BitsStr<Str..., '\0'>::width + 1) <= _Bits<(BitsStr<Str..., '\0'>::width + 1), false>::MaxNativePrecision)
988+
{
989+
return BitsStr<Str..., '\0'>::val;
990+
}
991+
else
992+
{
993+
return mpz_class{BitsStr<Str..., '\0'>::str};
994+
}
995+
}
996+
983997
static_assert((0x0_b).Width == 1);
984998
static_assert((0x1_b).Width == 1);
985999
static_assert((0x2_b).Width == 2);

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ namespace udb {
178178
virtual bool implemented_Q_(const ExtensionName& ext) = 0;
179179
virtual bool implemented_Q_(const ExtensionName& ext, const VersionRequirement& req) = 0;
180180

181+
template <unsigned M>
182+
Bits<64> read_hpm_counter(const Bits<M>& hpm_num) { return 0; }
183+
184+
Bits<64> read_mcycle() { return 0; }
185+
186+
Bits<64> sw_write_mcycle(const Bits<64>& cycle) { return 0; }
187+
188+
unsigned hartid() const { return m_hart_id; }
189+
181190
protected:
182191
const unsigned m_hart_id;
183192
Memory& m_mem;

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

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ namespace udb {
109109
static constexpr Bits<Size> MaximumValue = (Bits<1>(1).template sll<Size>()) - 1;
110110
static constexpr Bits<ParentSize> Mask = MaximumValue.template sll<Start>();
111111

112-
operator Bits<Size>() const;
112+
template <unsigned N>
113+
requires (N >= Size)
114+
operator Bits<N>() const;
115+
113116
operator PossiblyUndefinedBits() const;
114117

115118
bool operator!() const {
@@ -131,6 +134,12 @@ namespace udb {
131134
template <unsigned N, bool Signed>
132135
bool operator>=(const _Bits<N, Signed>& other) { return static_cast<Bits<Size>>(*this) >= other; }
133136

137+
template <unsigned N, bool Signed>
138+
bool operator<=(const _Bits<N, Signed>& other) { return static_cast<Bits<Size>>(*this) <= other; }
139+
140+
template <unsigned OtherParentSize, unsigned OtherStart, unsigned OtherSize>
141+
bool operator<(const BitfieldMember<OtherParentSize, OtherStart, OtherSize>& other) { return static_cast<Bits<Size>>(*this) > static_cast<Bits<OtherSize>>(*this); }
142+
134143
template <unsigned N, bool Signed>
135144
Bits<Size> operator&(const _Bits<N, Signed>& other) { return static_cast<Bits<Size>>(*this) & other; }
136145

@@ -168,7 +177,9 @@ namespace udb {
168177
static_assert(std::is_copy_constructible_v<BitfieldMember<64, 0, 1>>);
169178

170179
template <unsigned ParentSize, unsigned Start, unsigned Size>
171-
BitfieldMember<ParentSize, Start, Size>::operator Bits<Size>() const
180+
template <unsigned N>
181+
requires (N >= Size)
182+
BitfieldMember<ParentSize, Start, Size>::template operator Bits<N>() const
172183
{
173184
return (static_cast<Bits<ParentSize>>(m_parent) >> Start) & MaximumValue;
174185
}
@@ -186,12 +197,4 @@ namespace udb {
186197
m_parent = (static_cast<Bits<ParentSize>>(m_parent) & ~Mask) | ((value.template sll<Size>()) & Mask);
187198
return *this;
188199
}
189-
190-
// struct to define types based on XLEN
191-
template <unsigned XLEN>
192-
struct BaseIsa {
193-
static_assert(XLEN == 32 || XLEN == 64);
194-
195-
using XReg = Bits<XLEN>; //std::conditional_t<(XLEN == 64), uint64_t, uint32_t>;
196-
};
197200
}

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace udb {
2727

2828
// extract bits from a Bits type
2929
template <unsigned start, unsigned size, unsigned bits_len>
30-
constexpr Bits<size> extract(Bits<bits_len> value)
30+
constexpr Bits<size> extract(const Bits<bits_len>& value)
3131
{
3232
static_assert((start + size) <= bits_len, "Cannot extract more bits than type contains");
3333

@@ -39,6 +39,19 @@ namespace udb {
3939
}
4040
}
4141

42+
// extract from a bitfield member
43+
template <unsigned start, unsigned size, unsigned BitfieldParentSize, unsigned BitfieldMemberStart, unsigned BitfieldMemberSize>
44+
constexpr Bits<size> extract(const BitfieldMember<BitfieldParentSize, BitfieldMemberStart, BitfieldMemberSize>& value)
45+
{
46+
static_assert((start + size) <= (BitfieldMemberSize), "Cannot extract more bits than type contains");
47+
48+
if constexpr (size == BitfieldMemberSize) {
49+
return value;
50+
} else {
51+
constexpr Bits<BitfieldMemberSize> mask = (static_cast<Bits<BitfieldMemberSize>>(1).template const_sll<size>()) - 1;
52+
return (value >> start) & mask;
53+
}
54+
}
4255
// extract bits, where the extraction is not known at compile time
4356
template <typename T>
4457
T extract(T value, unsigned start, unsigned size)

backends/cpp_hart_gen/lib/csr_template_helpers.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def type_to_cpp(xlen)
2424
symtab = fill_symtab_for_type(xlen, pruned_ast)
2525
value_result = pruned_ast.value_try do
2626
type_value = pruned_ast.return_value(symtab)
27-
cpp = "return CsfFieldType::#{TYPE_VALUE_TO_CPP_NAME[type_value]};"
27+
cpp = "return CsrFieldType::#{TYPE_VALUE_TO_CPP_NAME[type_value]};"
2828
end
2929
pruned_ast.value_else(value_result) do
3030
cpp = pruned_ast.gen_cpp(symtab)

backends/cpp_hart_gen/lib/gen_cpp.rb

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,12 @@ def gen_cpp(symtab, indent = 0, indent_spaces: 2)
8383

8484
class UserTypeNameAst
8585
def gen_cpp(symtab, indent = 0, indent_spaces: 2)
86-
"#{' ' * indent}#{text_value}"
86+
type = symtab.get(text_value)
87+
if type.kind == :struct
88+
"#{' ' * indent}__UDB_STRUCT(#{text_value})"
89+
else
90+
"#{' ' * indent}#{text_value}"
91+
end
8792
end
8893
end
8994

@@ -290,6 +295,12 @@ def gen_cpp(symtab, indent = 0, indent_spaces: 2)
290295
else
291296
"#{' ' * indent}__UDB_STATIC_PARAM(#{text_value}) /* #{var.value} */"
292297
end
298+
elsif !var.nil? && var.type.global?
299+
if var.type.const?
300+
"#{' ' * indent}__UDB_CONST_GLOBAL(#{text_value})"
301+
else
302+
"#{' ' * indent}__UDB_MUTABLE_GLOBAL(#{text_value})"
303+
end
293304
else
294305
"#{' ' * indent}#{text_value}"
295306
end
@@ -343,11 +354,19 @@ def gen_cpp(symtab, indent = 0, indent_spaces: 2)
343354
result = "#{' '*indent}Bits<#{bits_expression.gen_cpp(symtab, 0, indent_spaces:)}>"
344355
end
345356
value_else(value_result) do
346-
result = "#{' '*indent}Bits<BitsInfinitePrecision>"
357+
# see if this is a param with a bound
358+
if bits_expression.is_a?(IdAst)
359+
sym = symtab.get(bits_expression.text_value)
360+
if !sym.nil? && sym.param?
361+
param = symtab.cfg_arch.param(bits_expression.text_value)
362+
result = "#{' '*indent}Bits<#{param.schema.max_val}>" if param.schema.max_val_known?
363+
end
364+
end
365+
result = "#{' '*indent}Bits<BitsInfinitePrecision>" if result == ""
347366
end
348367
result
349368
elsif @type_name == "XReg"
350-
"#{' '*indent}Bits<#{symtab.cfg_arch.possible_xlens.max()}>"
369+
"#{' '*indent}Bits<#{symtab.cfg_arch.possible_xlens.max}>"
351370
elsif @type_name == "Boolean"
352371
"#{' '*indent}bool"
353372
elsif @type_name == "U32"
@@ -507,20 +526,26 @@ def gen_cpp(symtab, indent = 0, indent_spaces: 2)
507526

508527
class FunctionCallExpressionAst
509528
def gen_cpp(symtab, indent = 0, indent_spaces: 2)
510-
targs_cpp = template_arg_nodes.map { |t| t.gen_cpp(symtab, 0, indent_spaces:) }
511-
args_cpp = arg_nodes.map { |a| a.gen_cpp(symtab, 0, indent_spaces:) }
512-
ftype = func_type(symtab)
513-
if ftype.func_def_ast.constexpr?(symtab)
514-
if targs_cpp.empty?
515-
"__UDB_CONSTEXPR_FUNC_CALL #{name.gsub("?", "_Q_")}(#{args_cpp.join(', ')})"
516-
else
517-
"__UDB_CONSTEXPR_FUNC_CALL #{name.gsub("?", "_Q_")}<#{targs_cpp.join(', ')}>(#{args_cpp.join(', ')})"
518-
end
529+
if name == "ary_includes?"
530+
# special case
531+
args_cpp = arg_nodes.map { |a| a.gen_cpp(symtab, 0, indent_spaces:) }
532+
"(std::find(#{args_cpp[0]}.begin(), #{args_cpp[0]}.end(), #{args_cpp[1]}) != #{args_cpp[0]}.end())"
519533
else
520-
if targs_cpp.empty?
521-
"__UDB_FUNC_CALL #{name.gsub("?", "_Q_")}(#{args_cpp.join(', ')})"
534+
targs_cpp = template_arg_nodes.map { |t| t.gen_cpp(symtab, 0, indent_spaces:) }
535+
args_cpp = arg_nodes.map { |a| a.gen_cpp(symtab, 0, indent_spaces:) }
536+
ftype = func_type(symtab)
537+
if ftype.func_def_ast.constexpr?(symtab)
538+
if targs_cpp.empty?
539+
"__UDB_CONSTEXPR_FUNC_CALL #{name.gsub("?", "_Q_")}(#{args_cpp.join(', ')})"
540+
else
541+
"__UDB_CONSTEXPR_FUNC_CALL #{name.gsub("?", "_Q_")}<#{targs_cpp.join(', ')}>(#{args_cpp.join(', ')})"
542+
end
522543
else
523-
"__UDB_FUNC_CALL #{name.gsub("?", "_Q_")}<#{targs_cpp.join(', ')}>(#{args_cpp.join(', ')})"
544+
if targs_cpp.empty?
545+
"__UDB_FUNC_CALL #{name.gsub("?", "_Q_")}(#{args_cpp.join(', ')})"
546+
else
547+
"__UDB_FUNC_CALL #{name.gsub("?", "_Q_")}<#{targs_cpp.join(', ')}>(#{args_cpp.join(', ')})"
548+
end
524549
end
525550
end
526551
end

backends/cpp_hart_gen/lib/template_helpers.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ def name_of(kind, cfg_arch_or_config_name, *extras)
9797
raise "Missing Instruction name" unless extras.size == 1
9898

9999
"#{config_name.camelize}_#{extras[0].gsub(".", "_").capitalize}_Inst"
100+
when :struct
101+
raise "Missing struct name" unless extras.size == 1
102+
103+
"#{config_name.camelize}_#{extras[0]}_Struct"
100104
else
101105
raise "TODO: #{kind}"
102106
end

backends/cpp_hart_gen/tasks.rake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ namespace :gen do
235235
Rake::Task["#{CPP_HART_GEN_DST}/#{build_name}/include/udb/cfgs/#{config}/csrs.hxx"].invoke
236236
Rake::Task["#{CPP_HART_GEN_DST}/#{build_name}/src/cfgs/#{config}/csrs.cxx"].invoke
237237
Rake::Task["#{CPP_HART_GEN_DST}/#{build_name}/include/udb/cfgs/#{config}/csr_container.hxx"].invoke
238+
Rake::Task["#{CPP_HART_GEN_DST}/#{build_name}/include/udb/cfgs/#{config}/structs.hxx"].invoke
238239
Rake::Task["#{CPP_HART_GEN_DST}/#{build_name}/include/udb/cfgs/#{config}/func_prototypes.hxx"].invoke
239240

240241
Dir.glob("#{CPP_HART_GEN_SRC}/cpp/include/udb/*.hpp") do |f|

backends/cpp_hart_gen/templates/csrs.cxx.erb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
2+
#include <algorithm>
3+
14
#include "udb/util.hpp"
25
#include "udb/cfgs/<%= cfg_arch.name %>/hart.hxx"
6+
#include "udb/inst.hpp"
37

48
using namespace udb;
59

@@ -12,6 +16,11 @@ using namespace udb;
1216
#define __UDB_STATIC_PARAM(param_name) <%= name_of(:params, cfg_arch) %>::param_name
1317
#define __UDB_FUNC_CALL m_hart->
1418
#define __UDB_CONSTEXPR_FUNC_CALL <%= name_of(:hart, cfg_arch) %>::
19+
#define __UDB_CSR_BY_NAME(csr_name) m_hart->m_csrs.csr_name
20+
#define __UDB_CONST_GLOBAL(global_name) <%= name_of(:hart, cfg_arch) %>::global_name
21+
#define __UDB_MUTABLE_GLOBAL(global_name) m_hart->global_name
22+
#define __UDB_STRUCT(struct_name) <%= cfg_arch.name.camelize %>_ ## struct_name ## _Struct
23+
1524

1625
<%- fields.each do |field| -%>
1726
<%- max_width = cfg_arch.possible_xlens.map { |xlen| field.defined_in_base?(xlen) ? field.location(xlen).size : 0 }.max -%>
@@ -65,6 +74,10 @@ void <%= name_of(:csr_field, cfg_arch, csr.name, field.name) %>::reset() {
6574
#undef __UDB_STATIC_PARAM
6675
#undef __UDB_CONSTEXPR_FUNC_CALL
6776
#undef __UDB_FUNC_CALL
77+
#undef __UDB_CSR_BY_NAME
78+
#undef __UDB_CONST_GLOBAL
79+
#undef __UDB_MUTABLE_GLOBAL
80+
#undef __UDB_STRUCT
6881

6982
#define __UDB_RUNTIME_PARAM(param_name) m_parent->m_params.param_name
7083
#define __UDB_STATIC_PARAM(param_name) <%= name_of(:params, cfg_arch) %>::param_name
@@ -74,6 +87,10 @@ void <%= name_of(:csr_field, cfg_arch, csr.name, field.name) %>::reset() {
7487
#define __UDB_FUNC_CALL m_parent->
7588
#define __UDB_CONSTEXPR_FUNC_CALL <%= name_of(:hart, cfg_arch) %>::
7689
#define __UDB_XLEN m_parent->xlen()
90+
#define __UDB_ENCODING m_parent->m_cur_inst->encoding()
91+
#define __UDB_CONST_GLOBAL(global_name) <%= name_of(:hart, cfg_arch) %>::global_name
92+
#define __UDB_MUTABLE_GLOBAL(global_name) m_parent->global_name
93+
#define __UDB_STRUCT(struct_name) <%= cfg_arch.name.camelize %>_ ## struct_name ## _Struct
7794

7895
// constructor
7996
<%- fields_for_xlen = fields.select { |f| cfg_arch.possible_xlens.any? { |xlen| f.defined_in_base?(xlen) } } -%>
@@ -191,6 +208,9 @@ bool <%= name_of(:csr, cfg_arch, csr.name) %>::_sw_write(const Bits<<%= csr.max_
191208
#undef __UDB_FUNC_CALL
192209
#undef __UDB_CONSTEXPR_FUNC_CALL
193210
#undef __UDB_XLEN
211+
#undef __UDB_CONST_GLOBAL
212+
#undef __UDB_MUTABLE_GLOBAL
213+
#undef __UDB_STRUCT
194214
195215
<%- end -%>
196216

backends/cpp_hart_gen/templates/func_prototypes.hxx.erb

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

44
#define __UDB_CONSTEXPR_FUNC_CALL
5+
#define __UDB_CONST_GLOBAL(global_name) <%= name_of(:hart, cfg_arch) %>::global_name
6+
#define __UDB_MUTABLE_GLOBAL(global_name) global_name
7+
#define __UDB_STRUCT(struct_name) <%= cfg_arch.name.camelize %>_ ## struct_name ## _Struct
58

69
<%# need to get symtab at function scope -%>
710
<%- symtab = cfg_arch.symtab.global_clone.push(nil) -%>
@@ -14,5 +17,8 @@
1417
<%- end -%>
1518

1619
#undef __UDB_CONSTEXPR_FUNC_CALL
20+
#undef __UDB_CONST_GLOBAL
21+
#undef __UDB_MUTABLE_GLOBAL
22+
#undef __UDB_STRUCT
1723

1824
<%- symtab.release -%>

0 commit comments

Comments
 (0)