idlc 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,135 @@
1
+ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
2
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
3
+
4
+ # typed: strict
5
+ # frozen_string_literal: true
6
+
7
+ require "sorbet-runtime"
8
+
9
+ require_relative "type"
10
+
11
+ module Idl
12
+ # interface for a parameter that may only be known at runtime
13
+ module RuntimeParam
14
+ extend T::Sig
15
+ extend T::Helpers
16
+ interface!
17
+
18
+ include Kernel
19
+
20
+ ValueType =
21
+ T.type_alias { T.any(Integer, T::Boolean, String, T::Array[Integer], T::Array[Integer], T::Array[T::Boolean], T::Array[String]) }
22
+
23
+ sig { abstract.returns(String) }
24
+ def name; end
25
+
26
+ sig { abstract.returns(String) }
27
+ def description; end
28
+
29
+ sig { abstract.returns(Schema) }
30
+ def schema; end
31
+
32
+ sig { abstract.returns(T::Boolean) }
33
+ def value_known?; end
34
+
35
+ sig { abstract.returns(ValueType) }
36
+ def value; end
37
+
38
+ sig { abstract.returns(Type) }
39
+ def idl_type; end
40
+ end
41
+
42
+ # basic interface for objects that are described with JSON Schema
43
+ module Schema
44
+ extend T::Sig
45
+ extend T::Helpers
46
+ interface!
47
+
48
+ sig { abstract.returns(T::Boolean) }
49
+ def max_val_known?; end
50
+
51
+ sig { abstract.returns(Integer) }
52
+ def max_val; end
53
+
54
+ sig { abstract.returns(T::Boolean) }
55
+ def min_val_known?; end
56
+
57
+ sig { abstract.returns(Integer) }
58
+ def min_val; end
59
+
60
+ sig { abstract.returns(Type) }
61
+ def to_idl_type; end
62
+ end
63
+
64
+ module CsrField
65
+ extend T::Sig
66
+ extend T::Helpers
67
+ interface!
68
+
69
+ sig { abstract.returns(String) }
70
+ def name; end
71
+
72
+ # whether or not this field is defined in both RV32 and RV64
73
+ sig { abstract.returns(T::Boolean) }
74
+ def defined_in_all_bases?; end
75
+
76
+ sig { abstract.returns(T::Boolean) }
77
+ def defined_in_base32?; end
78
+
79
+ sig { abstract.returns(T::Boolean) }
80
+ def defined_in_base64?; end
81
+
82
+ # whether or not this field is defined only in RV64
83
+ sig { abstract.returns(T::Boolean) }
84
+ def base64_only?; end
85
+
86
+ # whether or not this field is defined only in RV32
87
+ sig { abstract.returns(T::Boolean) }
88
+ def base32_only?; end
89
+
90
+ # returns the location of the field in the CSR.
91
+ # base is required when the field moves locations between RV32 and RV64
92
+ sig { abstract.params(base: T.nilable(Integer)).returns(T::Range[Integer]) }
93
+ def location(base); end
94
+
95
+ sig { abstract.params(base: T.nilable(Integer)).returns(Integer) }
96
+ def width(base); end
97
+
98
+ sig { abstract.params(base: T.nilable(Integer)).returns(T.nilable(String)) }
99
+ def type(base); end
100
+
101
+ # whether or not the field is supposed to exist/be implemented in the
102
+ # execution context
103
+ sig { abstract.returns(T::Boolean) }
104
+ def exists?; end
105
+
106
+ sig { abstract.returns(ValueRbType) }
107
+ def reset_value; end
108
+ end
109
+
110
+ module Csr
111
+ extend T::Sig
112
+ extend T::Helpers
113
+ interface!
114
+
115
+ sig { abstract.returns(String) }
116
+ def name; end
117
+
118
+ sig { abstract.params(base: T.nilable(Integer)).returns(T.nilable(Integer)) }
119
+ def length(base); end
120
+
121
+ sig { abstract.returns(Integer) }
122
+ def max_length; end
123
+
124
+ sig { abstract.returns(T::Boolean) }
125
+ def dynamic_length?; end
126
+
127
+ sig { abstract.returns(T::Array[CsrField]) }
128
+ def fields; end
129
+
130
+ # If the entire CSR is read-only with a known reset value, returns the value
131
+ # otherwise, returns nil
132
+ sig { abstract.returns(T.nilable(Integer)) }
133
+ def value; end
134
+ end
135
+ end
data/lib/idlc/log.rb ADDED
@@ -0,0 +1,23 @@
1
+ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
2
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
3
+
4
+ # typed: true
5
+ # frozen_string_literal: true
6
+
7
+ require "logger"
8
+
9
+ require "sorbet-runtime"
10
+
11
+ module Idl
12
+ extend T::Sig
13
+
14
+ sig { returns(Logger).checked(:tests) }
15
+ def self.logger
16
+ @logger ||= Logger.new($stdout, level: :warn)
17
+ end
18
+
19
+ sig { params(logger: Logger).returns(Logger) }
20
+ def self.set_logger(logger)
21
+ @logger = logger
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
2
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
3
+
4
+ # typed: true
5
+ # frozen_string_literal: true
6
+
7
+ require "sorbet-runtime"
8
+
9
+ module Idl
10
+ class AstNode
11
+ extend T::Sig
12
+ sig { overridable.returns(T::Array[String]) }
13
+ def find_referenced_csrs
14
+ csrs = T.let([], T::Array[String])
15
+ @children.each do |child|
16
+ csrs += child.find_referenced_csrs
17
+ end
18
+ csrs.uniq
19
+ end
20
+ end
21
+
22
+ class CsrReadExpressionAst < AstNode
23
+ sig { override.returns(T::Array[String]) }
24
+ def find_referenced_csrs
25
+ [csr_name]
26
+ end
27
+ end
28
+
29
+ class CsrWriteAst < AstNode
30
+ sig { override.returns(T::Array[String]) }
31
+ def find_referenced_csrs
32
+ if idx.is_a?(IntLiteralAst)
33
+ []
34
+ else
35
+ [idx.text_value]
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,76 @@
1
+ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
2
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
3
+
4
+ # frozen_string_literal: true
5
+
6
+ # pass to find all the possible return values from a function body
7
+
8
+ module Idl
9
+
10
+ class AstNode
11
+ def pass_find_return_values(values, current_conditions)
12
+ children.each do |c|
13
+ c.pass_find_return_values(values, current_conditions)
14
+ end
15
+ end
16
+ end
17
+
18
+ class ReturnStatementAst < AstNode
19
+ def pass_find_return_values(values, current_conditions, symtab)
20
+ # if the action is a ternary operator, there is another condition to consider
21
+ if first.is_a?(TernaryOperatorExpressionAst)
22
+ current_conditions.push first.condition
23
+ values << [first.true_expression, current_conditions.clone]
24
+ current_conditions.pop
25
+ current_conditions.push first.condition.invert(symtab)
26
+ values << [first.false_expression, current_conditions.clone]
27
+ current_conditions.pop
28
+ else
29
+ values << [self, current_conditions.clone]
30
+ end
31
+ end
32
+ end
33
+
34
+ class IfAst < AstNode
35
+ def pass_find_return_values(values, current_conditions, symtab)
36
+ current_conditions.push if_cond
37
+ if_body.elements.each do |e|
38
+ e.e.pass_find_return_values(values, current_conditions, symtab)
39
+ end
40
+ current_conditions.pop
41
+
42
+ unless elseifs.empty?
43
+ elseifs.elements.each do |eif|
44
+ current_conditions.push eif.expression
45
+
46
+ eif.body.elements.each do |e|
47
+ e.e.pass_find_return_values(values, current_conditions, symtab)
48
+ end
49
+
50
+ current_conditions.pop
51
+ end
52
+ end
53
+
54
+ unless final_else.empty?
55
+ current_conditions.push if_cond.invert(symtab)
56
+
57
+ final_else.body.elements.each do |e|
58
+ e.e.pass_find_return_values(values, current_conditions, symtab)
59
+ end
60
+ current_conditions.pop
61
+ end
62
+ end
63
+ end
64
+
65
+ class FunctionBodyAst < AstNode
66
+ # @return [Array<Ast, Array<Ast>>] List of possible return values, along with the condition it occurs under
67
+ def pass_find_return_values(symtab)
68
+ values = []
69
+ current_conditions = []
70
+ statements.each do |s|
71
+ s.pass_find_return_values(values, current_conditions, symtab)
72
+ end
73
+ values
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,125 @@
1
+ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
2
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
3
+
4
+ # frozen_string_literal: true
5
+
6
+ module Idl
7
+ class ComplexRegDetermination < RuntimeError
8
+ end
9
+
10
+ class AstNode
11
+ def find_src_registers(symtab)
12
+ # if is_a?(Executable)
13
+ # value_result = value_try do
14
+ # execute(symtab)
15
+ # end
16
+ # value_else(value_result) do
17
+ # execute_unknown(symtab)
18
+ # end
19
+ # end
20
+ add_symbol(symtab) if is_a?(Declaration)
21
+
22
+ srcs = []
23
+ @children.each do |child|
24
+ srcs.concat(child.find_src_registers(symtab))
25
+ end
26
+ srcs.uniq
27
+ end
28
+
29
+ def find_dst_registers(symtab)
30
+ # if is_a?(Executable)
31
+ # value_result = value_try do
32
+ # execute(symtab)
33
+ # end
34
+ # value_else(value_result) do
35
+ # execute_unknown(symtab)
36
+ # end
37
+ # end
38
+ add_symbol(symtab) if is_a?(Declaration)
39
+
40
+ srcs = []
41
+ @children.each do |child|
42
+ srcs.concat(child.find_dst_registers(symtab))
43
+ end
44
+ srcs.uniq
45
+ end
46
+ end
47
+
48
+ class ForLoopAst
49
+ # we don't unroll, but we don't add the index variable to the symtab, either
50
+ # that will cause any register accesses dependent on the index variable to raise Complex
51
+ def find_src_registers(symtab)
52
+ srcs = init.find_src_registers(symtab)
53
+ # don't add init to the symtab, since we don't want to use it...
54
+ srcs += condition.find_src_registers(symtab)
55
+
56
+ stmts.each do |stmt|
57
+ srcs += stmt.find_src_registers(symtab)
58
+ end
59
+ srcs += update.find_src_registers(symtab)
60
+
61
+ srcs
62
+ end
63
+
64
+ # we don't unroll, but we don't add the index variable to the symtab, either
65
+ # that will cause any register accesses dependent on the index variable to raise Complex
66
+ def find_dst_registers(symtab)
67
+ dsts = init.find_dst_registers(symtab)
68
+ # don't add init to the symtab, since we don't want to use it...
69
+ dsts += condition.find_dst_registers(symtab)
70
+
71
+ stmts.each do |stmt|
72
+ dsts += stmt.find_dst_registers(symtab)
73
+ end
74
+ dsts += update.find_dst_registers(symtab)
75
+
76
+ dsts
77
+ end
78
+ end
79
+
80
+ class AryElementAccessAst
81
+ def find_src_registers(symtab)
82
+ value_result = value_try do
83
+ if var.text_value == "X"
84
+ return [index.value(symtab)]
85
+ else
86
+ return []
87
+ end
88
+ end
89
+ value_else(value_result) do
90
+ if var.text_value == "X"
91
+ if index.type(symtab).const?
92
+ return [index.gen_cpp(symtab, 0)]
93
+ else
94
+ raise ComplexRegDetermination
95
+ end
96
+ else
97
+ return []
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ class AryElementAssignmentAst
104
+ def find_dst_registers(symtab)
105
+ value_result = value_try do
106
+ if lhs.text_value == "X"
107
+ return [idx.value(symtab)]
108
+ else
109
+ return []
110
+ end
111
+ end
112
+ value_else(value_result) do
113
+ if lhs.text_value == "X"
114
+ if idx.type(symtab).const?
115
+ return [idx.gen_cpp(symtab, 0)]
116
+ else
117
+ raise ComplexRegDetermination
118
+ end
119
+ else
120
+ return []
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end