From 5bd4be313c1d9f1ff3a47219704acdd1b7961bed Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Wed, 16 Apr 2014 12:02:28 +0300 Subject: [PATCH] lift label out of the code generator --- lib/asm/arm/code_generator.rb | 195 +++++++++++++++------------------ lib/asm/arm/generator_label.rb | 18 +++ 2 files changed, 104 insertions(+), 109 deletions(-) create mode 100644 lib/asm/arm/generator_label.rb diff --git a/lib/asm/arm/code_generator.rb b/lib/asm/arm/code_generator.rb index 8329a56a..9195250f 100644 --- a/lib/asm/arm/code_generator.rb +++ b/lib/asm/arm/code_generator.rb @@ -5,125 +5,102 @@ require 'asm/parser' require 'stream_reader' require 'stringio' -module Asm - module Arm - class CodeGenerator - def initialize - @asm = Asm::Assembler.new - @externs = [] - end +class Asm::Arm::CodeGenerator + def initialize + @asm = Asm::Assembler.new + @externs = [] + end - def data(str) - @asm.add_object Asm::DataObject.new(str) - end + def data(str) + @asm.add_object Asm::DataObject.new(str) + end - %w(r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 - r13 r14 r15 a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 - rfp sl fp ip sp lr pc - ).each { |reg| - define_method(reg) { - [:reg, reg] - } - } + %w(r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 + r13 r14 r15 a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 + rfp sl fp ip sp lr pc + ).each { |reg| + define_method(reg) { + [:reg, reg] + } + } - def instruction(name, *args) - node = Asm::Parser::InstructionNode.new - node.opcode = name.to_s - node.args = [] + def instruction(name, *args) + node = Asm::InstructionNode.new + node.opcode = name.to_s + node.args = [] - args.each { |arg| - if (arg.is_a?(Array)) - if (arg[0] == :reg) - node.args << Asm::Parser::RegisterArgNode.new { |n| - n.name = arg[1] - } - end - elsif (arg.is_a?(Integer)) - node.args << Asm::Parser::NumLiteralArgNode.new { |n| - n.value = arg - } - elsif (arg.is_a?(Symbol)) - node.args << Asm::Parser::LabelRefArgNode.new { |n| - n.label = arg.to_s - } - elsif (arg.is_a?(GeneratorLabel) or arg.is_a?(GeneratorExternLabel)) - node.args << arg - else - raise 'Invalid argument `%s\' for instruction' % arg.inspect - end - } - - @asm.add_object Asm::Arm::Instruction.new(node) - end - - %w(adc add and bic eor orr rsb rsc sbc sub - mov mvn cmn cmp teq tst b bl bx swi strb - ).each { |inst| - define_method(inst) { |*args| - instruction inst.to_sym, *args - } - define_method(inst+'s') { |*args| - instruction (inst+'s').to_sym, *args - } - %w(al eq ne cs mi hi cc pl ls vc - lt le ge gt vs - ).each { |cond_suffix| - define_method(inst+cond_suffix) { |*args| - instruction (inst+cond_suffix).to_sym, *args - } - define_method(inst+'s'+cond_suffix) { |*args| - instruction (inst+'s'+cond_suffix).to_sym, *args + args.each { |arg| + if (arg.is_a?(Array)) + if (arg[0] == :reg) + node.args << Asm::RegisterArgNode.new { |n| + n.name = arg[1] } + end + elsif (arg.is_a?(Integer)) + node.args << Asm::NumLiteralArgNode.new { |n| + n.value = arg } + elsif (arg.is_a?(Symbol)) + node.args << Asm::LabelRefArgNode.new { |n| + n.label = arg.to_s + } + elsif (arg.is_a?(GeneratorLabel) or arg.is_a?(GeneratorExternLabel)) + node.args << arg + else + raise 'Invalid argument `%s\' for instruction' % arg.inspect + end + } + + @asm.add_object Asm::Arm::Instruction.new(node) + end + + %w(adc add and bic eor orr rsb rsc sbc sub mov mvn cmn cmp teq tst b bl bx swi strb + ).each { |inst| + define_method(inst) { |*args| + instruction inst.to_sym, *args + } + define_method(inst+'s') { |*args| + instruction (inst+'s').to_sym, *args + } + %w(al eq ne cs mi hi cc pl ls vc lt le ge gt vs + ).each { |cond_suffix| + define_method(inst+cond_suffix) { |*args| + instruction (inst+cond_suffix).to_sym, *args } + define_method(inst+'s'+cond_suffix) { |*args| + instruction (inst+'s'+cond_suffix).to_sym, *args + } + } + } - class GeneratorLabel < Asm::LabelObject - def initialize(asm) - @asm = asm - end - def set! - @asm.add_object self - end - end + def label + GeneratorLabel.new(@asm) + end - class GeneratorExternLabel < Asm::LabelObject - def initialize(name) - @name = name - extern! - end - attr_reader :name - end + def label! + lbl = GeneratorLabel.new(@asm) + lbl.set! + lbl + end - def label - GeneratorLabel.new(@asm) - end - - def label! - lbl = GeneratorLabel.new(@asm) - lbl.set! - lbl - end - - def extern(sym) - if (lbl = @externs.find { |extern| extern.name == sym }) - lbl - else - @externs << lbl = GeneratorExternLabel.new(sym) - @asm.add_object lbl - lbl - end - end - - def assemble - io = StringIO.new - @asm.assemble(io) - io.string - end - - def relocations - @asm.relocations - end + def extern(sym) + if (lbl = @externs.find { |extern| extern.name == sym }) + lbl + else + @externs << lbl = GeneratorExternLabel.new(sym) + @asm.add_object lbl + lbl end end -end \ No newline at end of file + + def assemble + io = StringIO.new + @asm.assemble(io) + io.string + end + + def relocations + @asm.relocations + end +end diff --git a/lib/asm/arm/generator_label.rb b/lib/asm/arm/generator_label.rb new file mode 100644 index 00000000..c5f9634d --- /dev/null +++ b/lib/asm/arm/generator_label.rb @@ -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