diff --git a/lib/asm/arm/builder_a.rb b/lib/asm/arm/builder_a.rb index 77c0149c..90008a7b 100644 --- a/lib/asm/arm/builder_a.rb +++ b/lib/asm/arm/builder_a.rb @@ -50,7 +50,7 @@ module Asm # Build representation for source value def build_operand(arg) - if (arg.is_a?(Asm::Parser::NumLiteralArgNode)) + if (arg.is_a?(Asm::NumLiteralArgNode)) if (arg.value.fits_u8?) # no shifting needed @operand = arg.value @@ -61,10 +61,10 @@ module Asm else raise Asm::AssemblyError.new(Asm::ERRSTR_NUMERIC_TOO_LARGE, arg) end - elsif (arg.is_a?(Asm::Parser::RegisterArgNode)) + elsif (arg.is_a?(Asm::RegisterArgNode)) @operand = reg_ref(arg) @i = 0 - elsif (arg.is_a?(Asm::Parser::ShiftNode)) + elsif (arg.is_a?(Asm::ShiftNode)) rm_ref = reg_ref(arg.argument) @i = 0 shift_op = {'lsl' => 0b000, 'lsr' => 0b010, 'asr' => 0b100, @@ -75,12 +75,12 @@ module Asm end arg1 = arg.value - if (arg1.is_a?(Asm::Parser::NumLiteralArgNode)) + if (arg1.is_a?(Asm::NumLiteralArgNode)) if (arg1.value >= 32) raise Asm::AssemblyError.new('cannot shift by more than 31', arg1) end shift_imm = arg1.value - elsif (arg1.is_a?(Asm::Parser::RegisterArgNode)) + elsif (arg1.is_a?(Asm::RegisterArgNode)) shift_op |= 0x1; shift_imm = reg_ref(arg1) << 1 elsif (arg.type == 'rrx') diff --git a/lib/asm/arm/builder_b.rb b/lib/asm/arm/builder_b.rb index f5faa444..6bba2914 100644 --- a/lib/asm/arm/builder_b.rb +++ b/lib/asm/arm/builder_b.rb @@ -31,13 +31,13 @@ module Asm a end - class MathReferenceArgNode < Asm::Parser::ReferenceArgNode + class MathReferenceArgNode < Asm::ReferenceArgNode attr_accessor :op, :right end def simplify_reference(arg) node = MathReferenceArgNode.new - if (arg.is_a?(Asm::Parser::MathNode)) + if (arg.is_a?(Asm::MathNode)) node.argument = arg.left node.op = arg.op node.right = arg.right @@ -50,17 +50,17 @@ module Asm # Build representation for target address def build_operand(arg1) - if (arg1.is_a?(Asm::Parser::ReferenceArgNode)) + if (arg1.is_a?(Asm::ReferenceArgNode)) argr = simplify_reference(arg1.argument) arg = argr.argument - if (arg.is_a?(Asm::Parser::RegisterArgNode)) + if (arg.is_a?(Asm::RegisterArgNode)) @i = 0 @pre_post_index = 1 @w = 0 @rn = reg_ref(arg) @operand = 0 - if (argr.op and argr.right.is_a?(Asm::Parser::NumLiteralArgNode)) + if (argr.op and argr.right.is_a?(Asm::NumLiteralArgNode)) val = argr.right.value if (val < 0) @add_offset = 0 @@ -78,7 +78,7 @@ module Asm else raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg) end - elsif (arg1.is_a?(Asm::Parser::LabelEquivAddrArgNode) or arg1.is_a?(Asm::Parser::NumEquivAddrArgNode)) + elsif (arg1.is_a?(Asm::LabelEquivAddrArgNode) or arg1.is_a?(Asm::NumEquivAddrArgNode)) @i = 0 @pre_post_index = 1 @w = 0 @@ -99,10 +99,10 @@ module Asm (inst_class << 12+4+4+1+1+1+1+1+1) | (cond << 12+4+4+1+1+1+1+1+1+2) if (@use_addrtable_reloc) closest_addrtable = Asm::Arm.closest_addrtable(as) - if (@addrtable_reloc_target.is_a?(Asm::Parser::LabelEquivAddrArgNode)) + if (@addrtable_reloc_target.is_a?(Asm::LabelEquivAddrArgNode)) obj = ast_asm.object_for_label(@addrtable_reloc_target.label, inst) ref_label = closest_addrtable.add_label(obj) - elsif (@addrtable_reloc_target.is_a?(Asm::Parser::NumEquivAddrArgNode)) + elsif (@addrtable_reloc_target.is_a?(Asm::NumEquivAddrArgNode)) ref_label = closest_addrtable.add_const(@addrtable_reloc_target.value) end as.add_relocation io.tell, ref_label, Asm::Arm::R_ARM_PC12, diff --git a/lib/asm/arm/builder_d.rb b/lib/asm/arm/builder_d.rb index deac6306..ff6ac4f0 100644 --- a/lib/asm/arm/builder_d.rb +++ b/lib/asm/arm/builder_d.rb @@ -29,7 +29,7 @@ module Asm # Build representation for source value def build_operand(arg) - if (arg.is_a?(Asm::Parser::RegisterListArgNode)) + if (arg.is_a?(Asm::RegisterListArgNode)) @operand = 0 arg.registers.each do |reg_node| reg = reg_ref(reg_node) diff --git a/lib/asm/arm/instruction.rb b/lib/asm/arm/instruction.rb index 7868001a..005d10ec 100644 --- a/lib/asm/arm/instruction.rb +++ b/lib/asm/arm/instruction.rb @@ -121,14 +121,14 @@ module Asm a.write io, as when :b, :bl arg = args[0] - if (arg.is_a?(Asm::Parser::NumLiteralArgNode)) + if (arg.is_a?(Asm::NumLiteralArgNode)) jmp_val = arg.value >> 2 packed = [jmp_val].pack('l') # signed 32-bit, condense to 24-bit # TODO add check that the value fits into 24 bits io << packed[0,3] - elsif (arg.is_a?(Asm::LabelObject) or arg.is_a?(Asm::Parser::LabelRefArgNode)) - arg = @ast_asm.object_for_label(arg.label, self) if arg.is_a?(Asm::Parser::LabelRefArgNode) + elsif (arg.is_a?(Asm::LabelObject) or arg.is_a?(Asm::LabelRefArgNode)) + arg = @ast_asm.object_for_label(arg.label, self) if arg.is_a?(Asm::LabelRefArgNode) as.add_relocation(io.tell, arg, Asm::Arm::R_ARM_PC24, RelocHandler) io << "\x00\x00\x00" end @@ -139,7 +139,7 @@ module Asm (COND_BITS[@cond] << 16+4+8) when :swi arg = args[0] - if (arg.is_a?(Asm::Parser::NumLiteralArgNode)) + if (arg.is_a?(Asm::NumLiteralArgNode)) packed = [arg.value].pack('L')[0,3] io << packed io.write_uint8 0b1111 | (COND_BITS[@cond] << 4) diff --git a/lib/asm/arm/instruction_tools.rb b/lib/asm/arm/instruction_tools.rb index 36585b79..eb52e74d 100644 --- a/lib/asm/arm/instruction_tools.rb +++ b/lib/asm/arm/instruction_tools.rb @@ -2,7 +2,7 @@ module Asm module Arm module Asm::Arm::InstructionTools def reg_ref(arg) - if (not arg.is_a?(Asm::Parser::RegisterArgNode)) + if (not arg.is_a?(Asm::RegisterArgNode)) raise Asm::AssemblyError.new('argument must be a register', arg) end diff --git a/lib/asm/ast_assembler.rb b/lib/asm/ast_assembler.rb index 2b4422fd..4fff46bd 100644 --- a/lib/asm/ast_assembler.rb +++ b/lib/asm/ast_assembler.rb @@ -16,17 +16,17 @@ module Asm def load_ast(ast) label_breadcrumb = [] ast.children.each do |cmd| - if (cmd.is_a?(Asm::Parser::LabelNode)) + if (cmd.is_a?(Asm::LabelNode)) m = /^\/+/.match(cmd.name) count = m ? m[0].length : 0 label_breadcrumb = label_breadcrumb[0,count] label_breadcrumb << cmd.name[count..-1] @asm.add_object object_for_label(label_breadcrumb.join('/')) - elsif (cmd.is_a?(Asm::Parser::InstructionNode)) + elsif (cmd.is_a?(Asm::InstructionNode)) inst = @asm_arch::Instruction.new(cmd, self) @asm.add_object inst @inst_label_context[inst] = label_breadcrumb - elsif (cmd.is_a?(Asm::Parser::DirectiveNode)) + elsif (cmd.is_a?(Asm::DirectiveNode)) if (cmd.name == 'global') symbol_for_label(cmd.value)[:linkage] = Elf::Constants::STB_GLOBAL elsif (cmd.name == 'extern') diff --git a/lib/asm/nodes.rb b/lib/asm/nodes.rb new file mode 100644 index 00000000..36013c0a --- /dev/null +++ b/lib/asm/nodes.rb @@ -0,0 +1,80 @@ +module Asm + + class Node + def initialize(s = nil) + if (s) + @line = s.prev_line + @column = s.prev_column + else + @line = 0 + @column = 0 + end + + yield self if block_given? + end + attr_reader :line, :column + end + + class ToplevelNode < Node + attr_accessor :children + end + + class DirectiveNode < Node + attr_accessor :name, :value + end + + class LabelNode < Node + attr_accessor :name + end + + class InstructionNode < Node + attr_accessor :opcode, :args + end + + class ArgNode < Node + end + + class ShiftNode < Node + attr_accessor :type, :value, :argument + end + + class MathNode < Node + attr_accessor :left, :right, :op + alias_method :argument, :left + alias_method :argument=, :left= + end + + class RegisterArgNode < ArgNode + attr_accessor :name + end + + class RegisterListArgNode < ArgNode + attr_accessor :registers + end + + class NumLiteralArgNode < ArgNode + attr_accessor :value + end + + class NumEquivAddrArgNode < NumLiteralArgNode + end + class LabelRefArgNode < ArgNode + attr_accessor :label, :label_object + end + class LabelEquivAddrArgNode < LabelRefArgNode + end + + class ReferenceArgNode < ArgNode + attr_accessor :argument + end + + class ParseError < StandardError + def initialize(message, s) + super(message) + + @line = s.line + @column = s.column + end + attr_reader :line, :column + end +end diff --git a/lib/asm/parser.rb b/lib/asm/parser.rb index 4a99cb81..4f703835 100644 --- a/lib/asm/parser.rb +++ b/lib/asm/parser.rb @@ -1,16 +1,7 @@ require_relative 'str_scanner' +require_relative 'nodes' module Asm - class ParseError < StandardError - def initialize(message, s) - super(message) - - @line = s.line - @column = s.column - end - attr_reader :line, :column - end - class Parser def initialize(str) scanner = Asm::Scanner.new(str) @@ -23,24 +14,6 @@ module Asm new(str).ast end - class Node - def initialize(s = nil) - if (s) - @line = s.prev_line - @column = s.prev_column - else - @line = 0 - @column = 0 - end - - yield self if block_given? - end - attr_reader :line, :column - end - - class ToplevelNode < Node - attr_accessor :children - end def parse_toplevel(s) node = ToplevelNode.new(s) node.children = [] @@ -63,16 +36,12 @@ module Asm node end - class CommentNode < Node; end def parse_comment(s) if (s.scan(/;.*?$/)) CommentNode.new(s) end end - class DirectiveNode < Node - attr_accessor :name, :value - end def parse_directive(s) if (m = s.scan(/\.(\w+)(?:(?!$)\s+(.+)\s*?$)?/)) DirectiveNode.new(s) { |n| @@ -82,9 +51,6 @@ module Asm end end - class LabelNode < Node - attr_accessor :name - end def parse_label(s) if (m = s.scan(/(\/*\w+):/)) LabelNode.new(s) { |n| @@ -93,9 +59,6 @@ module Asm end end - class InstructionNode < Node - attr_accessor :opcode, :args - end def parse_instruction(s) if (m = s.scan(/(\w+)/)) node = InstructionNode.new(s) { |n| @@ -113,8 +76,6 @@ module Asm end end - class ArgNode < Node - end def parse_arg(s) s.scan /\s*/ node = nil @@ -146,9 +107,6 @@ module Asm node end - class ShiftNode < Node - attr_accessor :type, :value, :argument - end def parse_shift(s) if (m = s.scan(/(lsl|lsr|asr|ror|rrx)\s+/i)) op = m[0].downcase @@ -163,11 +121,6 @@ module Asm end end - class MathNode < Node - attr_accessor :left, :right, :op - alias_method :argument, :left - alias_method :argument=, :left= - end def parse_math(s) if (m = s.scan_str(/[\+\-]/)) if (arg1 = parse_arg(s)) @@ -185,9 +138,6 @@ module Asm r13 r14 r15 a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 rfp sl fp ip sp lr pc )) - class RegisterArgNode < ArgNode - attr_accessor :name - end def parse_register(s) if (m = s.scan_str(REGISTER_REGEXP)) RegisterArgNode.new(s) { |n| @@ -196,9 +146,6 @@ module Asm end end - class RegisterListArgNode < ArgNode - attr_accessor :registers - end def parse_register_list(s) if (m = s.scan(/\{/)) node = RegisterListArgNode.new(s) do |n| @@ -222,11 +169,6 @@ module Asm end end - class NumLiteralArgNode < ArgNode - attr_accessor :value - end - class NumEquivAddrArgNode < NumLiteralArgNode - end def parse_num_literal(s) if (m = s.scan(/(=?)#(-?(?:0x)?[0-9A-Fa-f]+)/)) (m[0] == '=' ? NumEquivAddrArgNode : NumLiteralArgNode).new(s) { |n| @@ -235,11 +177,6 @@ module Asm end end - class LabelRefArgNode < ArgNode - attr_accessor :label, :label_object - end - class LabelEquivAddrArgNode < LabelRefArgNode - end def parse_label_ref(s) if (m = s.scan(/(=?)(\/*\w+)/)) (m[0] == '=' ? LabelEquivAddrArgNode : LabelRefArgNode).new(s) { |n| @@ -248,9 +185,6 @@ module Asm end end - class ReferenceArgNode < ArgNode - attr_accessor :argument - end def parse_reference(s) if (m = s.scan(/\[/)) arg = parse_arg(s)