Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/ADL/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def self.state
end

# reset state
def siminfra_reset_module_state; @@instructions = []; end
def siminfra_reset_module_state; @@instructions = []; @@operands = []; end

# mixin for global counter, function returns 0,1,2,....
module GlobalCounter
Expand Down
146 changes: 99 additions & 47 deletions lib/ADL/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def self.from_h(h)
end

# Basics
module SimInfra
module SimInfra
def assert(condition, msg = nil); raise msg if !condition; end

@@instructions = []
Expand All @@ -40,11 +40,13 @@ def self.interface_functions
end

class InstructionInfo
attr_accessor :name, :fields, :frmt, :map, :code, :map_code_blocks, :asm_str, :feature
attr_accessor :name, :fields, :frmt, :map, :code, :map_code_blocks, :asm_str, :feature,
:operand_map
def initialize(name, feature)
@name = name;
@map_code_blocks = {}
@feature = feature
@operand_map = {}
end

def to_h
Expand All @@ -54,8 +56,8 @@ def to_h
frmt: @frmt,
asm_str: @asm_str,
code: @code.to_h,
map: @map.to_h,
feature: @feature,
operand_map: @operand_map.transform_values(&:to_h),
operand_list: @operand_map.keys,
}
end

Expand All @@ -66,24 +68,45 @@ def self.from_h(h)
info.asm_str = h[:asm_str]
info.code = Scope.new(nil)
info.code.instance_variable_set(:@tree, h[:code][:tree].map { |s| IrStmt.from_h(s) })
info.map = Scope.new(nil)
info.map.instance_variable_set(:@tree, h[:map][:tree].map { |s| IrStmt.from_h(s) })
if h[:operand_map]
info.operand_map = h[:operand_map].transform_values { |v| Scope.from_h(v) }
end
info
end
end

class OperandInfo
attr_accessor :name, :type, :regset, :map_proc

def initialize(name, type = nil, regset = nil)
@name = name
@type = type
@regset = regset
@map_proc = nil
end

def for(op_name)
info = OperandInfo.new(op_name, @type, @regset)
info.map_proc = @map_proc
info
end

alias_method :[], :for
end

class InstructionInfoBuilder
include SimInfra

def initialize(name, feature)
@info = InstructionInfo.new(name, feature)
@info.code = Scope.new(nil)
def initialize(name, feature)
@info = InstructionInfo.new(name, feature)
@info.code = Scope.new(nil)

