# This file is part of Metasm, the Ruby assembly manipulation suite # Copyright (C) 2006-2010 Yoann GUILLOT # # Licence is LGPL, see LICENCE in the top-level directory require 'metasm/main' module Metasm class ARC < CPU def initialize(e = :little) super() @endianness = e @size = 32 end class Reg include Renderable attr_accessor :i def initialize(i); @i = i end def ==(o) o.class == self.class and o.i == i end end # general purpose reg # Result R0-R1 # Arguments R0-R7 # Caller Saved Registers R0-R12 # Callee Saved Registers R13-R25 # Static chain pointer (if required) R11 # Register for temp calculation R12 # Global Pointer R26 (GP) # Frame Pointer R27 (FP) # Stack Pointer R28 (SP) # Interrupt Link Register 1 R29 (ILINK1) # Interrupt Link Register 2 R30 (ILINK2) # Branch Link Register R31 (BLINK) class GPR < Reg Sym = (0..64).map { |i| "r#{i}".to_sym } def symbolic(di=nil); Sym[@i] end Render = { 26 => 'gp', # global pointer, used to point to small sets of shared data throughout execution of a program 27 => 'fp', # frame pointer 28 => 'sp', # stak pointer 29 => 'ilink1', # maskable interrupt link register 30 => 'ilink2', # maskable interrupt link register 2 31 => 'blink', # branch link register 60 => 'lp_count', # loop count register (24 bits) # "When a destination register is set to r62 there is no destination for the result of the instruction so the # result is discarded. Any flag updates will still occur according to the set flags directive (.F or implicit # in the instruction)." 62 => 'zero' } def render if s = Render[i] [s] else # r0-r28 general purpose registers # r32-r59 reserved for extentions ["r#@i"] end end end class AUX < Reg def symbolic(di=nil); "aux#{i}".to_sym end Render = { 0x00 => 'status', # Status register (Original ARCtangent-A4 processor format) 0x01 => 'semaphore', # Inter-process/Host semaphore register 0x02 => 'lp_start', # Loop start address (32-bit) 0x03 => 'lp_end', # Loop end address (32-bit) 0x04 => 'identity', # Processor Identification register 0x05 => 'debug', # Debug register 0x06 => 'pc', # PC register (32-bit) 0x0A => 'status32', # Status register (32-bit) 0x0B => 'status32_l1', # Status register save for level 1 interrupts 0x0C => 'status32_l2', # Status register save for level 2 interrupts 0x10 => 'ic_ivic', # Cache invalidate 0x11 => 'ic_ctrl', # Mode bits for cache controller 0x12 => 'mulhi', # High part of Multiply 0x19 => 'ic_ivil', 0x21 => 'timer0_cnt', # Processor Timer 0 Count value 0x22 => 'timer0_ctrl', # Processor Timer 0 Control value 0x23 => 'timer0_limit', # Processor Timer 0 Limit value 0x25 => 'int_vector_base', # Interrupt Vector Base address 0x40 => 'im_set_dc_ctrl', 0x41 => 'aux_macmode', # Extended Arithmetic Status and Mode 0x43 => 'aux_irq_lv12', # Interrupt Level Status 0x47 => 'dc_ivdc', # Invalidate cache 0x48 => 'dc_ctrl', # Cache control register 0x49 => 'dc_ldl', # Lock data line 0x4A => 'dc_ivdl', # Invalidate data line 0x4B => 'dc_flsh', # Flush data cache 0x4C => 'dc_fldl', # Flush data line 0x58 => 'dc_ram_addr', # Access RAM address 0x59 => 'dc_tag', # Tag Access 0x5A => 'dc_wp', # Way Pointer Access 0x5B => 'dc_data', # Data Access 0x62 => 'crc_bcr', 0x64 => 'dvfb_bcr', 0x65 => 'extarith_bcr', 0x68 => 'vecbase_bcr', 0x69 => 'perbase_bcr', 0x6f => 'mmu_bcr', 0x72 => 'd_cache_build', # Build: Data Cache 0x73 => 'madi_build', # Build: Multiple ARC Debug I/F 0x74 => 'ldstram_build', # Build: LD/ST RAM 0x75 => 'timer_build', # Build: Timer 0x76 => 'ap_build', # Build: Actionpoints 0x77 => 'i_cache_build', # Build: I-Cache 0x78 => 'addsub_build', # Build: Saturated Add/Sub 0x79 => 'dspram_build', # Build: Scratch RAM & XY Memory 0x7B => 'multiply_build', # Build: Multiply 0x7C => 'swap_build', # Build: Swap 0x7D => 'norm_build', # Build: Normalise 0x7E => 'minmax_build', # Build: Min/Max 0x7F => 'barrel_build', # Build: Barrel Shift 0x100 => 'timer1_cnt', # Processor Timer 1 Count value 0x101 => 'timer1_ctrl', # Processor Timer 1 Control value 0x102 => 'timer1_limit', # Processor Timer 1 Limit value 0x200 => 'aux_irq_lev', # Interrupt Level Programming 0x201 => 'aux_irq_hint', # Software Triggered Interrupt 0x202 => 'aux_irq_mask', # Masked bits for Interrupts 0x203 => 'aux_irq_base', # Interrupt Vector base address 0x400 => 'eret', # Exception Return Address 0x401 => 'erbta', # Exception Return Branch Target Address 0x402 => 'erstatus', # Exception Return Status 0x403 => 'ecr', # Exception Cause Register 0x404 => 'efa', # Exception Fault Address 0x40A => 'icause1', # Level 1 Interrupt Cause Register 0x40B => 'icause2', # Level 2 Interrupt Cause Register 0x40C => 'aux_ienable', # Interrupt Mask Programming 0x40D => 'aux_itrigger', # Interrupt Sensitivity Programming 0x410 => 'xpu', # User Mode Extension Enables 0x412 => 'bta', # Branch Target Address 0x413 => 'bta_l1', # Level 1 Return Branch Target 0x414 => 'bta_l2', # Level 2 Return Branch Target 0x415 => 'aux_irq_pulse_cancel', # Interrupt Pulse Cancel 0x416 => 'aux_irq_pending', # Interrupt Pending Register } def render if s = Render[i] [s] else ["aux#@i"] end end end class Memref attr_accessor :base, :disp def initialize(base, disp, sz) @base, @disp, @size = base, disp, sz end def symbolic(di=nil) b = @base b = b.symbolic if b.kind_of? Reg if disp o = @disp o = o.symbolic if o.kind_of? Reg e = Expression[b, :+, o].reduce else e = Expression[b].reduce end Indirection[e, @size, (di.address if di)] end include Renderable def render if @disp and @disp != 0 ['[', @base, ', ', @disp, ']'] else ['[', @base, ']'] end end end end end