require "asm/instruction" module Asm # ADDRESSING MODE 4 class StackInstruction < Instruction include Asm::InstructionTools def initialize(opcode , args) super(opcode,args) @inst_class = Asm::Instruction::OPC_STACK @update_status_flag= 0 @rn = reg "r0" # register zero = zero bit pattern # 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 @is_pop = 0 else #pop @pre_post_index = 0 @up_down = 1 @is_pop = 1 end end attr_accessor :cond, :inst_class, :pre_post_index, :up_down, :update_status_flag, :write_base, :is_pop, :rn, :operand def assemble(io, as) build cond = @cond.is_a?(Symbol) ? COND_CODES[@cond] : @cond rn = reg "sp" # sp register #assemble of old val = operand val |= (rn.bits << 16) val |= (is_pop << 16+4) #20 val |= (write_base << 16+4+ 1) val |= (update_status_flag << 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) io.write_uint32 val end private # Build representation for source value def build if (args.is_a?(Array)) @operand = 0 args.each do |reg | @operand |= (1 << reg.bits) end else raise Asm::AssemblyError.new("invalid operand argument #{args.inspect}") end end end end