@@interface_functions.each do |func|
next if func[:kind] == :memory
if !func[:return_types].empty?
@info.code.instance_eval "def #{func[:name]}(*args)
in_s = *args.map { |a| resolve_const(a) }
in_stmt = [tmpvar(#{func[:return_types][0]})]
in_stmt = [tmpvar(#{func[:return_types][0]})]
in_stmt.concat(in_s)
return stmt :#{func[:name]}, in_stmt
end
Expand All @@ -101,14 +124,9 @@ def initialize(name, feature)
end

def encoding(frmt, fields, *args)
@info.fields = fields
@info.frmt= frmt
map args

sum_bits = 0
for f in fields
sum_bits += Utility.get_type(f.value.type).bitsize
end
@info.fields = fields
@info.frmt= frmt
map args
end
attr_reader :info
end
Expand All @@ -122,17 +140,34 @@ def Instruction(name, &block)
nil # only for debugging in IRB
end

class OperandBuilder
include SimInfra

def initialize(name, type = nil, regset = nil)
@info = OperandInfo.new(name, type, regset)
end

attr_reader :info
end

def Operand(name, type = nil, regset = nil, &block)
bldr = OperandBuilder.new(name, type, regset)
bldr.info.map_proc = block if block
bldr.info
end

module_function :Operand

class InterfaceBuilder
include SimInfra

def Function(name, output_types = [], input_types = [])
@@interface_functions << {:name => name, :return_types => output_types, :argument_types => input_types}
def Function(name, output_types = [], input_types = [], attrs = [])
@@interface_functions << {name: name, return_types: output_types, argument_types: input_types, attrs: attrs}
end
end

def Interface(&blck)
bldr = InterfaceBuilder.new()

bldr.instance_eval &blck
end

Expand Down Expand Up @@ -177,25 +212,25 @@ def self.from_h(h)

@@regfiles = []
class RegisterFileBuilder
attr_reader :info
def initialize(name)
attr_reader :info

def initialize(name)
@info = RegisterFileInfo.new(name)
@info.regs = []
end
end

def method_missing(name, *args)
def method_missing(name, *args)
if name.to_s.start_with?('r')
size = name.to_s[1..].to_i
instance_eval "def #{name}(sym, *args); @info.regs << Register.new(sym, #{size}, args.size > 0 ? args : []); end", __FILE__, __LINE__
@info.regs << Register.new(args[0], size, args.size > 1 ? args[1..] : [])
size = name.to_s[1..].to_i
instance_eval "def #{name}(sym, *args); @info.regs << Register.new(sym, #{size}, args.size > 0 ? args : []); end", __FILE__, __LINE__
@info.regs << Register.new(args[0], size, args.size > 1 ? args[1..] : [])
else
error "Unknown method #{name}"
error "Unknown method #{name}"
end
end
end

def zero = :zero
def pc = :pc
def zero = :zero
def pc = :pc
end

def RegisterFile(name, &block)
Expand All @@ -214,17 +249,13 @@ def RegFiles()
module SimInfra
class InstructionInfoBuilder
def code(&block)
if !@info.map_code_blocks.empty?
@info.fields.each { |f|
@info.map.method(f.value.name, f.value.type)
}
end
@info.map_code_blocks.each do |k, v|
@info.map.instance_eval v[1]
end
@info.map_code_blocks.each do |k, v|
@info.code.method(k, v[0], @info.map.vars[k].regset)
# Link code scope methods to operand vars
@info.operand_map.each do |name, scope|
var = scope.vars[name]
@info.code.method(name, var.type, var.regset) if var
end

# Register files
for regfile in @@regfiles
for reg in regfile.regs
@info.code.method(reg.name, ('r' + reg.size.to_s).to_sym)
Expand All @@ -234,11 +265,32 @@ def code(&block)
end

def map(blocks)
if (!blocks.nil? && !blocks.empty?)
for blck in blocks
@info.map_code_blocks[blck[0]] = [blck[1], blck[2]]
end
return if blocks.nil? || blocks.empty?

blocks.each do |block|
@info.operand_map[block.name] = build_scope(block)
end
end

private

def build_scope(block)
scope = Scope.new(nil)
@info.fields.each { |f| scope.method(f.value.name, f.value.type) }
op_name = block.name
value = if block.map_proc
scope.instance_eval(&block.map_proc)
elsif block.regset
scope.send("f_#{op_name}")
else
raise "operand '#{op_name}' has no map rule"
end
if block.regset
scope.arlet(op_name, block.regset, [:op], block.type, value)
else
scope.alet(op_name, [:op], block.type, value)
end
scope
end

def asm(&block)
Expand Down
10 changes: 5 additions & 5 deletions lib/Target/RISC-V/32I.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,19 +158,19 @@ module RV32I
}

Instruction(:slli) {
encoding *format_i_shift(0b0010011, 0b001, 0b00000)
encoding *format_i_shift(0b0010011, 0b001, 0b0000000)
asm { "slli {rd}, {rs1}, {imm}" }
code { rd[]= rs1 << imm }
}

Instruction(:srli) {
encoding *format_i_shift(0b0010011, 0b101, 0b00000)
encoding *format_i_shift(0b0010011, 0b101, 0b0000000)
asm { "srli {rd}, {rs1}, {imm}" }
code { rd[]= rs1 >> imm }
}

Instruction(:srai) {
encoding *format_i_shift(0b0010011, 0b101, 0b01000)
encoding *format_i_shift(0b0010011, 0b101, 0b0100000)
asm { "srai {rd}, {rs1}, {imm}" }
code { rd[]= rs1.s >> imm }
}
Expand Down Expand Up @@ -220,7 +220,7 @@ module RV32I
Instruction(:jalr) {
encoding *format_i(0b1100111, 0b000)
asm { "jalr {rd}, {rs1}, {imm}" }
code {
code {
let :t, :b32, pc + 4
branch((rs1 + imm) & (~1))
rd[]= t
Expand Down Expand Up @@ -262,7 +262,7 @@ module RV32I
asm { "lw {rd}, {imm}({rs1})" }
code { rd[]= mem[rs1 + imm, :b32] }
}

Instruction(:lbu) {
encoding *format_i(0b0000011, 0b100)
asm { "lbu {rd}, {imm}({rs1})" }
Expand Down
Loading
Loading