def from_bitarray(instr, processor): mode = substring(instr, 4, 0) affect_f = bit_at(instr, 5) affect_i = bit_at(instr, 6) affect_a = bit_at(instr, 7) change_mode = bit_at(instr, 8) imod = substring(instr, 10, 9) imod_1 = bit_at(imod, 1) enable = imod == 0b10 disable = imod == 0b11 if (mode != 0b00000 and not change_mode) or ( imod_1 and not affect_a and not affect_f and not affect_i) or ( not imod_1 and (affect_a or affect_i or affect_f)) or imod == 0b01 or processor.in_it_block(): print('unpredictable') else: return CpsThumbT2(instr, affect_a=affect_a, affect_i=affect_i, affect_f=affect_f, enable=enable, disable=disable, change_mode=change_mode, mode=mode)
def execute(self, processor): if processor.condition_passed(): if processor.registers.current_mode_is_hyp(): raise UndefinedInstructionException() elif (processor.registers.current_mode_is_user_or_system() or processor.registers.current_instr_set() == InstrSet.THUMB_EE): print('unpredictable') else: length = (4 * bit_count(self.registers, 1, 16)) + 4 address = processor.registers.get( self.n) if self.increment else sub( processor.registers.get(self.n), length, 32) if self.word_higher: address = add(address, 4, 32) for i in range(15): if bit_at(self.registers, i): processor.registers.set( i, processor.mem_a_get(address, 4)) address = add(address, 4, 32) new_pc_value = processor.mem_a_get(address, 4) if self.wback and not bit_at(self.registers, self.n): processor.registers.set( self.n, (add(processor.registers.get( self.n), length, 32) if self.increment else sub( processor.registers.get(self.n), length, 32))) if self.wback and bit_at(self.registers, self.n): processor.registers.set(self.n, 0x00000000) # unknown processor.registers.cpsr_write_by_instr( processor.registers.get_spsr(), 0b1111, True) if processor.registers.cpsr.m == 0b11010 and processor.registers.cpsr.j and processor.registers.cpsr.t: print('unpredictable') else: processor.branch_write_pc(new_pc_value)
def from_bitarray(instr, processor): mode = substring(instr, 4, 0) wback = bit_at(instr, 21) increment = bit_at(instr, 23) p = bit_at(instr, 24) word_higher = p == increment return SrsArmA1(instr, increment=increment, word_higher=word_higher, wback=wback, mode=mode)
def from_bitarray(instr, processor): rn = substring(instr, 2, 0) imm5 = substring(instr, 7, 3) i = bit_at(instr, 9) nonzero = bit_at(instr, 11) imm32 = chain(i, imm5, 5) << 2 return CbzT1(instr, nonzero=nonzero, n=rn, imm32=imm32)
def decode_instruction(instr): op = bit_at(instr, 22) op1 = substring(instr, 19, 16) op2 = substring(instr, 7, 0) if not op and op1 == 0b0000 and op2 == 0b00000000: # No Operation hint return NopA1 elif not op and op1 == 0b0000 and op2 == 0b00000001: # Yield hint return YieldA1 elif not op and op1 == 0b0000 and op2 == 0b00000010: # Wait For Event hint return WfeA1 elif not op and op1 == 0b0000 and op2 == 0b00000011: # Wait For Interrupt hint return WfiA1 elif not op and op1 == 0b0000 and op2 == 0b00000100: # Send Event hint return SevA1 elif not op and op1 == 0b0000 and substring(instr, 7, 4) == 0b1111: # Debug hint raise NotImplementedError() elif not op and (op1 == 0b0100 or (bit_at(instr, 19) and substring(instr, 17, 16) == 0b00)): # Move to Special register, Application level return MsrImmediateApplicationA1 elif op or (not op and (bit_at(instr, 17) or substring(instr, 17, 16) == 0b01)): # Move to Special register, System level return MsrImmediateSystemA1
def decode_instruction(instr): op2 = substring(instr, 6, 5) op = bit_at(instr, 20) instr_22 = bit_at(instr, 22) if op2 == 0b01 and not op: # Store Halfword Unprivileged if instr_22: return StrhtA1 else: return StrhtA2 elif op2 == 0b01 and op: # Load Halfword Unprivileged if instr_22: return LdrhtA1 else: return LdrhtA2 elif op2 == 0b10 and op: # Load Signed Byte Unprivileged if instr_22: return LdrsbtA1 else: return LdrsbtA2 elif op2 == 0b11 and op: # Load Signed Halfword Unprivileged if instr_22: return LdrshtA1 else: return LdrshtA2
def decode_instruction(instr): instr_l = bit_at(instr, 20) instr_op = substring(instr, 24, 23) instr_w_rn = chain(bit_at(instr, 21), substring(instr, 19, 16), 4) if instr_op == 0b00 and not instr_l: # Store Return State return SrsThumbT1 elif instr_op == 0b00 and instr_l: # Return From Exception return RfeT1 elif instr_op == 0b01 and not instr_l: # Store Multiple (Increment After, Empty Ascending) return StmT2 elif instr_op == 0b01 and instr_l and instr_w_rn != 0b11101: # Load Multiple (Increment After, Full Descending) return LdmThumbT2 elif instr_op == 0b01 and instr_l and instr_w_rn == 0b11101: # Pop Multiple Registers from the stack return PopThumbT2 elif instr_op == 0b10 and not instr_l and instr_w_rn != 0b11101: # Store Multiple (Decrement Before, Full Descending) return StmdbT1 elif instr_op == 0b10 and not instr_l and instr_w_rn == 0b11101: # Push Multiple Registers to the stack. return PushT2 elif instr_op == 0b10 and instr_l: # Load Multiple (Decrement Before, Empty Ascending) return LdmdbT1 elif instr_op == 0b11 and not instr_l: # Store Return State return SrsThumbT2 elif instr_op == 0b11 and instr_l: # Return From Exception return RfeT2
def execute(self, processor): if processor.condition_passed(): try: processor.null_check_if_thumbee(self.n) except EndOfInstruction: pass else: address = sub(processor.registers.get(self.n), 4 * bit_count(self.registers, 1, 16), 32) for i in range(15): if bit_at(self.registers, i): if i == self.n and self.wback and i != lowest_set_bit_ref( self.registers): processor.mem_a_set(address, 4, 0x00000000) # unknown else: processor.mem_a_set(address, 4, processor.registers.get(i)) address = add(address, 4, 32) if bit_at(self.registers, 15): processor.mem_a_set(address, 4, processor.registers.pc_store_value()) if self.wback: processor.registers.set( self.n, sub(processor.registers.get(self.n), 4 * bit_count(self.registers, 1, 16), 32))
def execute(self, processor): if processor.condition_passed(): try: processor.null_check_if_thumbee(13) except EndOfInstruction: pass else: address = sub(processor.registers.get_sp(), 4 * bit_count(self.registers, 1, 32), 32) for i in range(15): if bit_at(self.registers, i): if i == 13 and i != lowest_set_bit_ref(self.registers): processor.mem_a_set(address, 4, 0x00000000) # unknown else: if self.unaligned_allowed: processor.mem_u_set(address, 4, processor.registers.get(i)) else: processor.mem_a_set(address, 4, processor.registers.get(i)) address = add(address, 4, 32) if bit_at(self.registers, 15): if self.unaligned_allowed: processor.mem_u_set( address, 4, processor.registers.pc_store_value()) else: processor.mem_a_set( address, 4, processor.registers.pc_store_value()) processor.registers.set_sp( sub(processor.registers.get_sp(), 4 * bit_count(self.registers, 1, 32), 32))
def execute(self, processor): if processor.condition_passed(): try: processor.null_check_if_thumbee(13) except EndOfInstruction: pass else: address = processor.registers.get_sp() for i in range(15): if bit_at(self.registers, i): processor.registers.set( i, (processor.mem_u_get(address, 4) if self.unaligned_allowed else processor.mem_a_get(address, 4)) ) address = add(address, 4, 32) if bit_at(self.registers, 15): if self.unaligned_allowed: if substring(address, 1, 0) == 0b00: processor.load_write_pc(processor.mem_u_get(address, 4)) else: print('unpredictable') else: processor.load_write_pc(processor.mem_a_get(address, 4)) if not bit_at(self.registers, 13): processor.registers.set_sp(add( processor.registers.get_sp(), 4 * bit_count(self.registers, 1, 16), 32 )) if bit_at(self.registers, 13): processor.registers.set_sp(0x00000000) # unknown
def from_bitarray(instr, processor): registers = substring(instr, 15, 0) rn = substring(instr, 19, 16) wback = bit_at(instr, 21) if rn == 15 or bit_count(registers, 1, 16) < 1 or (wback and bit_at( registers, rn) and arch_version() >= 7): print('unpredictable') else: return LdmArmA1(instr, wback=wback, registers=registers, n=rn)
def from_bitarray(instr, processor): imm32 = substring(instr, 11, 0) rn = substring(instr, 19, 16) is_pldw = bit_at(instr, 22) == 0 add = bit_at(instr, 23) return PldImmediateA1(instr, add=add, is_pldw=is_pldw, n=rn, imm32=imm32)
def from_bitarray(instr, processor): imm12 = substring(instr, 11, 0) imm32 = arm_expand_imm(imm12) mask = substring(instr, 19, 18) write_nzcvq = bit_at(mask, 1) write_g = bit_at(mask, 0) return MsrImmediateApplicationA1(instr, write_nzcvq=write_nzcvq, write_g=write_g, imm32=imm32)
def execute(self, processor): if processor.condition_passed(): if self.write_nzcvq: processor.registers.cpsr.n = bit_at(self.imm32, 31) processor.registers.cpsr.z = bit_at(self.imm32, 30) processor.registers.cpsr.c = bit_at(self.imm32, 29) processor.registers.cpsr.v = bit_at(self.imm32, 28) processor.registers.cpsr.q = bit_at(self.imm32, 27) if self.write_g: processor.registers.cpsr.ge = substring(self.imm32, 19, 16)
def from_bitarray(instr, processor): imm8 = substring(instr, 7, 0) rt2 = substring(instr, 11, 8) rt = substring(instr, 15, 12) add = bit_at(instr, 23) imm32 = imm8 << 2 if rt == rt2 or rt in (13, 15) or rt2 in (13, 15) or bit_at(instr, 21): print('unpredictable') else: return LdrdLiteralT1(instr, add=add, imm32=imm32, t=rt, t2=rt2)
def from_bitarray(instr, processor): index = bit_at(instr, 24) add = bit_at(instr, 23) w = bit_at(instr, 21) imm32 = substring(instr, 11, 0) rt = substring(instr, 15, 12) if index == w: print('unpredictable') else: return LdrLiteralA1(instr, add=add, imm32=imm32, t=rt)
def from_bitarray(instr, processor): rn = substring(instr, 3, 0) n_high = bit_at(instr, 5) m_high = bit_at(instr, 6) rm = substring(instr, 11, 8) rd_lo = substring(instr, 15, 12) rd_hi = substring(instr, 19, 16) if rm == 15 or rd_hi == 15 or rd_lo == 15 or rn == 15 or rd_hi == rd_lo: print('unpredictable') else: return SmlalxyA1(instr, m_high=m_high, n_high=n_high, m=rm, d_hi=rd_hi, d_lo=rd_lo, n=rn)
def from_bitarray(instr, processor): imm8 = substring(instr, 7, 0) rd = substring(instr, 11, 8) imm3 = substring(instr, 14, 12) setflags = bit_at(instr, 20) i = bit_at(instr, 26) imm32 = thumb_expand_imm(chain(i, chain(imm3, imm8, 8), 11)) if rd == 15 and not setflags: print('unpredictable') else: return SubSpMinusImmediateT2(instr, setflags=setflags, d=rd, imm32=imm32)
def from_bitarray(instr, processor): register_list = substring(instr, 12, 0) m = bit_at(instr, 14) wback = bit_at(instr, 21) rn = substring(instr, 19, 16) registers = chain(m, register_list, 14) if rn == 15 or bit_count(registers, 1, 16) < 2 or (wback and bit_at( registers, rn)): print('unpredictable') else: return StmT2(instr, wback=wback, registers=registers, n=rn)
def from_bitarray(instr, processor): rn = substring(instr, 19, 16) write_nzcvq = bit_at(instr, 11) write_g = bit_at(instr, 10) if (not write_g and not write_nzcvq) or rn in (13, 15): print('unpredictable') else: return MsrRegisterApplicationT1(instr, write_nzcvq=write_nzcvq, write_g=write_g, n=rn)
def from_bitarray(instr, processor): register_list = substring(instr, 15, 0) rn = substring(instr, 19, 16) increment = bit_at(instr, 23) word_higher = increment == bit_at(instr, 24) wback = bit_at(instr, 21) if rn == 15 or (wback and bit_at(register_list, rn) and arch_version() >= 7): print('unpredictable') else: return LdmExceptionReturnA1(instr, increment=increment, word_higher=word_higher, wback=wback, registers=register_list, n=rn)
def from_bitarray(instr, processor): imm8 = substring(instr, 7, 0) rd = substring(instr, 11, 8) imm3 = substring(instr, 14, 12) setflags = bit_at(instr, 20) i = bit_at(instr, 26) imm32, carry = thumb_expand_imm_c(chain(i, chain(imm3, imm8, 8), 11), processor.registers.cpsr.c) if rd in (13, 15): print('unpredictable') else: return MovImmediateT2(instr, setflags=setflags, d=rd, imm32=imm32, carry=carry)
def from_bitarray(instr, processor): imm4_l = substring(instr, 3, 0) imm4_h = substring(instr, 11, 8) rt = substring(instr, 15, 12) add = bit_at(instr, 23) imm32 = chain(imm4_h, imm4_l, 4) t2 = rt + 1 if bit_at(rt, 0) or t2 == 15: print('unpredictable') else: return LdrdLiteralA1(instr, add=add, imm32=imm32, t=rt, t2=t2)
def from_bitarray(instr, processor): rn = substring(instr, 3, 0) write_nzcvq = bit_at(instr, 19) write_g = bit_at(instr, 18) if rn == 15 or (not write_g and not write_nzcvq): print('unpredictable') else: return MsrRegisterApplicationA1(instr, write_nzcvq=write_nzcvq, write_g=write_g, n=rn)
def from_bitarray(instr, processor): unaligned_allowed = False registers_list = substring(instr, 7, 0) p = bit_at(instr, 8) registers = chain(p, registers_list, 15) if not registers or (bit_at(registers, 15) and processor.in_it_block() and not processor.last_in_it_block()): print('unpredictable') else: return PopThumbT1(instr, registers=registers, unaligned_allowed=unaligned_allowed)
def from_bitarray(instr, processor): register_list = substring(instr, 12, 0) p_m = substring(instr, 15, 14) wback = bit_at(instr, 21) rn = substring(instr, 19, 16) registers = chain(p_m, register_list, 14) if rn == 15 or bit_count(registers, 1, 16) < 2 or p_m == 0b11 or ( bit_at(registers, 15) and processor.in_it_block() and not processor.last_in_it_block()) or ( wback and bit_at(registers, rn)): print('unpredictable') else: return LdmdbT1(instr, wback=wback, registers=registers, n=rn)
def from_bitarray(instr, processor): imm8 = substring(instr, 7, 0) rd = substring(instr, 11, 8) imm3 = substring(instr, 14, 12) rn = substring(instr, 19, 16) setflags = bit_at(instr, 20) i = bit_at(instr, 26) imm32, carry = thumb_expand_imm_c(chain(i, chain(imm3, imm8, 8), 11), processor.registers.cpsr.c) if rd == 13 or (rd == 15 and not setflags) or rn in (13, 15): print('unpredictable') else: return BicImmediateT1(instr, setflags=setflags, d=rd, n=rn, imm32=imm32, carry=carry)
def from_bitarray(instr, processor): imm8 = substring(instr, 7, 0) coproc = substring(instr, 11, 8) rn = substring(instr, 19, 16) wback = bit_at(instr, 21) add = bit_at(instr, 23) index = bit_at(instr, 24) imm32 = imm8 << 2 if substring(instr, 24, 21) == 0b0000: raise UndefinedInstructionException() else: return LdcLdc2ImmediateT1(instr, cp=coproc, n=rn, add=add, imm32=imm32, index=index, wback=wback)
def from_bitarray(instr, processor): imm8 = substring(instr, 7, 0) rd = substring(instr, 11, 8) imm3 = substring(instr, 14, 12) rn = substring(instr, 19, 16) setflags = bit_at(instr, 20) i = bit_at(instr, 26) imm32 = thumb_expand_imm(chain(i, chain(imm3, imm8, 8), 11)) if rd in (13, 15) or rn in (13, 15): print('unpredictable') else: return SbcImmediateT1(instr, setflags=setflags, d=rd, n=rn, imm32=imm32)
def from_bitarray(instr, processor): w = bit_at(instr, 21) p = bit_at(instr, 24) imm4_l = substring(instr, 3, 0) imm4_h = substring(instr, 11, 8) rt = substring(instr, 15, 12) add = bit_at(instr, 23) imm32 = chain(imm4_h, imm4_l, 4) if p == w or rt == 15: print('unpredictable') else: return LdrshLiteralA1(instr, add=add, imm32=imm32, t=rt)