cleanup, requires, namespacing to actually get it to work
This commit is contained in:
@ -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|
|
||||
|
@ -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
|
||||
|
||||
|
@ -3,7 +3,7 @@ module Asm
|
||||
# ADDRESSING MODE 1
|
||||
# Complete!
|
||||
class BuilderA
|
||||
include Asm::ARM::InstructionTools
|
||||
include Asm::Arm::InstructionTools
|
||||
|
||||
def initialize
|
||||
@cond = 0b1110
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user