#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "dbg_msg.h"
#include "arm_emu.h"
#include "jt_arm.h"
#include "jt_instr.h"
#define OK 1 |
Referenced by arm_emu_opcode(), arm_step_emu(), and thumb_step_emu().
#define FAIL 0 |
Referenced by arm_step_emu(), and thumb_step_emu().
#define WRONG -1 |
Referenced by arm_emu_opcode().
#define GET_S_BIT | ( | _S_bit_, | |||
_INSTR_ | ) |
Referenced by arm_step_emu().
#define GET_VZN_FLAGS |
Referenced by arm_step_emu(), and thumb_step_emu().
#define GET_C_FLAG |
Referenced by arm_emu_asr(), arm_emu_lsl(), arm_emu_lsr(), arm_emu_ror(), arm_step_emu(), and thumb_step_emu().
#define GET_VALUE_FROM_CPU_REGISTER | ( | _VAL_, | |||
_RN_ | ) |
Referenced by arm_step_emu().
#define THUMB_GET_VALUE_FROM_CPU_LOW_REGISTER | ( | _VAL_, | |||
_RN_ | ) |
Referenced by thumb_step_emu().
#define THUMB_GET_VALUE_FROM_CPU_HIGH_REGISTER | ( | _VAL_, | |||
_RN_ | ) |
Referenced by thumb_step_emu().
static void arm_update_flags | ( | void | ) | [static] |
update all CPSR Flags
References armEmuFlags::carry, reg_set::CPSR, CPU, CPU_CPSR_FLAG_CARRY, CPU_CPSR_FLAG_NEGATIVE, CPU_CPSR_FLAG_OVERFLOW, CPU_CPSR_FLAG_ZERO, armEmuFlags::negative, armEmuFlags::overflow, and armEmuFlags::zero.
Referenced by arm_emu_opcode(), arm_step_emu(), and thumb_step_emu().
void arm_recalculate_flags_Z_N | ( | uint32_t | val | ) |
recalculate Z and N flags (for CPSR)
References armEmuFlags::negative, and armEmuFlags::zero.
Referenced by arm_emu_add(), arm_emu_opcode(), arm_emu_sub(), arm_step_emu(), doCmdSequence(), and thumb_step_emu().
uint32_t arm_emu_add | ( | uint32_t | l_val, | |
uint32_t | r_val, | |||
int | carry_in | |||
) |
calculate add: l_val + r_val and recalculate global flags: overflow, carry, zero and negative 2 bit adder 00 00 00 00 + 00 01 10 11 = 00 01 10 11
01 01 01 01 + 00 01 10 11 = 01 10v 11 c00
10 10 10 10 + 00 01 10 11 = 10 11 c00v c01v
11 11 11 11 + 00 01 10 11 = 11 c00 c01v c10
l_val | := left 32 bit value | |
r_val | := right 32 bit value | |
carry_in | flag (0 or 1) |
References arm_recalculate_flags_Z_N(), armEmuFlags::carry, armEmuFlags::negative, and armEmuFlags::overflow.
Referenced by arm_emu_opcode(), doCmdSequence(), and thumb_step_emu().
uint32_t arm_emu_sub | ( | uint32_t | l_val, | |
uint32_t | r_val, | |||
int | borrow_in | |||
) |
calculate sub: l_val - r_val and recalculate global flags: overflow, carry, zero and negative 2 bit subtracter 00 00 00 00
01 01 01 01
10 10 10 10
11 11 11 11
l_val | := left 32 bit value | |
r_val | := right 32 bit value | |
borrow_in | flag (0 or 1) |
References arm_recalculate_flags_Z_N(), armEmuFlags::carry, armEmuFlags::negative, and armEmuFlags::overflow.
Referenced by arm_emu_opcode(), doCmdSequence(), and thumb_step_emu().
uint32_t arm_emu_lsl | ( | uint32_t | sh_val, | |
uint32_t | imm, | |||
int | fetch_c_flag | |||
) |
logical shift left
sh_val | value to be shifted | |
imm | number of bit to shift | |
fetch_c_flag | fetch previous carry flag from CPSR (if needed) |
References armEmuFlags::carry, and GET_C_FLAG.
Referenced by arm_step_emu(), doCmdSequence(), and thumb_step_emu().
uint32_t arm_emu_lsr | ( | uint32_t | sh_val, | |
uint32_t | imm, | |||
int | fetch_c_flag | |||
) |
logical shift right
sh_val | value to be shifted | |
imm | number of bit to shift | |
fetch_c_flag | fetch previous carry flag from CPSR (if needed) |
References armEmuFlags::carry, and GET_C_FLAG.
Referenced by arm_step_emu(), doCmdSequence(), and thumb_step_emu().
uint32_t arm_emu_asr | ( | uint32_t | sh_val, | |
uint32_t | imm, | |||
int | fetch_c_flag | |||
) |
arithmetic shift right
sh_val | value to be shifted | |
imm | number of bit to shift | |
fetch_c_flag | fetch previous carry flag from CPSR (if needed) |
References armEmuFlags::carry, and GET_C_FLAG.
Referenced by arm_step_emu(), and thumb_step_emu().
uint32_t arm_emu_ror | ( | uint32_t | rot_val, | |
uint32_t | imm, | |||
int | fetch_c_flag, | |||
int | with_carry | |||
) |
rotate right
rot_val | value to be rotated | |
imm | number of bit to rotate | |
fetch_c_flag | fetch previous carry flag from CPSR (if needed) | |
with_carry | imm == 32 use carry bit as bit 33 and rotate one position |
References armEmuFlags::carry, and GET_C_FLAG.
Referenced by arm_step_emu(), doCmdSequence(), and thumb_step_emu().
static int arm_emu_opcode | ( | int | opcode, | |
int | rd, | |||
int | rn, | |||
uint32_t | l_op_val, | |||
uint32_t | r_op_val, | |||
int | S_bit | |||
) | [static] |
ARM Opcode data processing
opcode | one of the 15-ARM opcodes (AND,OR,ADD,SUB..) | |
rd | number of the destination register | |
rn | ||
l_op_val | ||
r_op_val | ||
S_bit | if S Bit set then update CPSR |
0 | OK | |
-1 | WRONG |
References arm_emu_add(), arm_emu_sub(), arm_recalculate_flags_Z_N(), arm_update_flags(), armEmuFlags::carry, CPU, OK, reg_set::Regs::r, reg_set::regs, and WRONG.
Referenced by arm_step_emu().
int arm_step_emu | ( | uint32_t | instr | ) |
Try to emulate an ARM-instruction step. Only a small subset is supported.
instr | 32-bit ARM instruction |
1 | OK if CPU changed | |
0 | FAIL if failed to change CPU |
References arm_emu_asr(), arm_emu_lsl(), arm_emu_lsr(), arm_emu_opcode(), arm_emu_ror(), arm_recalculate_flags_Z_N(), arm_update_flags(), armEmuFlags::carry, CPU, FAIL, GET_C_FLAG, GET_S_BIT, GET_VALUE_FROM_CPU_REGISTER, GET_VZN_FLAGS, jt_arm_condition_pass(), armEmuFlags::negative, OK, reg_set::Regs::r, reg_set::regs, and armEmuFlags::zero.
Referenced by gdb_action_step(), and jtag_test().
int thumb_step_emu | ( | uint16_t | instr | ) |
Try to emulate an THUMB-instruction step. Only a small subset is supported. Some instructions are like bl and bx are already handled.
instr | 16-bit THUMB instruction |
1 | OK if emulation succeed and CPU register changed | |
0 | FAIL if faild to change CPU |
References arm_emu_add(), arm_emu_asr(), arm_emu_lsl(), arm_emu_lsr(), arm_emu_ror(), arm_emu_sub(), arm_recalculate_flags_Z_N(), arm_update_flags(), armEmuFlags::carry, CPU, FAIL, GET_C_FLAG, GET_VZN_FLAGS, jt_arm_condition_pass(), OK, reg_set::Regs::r, reg_set::regs, THUMB_GET_VALUE_FROM_CPU_HIGH_REGISTER, and THUMB_GET_VALUE_FROM_CPU_LOW_REGISTER.
Referenced by gdb_action_step(), jtag_arm9_Step(), and jtag_test().
struct armEmuFlags armEmuFlags |