cleanup, requires, namespacing to actually get it to work

This commit is contained in:
Torsten Ruger
2014-04-14 21:52:16 +03:00
parent 5ad36bbd56
commit 2e6b90b12e
16 changed files with 379 additions and 299 deletions

View File

@ -1,4 +1,4 @@
class Asm::ARM::AddrTableObject
class Asm::Arm::AddrTableObject
def initialize
@table = []
@const = []
@ -21,8 +21,8 @@ class Asm::ARM::AddrTableObject
@table.each do |pair|
target_label, here_label = *pair
here_label.assemble io, as
as.add_relocation io.tell, target_label, Asm::ARM::R_ARM_ABS32,
Asm::ARM::Instruction::RelocHandler
as.add_relocation io.tell, target_label, Asm::Arm::R_ARM_ABS32,
Asm::Arm::Instruction::RelocHandler
io.write_uint32 0
end
@const.each do |pair|

View File

@ -1,54 +1,54 @@
require_relative 'assembler'
require 'asm/assembler'
module Asm
module Arm
# Relocation constants
# Note that in this assembler, a relocation simply means any
# reference to a label that can only be determined at assembly time
# or later (as in the normal meaning)
# Relocation constants
# Note that in this assembler, a relocation simply means any
# reference to a label that can only be determined at assembly time
# or later (as in the normal meaning)
R_ARM_PC24 = 0x01
R_ARM_ABS32 = 0x02
R_ARM_PC24 = 0x01
R_ARM_ABS32 = 0x02
# Unofficial (cant be used for extern relocations)
R_ARM_PC12 = 0xF0
# Unofficial (cant be used for extern relocations)
R_ARM_PC12 = 0xF0
# TODO actually find the closest somehow
def self.closest_addrtable(as)
as.objects.find do |obj|
obj.is_a?(Asm::ARM::AddrTableObject)
end || (raise Asm::AssemblyError.new('could not find addrtable to use', nil))
end
# TODO actually find the closest somehow
def self.closest_addrtable(as)
as.objects.find do |obj|
obj.is_a?(Asm::Arm::AddrTableObject)
end || (raise Asm::AssemblyError.new('could not find addrtable to use', nil))
end
def self.write_resolved_relocation(io, addr, type)
case type
when R_ARM_PC24
diff = addr - io.tell - 8
packed = [diff >> 2].pack('l')
io << packed[0,3]
when R_ARM_ABS32
packed = [addr].pack('l')
io << packed
when R_ARM_PC12
diff = addr - io.tell - 8
if (diff.abs > 2047)
raise Asm::AssemblyError.new('offset too large for R_ARM_PC12 relocation',
nil)
def self.write_resolved_relocation(io, addr, type)
case type
when R_ARM_PC24
diff = addr - io.tell - 8
packed = [diff >> 2].pack('l')
io << packed[0,3]
when R_ARM_ABS32
packed = [addr].pack('l')
io << packed
when R_ARM_PC12
diff = addr - io.tell - 8
if (diff.abs > 2047)
raise Asm::AssemblyError.new('offset too large for R_ARM_PC12 relocation',
nil)
end
val = diff.abs
sign = (diff>0)?1:0
curr = io.read_uint32
io.seek(-4, IO::SEEK_CUR)
io.write_uint32 (curr & ~0b00000000100000000000111111111111) |
val | (sign << 23)
else
raise 'unknown relocation type'
end
val = diff.abs
sign = (diff>0)?1:0
curr = io.read_uint32
io.seek(-4, IO::SEEK_CUR)
io.write_uint32 (curr & ~0b00000000100000000000111111111111) |
val | (sign << 23)
else
raise 'unknown relocation type'
end
end
end

View File

@ -3,7 +3,7 @@ module Asm
# ADDRESSING MODE 1
# Complete!
class BuilderA
include Asm::ARM::InstructionTools
include Asm::Arm::InstructionTools
def initialize
@cond = 0b1110

View File

@ -1,9 +1,11 @@
require "asm/parser"
module Asm
module Arm
# ADDRESSING MODE 2
# Implemented: immediate offset with offset=0
class BuilderB
include Asm::ARM::InstructionTools
include Asm::Arm::InstructionTools
def initialize
@cond = 0b1110
@ -96,15 +98,15 @@ module Asm
(pre_post_index << 12+4+4+1+1+1+1) | (i << 12+4+4+1+1+1+1+1) |
(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)
closest_addrtable = Asm::Arm.closest_addrtable(as)
if (@addrtable_reloc_target.is_a?(Asm::Parser::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))
ref_label = closest_addrtable.add_const(@addrtable_reloc_target.value)
end
as.add_relocation io.tell, ref_label, Asm::ARM::R_ARM_PC12,
Asm::ARM::Instruction::RelocHandler
as.add_relocation io.tell, ref_label, Asm::Arm::R_ARM_PC12,
Asm::Arm::Instruction::RelocHandler
end
io.write_uint32 val
end

View File

@ -2,11 +2,11 @@ module Asm
module Arm
# ADDRESSING MODE 4
class BuilderD
include Asm::ARM::InstructionTools
include Asm::Arm::InstructionTools
def initialize
@cond = 0b1110
@inst_class = Asm::ARM::Instruction::OPC_STACK
@inst_class = Asm::Arm::Instruction::OPC_STACK
@pre_post_index = 0
@up_down = 0
@s = 0

View File

@ -1,5 +1,8 @@
require_relative 'arm_assembler'
require_relative 'parser'
require 'asm/arm/arm_assembler'
require 'asm/arm/instruction'
require 'asm/label_object'
require 'asm/parser'
require 'stream_reader'
require 'stringio'
module Asm
@ -51,7 +54,7 @@ module Asm
end
}
@asm.add_object Asm::ARM::Instruction.new(node)
@asm.add_object Asm::Arm::Instruction.new(node)
end
%w(adc add and bic eor orr rsb rsc sbc sub

View File

@ -1,7 +1,13 @@
require "asm/arm/instruction_tools"
require "asm/arm/builder_a"
require "asm/arm/builder_b"
require "asm/arm/builder_d"
module Asm
module Arm
class Asm::ARM::Instruction
include Asm::ARM::InstructionTools
class Instruction
include InstructionTools
COND_POSTFIXES = Regexp.union(%w(eq ne cs cc mi pl vs vc hi ls ge lt gt le al)).source
def initialize(node, ast_asm = nil)
@ -63,7 +69,7 @@ module Asm
:vs => 0b0110
}
RelocHandler = Asm::ARM.method(:write_resolved_relocation)
RelocHandler = Asm::Arm.method(:write_resolved_relocation)
def assemble(io, as)
s = @s ? 1 : 0
@ -123,7 +129,7 @@ module Asm
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)
as.add_relocation(io.tell, arg, Asm::ARM::R_ARM_PC24, RelocHandler)
as.add_relocation(io.tell, arg, Asm::Arm::R_ARM_PC24, RelocHandler)
io << "\x00\x00\x00"
end
io.write_uint8 OPCODES[opcode] | (COND_BITS[@cond] << 4)

View File

@ -1,6 +1,6 @@
module Asm
module Arm
module Asm::ARM::InstructionTools
module Asm::Arm::InstructionTools
def reg_ref(arg)
if (not arg.is_a?(Asm::Parser::RegisterArgNode))
raise Asm::AssemblyError.new('argument must be a register', arg)