first step to overloading assemble
This commit is contained in:
parent
b2f45d9f9c
commit
c98547137b
@ -25,7 +25,7 @@ module Asm
|
|||||||
end
|
end
|
||||||
attr_reader :values , :position
|
attr_reader :values , :position
|
||||||
|
|
||||||
def instruction(name, *args)
|
def instruction(clazz,name, *args)
|
||||||
opcode = name.to_s
|
opcode = name.to_s
|
||||||
arg_nodes = []
|
arg_nodes = []
|
||||||
|
|
||||||
@ -43,28 +43,35 @@ module Asm
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
add_value Asm::Instruction.new(opcode , arg_nodes)
|
add_value clazz.new(opcode , arg_nodes)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def self.define_instruction(inst , clazz )
|
||||||
|
define_method(inst) do |*args|
|
||||||
|
instruction clazz , inst.to_sym, *args
|
||||||
|
end
|
||||||
|
define_method(inst+'s') do |*args|
|
||||||
|
instruction clazz , (inst+'s').to_sym, *args
|
||||||
|
end
|
||||||
|
%w(al eq ne cs mi hi cc pl ls vc lt le ge gt vs).each do |cond_suffix|
|
||||||
|
define_method(inst+cond_suffix) do |*args|
|
||||||
|
instruction clazz , (inst+cond_suffix).to_sym, *args
|
||||||
|
end
|
||||||
|
define_method(inst+'s'+cond_suffix) do |*args|
|
||||||
|
instruction clazz , (inst+'s'+cond_suffix).to_sym, *args
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
["push", "pop"].each do |inst|
|
||||||
|
define_instruction(inst , StackInstruction)
|
||||||
end
|
end
|
||||||
|
|
||||||
%w(adc add and bic eor orr rsb rsc sbc sub mov mvn cmn cmp teq tst b bl bx
|
%w(adc add and bic eor orr rsb rsc sbc sub mov mvn cmn cmp teq tst b bl bx
|
||||||
push pop swi str strb ldr ldrb
|
swi str strb ldr ldrb ).each do |inst|
|
||||||
).each { |inst|
|
define_instruction(inst , Instruction)
|
||||||
define_method(inst) { |*args|
|
end
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def assemble_to_string
|
def assemble_to_string
|
||||||
#put the strings at the end of the assembled code.
|
#put the strings at the end of the assembled code.
|
||||||
|
@ -2,7 +2,6 @@ require "asm/assembly_error"
|
|||||||
require "asm/instruction_tools"
|
require "asm/instruction_tools"
|
||||||
require "asm/normal_builder"
|
require "asm/normal_builder"
|
||||||
require "asm/memory_access_builder"
|
require "asm/memory_access_builder"
|
||||||
require "asm/stack_builder"
|
|
||||||
require "asm/label"
|
require "asm/label"
|
||||||
|
|
||||||
module Asm
|
module Asm
|
||||||
@ -14,7 +13,7 @@ module Asm
|
|||||||
def initialize(opcode , args)
|
def initialize(opcode , args)
|
||||||
|
|
||||||
opcode = opcode.downcase
|
opcode = opcode.downcase
|
||||||
@cond = :al
|
@cond = 0b1011
|
||||||
if (opcode =~ /(#{COND_POSTFIXES})$/)
|
if (opcode =~ /(#{COND_POSTFIXES})$/)
|
||||||
@cond = $1.to_sym
|
@cond = $1.to_sym
|
||||||
opcode = opcode[0..-3]
|
opcode = opcode[0..-3]
|
||||||
@ -78,18 +77,6 @@ module Asm
|
|||||||
builder.rd = reg_ref(args[0])
|
builder.rd = reg_ref(args[0])
|
||||||
builder.build_operand args[1]
|
builder.build_operand args[1]
|
||||||
builder.assemble io, as, self
|
builder.assemble io, as, self
|
||||||
when :push, :pop
|
|
||||||
# downward growing, decrement before memory access
|
|
||||||
# official ARM style stack as used by gas
|
|
||||||
if (opcode == :push)
|
|
||||||
builder = StackBuilder.new(1,0,1,0)
|
|
||||||
else
|
|
||||||
builder = StackBuilder.new(0,1,1,1)
|
|
||||||
end
|
|
||||||
builder.cond = COND_CODES[@cond]
|
|
||||||
builder.rn = 13 # sp
|
|
||||||
builder.build_operand args
|
|
||||||
builder.assemble io, as
|
|
||||||
when :b, :bl
|
when :b, :bl
|
||||||
arg = args[0]
|
arg = args[0]
|
||||||
if arg.is_a? Label
|
if arg.is_a? Label
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
module Asm
|
|
||||||
# ADDRESSING MODE 4
|
|
||||||
class StackBuilder
|
|
||||||
include Asm::InstructionTools
|
|
||||||
|
|
||||||
def initialize(pre_post, up_down, write, store_load)
|
|
||||||
@cond = 0b1110
|
|
||||||
@inst_class = Asm::Instruction::OPC_STACK
|
|
||||||
@pre_post_index = 0
|
|
||||||
@up_down = 0
|
|
||||||
@s = 0
|
|
||||||
@write_base = 0
|
|
||||||
@store_load = 0
|
|
||||||
@rn = 0
|
|
||||||
@operand = 0
|
|
||||||
@pre_post_index = pre_post
|
|
||||||
@up_down = up_down
|
|
||||||
@write_base = write
|
|
||||||
@store_load = store_load
|
|
||||||
end
|
|
||||||
attr_accessor :cond, :inst_class, :pre_post_index, :up_down,
|
|
||||||
:s, :write_base, :store_load, :rn, :operand
|
|
||||||
|
|
||||||
# Build representation for source value
|
|
||||||
def build_operand(arg)
|
|
||||||
if (arg.is_a?(Array))
|
|
||||||
@operand = 0
|
|
||||||
arg.each do |reg |
|
|
||||||
reg = reg_ref(reg)
|
|
||||||
@operand |= (1 << reg)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
raise Asm::AssemblyError.new("invalid operand argument #{arg.inspect}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def assemble(io, as)
|
|
||||||
val = operand | (rn << 16) | (store_load << 16+4) |
|
|
||||||
(write_base << 16+4+1) | (s << 16+4+1+1) | (up_down << 16+4+1+1+1) |
|
|
||||||
(pre_post_index << 16+4+1+1+1+1) | (inst_class << 16+4+1+1+1+1+2) |
|
|
||||||
(cond << 16+4+1+1+1+1+2+2)
|
|
||||||
io.write_uint32 val
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
65
lib/asm/stack_instruction.rb
Normal file
65
lib/asm/stack_instruction.rb
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
require "asm/instruction"
|
||||||
|
|
||||||
|
module Asm
|
||||||
|
# ADDRESSING MODE 4
|
||||||
|
class StackInstruction < Instruction
|
||||||
|
include Asm::InstructionTools
|
||||||
|
|
||||||
|
def initialize(opcode , args)
|
||||||
|
super(opcode,args)
|
||||||
|
@operand = 0
|
||||||
|
@cond = 0b1110
|
||||||
|
@inst_class = Asm::Instruction::OPC_STACK
|
||||||
|
@s = 0
|
||||||
|
@rn = 0
|
||||||
|
# downward growing, decrement before memory access
|
||||||
|
# official ARM style stack as used by gas
|
||||||
|
@write_base = 1
|
||||||
|
if (opcode == :push)
|
||||||
|
@pre_post_index = 1
|
||||||
|
@up_down = 0
|
||||||
|
@store_load = 0
|
||||||
|
else #pop
|
||||||
|
@pre_post_index = 0
|
||||||
|
@up_down = 1
|
||||||
|
@store_load = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
attr_accessor :cond, :inst_class, :pre_post_index, :up_down,
|
||||||
|
:s, :write_base, :store_load, :rn, :operand
|
||||||
|
|
||||||
|
def assemble(io, as)
|
||||||
|
cond = @cond.is_a?(Symbol) ? COND_CODES[@cond] : @cond
|
||||||
|
rn = 13 # sp
|
||||||
|
build_operand args
|
||||||
|
|
||||||
|
#assemble of old
|
||||||
|
val = @operand
|
||||||
|
val |= (rn << 16)
|
||||||
|
val |= (store_load << 16+4) #20
|
||||||
|
val |= (write_base << 16+4+ 1)
|
||||||
|
val |= (s << 16+4+ 1+1)
|
||||||
|
val |= (up_down << 16+4+ 1+1+1)
|
||||||
|
val |= (pre_post_index << 16+4+ 1+1+1+1)#24
|
||||||
|
val |= (inst_class << 16+4+ 1+1+1+1 +2)
|
||||||
|
val |= (cond << 16+4+ 1+1+1+1 +2+2)
|
||||||
|
puts "#{self.inspect}"
|
||||||
|
io.write_uint32 val
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Build representation for source value
|
||||||
|
def build_operand(arg)
|
||||||
|
if (arg.is_a?(Array))
|
||||||
|
@operand = 0
|
||||||
|
arg.each do |reg |
|
||||||
|
reg = reg_ref(reg)
|
||||||
|
@operand |= (1 << reg)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise Asm::AssemblyError.new("invalid operand argument #{arg.inspect}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
@ -1,2 +1,3 @@
|
|||||||
|
require "asm/stack_instruction"
|
||||||
require "asm/arm_assembler"
|
require "asm/arm_assembler"
|
||||||
require "elf/object_writer"
|
require "elf/object_writer"
|
||||||
|
Loading…
Reference in New Issue
Block a user