lift label out of the code generator

This commit is contained in:
Torsten Ruger 2014-04-16 12:02:28 +03:00
parent e47b1dcadd
commit 5bd4be313c
2 changed files with 104 additions and 109 deletions

View File

@ -5,10 +5,8 @@ require 'asm/parser'
require 'stream_reader' require 'stream_reader'
require 'stringio' require 'stringio'
module Asm
module Arm
class CodeGenerator class Asm::Arm::CodeGenerator
def initialize def initialize
@asm = Asm::Assembler.new @asm = Asm::Assembler.new
@externs = [] @externs = []
@ -28,23 +26,23 @@ module Asm
} }
def instruction(name, *args) def instruction(name, *args)
node = Asm::Parser::InstructionNode.new node = Asm::InstructionNode.new
node.opcode = name.to_s node.opcode = name.to_s
node.args = [] node.args = []
args.each { |arg| args.each { |arg|
if (arg.is_a?(Array)) if (arg.is_a?(Array))
if (arg[0] == :reg) if (arg[0] == :reg)
node.args << Asm::Parser::RegisterArgNode.new { |n| node.args << Asm::RegisterArgNode.new { |n|
n.name = arg[1] n.name = arg[1]
} }
end end
elsif (arg.is_a?(Integer)) elsif (arg.is_a?(Integer))
node.args << Asm::Parser::NumLiteralArgNode.new { |n| node.args << Asm::NumLiteralArgNode.new { |n|
n.value = arg n.value = arg
} }
elsif (arg.is_a?(Symbol)) elsif (arg.is_a?(Symbol))
node.args << Asm::Parser::LabelRefArgNode.new { |n| node.args << Asm::LabelRefArgNode.new { |n|
n.label = arg.to_s n.label = arg.to_s
} }
elsif (arg.is_a?(GeneratorLabel) or arg.is_a?(GeneratorExternLabel)) elsif (arg.is_a?(GeneratorLabel) or arg.is_a?(GeneratorExternLabel))
@ -57,8 +55,7 @@ module Asm
@asm.add_object Asm::Arm::Instruction.new(node) @asm.add_object Asm::Arm::Instruction.new(node)
end end
%w(adc add and bic eor orr rsb rsc sbc sub %w(adc add and bic eor orr rsb rsc sbc sub mov mvn cmn cmp teq tst b bl bx swi strb
mov mvn cmn cmp teq tst b bl bx swi strb
).each { |inst| ).each { |inst|
define_method(inst) { |*args| define_method(inst) { |*args|
instruction inst.to_sym, *args instruction inst.to_sym, *args
@ -66,8 +63,7 @@ module Asm
define_method(inst+'s') { |*args| define_method(inst+'s') { |*args|
instruction (inst+'s').to_sym, *args instruction (inst+'s').to_sym, *args
} }
%w(al eq ne cs mi hi cc pl ls vc %w(al eq ne cs mi hi cc pl ls vc lt le ge gt vs
lt le ge gt vs
).each { |cond_suffix| ).each { |cond_suffix|
define_method(inst+cond_suffix) { |*args| define_method(inst+cond_suffix) { |*args|
instruction (inst+cond_suffix).to_sym, *args instruction (inst+cond_suffix).to_sym, *args
@ -78,23 +74,6 @@ module Asm
} }
} }
class GeneratorLabel < Asm::LabelObject
def initialize(asm)
@asm = asm
end
def set!
@asm.add_object self
end
end
class GeneratorExternLabel < Asm::LabelObject
def initialize(name)
@name = name
extern!
end
attr_reader :name
end
def label def label
GeneratorLabel.new(@asm) GeneratorLabel.new(@asm)
end end
@ -125,5 +104,3 @@ module Asm
@asm.relocations @asm.relocations
end end
end end
end
end

View File

@ -0,0 +1,18 @@
require "asm/label_object"
class Asm::Arm::GeneratorLabel < Asm::LabelObject
def initialize(asm)
@asm = asm
end
def set!
@asm.add_object self
end
end
class Asm::Arm::GeneratorExternLabel < Asm::LabelObject
def initialize(name)
@name = name
extern!
end
attr_reader :name
end