rggen-default-register-map 0.13.0
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.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/LICENSE +21 -0
- data/README.md +45 -0
- data/lib/rggen/default_register_map.rb +46 -0
- data/lib/rggen/default_register_map/bit_field/bit_assignment.rb +122 -0
- data/lib/rggen/default_register_map/bit_field/comment.rb +18 -0
- data/lib/rggen/default_register_map/bit_field/initial_value.rb +75 -0
- data/lib/rggen/default_register_map/bit_field/name.rb +37 -0
- data/lib/rggen/default_register_map/bit_field/reference.rb +142 -0
- data/lib/rggen/default_register_map/bit_field/type.rb +117 -0
- data/lib/rggen/default_register_map/bit_field/type/rc.rb +9 -0
- data/lib/rggen/default_register_map/bit_field/type/reserved.rb +8 -0
- data/lib/rggen/default_register_map/bit_field/type/ro.rb +8 -0
- data/lib/rggen/default_register_map/bit_field/type/rof.rb +9 -0
- data/lib/rggen/default_register_map/bit_field/type/rs.rb +8 -0
- data/lib/rggen/default_register_map/bit_field/type/rw.rb +9 -0
- data/lib/rggen/default_register_map/bit_field/type/rwc.rb +9 -0
- data/lib/rggen/default_register_map/bit_field/type/rwe_rwl.rb +10 -0
- data/lib/rggen/default_register_map/bit_field/type/w0c_w1c.rb +9 -0
- data/lib/rggen/default_register_map/bit_field/type/w0s_w1s.rb +8 -0
- data/lib/rggen/default_register_map/bit_field/type/w0trg_w1trg.rb +8 -0
- data/lib/rggen/default_register_map/bit_field/type/wo.rb +9 -0
- data/lib/rggen/default_register_map/global/address_width.rb +34 -0
- data/lib/rggen/default_register_map/global/bus_width.rb +35 -0
- data/lib/rggen/default_register_map/register/name.rb +36 -0
- data/lib/rggen/default_register_map/register/offset_address.rb +106 -0
- data/lib/rggen/default_register_map/register/size.rb +95 -0
- data/lib/rggen/default_register_map/register/type.rb +135 -0
- data/lib/rggen/default_register_map/register/type/external.rb +16 -0
- data/lib/rggen/default_register_map/register/type/indirect.rb +256 -0
- data/lib/rggen/default_register_map/register_block/byte_size.rb +61 -0
- data/lib/rggen/default_register_map/register_block/name.rb +38 -0
- data/lib/rggen/default_register_map/setup.rb +18 -0
- data/lib/rggen/default_register_map/version.rb +7 -0
- metadata +95 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RgGen.define_simple_feature(:register, :name) do
|
4
|
+
register_map do
|
5
|
+
property :name
|
6
|
+
|
7
|
+
input_pattern variable_name
|
8
|
+
|
9
|
+
build do |value|
|
10
|
+
@name =
|
11
|
+
if pattern_matched?
|
12
|
+
match_data.to_s
|
13
|
+
else
|
14
|
+
error "illegal input value for register name: #{value.inspect}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
verify(:feature) do
|
19
|
+
error_condition { !name }
|
20
|
+
message { 'no register name is given' }
|
21
|
+
end
|
22
|
+
|
23
|
+
verify(:feature) do
|
24
|
+
error_condition { duplicated_name? }
|
25
|
+
message { "duplicated register name: #{name}" }
|
26
|
+
end
|
27
|
+
|
28
|
+
printable :name
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def duplicated_name?
|
33
|
+
register_block.registers.any? { |register| register.name == name }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RgGen.define_simple_feature(:register, :offset_address) do
|
4
|
+
register_map do
|
5
|
+
property :offset_address
|
6
|
+
property :address_range, initial: -> { start_address..end_address }
|
7
|
+
property :overlap?, forward_to: :overlap_address_range?
|
8
|
+
|
9
|
+
build do |value|
|
10
|
+
@offset_address =
|
11
|
+
begin
|
12
|
+
Integer(value)
|
13
|
+
rescue ArgumentError, TypeError
|
14
|
+
error "cannot convert #{value.inspect} into offset address"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
verify(:feature) do
|
19
|
+
error_condition { !offset_address }
|
20
|
+
message { 'no offset address is given' }
|
21
|
+
end
|
22
|
+
|
23
|
+
verify(:feature) do
|
24
|
+
error_condition { offset_address.negative? }
|
25
|
+
message { "offset address is less than 0: #{offset_address}" }
|
26
|
+
end
|
27
|
+
|
28
|
+
verify(:feature) do
|
29
|
+
error_condition { (offset_address % byte_width).positive? }
|
30
|
+
message do
|
31
|
+
"offset address is not aligned with bus width(#{bus_width}): "\
|
32
|
+
"0x#{offset_address.to_s(16)}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
verify(:component) do
|
37
|
+
error_condition { end_address > register_block.byte_size }
|
38
|
+
message do
|
39
|
+
'offset address range exceeds byte size of register block' \
|
40
|
+
"(#{register_block.byte_size}): " \
|
41
|
+
"0x#{start_address.to_s(16)}-0x#{end_address.to_s(16)}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
verify(:component) do
|
46
|
+
error_condition do
|
47
|
+
register_block.registers.any? do |register|
|
48
|
+
overlap_address_range?(register) &&
|
49
|
+
support_unique_range_only?(register)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
message do
|
53
|
+
'offset address range overlaps with other offset address range: ' \
|
54
|
+
"0x#{start_address.to_s(16)}-0x#{end_address.to_s(16)}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
printable(:offset_address) do
|
59
|
+
[start_address, end_address]
|
60
|
+
.map(&method(:printable_address)).join(' - ')
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def bus_width
|
66
|
+
configuration.bus_width
|
67
|
+
end
|
68
|
+
|
69
|
+
def byte_width
|
70
|
+
configuration.byte_width
|
71
|
+
end
|
72
|
+
|
73
|
+
def start_address
|
74
|
+
offset_address
|
75
|
+
end
|
76
|
+
|
77
|
+
def end_address
|
78
|
+
start_address + register.byte_size - 1
|
79
|
+
end
|
80
|
+
|
81
|
+
def overlap_address_range?(other_register)
|
82
|
+
overlap_range?(other_register) && match_access?(other_register)
|
83
|
+
end
|
84
|
+
|
85
|
+
def overlap_range?(other_register)
|
86
|
+
own = address_range
|
87
|
+
other = other_register.address_range
|
88
|
+
own.include?(other.first) || other.include?(own.first)
|
89
|
+
end
|
90
|
+
|
91
|
+
def match_access?(other_register)
|
92
|
+
(register.writable? && other_register.writable?) ||
|
93
|
+
(register.readable? && other_register.readable?)
|
94
|
+
end
|
95
|
+
|
96
|
+
def support_unique_range_only?(other_register)
|
97
|
+
!(register.settings[:support_overlapped_address] &&
|
98
|
+
register.match_type?(other_register))
|
99
|
+
end
|
100
|
+
|
101
|
+
def printable_address(address)
|
102
|
+
print_width = (register_block.local_address_width + 3) / 4
|
103
|
+
format('0x%0*x', print_width, address)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RgGen.define_simple_feature(:register, :size) do
|
4
|
+
register_map do
|
5
|
+
property :size
|
6
|
+
property :width, initial: -> { calc_width }
|
7
|
+
property :byte_width, initial: -> { width / 8 }
|
8
|
+
property :byte_size, initial: -> { calc_byte_size }
|
9
|
+
property :array?, forward_to: :array_register?
|
10
|
+
property :array_size, forward_to: :array_registers
|
11
|
+
property :count, initial: -> { calc_count }
|
12
|
+
|
13
|
+
input_pattern [
|
14
|
+
/(#{integer}(:?,#{integer})*)/,
|
15
|
+
/\[(#{integer}(:?,#{integer})*)\]/
|
16
|
+
], match_automatically: false
|
17
|
+
|
18
|
+
build do |values|
|
19
|
+
@size = parse_values(values)
|
20
|
+
end
|
21
|
+
|
22
|
+
verify(:feature) do
|
23
|
+
error_condition { size && !size.all?(&:positive?) }
|
24
|
+
message do
|
25
|
+
"non positive value(s) are not allowed for register size: #{size}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
printable(:array_size) do
|
30
|
+
(array_register? || nil) && "[#{array_registers.join(', ')}]"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def parse_values(values)
|
36
|
+
Array(
|
37
|
+
values.is_a?(String) && parse_string_values(values) || values
|
38
|
+
).map(&method(:convert_value))
|
39
|
+
end
|
40
|
+
|
41
|
+
def parse_string_values(values)
|
42
|
+
if match_pattern(values)
|
43
|
+
split_match_data(match_data)
|
44
|
+
else
|
45
|
+
error "illegal input value for register size: #{values.inspect}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def split_match_data(match_data)
|
50
|
+
match_data.captures.first.split(',')
|
51
|
+
end
|
52
|
+
|
53
|
+
def convert_value(value)
|
54
|
+
Integer(value)
|
55
|
+
rescue ArgumentError, TypeError
|
56
|
+
error "cannot convert #{value.inspect} into register size"
|
57
|
+
end
|
58
|
+
|
59
|
+
def calc_width
|
60
|
+
bus_width = configuration.bus_width
|
61
|
+
if register.bit_fields.empty?
|
62
|
+
bus_width
|
63
|
+
else
|
64
|
+
((max_msb + bus_width) / bus_width) * bus_width
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def max_msb
|
69
|
+
register
|
70
|
+
.bit_fields
|
71
|
+
.map { |bit_field| bit_field.msb((bit_field.sequence_size || 1) - 1) }
|
72
|
+
.max
|
73
|
+
end
|
74
|
+
|
75
|
+
def calc_byte_size
|
76
|
+
if register.settings[:byte_size]
|
77
|
+
instance_exec(®ister.settings[:byte_size])
|
78
|
+
else
|
79
|
+
Array(@size).reduce(1, :*) * byte_width
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def array_register?
|
84
|
+
register.settings[:support_array] && !@size.nil? || false
|
85
|
+
end
|
86
|
+
|
87
|
+
def array_registers
|
88
|
+
array_register? && @size || nil
|
89
|
+
end
|
90
|
+
|
91
|
+
def calc_count
|
92
|
+
Array(array_registers).reduce(1, :*)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RgGen.define_list_feature(:register, :type) do
|
4
|
+
register_map do
|
5
|
+
base_feature do
|
6
|
+
define_helpers do
|
7
|
+
def writable?(&block)
|
8
|
+
@writability = block
|
9
|
+
end
|
10
|
+
|
11
|
+
def readable?(&block)
|
12
|
+
@readability = block
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :writability
|
16
|
+
attr_reader :readability
|
17
|
+
|
18
|
+
def no_bit_fields
|
19
|
+
@no_bit_fields = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def need_bit_fields?
|
23
|
+
!@no_bit_fields
|
24
|
+
end
|
25
|
+
|
26
|
+
def settings
|
27
|
+
@settings ||= {}
|
28
|
+
end
|
29
|
+
|
30
|
+
def support_array_register
|
31
|
+
settings[:support_array] = true
|
32
|
+
end
|
33
|
+
|
34
|
+
def byte_size(&block)
|
35
|
+
settings[:byte_size] = block
|
36
|
+
end
|
37
|
+
|
38
|
+
def support_overlapped_address
|
39
|
+
settings[:support_overlapped_address] = true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
property :type, default: :default
|
44
|
+
property :match_type?, body: ->(register) { register.type == type }
|
45
|
+
property :writable?, initial: -> { writability }
|
46
|
+
property :readable?, initial: -> { readability }
|
47
|
+
property :settings, forward_to_helper: true
|
48
|
+
|
49
|
+
build do |value|
|
50
|
+
@type = value[:type]
|
51
|
+
@options = value[:options]
|
52
|
+
helper.need_bit_fields? || register.need_no_children
|
53
|
+
end
|
54
|
+
|
55
|
+
verify(:component) do
|
56
|
+
error_condition do
|
57
|
+
helper.need_bit_fields? && register.bit_fields.empty?
|
58
|
+
end
|
59
|
+
message { 'no bit fields are given' }
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
attr_reader :options
|
65
|
+
|
66
|
+
def writability
|
67
|
+
instance_exec(&(helper.writability || default_writability))
|
68
|
+
end
|
69
|
+
|
70
|
+
def default_writability
|
71
|
+
-> { register.bit_fields.any?(&:writable?) }
|
72
|
+
end
|
73
|
+
|
74
|
+
def readability
|
75
|
+
instance_exec(&(helper.readability || default_readability))
|
76
|
+
end
|
77
|
+
|
78
|
+
def default_readability
|
79
|
+
lambda do
|
80
|
+
block = ->(bit_field) { bit_field.readable? || bit_field.reserved? }
|
81
|
+
register.bit_fields.any?(&block)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
default_feature do
|
87
|
+
support_array_register
|
88
|
+
|
89
|
+
verify(:feature) do
|
90
|
+
error_condition { @type }
|
91
|
+
message { "unknown register type: #{@type.inspect}" }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
factory do
|
96
|
+
convert_value do |value|
|
97
|
+
type, options = split_input_value(value)
|
98
|
+
{ type: find_type(type), options: Array(options) }
|
99
|
+
end
|
100
|
+
|
101
|
+
def select_feature(cell)
|
102
|
+
if cell.empty_value?
|
103
|
+
target_feature
|
104
|
+
else
|
105
|
+
target_features[cell.value[:type]]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def split_input_value(value)
|
112
|
+
if value.is_a?(String)
|
113
|
+
split_string_value(value)
|
114
|
+
else
|
115
|
+
input_value = Array(value)
|
116
|
+
[input_value[0], input_value[1..-1]]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def split_string_value(value)
|
121
|
+
type, options = split_string(value, ':', 2)
|
122
|
+
[type, split_string(options, /[,\n]/, 0)]
|
123
|
+
end
|
124
|
+
|
125
|
+
def split_string(value, separator, limit)
|
126
|
+
value&.split(separator, limit)&.map(&:strip)
|
127
|
+
end
|
128
|
+
|
129
|
+
def find_type(type)
|
130
|
+
types = target_features.keys
|
131
|
+
types.find(&type.to_sym.method(:casecmp?)) || type
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RgGen.define_list_item_feature(:register, :type, :external) do
|
4
|
+
register_map do
|
5
|
+
writable? { true }
|
6
|
+
readable? { true }
|
7
|
+
no_bit_fields
|
8
|
+
|
9
|
+
verify(:component) do
|
10
|
+
error_condition { register.size && register.size.length > 1 }
|
11
|
+
message do
|
12
|
+
'external register type supports single size definition only'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RgGen.define_list_item_feature(:register, :type, :indirect) do
|
4
|
+
register_map do
|
5
|
+
define_helpers do
|
6
|
+
index_verifier = Class.new do
|
7
|
+
def initialize(&block)
|
8
|
+
instance_eval(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def error_condition(&block)
|
12
|
+
@error_condition = block
|
13
|
+
end
|
14
|
+
|
15
|
+
def message(&block)
|
16
|
+
@message = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def verify(feature, index)
|
20
|
+
error?(feature, index) && raise_error(feature, index)
|
21
|
+
end
|
22
|
+
|
23
|
+
def error?(feature, index)
|
24
|
+
feature.instance_exec(index, &@error_condition)
|
25
|
+
end
|
26
|
+
|
27
|
+
def raise_error(feature, index)
|
28
|
+
error_message = feature.instance_exec(index, &@message)
|
29
|
+
feature.__send__(:error, error_message)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
define_method(:verify_index) do |&block|
|
34
|
+
index_verifiers << index_verifier.new(&block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def index_verifiers
|
38
|
+
@index_verifiers ||= []
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
define_struct :index_entry, [:name, :value] do
|
43
|
+
def value_index?
|
44
|
+
!array_index?
|
45
|
+
end
|
46
|
+
|
47
|
+
def array_index?
|
48
|
+
value.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
def distinguishable?(other)
|
52
|
+
name == other.name && value != other.value &&
|
53
|
+
[self, other].all?(&:value_index?)
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_index_field(bit_fields)
|
57
|
+
bit_fields.find { |bit_field| bit_field.full_name == name }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
property :index_entries
|
62
|
+
property :collect_index_fields do |bit_fields|
|
63
|
+
index_entries.map { |entry| entry.find_index_field(bit_fields) }
|
64
|
+
end
|
65
|
+
|
66
|
+
byte_size { byte_width }
|
67
|
+
support_array_register
|
68
|
+
support_overlapped_address
|
69
|
+
|
70
|
+
input_pattern [
|
71
|
+
/(#{variable_name}\.#{variable_name})/,
|
72
|
+
/(#{variable_name}\.#{variable_name}):(#{integer})?/,
|
73
|
+
/(#{variable_name})/,
|
74
|
+
/(#{variable_name}):(#{integer})?/
|
75
|
+
], match_automatically: false
|
76
|
+
|
77
|
+
build do
|
78
|
+
@index_entries = parse_index_entries
|
79
|
+
end
|
80
|
+
|
81
|
+
verify(:component) do
|
82
|
+
error_condition do
|
83
|
+
register.array? &&
|
84
|
+
register.array_size.length < array_index_fields.length
|
85
|
+
end
|
86
|
+
message { 'too many array indices are given' }
|
87
|
+
end
|
88
|
+
|
89
|
+
verify(:component) do
|
90
|
+
error_condition do
|
91
|
+
register.array? &&
|
92
|
+
register.array_size.length > array_index_fields.length
|
93
|
+
end
|
94
|
+
message { 'less array indices are given' }
|
95
|
+
end
|
96
|
+
|
97
|
+
verify(:all) do
|
98
|
+
check_error do
|
99
|
+
index_entries.each(&method(:verify_indirect_index))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
verify_index do
|
104
|
+
error_condition do |index|
|
105
|
+
!index_entries.one? { |other| other.name == index.name }
|
106
|
+
end
|
107
|
+
message do |index|
|
108
|
+
"same bit field is used as indirect index more than once: #{index.name}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
verify_index do
|
113
|
+
error_condition { |index| !index_field(index) }
|
114
|
+
message do |index|
|
115
|
+
"no such bit field for indirect index is found: #{index.name}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
verify_index do
|
120
|
+
error_condition do |index|
|
121
|
+
index_field(index).register.name == register.name
|
122
|
+
end
|
123
|
+
message do |index|
|
124
|
+
"own bit field is not allowed for indirect index: #{index.name}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
verify_index do
|
129
|
+
error_condition { |index| index_field(index).register.array? }
|
130
|
+
message do |index|
|
131
|
+
'bit field of array register is not allowed ' \
|
132
|
+
"for indirect index: #{index.name}"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
verify_index do
|
137
|
+
error_condition { |index| index_field(index).sequential? }
|
138
|
+
message do |index|
|
139
|
+
'sequential bit field is not allowed ' \
|
140
|
+
"for indirect index: #{index.name}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
verify_index do
|
145
|
+
error_condition { |index| index_field(index).reserved? }
|
146
|
+
message do |index|
|
147
|
+
'reserved bit field is not allowed ' \
|
148
|
+
"for indirect index: #{index.name}"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
verify_index do
|
153
|
+
error_condition do |index|
|
154
|
+
!index.array_index? &&
|
155
|
+
(index.value > (2**index_field(index).width - 1))
|
156
|
+
end
|
157
|
+
message do |index|
|
158
|
+
'bit width of indirect index is not enough for ' \
|
159
|
+
"index value #{index.value}: #{index.name}"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
verify_index do
|
164
|
+
error_condition do |index|
|
165
|
+
index.array_index? &&
|
166
|
+
(array_index_value(index) > 2**index_field(index).width)
|
167
|
+
end
|
168
|
+
message do |index|
|
169
|
+
'bit width of indirect index is not enough for ' \
|
170
|
+
"array size #{array_index_value(index)}: #{index.name}"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
verify(:all) do
|
175
|
+
error_condition { !distinguishable? }
|
176
|
+
message { 'cannot be distinguished from other registers' }
|
177
|
+
end
|
178
|
+
|
179
|
+
private
|
180
|
+
|
181
|
+
def parse_index_entries
|
182
|
+
(!options.empty? && options.map(&method(:create_index_entry))) ||
|
183
|
+
(error 'no indirect indices are given')
|
184
|
+
end
|
185
|
+
|
186
|
+
def create_index_entry(value)
|
187
|
+
input_values = split_value(value)
|
188
|
+
if input_values.size == 2
|
189
|
+
index_entry.new(input_values[0], convert_index_value(input_values[1]))
|
190
|
+
elsif input_values.size == 1
|
191
|
+
index_entry.new(input_values[0])
|
192
|
+
else
|
193
|
+
error 'too many arguments for indirect index ' \
|
194
|
+
"are given: #{value.inspect}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def split_value(value)
|
199
|
+
input_value = Array(value)
|
200
|
+
field_name = input_value.first
|
201
|
+
if sting_or_symbol?(field_name) && match_pattern(field_name)
|
202
|
+
[*match_data.captures, *input_value[1..-1]]
|
203
|
+
else
|
204
|
+
error "illegal input value for indirect index: #{value.inspect}"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def sting_or_symbol?(value)
|
209
|
+
[String, Symbol].any?(&value.method(:is_a?))
|
210
|
+
end
|
211
|
+
|
212
|
+
def convert_index_value(value)
|
213
|
+
Integer(value)
|
214
|
+
rescue ArgumentError, TypeError
|
215
|
+
error "cannot convert #{value.inspect} into indirect index value"
|
216
|
+
end
|
217
|
+
|
218
|
+
def verify_indirect_index(index)
|
219
|
+
helper.index_verifiers.each { |verifier| verifier.verify(self, index) }
|
220
|
+
end
|
221
|
+
|
222
|
+
def index_field(index)
|
223
|
+
@index_fields ||= {}
|
224
|
+
@index_fields[index.name] ||=
|
225
|
+
index.find_index_field(register_block.bit_fields)
|
226
|
+
end
|
227
|
+
|
228
|
+
def array_index_fields
|
229
|
+
@array_index_fields ||= index_entries.select(&:array_index?)
|
230
|
+
end
|
231
|
+
|
232
|
+
def array_index_value(index)
|
233
|
+
@array_index_values ||=
|
234
|
+
array_index_fields
|
235
|
+
.map.with_index { |entry, i| [entry.name, register.array_size[i]] }
|
236
|
+
.to_h
|
237
|
+
@array_index_values[index.name]
|
238
|
+
end
|
239
|
+
|
240
|
+
def distinguishable?
|
241
|
+
register_block
|
242
|
+
.registers.select { |other| share_same_range?(other) }
|
243
|
+
.all? { |other| distinguishable_indices?(other.index_entries) }
|
244
|
+
end
|
245
|
+
|
246
|
+
def share_same_range?(other)
|
247
|
+
register.name != other.name && register.overlap?(other)
|
248
|
+
end
|
249
|
+
|
250
|
+
def distinguishable_indices?(other_entries)
|
251
|
+
index_entries.any? do |entry|
|
252
|
+
other_entries.any?(&entry.method(:distinguishable?))
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|