make operator_instruction single ass
create result register automatically usually not used, but register allocation will sort that
This commit is contained in:
parent
1378745907
commit
61fc8a3991
@ -3,33 +3,42 @@ module Risc
|
|||||||
def self.operators
|
def self.operators
|
||||||
[:+, :-, :>>, :<<, :*, :&, :|]
|
[:+, :-, :>>, :<<, :*, :&, :|]
|
||||||
end
|
end
|
||||||
# Destructive operator instructions on the two registers given
|
|
||||||
|
# Operator instructions on the first two registers given
|
||||||
|
# # Result into the last register
|
||||||
#
|
#
|
||||||
# left = left OP right
|
# result = left OP right
|
||||||
#
|
#
|
||||||
# With OP being the normal logical and mathematical operations provided by
|
# With OP being the normal logical and mathematical operations provided by
|
||||||
# cpus. Ie "+" , "-", ">>", "<<", "*", "&", "|"
|
# cpus. Ie "+" , "-", ">>", "<<", "*", "&", "|"
|
||||||
#
|
#
|
||||||
|
# Result may be nil, then register is autogenerated
|
||||||
|
#
|
||||||
class OperatorInstruction < Instruction
|
class OperatorInstruction < Instruction
|
||||||
def initialize( source , operator , left , right )
|
def initialize( source , operator , left , right , result = nil)
|
||||||
super(source)
|
super(source)
|
||||||
operator = operator.value if operator.is_a?(Sol::Constant)
|
operator = operator.value if operator.is_a?(Sol::Constant)
|
||||||
@operator = operator
|
@operator = operator
|
||||||
raise "unsuported operator :#{operator}:#{operator.class}:" unless Risc.operators.include?(operator)
|
raise "unsuported operator :#{operator}:#{operator.class}:" unless Risc.operators.include?(operator)
|
||||||
@left = left
|
@left = left
|
||||||
@right = right
|
@right = right
|
||||||
raise "Not register #{left}" unless RegisterValue.look_like_reg(left)
|
raise "Not register #{left}" unless left.is_a?(RegisterValue)
|
||||||
raise "Not register #{right}" unless RegisterValue.look_like_reg(right)
|
raise "Not register #{right}" unless right.is_a?(RegisterValue)
|
||||||
|
unless result
|
||||||
|
result = RegisterValue.new("op_#{operator}_#{object_id.to_s(16)}".to_sym , :Integer)
|
||||||
|
end
|
||||||
|
raise "Not register #{result}" unless result.is_a?(RegisterValue)
|
||||||
|
@result = result
|
||||||
end
|
end
|
||||||
attr_reader :operator, :left , :right
|
attr_reader :operator, :left , :right , :result
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
class_source "#{left} #{operator} #{right}"
|
class_source "#{left} #{operator} #{right}"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
def self.op( source , operator , left , right )
|
def self.op( source , operator , left , right , result = nil)
|
||||||
OperatorInstruction.new( source , operator , left , right )
|
OperatorInstruction.new( source , operator , left , right , result)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -23,6 +23,7 @@ module Risc
|
|||||||
extra = {} unless extra
|
extra = {} unless extra
|
||||||
@extra = extra
|
@extra = extra
|
||||||
@symbol = reg
|
@symbol = reg
|
||||||
|
raise "not Symbol #{symbol}:#{symbol.class}" unless symbol.is_a?(Symbol)
|
||||||
raise "Not Hash #{extra}" unless extra.is_a?(Hash)
|
raise "Not Hash #{extra}" unless extra.is_a?(Hash)
|
||||||
known_type(type)
|
known_type(type)
|
||||||
end
|
end
|
||||||
|
23
test/risc/instructions/test_operator_instruction.rb
Normal file
23
test/risc/instructions/test_operator_instruction.rb
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
require_relative "../helper"
|
||||||
|
|
||||||
|
module Risc
|
||||||
|
class TestOperatorInstruction < MiniTest::Test
|
||||||
|
def setup
|
||||||
|
Parfait.boot!({})
|
||||||
|
@left = RegisterValue.new(:left , :Integer)
|
||||||
|
@right = RegisterValue.new(:right , :Integer)
|
||||||
|
end
|
||||||
|
def risc(i)
|
||||||
|
@left.op :- , @right
|
||||||
|
end
|
||||||
|
def test_min
|
||||||
|
assert_operator 1 , :- , :left , :right , "op_-_"
|
||||||
|
end
|
||||||
|
def test_reg
|
||||||
|
result = risc(1).result
|
||||||
|
assert_equal RegisterValue , result.class
|
||||||
|
assert_equal "Integer_Type" , result.type.name
|
||||||
|
assert result.symbol.to_s.start_with?("op_-_")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -94,7 +94,7 @@ module Minitest
|
|||||||
assert_equal Risc::Branch , branch.class , "Class at:#{branch_i}"
|
assert_equal Risc::Branch , branch.class , "Class at:#{branch_i}"
|
||||||
assert_label branch.label , label_name , "Label at #{branch_i}"
|
assert_label branch.label , label_name , "Label at #{branch_i}"
|
||||||
end
|
end
|
||||||
def assert_operator ins_i , op , left , right
|
def assert_operator ins_i , op , left , right , result
|
||||||
if(ins_i.is_a?(Integer))
|
if(ins_i.is_a?(Integer))
|
||||||
ins = risc(ins_i)
|
ins = risc(ins_i)
|
||||||
else
|
else
|
||||||
@ -105,6 +105,7 @@ module Minitest
|
|||||||
assert_equal op , ins.operator
|
assert_equal op , ins.operator
|
||||||
assert_register :left , left , ins.left , ins_i
|
assert_register :left , left , ins.left , ins_i
|
||||||
assert_register :right , right , ins.right, ins_i
|
assert_register :right , right , ins.right, ins_i
|
||||||
|
assert_register :result , result , ins.result, ins_i
|
||||||
end
|
end
|
||||||
def assert_zero ins_i , label
|
def assert_zero ins_i , label
|
||||||
assert_equal Integer , ins_i.class, "assert_zero #{ins_i}"
|
assert_equal Integer , ins_i.class, "assert_zero #{ins_i}"
|
||||||
|
Loading…
Reference in New Issue
Block a user