module BOAST::Intrinsics
@private
Constants
- CONVERSIONS
- INTRINSICS
Public Class Methods
check_coverage()
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 43 def check_coverage instrs = [X86, ARM].collect { |ar| ins = [] INTRINSICS[ar].each { |i,v| if i == :CVT then v.each { |type1, h| h.each { |type2, instr| ins.push instr.to_s } } else v.each { |type, instr| ins.push instr.to_s } end } ins - INSTRUCTIONS[ar].keys } return instrs end
generate_conversions()
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 451 def generate_conversions [X86, ARM].each { |arch| cvt_dgraph = RGL::DirectedAdjacencyGraph::new INTRINSICS[arch][:CVT].each { |dest, origs| origs.each { |orig, intrinsic| supported = false if MODELS[get_model.to_s] then INSTRUCTIONS[arch][intrinsic.to_s].each { |cpuid| if cpuid.kind_of?( Array ) then supported = true if (cpuid - MODELS[get_model.to_s]).empty? else supported = true if MODELS[get_model.to_s].include?( cpuid ) end } end cvt_dgraph.add_edge(orig, dest) if supported } } cvt_dgraph.vertices.each { |source| hash = {} cvt_dgraph.edges.each { |e| hash[e.to_a] = 1 } paths = cvt_dgraph.dijkstra_shortest_paths( hash, source ) paths.each { |dest, path| CONVERSIONS[arch][dest][source] = path if path } } types = [] INTRINSICS[arch].each { |intrinsic, instructions| types += instructions.keys } types.uniq types.each { |type| CONVERSIONS[arch][type][type] = [type] } } end
get_conversion_path(type_dest, type_orig)
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 105 def get_conversion_path(type_dest, type_orig) conversion_path = CONVERSIONS[get_architecture][get_vector_name(type_dest)][get_vector_name(type_orig)] raise IntrinsicsError, "Unavailable conversion from #{get_vector_name(type_orig)} to #{get_vector_name(type_dest)} on #{get_architecture_name}#{get_architecture==X86 ? "(#{get_model})" : "" }!" unless conversion_path return conversion_path end
get_vector_decl( data_type )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 147 def get_vector_decl( data_type ) case get_architecture when X86 get_vector_decl_X86( data_type ) when ARM get_vector_decl_ARM( data_type ) else return get_vector_name( data_type ) end end
get_vector_decl_ARM( data_type )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 131 def get_vector_decl_ARM( data_type ) raise IntrinsicsError, "Unsupported vector size on ARM: #{data_type.total_size*8}!" unless [64,128].include?( data_type.total_size*8 ) case data_type when Int raise IntrinsicsError, "Unsupported data size for int vector on ARM: #{data_type.size*8}!" unless [1,2,4,8].include?( data_type.size ) return get_vector_name( data_type ).to_s when Real raise IntrinsicsError, "Unsupported data size for real vector on ARM: #{data_type.size*8}!" unless [4,8].include?( data_type.size ) return get_vector_name( data_type ).to_s else raise IntrinsicsError, "Unsupported data type #{data_type} for vector on ARM!" end end
get_vector_decl_X86( data_type )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 113 def get_vector_decl_X86( data_type ) raise IntrinsicsError, "Unsupported vector size on X86: #{data_type.total_size*8}!" unless [64,128,256,512].include?( data_type.total_size*8 ) s = "__m#{data_type.total_size*8}" case data_type when Int raise IntrinsicsError, "Unsupported data size for int vector on X86: #{data_type.size*8}!" unless [1,2,4,8].include?( data_type.size ) return s << "#{data_type.total_size*8>64 ? "i" : ""}" when Real return s if data_type.size == 4 return s << "d" if data_type.size == 8 raise IntrinsicsError, "Unsupported data size for real vector on X86: #{data_type.size*8}!" else raise IntrinsicsError, "Unsupported data type #{data_type} for vector on X86!" end end
get_vector_name( type )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 160 def get_vector_name( type ) s = "" case type when Int s << "u" unless type.signed? s << "int" when Real s << "float" else raise InternalIntrinsicsError, "Undefined vector type!" end s << "#{type.size*8}" s << "x#{type.vector_length}_t" return s.to_sym end
intrinsics(intr_symbol, type, type2=nil)
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 99 def intrinsics(intr_symbol, type, type2=nil) return intrinsics_by_vector_name(intr_symbol, get_vector_name(type), type2 ? get_vector_name(type2) : nil) end
intrinsics_by_vector_name(intr_symbol, type, type2=nil)
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 66 def intrinsics_by_vector_name(intr_symbol, type, type2=nil) if type2 then instruction = INTRINSICS[get_architecture][intr_symbol][type][type2] else instruction = INTRINSICS[get_architecture][intr_symbol][type] end raise IntrinsicsError, "Unsupported operation #{intr_symbol} for #{type}#{type2 ? " and #{type2}" : ""} on #{get_architecture_name}!" unless instruction supported = false INSTRUCTIONS[get_architecture][instruction.to_s].each { |cpuid| if cpuid.kind_of?( Array ) then supported = true if (cpuid - MODELS[get_model.to_s]).empty? else supported = true if MODELS[get_model.to_s].include?( cpuid ) end } # supported = (INSTRUCTIONS[instruction.to_s] & MODELS[get_model.to_s]).size > 0 unless supported then required = "" INSTRUCTIONS[get_architecture][instruction.to_s].each { |cpuid| required << " or " if required != "" if cpuid.kind_of?( Array ) then required << "( #{cpuid.join(" and ")} )" else required << "#{cpuid}" end } raise IntrinsicsError, "Unsupported operation #{intr_symbol} for #{type}#{type2 ? " and #{type2}" : ""} on #{get_model}! (requires #{required})" end return instruction end
type_name_ARM( type, size, sign = :signed )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 202 def type_name_ARM( type, size, sign = :signed ) s = "" case type when :int case sign when :signed s << "s" when :unsigned s << "u" else raise InternalIntrinsicsError, "Invalid sign!" end when :float s << "f" else raise InternalIntrinsicsError, "Invalid type!" end s << "#{size}" return s end
type_name_X86( type, size, vector_size, sign = :signed )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 225 def type_name_X86( type, size, vector_size, sign = :signed ) s = "" case type when :int e = ( vector_size > 64 ? "e" : "" ) s << "#{e}p" case sign when :signed s << "i" when :unsigned s << "u" else raise InternalIntrinsicsError, "Invalid sign!" end s << "#{size}" when :float s << "p" case size when 32 s << "s" when 64 s << "d" else raise InternalIntrinsicsError, "Invalid size!" end else raise InternalIntrinsicsError, "Invalid type!" end return s end
vector_type_name( type, size, vector_size, sign = :signed )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 178 def vector_type_name( type, size, vector_size, sign = :signed ) s = "" case type when :int case sign when :signed s << "int" when :unsigned s << "uint" else raise InternalIntrinsicsError, "Invalid sign!" end when :float s << "float" else raise InternalIntrinsicsError, "Invalid type!" end s << "#{size}" s << "x#{vector_size/size}_t" return s.to_sym end
Private Instance Methods
check_coverage()
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 43 def check_coverage instrs = [X86, ARM].collect { |ar| ins = [] INTRINSICS[ar].each { |i,v| if i == :CVT then v.each { |type1, h| h.each { |type2, instr| ins.push instr.to_s } } else v.each { |type, instr| ins.push instr.to_s } end } ins - INSTRUCTIONS[ar].keys } return instrs end
generate_conversions()
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 451 def generate_conversions [X86, ARM].each { |arch| cvt_dgraph = RGL::DirectedAdjacencyGraph::new INTRINSICS[arch][:CVT].each { |dest, origs| origs.each { |orig, intrinsic| supported = false if MODELS[get_model.to_s] then INSTRUCTIONS[arch][intrinsic.to_s].each { |cpuid| if cpuid.kind_of?( Array ) then supported = true if (cpuid - MODELS[get_model.to_s]).empty? else supported = true if MODELS[get_model.to_s].include?( cpuid ) end } end cvt_dgraph.add_edge(orig, dest) if supported } } cvt_dgraph.vertices.each { |source| hash = {} cvt_dgraph.edges.each { |e| hash[e.to_a] = 1 } paths = cvt_dgraph.dijkstra_shortest_paths( hash, source ) paths.each { |dest, path| CONVERSIONS[arch][dest][source] = path if path } } types = [] INTRINSICS[arch].each { |intrinsic, instructions| types += instructions.keys } types.uniq types.each { |type| CONVERSIONS[arch][type][type] = [type] } } end
get_conversion_path(type_dest, type_orig)
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 105 def get_conversion_path(type_dest, type_orig) conversion_path = CONVERSIONS[get_architecture][get_vector_name(type_dest)][get_vector_name(type_orig)] raise IntrinsicsError, "Unavailable conversion from #{get_vector_name(type_orig)} to #{get_vector_name(type_dest)} on #{get_architecture_name}#{get_architecture==X86 ? "(#{get_model})" : "" }!" unless conversion_path return conversion_path end
get_vector_decl( data_type )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 147 def get_vector_decl( data_type ) case get_architecture when X86 get_vector_decl_X86( data_type ) when ARM get_vector_decl_ARM( data_type ) else return get_vector_name( data_type ) end end
get_vector_decl_ARM( data_type )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 131 def get_vector_decl_ARM( data_type ) raise IntrinsicsError, "Unsupported vector size on ARM: #{data_type.total_size*8}!" unless [64,128].include?( data_type.total_size*8 ) case data_type when Int raise IntrinsicsError, "Unsupported data size for int vector on ARM: #{data_type.size*8}!" unless [1,2,4,8].include?( data_type.size ) return get_vector_name( data_type ).to_s when Real raise IntrinsicsError, "Unsupported data size for real vector on ARM: #{data_type.size*8}!" unless [4,8].include?( data_type.size ) return get_vector_name( data_type ).to_s else raise IntrinsicsError, "Unsupported data type #{data_type} for vector on ARM!" end end
get_vector_decl_X86( data_type )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 113 def get_vector_decl_X86( data_type ) raise IntrinsicsError, "Unsupported vector size on X86: #{data_type.total_size*8}!" unless [64,128,256,512].include?( data_type.total_size*8 ) s = "__m#{data_type.total_size*8}" case data_type when Int raise IntrinsicsError, "Unsupported data size for int vector on X86: #{data_type.size*8}!" unless [1,2,4,8].include?( data_type.size ) return s << "#{data_type.total_size*8>64 ? "i" : ""}" when Real return s if data_type.size == 4 return s << "d" if data_type.size == 8 raise IntrinsicsError, "Unsupported data size for real vector on X86: #{data_type.size*8}!" else raise IntrinsicsError, "Unsupported data type #{data_type} for vector on X86!" end end
get_vector_name( type )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 160 def get_vector_name( type ) s = "" case type when Int s << "u" unless type.signed? s << "int" when Real s << "float" else raise InternalIntrinsicsError, "Undefined vector type!" end s << "#{type.size*8}" s << "x#{type.vector_length}_t" return s.to_sym end
intrinsics(intr_symbol, type, type2=nil)
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 99 def intrinsics(intr_symbol, type, type2=nil) return intrinsics_by_vector_name(intr_symbol, get_vector_name(type), type2 ? get_vector_name(type2) : nil) end
intrinsics_by_vector_name(intr_symbol, type, type2=nil)
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 66 def intrinsics_by_vector_name(intr_symbol, type, type2=nil) if type2 then instruction = INTRINSICS[get_architecture][intr_symbol][type][type2] else instruction = INTRINSICS[get_architecture][intr_symbol][type] end raise IntrinsicsError, "Unsupported operation #{intr_symbol} for #{type}#{type2 ? " and #{type2}" : ""} on #{get_architecture_name}!" unless instruction supported = false INSTRUCTIONS[get_architecture][instruction.to_s].each { |cpuid| if cpuid.kind_of?( Array ) then supported = true if (cpuid - MODELS[get_model.to_s]).empty? else supported = true if MODELS[get_model.to_s].include?( cpuid ) end } # supported = (INSTRUCTIONS[instruction.to_s] & MODELS[get_model.to_s]).size > 0 unless supported then required = "" INSTRUCTIONS[get_architecture][instruction.to_s].each { |cpuid| required << " or " if required != "" if cpuid.kind_of?( Array ) then required << "( #{cpuid.join(" and ")} )" else required << "#{cpuid}" end } raise IntrinsicsError, "Unsupported operation #{intr_symbol} for #{type}#{type2 ? " and #{type2}" : ""} on #{get_model}! (requires #{required})" end return instruction end
type_name_ARM( type, size, sign = :signed )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 202 def type_name_ARM( type, size, sign = :signed ) s = "" case type when :int case sign when :signed s << "s" when :unsigned s << "u" else raise InternalIntrinsicsError, "Invalid sign!" end when :float s << "f" else raise InternalIntrinsicsError, "Invalid type!" end s << "#{size}" return s end
type_name_X86( type, size, vector_size, sign = :signed )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 225 def type_name_X86( type, size, vector_size, sign = :signed ) s = "" case type when :int e = ( vector_size > 64 ? "e" : "" ) s << "#{e}p" case sign when :signed s << "i" when :unsigned s << "u" else raise InternalIntrinsicsError, "Invalid sign!" end s << "#{size}" when :float s << "p" case size when 32 s << "s" when 64 s << "d" else raise InternalIntrinsicsError, "Invalid size!" end else raise InternalIntrinsicsError, "Invalid type!" end return s end
vector_type_name( type, size, vector_size, sign = :signed )
click to toggle source
# File lib/BOAST/Language/Intrinsics.rb, line 178 def vector_type_name( type, size, vector_size, sign = :signed ) s = "" case type when :int case sign when :signed s << "int" when :unsigned s << "uint" else raise InternalIntrinsicsError, "Invalid sign!" end when :float s << "float" else raise InternalIntrinsicsError, "Invalid type!" end s << "#{size}" s << "x#{vector_size/size}_t" return s.to_sym end