diff options
Diffstat (limited to 'src/core/arm')
28 files changed, 1405 insertions, 12013 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 9c4cc90f2..f6628ca33 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/arm/skyeye_common/armcpu.h" #include "core/arm/skyeye_common/armemu.h" #include "core/arm/skyeye_common/vfp/vfp.h" @@ -37,9 +36,8 @@ ARM_DynCom::ARM_DynCom() { state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext state->Emulate = 3; - state->pc = state->Reg[15] = 0x00000000; + state->Reg[15] = 0x00000000; state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack - state->servaddr = 0xFFFF0000; state->NirqSig = HIGH; VFPInit(state.get()); // Initialize the VFP @@ -51,7 +49,7 @@ ARM_DynCom::~ARM_DynCom() { } void ARM_DynCom::SetPC(u32 pc) { - state->pc = state->Reg[15] = pc; + state->Reg[15] = pc; } u32 ARM_DynCom::GetPC() const { @@ -107,7 +105,6 @@ void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) { ctx.fpscr = state->VFP[1]; ctx.fpexc = state->VFP[2]; - ctx.reg_15 = state->Reg[15]; ctx.mode = state->NextInstr; } @@ -117,13 +114,12 @@ void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) { state->Reg[13] = ctx.sp; state->Reg[14] = ctx.lr; - state->pc = ctx.pc; + state->Reg[15] = ctx.pc; state->Cpsr = ctx.cpsr; state->VFP[1] = ctx.fpscr; state->VFP[2] = ctx.fpexc; - state->Reg[15] = ctx.reg_15; state->NextInstr = ctx.mode; } diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h index 58784aeea..ee8ff5992 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.h +++ b/src/core/arm/dyncom/arm_dyncom_dec.h @@ -6,14 +6,6 @@ #define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1)) #define BIT(n) ((instr >> (n)) & 1) -#define BAD do { printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); } while(0); -#define ptr_N cpu->ptr_N -#define ptr_Z cpu->ptr_Z -#define ptr_C cpu->ptr_C -#define ptr_V cpu->ptr_V -#define ptr_I cpu->ptr_I -#define ptr_T cpu->ptr_T -#define ptr_CPSR cpu->ptr_gpr[16] // For MUL instructions #define RDHi ((instr >> 16) & 0xF) @@ -49,24 +41,6 @@ #define SBIT BIT(20) #define DESTReg (BITS (12, 15)) -// They are in unused state, give a corrent value when using -#define IS_V5E 0 -#define IS_V5 0 -#define IS_V6 0 -#define LHSReg 0 - -// Temp define the using the pc reg need implement a flow -#define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2)) - -#define OPERAND operand(cpu,instr,bb,NULL) -#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco) -#define BOPERAND boperand(instr) - -#define CHECK_RN_PC (RN == 15 ? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)) : R(RN)) -#define CHECK_RN_PC_WA (RN == 15 ? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)) : R(RN)) - -#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE)))) - int decode_arm_instr(uint32_t instr, int32_t *idx); enum DECODE_STATUS { @@ -83,23 +57,8 @@ struct instruction_set_encoding_item { typedef struct instruction_set_encoding_item ISEITEM; -#define RECORD_WB(value, flag) { cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag; } -#define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag) - -#define EXECUTE_WB(base_reg) { if(cpu->dyncom_engine->wb_flag) LET(base_reg, cpu->dyncom_engine->wb_value); } - -inline int get_reg_count(uint32_t instr) { - int i = BITS(0, 15); - int count = 0; - while (i) { - if (i & 1) - count++; - i = i >> 1; - } - return count; -} - -enum ARMVER { +// ARM versions +enum { INVALID = 0, ARMALL, ARMV4, diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index e3ca02e98..3be13de0c 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -24,37 +24,25 @@ using namespace std; #include "core/hle/hle.h" enum { - COND = (1 << 0), - NON_BRANCH = (1 << 1), - DIRECT_BRANCH = (1 << 2), + COND = (1 << 0), + NON_BRANCH = (1 << 1), + DIRECT_BRANCH = (1 << 2), INDIRECT_BRANCH = (1 << 3), - CALL = (1 << 4), - RET = (1 << 5), - END_OF_PAGE = (1 << 6), - THUMB = (1 << 7) + CALL = (1 << 4), + RET = (1 << 5), + END_OF_PAGE = (1 << 6), + THUMB = (1 << 7) }; -#define USER_MODE_OPT 1 -#define HYBRID_MODE 0 // Enable for JIT mode - -#define THRESHOLD 1000 -#define DURATION 500 - -#define CHECK_RS if(RS == 15) rs += 8 -#define CHECK_RM if(RM == 15) rm += 8 - -#undef BITS -#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) -#define BIT(s, n) ((s >> (n)) & 1) #define RM BITS(sht_oper, 0, 3) #define RS BITS(sht_oper, 8, 11) -#define glue(x, y) x ## y -#define DPO(s) glue(DataProcessingOperands, s) -#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) -#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) -#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) -#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) +#define glue(x, y) x ## y +#define DPO(s) glue(DataProcessingOperands, s) +#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) +#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) +#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) +#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) #define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) ) @@ -176,13 +164,11 @@ unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned i unsigned int shifter_operand; int shift_imm = BITS(sht_oper, 7, 11); if (shift_imm == 0) { - if (BIT(rm, 31)) { + if (BIT(rm, 31) == 0) shifter_operand = 0; - cpu->shifter_carry_out = BIT(rm, 31); - } else { + else shifter_operand = 0xFFFFFFFF; - cpu->shifter_carry_out = BIT(rm, 31); - } + cpu->shifter_carry_out = BIT(rm, 31); } else { shifter_operand = static_cast<int>(rm) >> shift_imm; cpu->shifter_carry_out = BIT(rm, shift_imm - 1); @@ -412,10 +398,21 @@ void LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, un } break; case 2: - DEBUG_MSG; + if (shift_imm == 0) { // ASR #32 + if (BIT(rm, 31) == 1) + index = 0xFFFFFFFF; + else + index = 0; + } else { + index = static_cast<int>(rm) >> shift_imm; + } break; case 3: - DEBUG_MSG; + if (shift_imm == 0) { + index = (cpu->CFlag << 31) | (rm >> 1); + } else { + index = ROTATE_RIGHT_32(rm, shift_imm); + } break; } @@ -451,10 +448,21 @@ void LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, u } break; case 2: - DEBUG_MSG; + if (shift_imm == 0) { // ASR #32 + if (BIT(rm, 31) == 1) + index = 0xFFFFFFFF; + else + index = 0; + } else { + index = static_cast<int>(rm) >> shift_imm; + } break; case 3: - DEBUG_MSG; + if (shift_imm == 0) { + index = (cpu->CFlag << 31) | (rm >> 1); + } else { + index = ROTATE_RIGHT_32(rm, shift_imm); + } break; } @@ -656,8 +664,8 @@ void LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsign } break; case 2: - if (shift_imm == 0){ // ASR #32 - if (rm >> 31) + if (shift_imm == 0) { // ASR #32 + if (BIT(rm, 31) == 1) index = 0xFFFFFFFF; else index = 0; @@ -666,7 +674,11 @@ void LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsign } break; case 3: - DEBUG_MSG; + if (shift_imm == 0) { + index = (cpu->CFlag << 31) | (rm >> 1); + } else { + index = ROTATE_RIGHT_32(rm, shift_imm); + } break; } @@ -678,9 +690,6 @@ void LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsign virt_addr = addr; } -#define ISNEG(n) (n < 0) -#define ISPOS(n) (n >= 0) - typedef struct _arm_inst { unsigned int idx; unsigned int cond; @@ -1300,15 +1309,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); adc_inst *inst_cream = (adc_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); if (CHECK_RN) inst_base->load_r15 = 1; inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -1323,15 +1332,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); add_inst *inst_cream = (add_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); if (CHECK_RN) inst_base->load_r15 = 1; inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -1346,15 +1355,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); and_inst *inst_cream = (and_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); if (CHECK_RN) inst_base->load_r15 = 1; inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -1371,9 +1380,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); bbl_inst *inst_cream = (bbl_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = DIRECT_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = DIRECT_BRANCH; if (BIT(inst, 24)) inst_base->br = CALL; @@ -1390,15 +1399,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); bic_inst *inst_cream = (bic_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); if (CHECK_RN) inst_base->load_r15 = 1; inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -1414,9 +1423,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); blx_inst *inst_cream = (blx_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = INDIRECT_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = INDIRECT_BRANCH; inst_cream->inst = inst; if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { @@ -1448,17 +1457,18 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); cdp_inst *inst_cream = (cdp_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->CRm = BITS(inst, 0, 3); - inst_cream->CRd = BITS(inst, 12, 15); - inst_cream->CRn = BITS(inst, 16, 19); + inst_cream->CRm = BITS(inst, 0, 3); + inst_cream->CRd = BITS(inst, 12, 15); + inst_cream->CRn = BITS(inst, 16, 19); inst_cream->cp_num = BITS(inst, 8, 11); - inst_cream->opcode_2 = BITS(inst, 5, 7); - inst_cream->opcode_1 = BITS(inst, 20, 23); + inst_cream->opcode_2 = BITS(inst, 5, 7); + inst_cream->opcode_1 = BITS(inst, 20, 23); inst_cream->inst = inst; LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index); @@ -1467,9 +1477,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){ ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) { arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; return inst_base; } @@ -1478,13 +1488,13 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); clz_inst *inst_cream = (clz_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); if (CHECK_RM) inst_base->load_r15 = 1; @@ -1495,15 +1505,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); cmn_inst *inst_cream = (cmn_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - //inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - //inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->Rn = BITS(inst, 16, 19); + if (CHECK_RN) inst_base->load_r15 = 1; inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -1515,13 +1524,13 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); cmp_inst *inst_cream = (cmp_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->I = BIT(inst, 25); + inst_cream->Rn = BITS(inst, 16, 19); if (CHECK_RN) inst_base->load_r15 = 1; inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -1533,16 +1542,16 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); cps_inst *inst_cream = (cps_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->imod0 = BIT(inst, 18); inst_cream->imod1 = BIT(inst, 19); inst_cream->mmod = BIT(inst, 17); - inst_cream->A = BIT(inst, 8); - inst_cream->I = BIT(inst, 7); - inst_cream->F = BIT(inst, 6); + inst_cream->A = BIT(inst, 8); + inst_cream->I = BIT(inst, 7); + inst_cream->F = BIT(inst, 6); inst_cream->mode = BITS(inst, 0, 4); return inst_base; @@ -1552,13 +1561,13 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); mov_inst *inst_cream = (mov_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); @@ -1572,15 +1581,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); eor_inst *inst_cream = (eor_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); if (CHECK_RN) inst_base->load_r15 = 1; inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -1593,9 +1602,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) { arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; return inst_base; } @@ -1605,8 +1614,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -1621,9 +1630,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->Rd = BITS(inst, 12, 15); @@ -1639,9 +1648,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->inst = inst; @@ -1658,9 +1667,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->inst = inst; @@ -1677,9 +1686,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); uxth_inst *inst_cream = (uxth_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->Rd = BITS(inst, 12, 15); @@ -1695,9 +1704,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->Rn = BITS(inst, 16, 19); @@ -1715,8 +1724,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -1728,25 +1737,21 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; - if (I_BIT == 0) { + if (BITS(inst, 25, 27) == 2) { inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); + } else if (BITS(inst, 25, 27) == 3) { + inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed); } else { DEBUG_MSG; } - #if 0 - inst_cream->get_addr = get_calc_addr_op(inst); - if(inst == 0x54f13001) { - DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr); - } - #endif if (BITS(inst, 12, 15) == 15) { inst_base->br = INDIRECT_BRANCH; @@ -1759,8 +1764,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -1799,8 +1804,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -1816,8 +1821,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -1833,8 +1838,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -1846,17 +1851,24 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) } ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; - if (I_BIT == 0) { + if (BITS(inst, 25, 27) == 2) { inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); + } else if (BITS(inst, 25, 27) == 3) { + inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed); } else { + // Reaching this would indicate the thumb version + // of this instruction, however the 3DS CPU doesn't + // support this variant (the 3DS CPU is only ARMv6K, + // while this variant is added in ARMv6T2). + // So it's sufficient for citra to not implement this. DEBUG_MSG; } @@ -1869,9 +1881,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) { arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); mcr_inst *inst_cream = (mcr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->crn = BITS(inst, 16, 19); inst_cream->crm = BITS(inst, 0, 3); @@ -1888,16 +1900,16 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); mla_inst *inst_cream = (mla_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 12, 15); - inst_cream->Rd = BITS(inst, 16, 19); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 12, 15); + inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->Rm = BITS(inst, 0, 3); if (CHECK_RM || CHECK_RN || CHECK_RS) inst_base->load_r15 = 1; @@ -1909,13 +1921,13 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); mov_inst *inst_cream = (mov_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); @@ -1928,9 +1940,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) { arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); mrc_inst *inst_cream = (mrc_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->crn = BITS(inst, 16, 19); inst_cream->crm = BITS(inst, 0, 3); @@ -1947,12 +1959,12 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); mrs_inst *inst_cream = (mrs_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->R = BIT(inst, 22); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->R = BIT(inst, 22); return inst_base; } @@ -1961,9 +1973,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); msr_inst *inst_cream = (msr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->field_mask = BITS(inst, 16, 19); inst_cream->R = BIT(inst, 22); @@ -1976,15 +1988,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); mul_inst *inst_cream = (mul_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->Rd = BITS(inst, 16, 19); if (CHECK_RM || CHECK_RS) inst_base->load_r15 = 1; @@ -1995,13 +2007,13 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); mvn_inst *inst_cream = (mvn_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); @@ -2016,15 +2028,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); orr_inst *inst_cream = (orr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rn = BITS(inst, 16, 19); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); @@ -2063,9 +2075,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) { arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; return inst_base; @@ -2172,15 +2184,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); rsb_inst *inst_cream = (rsb_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); if (CHECK_RN) @@ -2196,15 +2208,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); rsc_inst *inst_cream = (rsc_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); if (CHECK_RN) @@ -2259,15 +2271,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); sbc_inst *inst_cream = (sbc_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); if (CHECK_RN) @@ -2343,15 +2355,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); smla_inst *inst_cream = (smla_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->x = BIT(inst, 5); - inst_cream->y = BIT(inst, 6); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->x = BIT(inst, 5); + inst_cream->y = BIT(inst, 6); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); inst_cream->Rd = BITS(inst, 16, 19); inst_cream->Rn = BITS(inst, 12, 15); @@ -2396,14 +2408,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); umlal_inst *inst_cream = (umlal_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); inst_cream->RdHi = BITS(inst, 16, 19); inst_cream->RdLo = BITS(inst, 12, 15); @@ -2510,9 +2522,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); smul_inst *inst_cream = (smul_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->Rd = BITS(inst, 16, 19); @@ -2532,14 +2544,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); umull_inst *inst_cream = (umull_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); inst_cream->RdHi = BITS(inst, 16, 19); inst_cream->RdLo = BITS(inst, 12, 15); @@ -2553,14 +2565,14 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); smlad_inst *inst_cream = (smlad_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->m = BIT(inst, 6); - inst_cream->Rm = BITS(inst, 8, 11); - inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->m = BIT(inst, 6); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); inst_cream->Rd = BITS(inst, 16, 19); if (CHECK_RM || CHECK_RN) @@ -2606,9 +2618,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) { arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; return inst_base; } @@ -2618,8 +2630,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -2630,9 +2642,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->Rd = BITS(inst, 12, 15); @@ -2649,8 +2661,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -2665,9 +2677,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); uxth_inst *inst_cream = (uxth_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->Rd = BITS(inst, 12, 15); @@ -2683,9 +2695,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->Rd = BITS(inst, 12, 15); @@ -2701,8 +2713,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -2714,17 +2726,19 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) } ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; -// inst_cream->get_addr = get_calc_addr_op(inst); - if (I_BIT == 0) { + + if (BITS(inst, 25, 27) == 2) { inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); + } else if (BITS(inst, 25, 27) == 3) { + inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed); } else { DEBUG_MSG; } @@ -2739,8 +2753,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -2783,8 +2797,8 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = get_calc_addr_op(inst); @@ -2796,17 +2810,24 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) } ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_cream->inst = inst; - if (I_BIT == 0) { + if (BITS(inst, 25, 27) == 2) { inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed); + } else if (BITS(inst, 25, 27) == 3) { + inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed); } else { + // Reaching this would indicate the thumb version + // of this instruction, however the 3DS CPU doesn't + // support this variant (the 3DS CPU is only ARMv6K, + // while this variant is added in ARMv6T2). + // So it's sufficient for citra to not implement this. DEBUG_MSG; } @@ -2820,15 +2841,15 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); sub_inst *inst_cream = (sub_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = get_shtop(inst); if (inst_cream->Rd == 15) { @@ -3089,9 +3110,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); umlal_inst *inst_cream = (umlal_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->S = BIT(inst, 20); @@ -3131,10 +3152,10 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; - inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); + inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); - inst_base->idx = index; - inst_base->br = DIRECT_BRANCH; + inst_base->idx = index; + inst_base->br = DIRECT_BRANCH; return inst_base; } @@ -3144,10 +3165,10 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; - inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); - inst_cream->cond = ((tinst >> 8) & 0xf); - inst_base->idx = index; - inst_base->br = DIRECT_BRANCH; + inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); + inst_cream->cond = ((tinst >> 8) & 0xf); + inst_base->idx = index; + inst_base->br = DIRECT_BRANCH; return inst_base; } @@ -3157,10 +3178,10 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; - inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); + inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->idx = index; + inst_base->br = NON_BRANCH; return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) @@ -3168,10 +3189,10 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; - inst_cream->imm = (tinst & 0x07FF) << 1; + inst_cream->imm = (tinst & 0x07FF) << 1; - inst_base->idx = index; - inst_base->br = DIRECT_BRANCH; + inst_base->idx = index; + inst_base->br = DIRECT_BRANCH; return inst_base; } ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) @@ -3497,7 +3518,6 @@ void insert_bb(unsigned int addr, int start) { CreamCache[addr] = start; } -#define TRANS_THRESHOLD 65000 int find_bb(unsigned int addr, int &start) { int ret = -1; bb_map::const_iterator it = CreamCache.find(addr); @@ -3533,7 +3553,6 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr case 26: case 27: if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ - u32 cond = (tinstr & 0x0F00) >> 8; inst_index = table_length - 4; *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); } else { @@ -3673,6 +3692,9 @@ static bool InAPrivilegedMode(arm_core_t *core) { } unsigned InterpreterMainLoop(ARMul_State* state) { + #undef RM + #undef RS + #define CRn inst_cream->crn #define OPCODE_2 inst_cream->opcode_2 #define CRm inst_cream->crm @@ -3905,21 +3927,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } #endif - #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) - #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) - - #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop))) - #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) ) - #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag))) - #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop)) - #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop)) - #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out) - - #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \ - ((lop >= 0) && (rop) >= 0 && (dst < 0)))) - #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \ - ((lop >= 0) && (rop) >= 0 && (dst < 0)))) - #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31)) + #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) + #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) + #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out) #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \ (cpu->NFlag << 31) | \ @@ -3967,16 +3977,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) { &&INIT_INST_LENGTH,&&END }; #endif - arm_inst * inst_base; - unsigned int lop, rop, dst; + arm_inst* inst_base; unsigned int addr; unsigned int phys_addr; - unsigned int last_pc = 0; unsigned int num_instrs = 0; - static unsigned int last_physical_base = 0, last_logical_base = 0; int ptr; - bool single_step = (cpu->NumInstrsToExecute == 1); LOAD_NZCVT; DISPATCH: @@ -4003,12 +4009,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } ADC_INST: { - adc_inst *inst_cream = (adc_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - unsigned int sht_op = SHIFTER_OPERAND; - rop = SHIFTER_OPERAND + cpu->CFlag; - RD = dst = lop + rop; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + adc_inst* const inst_cream = (adc_inst*)inst_base->component; + + bool carry; + bool overflow; + RD = AddWithCarry(RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); + if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -4016,10 +4023,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag); - UPDATE_VFLAG((int)dst, (int)lop, (int)rop); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; } if (inst_cream->Rd == 15) { INC_PC(sizeof(adc_inst)); @@ -4033,14 +4040,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } ADD_INST: { - add_inst *inst_cream = (add_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - if (inst_cream->Rn == 15) { - lop += 2 * GET_INST_SIZE(cpu); - } - rop = SHIFTER_OPERAND; - RD = dst = lop + rop; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + add_inst* const inst_cream = (add_inst*)inst_base->component; + + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 2 * GET_INST_SIZE(cpu); + + bool carry; + bool overflow; + RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow); + if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -4048,10 +4058,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG(dst, lop, rop); - UPDATE_VFLAG((int)dst, (int)lop, (int)rop); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; } if (inst_cream->Rd == 15) { INC_PC(sizeof(add_inst)); @@ -4067,9 +4077,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { { and_inst *inst_cream = (and_inst *)inst_base->component; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - rop = SHIFTER_OPERAND; - RD = dst = lop & rop; + u32 lop = RN; + u32 rop = SHIFTER_OPERAND; + RD = lop & rop; if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -4077,8 +4087,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); UPDATE_CFLAG_WITH_SC; } if (inst_cream->Rd == 15) { @@ -4110,12 +4120,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) { { bic_inst *inst_cream = (bic_inst *)inst_base->component; if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; + u32 lop = RN; if (inst_cream->Rn == 15) { lop += 2 * GET_INST_SIZE(cpu); } - rop = SHIFTER_OPERAND; - RD = dst = lop & (~rop); + u32 rop = SHIFTER_OPERAND; + RD = lop & (~rop); if ((inst_cream->S) && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -4123,8 +4133,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); UPDATE_CFLAG_WITH_SC; } if (inst_cream->Rd == 15) { @@ -4153,7 +4163,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); cpu->TFlag = 0x1; int signed_int = inst_cream->val.signed_immed_24; - signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int; + signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int; signed_int = signed_int << 2; cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1); } @@ -4173,8 +4183,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { // // According to the ARM documentation on BXJ, if setting the J bit in the APSR // fails, then BXJ functions identically like a regular BX instruction. - // - // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle. + // + // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle. if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { bx_inst* const inst_cream = (bx_inst*)inst_base->component; @@ -4195,8 +4205,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { CDP_INST: { - cdp_inst *inst_cream = (cdp_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { // Undefined instruction here cpu->NumInstrsToExecute = 0; return num_instrs; @@ -4219,8 +4228,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } CLZ_INST: { - clz_inst *inst_cream = (clz_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + clz_inst* inst_cream = (clz_inst*)inst_base->component; RD = clz(RM); } cpu->Reg[15] += GET_INST_SIZE(cpu); @@ -4230,15 +4239,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } CMN_INST: { - cmn_inst *inst_cream = (cmn_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - rop = SHIFTER_OPERAND; - dst = lop + rop; - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG(dst, lop, rop); - UPDATE_VFLAG((int)dst, (int)lop, (int)rop); + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + cmn_inst* const inst_cream = (cmn_inst*)inst_base->component; + + bool carry; + bool overflow; + u32 result = AddWithCarry(RN, SHIFTER_OPERAND, 0, &carry, &overflow); + + UPDATE_NFLAG(result); + UPDATE_ZFLAG(result); + cpu->CFlag = carry; + cpu->VFlag = overflow; } cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(cmn_inst)); @@ -4247,19 +4258,21 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } CMP_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - cmp_inst *inst_cream = (cmp_inst *)inst_base->component; - lop = RN; - if (inst_cream->Rn == 15) { - lop += 2 * GET_INST_SIZE(cpu); - } - rop = SHIFTER_OPERAND; - dst = lop - rop; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + cmp_inst* const inst_cream = (cmp_inst*)inst_base->component; - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); - UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 2 * GET_INST_SIZE(cpu); + + bool carry; + bool overflow; + u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow); + + UPDATE_NFLAG(result); + UPDATE_ZFLAG(result); + cpu->CFlag = carry; + cpu->VFlag = overflow; } cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(cmp_inst)); @@ -4300,10 +4313,11 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } CPY_INST: { - mov_inst *inst_cream = (mov_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + mov_inst* inst_cream = (mov_inst*)inst_base->component; + RD = SHIFTER_OPERAND; - if ((inst_cream->Rd == 15)) { + if (inst_cream->Rd == 15) { INC_PC(sizeof(mov_inst)); goto DISPATCH; } @@ -4315,14 +4329,15 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } EOR_INST: { - eor_inst *inst_cream = (eor_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + eor_inst* inst_cream = (eor_inst*)inst_base->component; + + u32 lop = RN; if (inst_cream->Rn == 15) { lop += 2 * GET_INST_SIZE(cpu); } - rop = SHIFTER_OPERAND; - RD = dst = lop ^ rop; + u32 rop = SHIFTER_OPERAND; + RD = lop ^ rop; if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -4330,8 +4345,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); UPDATE_CFLAG_WITH_SC; } if (inst_cream->Rd == 15) { @@ -4355,8 +4370,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDM_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); unsigned int inst = inst_cream->inst; @@ -4425,8 +4440,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } SXTH_INST: { - sxth_inst *inst_cream = (sxth_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + sxth_inst* inst_cream = (sxth_inst*)inst_base->component; + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); if (BIT(operand2, 15)) { operand2 |= 0xffff0000; @@ -4470,9 +4486,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDRCOND_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; if (CondPassed(cpu, inst_base->cond)) { + ldst_inst *inst_cream = (ldst_inst *)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); + unsigned int value = Memory::Read32(addr); if (BIT(CP15_REG(CP15_CONTROL), 22) == 1) cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; @@ -4496,11 +4513,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } UXTH_INST: { - uxth_inst *inst_cream = (uxth_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) - & 0xffff; - RD = operand2; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + uxth_inst* inst_cream = (uxth_inst*)inst_base->component; + RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; } cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(uxth_inst)); @@ -4509,10 +4524,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } UXTAH_INST: { - uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) - & 0xffff; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component; + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; + RD = RN + operand2; if (inst_cream->Rn == 15 || inst_cream->Rm == 15) { LOG_ERROR(Core_ARM11, "invalid operands for UXTAH"); @@ -4526,9 +4541,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDRB_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read8(addr); if (BITS(inst_cream->inst, 12, 15) == 15) { @@ -4543,9 +4559,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDRBT_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read8(addr); if (BITS(inst_cream->inst, 12, 15) == 15) { @@ -4560,8 +4577,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDRD_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); @@ -4578,8 +4595,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LDREX_INST: { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; unsigned int read_addr = RN; add_exclusive_addr(cpu, read_addr); @@ -4598,8 +4615,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDREXB_INST: { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; unsigned int read_addr = RN; add_exclusive_addr(cpu, read_addr); @@ -4618,8 +4635,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDREXH_INST: { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; unsigned int read_addr = RN; add_exclusive_addr(cpu, read_addr); @@ -4638,8 +4655,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDREXD_INST: { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; unsigned int read_addr = RN; add_exclusive_addr(cpu, read_addr); @@ -4660,8 +4677,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDRH_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read16(addr); if (BITS(inst_cream->inst, 12, 15) == 15) { @@ -4676,8 +4693,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDRSB_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); unsigned int value = Memory::Read8(addr); if (BIT(value, 7)) { @@ -4696,8 +4713,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDRSH_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); unsigned int value = Memory::Read16(addr); if (BIT(value, 15)) { @@ -4716,9 +4733,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } LDRT_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); + unsigned int value = Memory::Read32(addr); cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; @@ -4739,8 +4757,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } MCR_INST: { - mcr_inst *inst_cream = (mcr_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + mcr_inst* inst_cream = (mcr_inst*)inst_base->component; + unsigned int inst = inst_cream->inst; if (inst_cream->Rd == 15) { DEBUG_MSG; @@ -4839,8 +4858,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { MCRR_INST: MLA_INST: { - mla_inst *inst_cream = (mla_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + mla_inst* inst_cream = (mla_inst*)inst_base->component; + uint64_t rm = RM; uint64_t rs = RS; uint64_t rn = RN; @@ -4848,10 +4868,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOG_ERROR(Core_ARM11, "invalid operands for MLA"); CITRA_IGNORE_EXIT(-1); } - RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); + RD = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); } if (inst_cream->Rd == 15) { INC_PC(sizeof(mla_inst)); @@ -4865,9 +4885,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } MOV_INST: { - mov_inst *inst_cream = (mov_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - RD = dst = SHIFTER_OPERAND; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + mov_inst* inst_cream = (mov_inst*)inst_base->component; + + RD = SHIFTER_OPERAND; if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -4875,8 +4896,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); UPDATE_CFLAG_WITH_SC; } if (inst_cream->Rd == 15) { @@ -4891,8 +4912,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } MRC_INST: { - mrc_inst *inst_cream = (mrc_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + mrc_inst* inst_cream = (mrc_inst*)inst_base->component; + unsigned int inst = inst_cream->inst; if (inst_cream->Rd == 15) { DEBUG_MSG; @@ -4948,8 +4970,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { MRRC_INST: MRS_INST: { - mrs_inst *inst_cream = (mrs_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + mrs_inst* inst_cream = (mrs_inst*)inst_base->component; + if (inst_cream->R) { RD = cpu->Spsr_copy; } else { @@ -4964,39 +4987,41 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } MSR_INST: { - msr_inst *inst_cream = (msr_inst *)inst_base->component; - const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; - unsigned int inst = inst_cream->inst; - unsigned int operand; - - if (BIT(inst, 25)) { - int rot_imm = BITS(inst, 8, 11) * 2; - operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); - } else { - operand = cpu->Reg[BITS(inst, 0, 3)]; - } - uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) - | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); - uint32_t mask; - if (!inst_cream->R) { - if (InAPrivilegedMode(cpu)) { - if ((operand & StateMask) != 0) { - /// UNPREDICTABLE - DEBUG_MSG; - } else - mask = byte_mask & (UserMask | PrivMask); + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + msr_inst* inst_cream = (msr_inst*)inst_base->component; + const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; + unsigned int inst = inst_cream->inst; + unsigned int operand; + + if (BIT(inst, 25)) { + int rot_imm = BITS(inst, 8, 11) * 2; + operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); } else { - mask = byte_mask & UserMask; + operand = cpu->Reg[BITS(inst, 0, 3)]; } - SAVE_NZCVT; + uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) + | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); + uint32_t mask = 0; + if (!inst_cream->R) { + if (InAPrivilegedMode(cpu)) { + if ((operand & StateMask) != 0) { + /// UNPREDICTABLE + DEBUG_MSG; + } else + mask = byte_mask & (UserMask | PrivMask); + } else { + mask = byte_mask & UserMask; + } + SAVE_NZCVT; - cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); - switch_mode(cpu, cpu->Cpsr & 0x1f); - LOAD_NZCVT; - } else { - if (CurrentModeHasSPSR) { - mask = byte_mask & (UserMask | PrivMask | StateMask); - cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); + cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); + switch_mode(cpu, cpu->Cpsr & 0x1f); + LOAD_NZCVT; + } else { + if (CurrentModeHasSPSR) { + mask = byte_mask & (UserMask | PrivMask | StateMask); + cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); + } } } cpu->Reg[15] += GET_INST_SIZE(cpu); @@ -5006,14 +5031,15 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } MUL_INST: { - mul_inst *inst_cream = (mul_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + mul_inst* inst_cream = (mul_inst*)inst_base->component; + uint64_t rm = RM; uint64_t rs = RS; - RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff); + RD = static_cast<uint32_t>((rm * rs) & 0xffffffff); if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); } if (inst_cream->Rd == 15) { INC_PC(sizeof(mul_inst)); @@ -5027,9 +5053,11 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } MVN_INST: { - mvn_inst *inst_cream = (mvn_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - RD = dst = ~SHIFTER_OPERAND; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + mvn_inst* const inst_cream = (mvn_inst*)inst_base->component; + + RD = ~SHIFTER_OPERAND; + if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -5037,8 +5065,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); UPDATE_CFLAG_WITH_SC; } if (inst_cream->Rd == 15) { @@ -5053,11 +5081,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } ORR_INST: { - orr_inst *inst_cream = (orr_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - rop = SHIFTER_OPERAND; - RD = dst = lop | rop; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + orr_inst* const inst_cream = (orr_inst*)inst_base->component; + + u32 lop = RN; + u32 rop = SHIFTER_OPERAND; + RD = lop | rop; + if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -5065,8 +5095,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); UPDATE_CFLAG_WITH_SC; } if (inst_cream->Rd == 15) { @@ -5286,14 +5316,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) { RFE_INST: RSB_INST: { - rsb_inst *inst_cream = (rsb_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - rop = RN; - lop = SHIFTER_OPERAND; - if (inst_cream->Rn == 15) { - rop += 2 * GET_INST_SIZE(cpu);; - } - RD = dst = lop - rop; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + rsb_inst* const inst_cream = (rsb_inst*)inst_base->component; + + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 2 * GET_INST_SIZE(cpu); + + bool carry; + bool overflow; + RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow); + if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -5301,10 +5334,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); - UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; } if (inst_cream->Rd == 15) { INC_PC(sizeof(rsb_inst)); @@ -5318,11 +5351,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } RSC_INST: { - rsc_inst *inst_cream = (rsc_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - rop = SHIFTER_OPERAND; - RD = dst = rop - lop - !cpu->CFlag; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + rsc_inst* const inst_cream = (rsc_inst*)inst_base->component; + + bool carry; + bool overflow; + RD = AddWithCarry(~RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); + if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -5330,10 +5365,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag); - UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; } if (inst_cream->Rd == 15) { INC_PC(sizeof(rsc_inst)); @@ -5456,11 +5491,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) { SBC_INST: { - sbc_inst *inst_cream = (sbc_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = SHIFTER_OPERAND + !cpu->CFlag; - rop = RN; - RD = dst = rop - lop; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + sbc_inst* const inst_cream = (sbc_inst*)inst_base->component; + + bool carry; + bool overflow; + RD = AddWithCarry(RN, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); + if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -5468,15 +5505,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - - if(rop >= !cpu->CFlag) - UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND); - else - UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag); - - UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; } if (inst_cream->Rd == 15) { INC_PC(sizeof(sbc_inst)); @@ -5604,8 +5636,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { SMLA_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - smla_inst *inst_cream = (smla_inst *)inst_base->component; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + smla_inst* inst_cream = (smla_inst*)inst_base->component; int32_t operand1, operand2; if (inst_cream->x == 0) operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); @@ -5685,8 +5717,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { SMLAL_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - umlal_inst *inst_cream = (umlal_inst *)inst_base->component; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + umlal_inst* inst_cream = (umlal_inst*)inst_base->component; long long int rm = RM; long long int rs = RS; if (BIT(rm, 31)) { @@ -5843,8 +5875,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { SMUL_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - smul_inst *inst_cream = (smul_inst *)inst_base->component; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + smul_inst* inst_cream = (smul_inst*)inst_base->component; uint32_t operand1, operand2; if (inst_cream->x == 0) operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); @@ -5864,8 +5896,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } SMULL_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - umull_inst *inst_cream = (umull_inst *)inst_base->component; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + umull_inst* inst_cream = (umull_inst*)inst_base->component; int64_t rm = RM; int64_t rs = RS; if (BIT(rm, 31)) { @@ -5973,9 +6005,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STM_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - unsigned int inst = inst_cream->inst; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + unsigned int inst = inst_cream->inst; + int i; unsigned int Rn = BITS(inst, 16, 19); unsigned int old_RN = cpu->Reg[Rn]; @@ -6033,8 +6066,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } SXTB_INST: { - sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component; + if (inst_cream->Rm == 15) { LOG_ERROR(Core_ARM11, "invalid operand for SXTB"); CITRA_IGNORE_EXIT(-1); @@ -6053,9 +6087,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STR_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; Memory::Write32(addr, value); } @@ -6066,11 +6101,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } UXTB_INST: { - uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) - & 0xff; - RD = operand2; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component; + RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; } cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(uxtb_inst)); @@ -6079,10 +6112,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } UXTAB_INST: { - uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) - & 0xff; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component; + + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; RD = RN + operand2; } cpu->Reg[15] += GET_INST_SIZE(cpu); @@ -6092,8 +6125,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STRB_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; Memory::Write8(addr, value); @@ -6105,8 +6138,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STRBT_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; Memory::Write8(addr, value); @@ -6118,8 +6151,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STRD_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; @@ -6134,9 +6167,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STREX_INST: { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; unsigned int write_addr = cpu->Reg[inst_cream->Rn]; if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { @@ -6157,9 +6189,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STREXB_INST: { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; unsigned int write_addr = cpu->Reg[inst_cream->Rn]; if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { @@ -6180,9 +6211,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STREXD_INST: { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; unsigned int write_addr = cpu->Reg[inst_cream->Rn]; if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { @@ -6205,9 +6235,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STREXH_INST: { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; unsigned int write_addr = cpu->Reg[inst_cream->Rn]; if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { @@ -6228,9 +6257,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STRH_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; Memory::Write16(addr, value); } @@ -6241,9 +6271,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } STRT_INST: { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; Memory::Write32(addr, value); } @@ -6254,14 +6285,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } SUB_INST: { - sub_inst *inst_cream = (sub_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - lop = RN; - if (inst_cream->Rn == 15) { - lop += 8; - } - rop = SHIFTER_OPERAND; - RD = dst = lop - rop; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + sub_inst* const inst_cream = (sub_inst*)inst_base->component; + + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 8; + + bool carry; + bool overflow; + RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow); + if (inst_cream->S && (inst_cream->Rd == 15)) { if (CurrentModeHasSPSR) { cpu->Cpsr = cpu->Spsr_copy; @@ -6269,10 +6303,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { LOAD_NZCVT; } } else if (inst_cream->S) { - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); - UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); - UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; } if (inst_cream->Rd == 15) { INC_PC(sizeof(sub_inst)); @@ -6286,10 +6320,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } SWI_INST: { - swi_inst *inst_cream = (swi_inst *)inst_base->component; - - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { HLE::CallSVC(Memory::Read32(cpu->Reg[15])); + } cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(swi_inst)); @@ -6298,8 +6331,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } SWP_INST: { - swp_inst *inst_cream = (swp_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + swp_inst* inst_cream = (swp_inst*)inst_base->component; + addr = RN; unsigned int value; value = Memory::Read32(addr); @@ -6314,8 +6348,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } SWPB_INST: { - swp_inst *inst_cream = (swp_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + swp_inst* inst_cream = (swp_inst*)inst_base->component; addr = RN; unsigned int value = Memory::Read8(addr); Memory::Write8(addr, (RM & 0xFF)); @@ -6328,8 +6362,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } SXTAB_INST: { - sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component; + // R15 should be check if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){ CITRA_IGNORE_EXIT(-1); @@ -6381,8 +6416,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { SXTAH_INST: { - sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component; + // R15 should be check if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15) { CITRA_IGNORE_EXIT(-1); @@ -6400,18 +6436,19 @@ unsigned InterpreterMainLoop(ARMul_State* state) { TEQ_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - teq_inst *inst_cream = (teq_inst *)inst_base->component; - lop = RN; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + teq_inst* const inst_cream = (teq_inst*)inst_base->component; + + u32 lop = RN; + u32 rop = SHIFTER_OPERAND; if (inst_cream->Rn == 15) lop += GET_INST_SIZE(cpu) * 2; - rop = SHIFTER_OPERAND; - dst = lop ^ rop; + u32 result = lop ^ rop; - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(result); + UPDATE_ZFLAG(result); UPDATE_CFLAG_WITH_SC; } cpu->Reg[15] += GET_INST_SIZE(cpu); @@ -6421,18 +6458,19 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } TST_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - tst_inst *inst_cream = (tst_inst *)inst_base->component; - lop = RN; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + tst_inst* const inst_cream = (tst_inst*)inst_base->component; + + u32 lop = RN; + u32 rop = SHIFTER_OPERAND; if (inst_cream->Rn == 15) lop += GET_INST_SIZE(cpu) * 2; - rop = SHIFTER_OPERAND; - dst = lop & rop; + u32 result = lop & rop; - UPDATE_NFLAG(dst); - UPDATE_ZFLAG(dst); + UPDATE_NFLAG(result); + UPDATE_ZFLAG(result); UPDATE_CFLAG_WITH_SC; } cpu->Reg[15] += GET_INST_SIZE(cpu); @@ -6712,8 +6750,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } UMLAL_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - umlal_inst *inst_cream = (umlal_inst *)inst_base->component; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + umlal_inst* inst_cream = (umlal_inst*)inst_base->component; unsigned long long int rm = RM; unsigned long long int rs = RS; unsigned long long int rst = rm * rs; @@ -6735,8 +6773,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } UMULL_INST: { - if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { - umull_inst *inst_cream = (umull_inst *)inst_base->component; + if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { + umull_inst* inst_cream = (umull_inst*)inst_base->component; unsigned long long int rm = RM; unsigned long long int rs = RS; unsigned long long int rst = rm * rs; @@ -6755,14 +6793,14 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } B_2_THUMB: { - b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; + b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component; cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; INC_PC(sizeof(b_2_thumb)); goto DISPATCH; } B_COND_THUMB: { - b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; + b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component; if(CondPassed(cpu, inst_cream->cond)) cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; @@ -6774,7 +6812,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } BL_1_THUMB: { - bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; + bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component; cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(bl_1_thumb)); @@ -6783,7 +6821,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { } BL_2_THUMB: { - bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; + bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component; int tmp = ((cpu->Reg[15] + 2) | 1); cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm); cpu->Reg[14] = tmp; @@ -6794,7 +6832,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { { // BLX 1 for armv5t and above u32 tmp = cpu->Reg[15]; - blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; + blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component; cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; cpu->Reg[14] = ((tmp + 2) | 1); cpu->TFlag = 0; diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h index c70522274..b1c0daaf7 100644 --- a/src/core/arm/dyncom/arm_dyncom_run.h +++ b/src/core/arm/dyncom/arm_dyncom_run.h @@ -16,10 +16,7 @@ * */ -#ifndef __ARM_DYNCOM_RUN__ -#define __ARM_DYNCOM_RUN__ - -#include "core/arm/skyeye_common/skyeye_types.h" +#pragma once void switch_mode(arm_core_t *core, uint32_t mode); @@ -51,5 +48,3 @@ static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn) { static inline u32 CHECK_READ_REG15(arm_core_t* core, int Rn) { return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; } - -#endif diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h index bf69b2fd4..a1785abb8 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.h +++ b/src/core/arm/dyncom/arm_dyncom_thumb.h @@ -24,11 +24,9 @@ * @date 2011-11-07 */ -#ifndef __ARM_DYNCOM_THUMB_H__ -#define __ARM_DYNCOM_THUMB_H__ +#pragma once #include "core/arm/skyeye_common/armdefs.h" -#include "core/arm/skyeye_common/skyeye_types.h" enum tdstate { t_undefined, // Undefined Thumb instruction @@ -47,5 +45,3 @@ static inline u32 get_thumb_instr(u32 instr, addr_t pc) { tinstr = instr & 0xFFFF; return tinstr; } - -#endif diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp deleted file mode 100644 index c76d371a2..000000000 --- a/src/core/arm/interpreter/arm_interpreter.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "core/arm/interpreter/arm_interpreter.h" - -#include "core/core.h" - -const static cpu_config_t arm11_cpu_info = { - "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE -}; - -ARM_Interpreter::ARM_Interpreter() { - state = new ARMul_State; - - ARMul_EmulateInit(); - memset(state, 0, sizeof(ARMul_State)); - - ARMul_NewState(state); - - state->abort_model = 0; - state->cpu = (cpu_config_t*)&arm11_cpu_info; - state->bigendSig = LOW; - - ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); - state->lateabtSig = LOW; - - // Reset the core to initial state - ARMul_CoProInit(state); - ARMul_Reset(state); - state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext - state->Emulate = 3; - - state->pc = state->Reg[15] = 0x00000000; - state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack - state->servaddr = 0xFFFF0000; -} - -ARM_Interpreter::~ARM_Interpreter() { - delete state; -} - -void ARM_Interpreter::SetPC(u32 pc) { - state->pc = state->Reg[15] = pc; -} - -u32 ARM_Interpreter::GetPC() const { - return state->pc; -} - -u32 ARM_Interpreter::GetReg(int index) const { - return state->Reg[index]; -} - -void ARM_Interpreter::SetReg(int index, u32 value) { - state->Reg[index] = value; -} - -u32 ARM_Interpreter::GetCPSR() const { - return state->Cpsr; -} - -void ARM_Interpreter::SetCPSR(u32 cpsr) { - state->Cpsr = cpsr; -} - -u64 ARM_Interpreter::GetTicks() const { - return state->NumInstrs; -} - -void ARM_Interpreter::AddTicks(u64 ticks) { - state->NumInstrs += ticks; -} - -void ARM_Interpreter::ExecuteInstructions(int num_instructions) { - state->NumInstrsToExecute = num_instructions - 1; - ARMul_Emulate32(state); -} - -void ARM_Interpreter::SaveContext(Core::ThreadContext& ctx) { - memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); - memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); - - ctx.sp = state->Reg[13]; - ctx.lr = state->Reg[14]; - ctx.pc = state->pc; - ctx.cpsr = state->Cpsr; - - ctx.fpscr = state->VFP[1]; - ctx.fpexc = state->VFP[2]; - - ctx.reg_15 = state->Reg[15]; - ctx.mode = state->NextInstr; -} - -void ARM_Interpreter::LoadContext(const Core::ThreadContext& ctx) { - memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); - memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); - - state->Reg[13] = ctx.sp; - state->Reg[14] = ctx.lr; - state->pc = ctx.pc; - state->Cpsr = ctx.cpsr; - - state->VFP[1] = ctx.fpscr; - state->VFP[2] = ctx.fpexc; - - state->Reg[15] = ctx.reg_15; - state->NextInstr = ctx.mode; -} - -void ARM_Interpreter::PrepareReschedule() { - state->NumInstrsToExecute = 0; -} diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h deleted file mode 100644 index e5ecc69c2..000000000 --- a/src/core/arm/interpreter/arm_interpreter.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "common/common.h" - -#include "core/arm/arm_interface.h" -#include "core/arm/skyeye_common/armdefs.h" -#include "core/arm/skyeye_common/armemu.h" - -class ARM_Interpreter final : virtual public ARM_Interface { -public: - - ARM_Interpreter(); - ~ARM_Interpreter(); - - /** - * Set the Program Counter to an address - * @param pc Address to set PC to - */ - void SetPC(u32 pc) override; - - /* - * Get the current Program Counter - * @return Returns current PC - */ - u32 GetPC() const override; - - /** - * Get an ARM register - * @param index Register index (0-15) - * @return Returns the value in the register - */ - u32 GetReg(int index) const override; - - /** - * Set an ARM register - * @param index Register index (0-15) - * @param value Value to set register to - */ - void SetReg(int index, u32 value) override; - - /** - * Get the current CPSR register - * @return Returns the value of the CPSR register - */ - u32 GetCPSR() const override; - - /** - * Set the current CPSR register - * @param cpsr Value to set CPSR to - */ - void SetCPSR(u32 cpsr) override; - - /** - * Returns the number of clock ticks since the last reset - * @return Returns number of clock ticks - */ - u64 GetTicks() const override; - - /** - * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time) - * @param ticks Number of ticks to advance the CPU core - */ - void AddTicks(u64 ticks) override; - - /** - * Saves the current CPU context - * @param ctx Thread context to save - */ - void SaveContext(Core::ThreadContext& ctx) override; - - /** - * Loads a CPU context - * @param ctx Thread context to load - */ - void LoadContext(const Core::ThreadContext& ctx) override; - - /// Prepare core for thread reschedule (if needed to correctly handle state) - void PrepareReschedule() override; - -protected: - - /** - * Executes the given number of instructions - * @param num_instructions Number of instructions to executes - */ - void ExecuteInstructions(int num_instructions) override; - -private: - - ARMul_State* state; - -}; diff --git a/src/core/arm/interpreter/armcopro.cpp b/src/core/arm/interpreter/armcopro.cpp index b4ddc3d96..bb9ca98fe 100644 --- a/src/core/arm/interpreter/armcopro.cpp +++ b/src/core/arm/interpreter/armcopro.cpp @@ -19,213 +19,45 @@ #include "core/arm/skyeye_common/armemu.h" #include "core/arm/skyeye_common/vfp/vfp.h" -//chy 2005-07-08 -//#include "ansidecl.h" -//chy ------- -//#include "iwmmxt.h" +// Dummy Co-processors. -/* Dummy Co-processors. */ - -static unsigned -NoCoPro3R(ARMul_State * state, -unsigned a, ARMword b) +static unsigned int NoCoPro3R(ARMul_State* state, unsigned int a, ARMword b) { return ARMul_CANT; } -static unsigned -NoCoPro4R(ARMul_State * state, -unsigned a, -ARMword b, ARMword c) +static unsigned int NoCoPro4R(ARMul_State* state, unsigned int a, ARMword b, ARMword c) { return ARMul_CANT; } -static unsigned -NoCoPro4W(ARMul_State * state, -unsigned a, -ARMword b, ARMword * c) +static unsigned int NoCoPro4W(ARMul_State* state, unsigned int a, ARMword b, ARMword* c) { return ARMul_CANT; } -static unsigned -NoCoPro5R(ARMul_State * state, -unsigned a, -ARMword b, -ARMword c, ARMword d) +static unsigned int NoCoPro5R(ARMul_State* state, unsigned int a, ARMword b, ARMword c, ARMword d) { return ARMul_CANT; } -static unsigned -NoCoPro5W(ARMul_State * state, -unsigned a, -ARMword b, -ARMword * c, ARMword * d) +static unsigned int NoCoPro5W(ARMul_State* state, unsigned int a, ARMword b, ARMword* c, ARMword* d) { return ARMul_CANT; } -/* The XScale Co-processors. */ - -/* Coprocessor 15: System Control. */ -static void write_cp14_reg(unsigned, ARMword); -static ARMword read_cp14_reg(unsigned); - -/* Check an access to a register. */ - -static unsigned -check_cp15_access(ARMul_State * state, -unsigned reg, -unsigned CRm, unsigned opcode_1, unsigned opcode_2) -{ - /* Do not allow access to these register in USER mode. */ - //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode - if (state->Mode == USER26MODE || state->Mode == USER32MODE) - return ARMul_CANT; - - /* Opcode_1should be zero. */ - if (opcode_1 != 0) - return ARMul_CANT; - - /* Different register have different access requirements. */ - switch (reg) { - case 0: - case 1: - /* CRm must be 0. Opcode_2 can be anything. */ - if (CRm != 0) - return ARMul_CANT; - break; - case 2: - case 3: - /* CRm must be 0. Opcode_2 must be zero. */ - if ((CRm != 0) || (opcode_2 != 0)) - return ARMul_CANT; - break; - case 4: - /* Access not allowed. */ - return ARMul_CANT; - case 5: - case 6: - /* Opcode_2 must be zero. CRm must be 0. */ - if ((CRm != 0) || (opcode_2 != 0)) - return ARMul_CANT; - break; - case 7: - /* Permissable combinations: - Opcode_2 CRm - 0 5 - 0 6 - 0 7 - 1 5 - 1 6 - 1 10 - 4 10 - 5 2 - 6 5 */ - switch (opcode_2) { - default: - return ARMul_CANT; - case 6: - if (CRm != 5) - return ARMul_CANT; - break; - case 5: - if (CRm != 2) - return ARMul_CANT; - break; - case 4: - if (CRm != 10) - return ARMul_CANT; - break; - case 1: - if ((CRm != 5) && (CRm != 6) && (CRm != 10)) - return ARMul_CANT; - break; - case 0: - if ((CRm < 5) || (CRm > 7)) - return ARMul_CANT; - break; - } - break; - - case 8: - /* Permissable combinations: - Opcode_2 CRm - 0 5 - 0 6 - 0 7 - 1 5 - 1 6 */ - if (opcode_2 > 1) - return ARMul_CANT; - if ((CRm < 5) || (CRm > 7)) - return ARMul_CANT; - if (opcode_2 == 1 && CRm == 7) - return ARMul_CANT; - break; - case 9: - /* Opcode_2 must be zero or one. CRm must be 1 or 2. */ - if (((CRm != 0) && (CRm != 1)) - || ((opcode_2 != 1) && (opcode_2 != 2))) - return ARMul_CANT; - break; - case 10: - /* Opcode_2 must be zero or one. CRm must be 4 or 8. */ - if (((CRm != 0) && (CRm != 1)) - || ((opcode_2 != 4) && (opcode_2 != 8))) - return ARMul_CANT; - break; - case 11: - /* Access not allowed. */ - return ARMul_CANT; - case 12: - /* Access not allowed. */ - return ARMul_CANT; - case 13: - /* Opcode_2 must be zero. CRm must be 0. */ - if ((CRm != 0) || (opcode_2 != 0)) - return ARMul_CANT; - break; - case 14: - /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */ - if (opcode_2 != 0) - return ARMul_CANT; - - if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8) - && (CRm != 9)) - return ARMul_CANT; - break; - case 15: - /* Opcode_2 must be zero. CRm must be 1. */ - if ((CRm != 1) || (opcode_2 != 0)) - return ARMul_CANT; - break; - default: - /* Should never happen. */ - return ARMul_CANT; - } - - return ARMul_DONE; -} - -/* Install co-processor instruction handlers in this routine. */ - -unsigned -ARMul_CoProInit(ARMul_State * state) +// Install co-processor instruction handlers in this routine. +unsigned int ARMul_CoProInit(ARMul_State* state) { - unsigned int i; - - /* Initialise tham all first. */ - for (i = 0; i < 16; i++) + // Initialise tham all first. + for (unsigned int i = 0; i < 16; i++) ARMul_CoProDetach(state, i); - /* Install CoPro Instruction handlers here. - The format is: - ARMul_CoProAttach (state, CP Number, Init routine, Exit routine - LDC routine, STC routine, MRC routine, MCR routine, - CDP routine, Read Reg routine, Write Reg routine). */ + // Install CoPro Instruction handlers here. + // The format is: + // ARMul_CoProAttach (state, CP Number, Init routine, Exit routine + // LDC routine, STC routine, MRC routine, MCR routine, + // CDP routine, Read Reg routine, Write Reg routine). if (state->is_v6) { ARMul_CoProAttach(state, 10, VFPInit, NULL, VFPLDC, VFPSTC, VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL); @@ -235,57 +67,44 @@ ARMul_CoProInit(ARMul_State * state) /*ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL, MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);*/ } - //chy 2003-09-03 do it in future!!!!???? -#if 0 - if (state->is_iWMMXt) { - ARMul_CoProAttach(state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC, - NULL, NULL, IwmmxtCDP, NULL, NULL); - ARMul_CoProAttach(state, 1, NULL, NULL, NULL, NULL, - IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, - NULL); - } -#endif - /* No handlers below here. */ + // No handlers below here. - /* Call all the initialisation routines. */ - for (i = 0; i < 16; i++) + // Call all the initialisation routines. + for (unsigned int i = 0; i < 16; i++) if (state->CPInit[i]) (state->CPInit[i]) (state); return TRUE; } -/* Install co-processor finalisation routines in this routine. */ - -void -ARMul_CoProExit(ARMul_State * state) +// Install co-processor finalisation routines in this routine. +void ARMul_CoProExit(ARMul_State * state) { - register unsigned i; - - for (i = 0; i < 16; i++) + for (unsigned int i = 0; i < 16; i++) if (state->CPExit[i]) (state->CPExit[i]) (state); - for (i = 0; i < 16; i++) /* Detach all handlers. */ + // Detach all handlers. + for (unsigned int i = 0; i < 16; i++) ARMul_CoProDetach(state, i); } -/* Routines to hook Co-processors into ARMulator. */ +// Routines to hook Co-processors into ARMulator. void -ARMul_CoProAttach(ARMul_State * state, +ARMul_CoProAttach(ARMul_State* state, unsigned number, -ARMul_CPInits * init, -ARMul_CPExits * exit, -ARMul_LDCs * ldc, -ARMul_STCs * stc, -ARMul_MRCs * mrc, -ARMul_MCRs * mcr, -ARMul_MRRCs * mrrc, -ARMul_MCRRs * mcrr, -ARMul_CDPs * cdp, -ARMul_CPReads * read, ARMul_CPWrites * write) +ARMul_CPInits* init, +ARMul_CPExits* exit, +ARMul_LDCs* ldc, +ARMul_STCs* stc, +ARMul_MRCs* mrc, +ARMul_MCRs* mcr, +ARMul_MRRCs* mrrc, +ARMul_MCRRs* mcrr, +ARMul_CDPs* cdp, +ARMul_CPReads* read, ARMul_CPWrites* write) { if (init != NULL) state->CPInit[number] = init; @@ -311,8 +130,7 @@ ARMul_CPReads * read, ARMul_CPWrites * write) state->CPWrite[number] = write; } -void -ARMul_CoProDetach(ARMul_State * state, unsigned number) +void ARMul_CoProDetach(ARMul_State* state, unsigned number) { ARMul_CoProAttach(state, number, NULL, NULL, NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp deleted file mode 100644 index 12166bf79..000000000 --- a/src/core/arm/interpreter/armemu.cpp +++ /dev/null @@ -1,6600 +0,0 @@ -/* armemu.c -- Main instruction emulation: ARM7 Instruction Emulator. - Copyright (C) 1994 Advanced RISC Machines Ltd. - Modifications to add arch. v4 support by <jsmith@cygnus.com>. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -//#include <util.h> // DEBUG() - -#include "core/arm/skyeye_common/arm_regformat.h" -#include "core/arm/skyeye_common/armdefs.h" -#include "core/arm/skyeye_common/armemu.h" -#include "core/hle/hle.h" - -//#include "svc.h" - -//ichfly -//#define callstacker 1 - -//#include "skyeye_callback.h" -//#include "skyeye_bus.h" -//#include "sim_control.h" -//#include "skyeye_pref.h" -//#include "skyeye.h" -//#include "skyeye2gdb.h" -//#include "code_cov.h" - -//#include "iwmmxt.h" -//chy 2003-07-11: for debug instrs -//extern int skyeye_instr_debug; -extern FILE *skyeye_logfd; - -static ARMword GetDPRegRHS (ARMul_State *, ARMword); -static ARMword GetDPSRegRHS (ARMul_State *, ARMword); -static void WriteR15 (ARMul_State *, ARMword); -static void WriteSR15 (ARMul_State *, ARMword); -static void WriteR15Branch (ARMul_State *, ARMword); -static ARMword GetLSRegRHS (ARMul_State *, ARMword); -static ARMword GetLS7RHS (ARMul_State *, ARMword); -static unsigned LoadWord (ARMul_State *, ARMword, ARMword); -static unsigned LoadHalfWord (ARMul_State *, ARMword, ARMword, int); -static unsigned LoadByte (ARMul_State *, ARMword, ARMword, int); -static unsigned StoreWord (ARMul_State *, ARMword, ARMword); -static unsigned StoreHalfWord (ARMul_State *, ARMword, ARMword); -static unsigned StoreByte (ARMul_State *, ARMword, ARMword); -static void LoadMult (ARMul_State *, ARMword, ARMword, ARMword); -static void StoreMult (ARMul_State *, ARMword, ARMword, ARMword); -static void LoadSMult (ARMul_State *, ARMword, ARMword, ARMword); -static void StoreSMult (ARMul_State *, ARMword, ARMword, ARMword); -static unsigned Multiply64 (ARMul_State *, ARMword, int, int); -static unsigned MultiplyAdd64 (ARMul_State *, ARMword, int, int); -static void Handle_Load_Double (ARMul_State *, ARMword); -static void Handle_Store_Double (ARMul_State *, ARMword); - -static int -handle_v6_insn (ARMul_State * state, ARMword instr); - -#define LUNSIGNED (0) /* unsigned operation */ -#define LSIGNED (1) /* signed operation */ -#define LDEFAULT (0) /* default : do nothing */ -#define LSCC (1) /* set condition codes on result */ - -#ifdef NEED_UI_LOOP_HOOK -/* How often to run the ui_loop update, when in use. */ -#define UI_LOOP_POLL_INTERVAL 0x32000 - -/* Counter for the ui_loop_hook update. */ -static int ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL; - -/* Actual hook to call to run through gdb's gui event loop. */ -extern int (*ui_loop_hook) (int); -#endif /* NEED_UI_LOOP_HOOK */ - -/* Short-hand macros for LDR/STR. */ - -/* Store post decrement writeback. */ -#define SHDOWNWB() \ - lhs = LHS ; \ - if (StoreHalfWord (state, instr, lhs)) \ - LSBase = lhs - GetLS7RHS (state, instr); - -/* Store post increment writeback. */ -#define SHUPWB() \ - lhs = LHS ; \ - if (StoreHalfWord (state, instr, lhs)) \ - LSBase = lhs + GetLS7RHS (state, instr); - -/* Store pre decrement. */ -#define SHPREDOWN() \ - (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr)); - -/* Store pre decrement writeback. */ -#define SHPREDOWNWB() \ - temp = LHS - GetLS7RHS (state, instr); \ - if (StoreHalfWord (state, instr, temp)) \ - LSBase = temp; - -/* Store pre increment. */ -#define SHPREUP() \ - (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr)); - -/* Store pre increment writeback. */ -#define SHPREUPWB() \ - temp = LHS + GetLS7RHS (state, instr); \ - if (StoreHalfWord (state, instr, temp)) \ - LSBase = temp; - -/* Load post decrement writeback. */ -#define LHPOSTDOWN() \ -{ \ - int done = 1; \ - lhs = LHS; \ - temp = lhs - GetLS7RHS (state, instr); \ - \ - switch (BITS (5, 6)) \ - { \ - case 1: /* H */ \ - if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \ - LSBase = temp; \ - break; \ - case 2: /* SB */ \ - if (LoadByte (state, instr, lhs, LSIGNED)) \ - LSBase = temp; \ - break; \ - case 3: /* SH */ \ - if (LoadHalfWord (state, instr, lhs, LSIGNED)) \ - LSBase = temp; \ - break; \ - case 0: /* SWP handled elsewhere. */ \ - default: \ - done = 0; \ - break; \ - } \ - if (done) \ - break; \ -} - -/* Load post increment writeback. */ -#define LHPOSTUP() \ -{ \ - int done = 1; \ - lhs = LHS; \ - temp = lhs + GetLS7RHS (state, instr); \ - \ - switch (BITS (5, 6)) \ - { \ - case 1: /* H */ \ - if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \ - LSBase = temp; \ - break; \ - case 2: /* SB */ \ - if (LoadByte (state, instr, lhs, LSIGNED)) \ - LSBase = temp; \ - break; \ - case 3: /* SH */ \ - if (LoadHalfWord (state, instr, lhs, LSIGNED)) \ - LSBase = temp; \ - break; \ - case 0: /* SWP handled elsewhere. */ \ - default: \ - done = 0; \ - break; \ - } \ - if (done) \ - break; \ -} - -/* Load pre decrement. */ -#define LHPREDOWN() \ -{ \ - int done = 1; \ - \ - temp = LHS - GetLS7RHS (state, instr); \ - switch (BITS (5, 6)) \ - { \ - case 1: /* H */ \ - (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \ - break; \ - case 2: /* SB */ \ - (void) LoadByte (state, instr, temp, LSIGNED); \ - break; \ - case 3: /* SH */ \ - (void) LoadHalfWord (state, instr, temp, LSIGNED); \ - break; \ - case 0: \ - /* SWP handled elsewhere. */ \ - default: \ - done = 0; \ - break; \ - } \ - if (done) \ - break; \ -} - -/* Load pre decrement writeback. */ -#define LHPREDOWNWB() \ -{ \ - int done = 1; \ - \ - temp = LHS - GetLS7RHS (state, instr); \ - switch (BITS (5, 6)) \ - { \ - case 1: /* H */ \ - if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \ - LSBase = temp; \ - break; \ - case 2: /* SB */ \ - if (LoadByte (state, instr, temp, LSIGNED)) \ - LSBase = temp; \ - break; \ - case 3: /* SH */ \ - if (LoadHalfWord (state, instr, temp, LSIGNED)) \ - LSBase = temp; \ - break; \ - case 0: \ - /* SWP handled elsewhere. */ \ - default: \ - done = 0; \ - break; \ - } \ - if (done) \ - break; \ -} - -/* Load pre increment. */ -#define LHPREUP() \ -{ \ - int done = 1; \ - \ - temp = LHS + GetLS7RHS (state, instr); \ - switch (BITS (5, 6)) \ - { \ - case 1: /* H */ \ - (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \ - break; \ - case 2: /* SB */ \ - (void) LoadByte (state, instr, temp, LSIGNED); \ - break; \ - case 3: /* SH */ \ - (void) LoadHalfWord (state, instr, temp, LSIGNED); \ - break; \ - case 0: \ - /* SWP handled elsewhere. */ \ - default: \ - done = 0; \ - break; \ - } \ - if (done) \ - break; \ -} - -/* Load pre increment writeback. */ -#define LHPREUPWB() \ -{ \ - int done = 1; \ - \ - temp = LHS + GetLS7RHS (state, instr); \ - switch (BITS (5, 6)) \ - { \ - case 1: /* H */ \ - if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \ - LSBase = temp; \ - break; \ - case 2: /* SB */ \ - if (LoadByte (state, instr, temp, LSIGNED)) \ - LSBase = temp; \ - break; \ - case 3: /* SH */ \ - if (LoadHalfWord (state, instr, temp, LSIGNED)) \ - LSBase = temp; \ - break; \ - case 0: \ - /* SWP handled elsewhere. */ \ - default: \ - done = 0; \ - break; \ - } \ - if (done) \ - break; \ -} - -/*ywc 2005-03-31*/ -//teawater add for arm2x86 2005.02.17------------------------------------------- -#ifdef DBCT -#include "dbct/tb.h" -#include "dbct/arm2x86_self.h" -#endif -//AJ2D-------------------------------------------------------------------------- - -//Diff register -unsigned int mirror_register_file[39]; - -/* EMULATION of ARM6. */ - -extern int debugmode; -int ARMul_ICE_debug(ARMul_State *state,ARMword instr,ARMword addr); -#ifdef MODE32 -//chy 2006-04-12, for ICE debug -int ARMul_ICE_debug(ARMul_State *state,ARMword instr,ARMword addr) -{ - return 0; -} - -static int dump = 0; -ARMword ARMul_Debug(ARMul_State * state, ARMword pc, ARMword instr) -{ - /*printf("[%08x] ", pc); - arm11_Disasm32(pc);*/ - - /*if (pc >= 0x0010303C && pc <= 0x00103050) - { - printf("[%08x] = %08X = ", pc, instr); - arm11_Disasm32(pc); - arm11_Dump(); - }*/ - - //fprintf(stderr,"[%08x]\n", pc); - - //if (pc == 0x00240C88) - // arm11_Dump(); - - /*if (pc == 0x188e04) - { - DEBUG("read %08X %08X %016X %08X %08X from %08X", state->Reg[0], state->Reg[1], state->Reg[2] | state->Reg[3] << 32, mem_Read32(state->Reg[13]), mem_Read32(state->Reg[13] + 4), state->Reg[14]); - } - if (pc == 0x21222c) - { - arm11_Dump(); - mem_Dbugdump(); - }*/ - - - /*if (pc == 0x0022D168) - { - int j = 0; - }*/ - - /*if (state->Reg[4] == 0x00105734) - { - printf("[%08x] ", pc); - arm11_Disasm32(pc); - }*/ - - return 0; -} - -/* -void chy_debug() -{ - printf("SkyEye chy_deubeg begin\n"); -} -*/ -ARMword -ARMul_Emulate32 (ARMul_State * state) -#else -ARMword -ARMul_Emulate26 (ARMul_State * state) -#endif -{ - /* The PC pipeline value depends on whether ARM - or Thumb instructions are being - d. */ - ARMword isize; - ARMword instr; /* The current instruction. */ - ARMword dest = 0; /* Almost the DestBus. */ - ARMword temp; /* Ubiquitous third hand. */ - ARMword pc = 0; /* The address of the current instruction. */ - ARMword lhs; /* Almost the ABus and BBus. */ - ARMword rhs; - ARMword decoded = 0; /* Instruction pipeline. */ - ARMword loaded = 0; - ARMword decoded_addr=0; - ARMword loaded_addr=0; - ARMword have_bp=0; - -#ifdef callstacker - char a[256]; -#endif - /* shenoubang */ - static int instr_sum = 0; - int reg_index = 0; -#if DIFF_STATE -//initialize all mirror register for follow mode - for (reg_index = 0; reg_index < 16; reg_index ++) { - mirror_register_file[reg_index] = state->Reg[reg_index]; - } - mirror_register_file[CPSR_REG] = state->Cpsr; - mirror_register_file[R13_SVC] = state->RegBank[SVCBANK][13]; - mirror_register_file[R14_SVC] = state->RegBank[SVCBANK][14]; - mirror_register_file[R13_ABORT] = state->RegBank[ABORTBANK][13]; - mirror_register_file[R14_ABORT] = state->RegBank[ABORTBANK][14]; - mirror_register_file[R13_UNDEF] = state->RegBank[UNDEFBANK][13]; - mirror_register_file[R14_UNDEF] = state->RegBank[UNDEFBANK][14]; - mirror_register_file[R13_IRQ] = state->RegBank[IRQBANK][13]; - mirror_register_file[R14_IRQ] = state->RegBank[IRQBANK][14]; - mirror_register_file[R8_FIRQ] = state->RegBank[FIQBANK][8]; - mirror_register_file[R9_FIRQ] = state->RegBank[FIQBANK][9]; - mirror_register_file[R10_FIRQ] = state->RegBank[FIQBANK][10]; - mirror_register_file[R11_FIRQ] = state->RegBank[FIQBANK][11]; - mirror_register_file[R12_FIRQ] = state->RegBank[FIQBANK][12]; - mirror_register_file[R13_FIRQ] = state->RegBank[FIQBANK][13]; - mirror_register_file[R14_FIRQ] = state->RegBank[FIQBANK][14]; - mirror_register_file[SPSR_SVC] = state->Spsr[SVCBANK]; - mirror_register_file[SPSR_ABORT] = state->Spsr[ABORTBANK]; - mirror_register_file[SPSR_UNDEF] = state->Spsr[UNDEFBANK]; - mirror_register_file[SPSR_IRQ] = state->Spsr[IRQBANK]; - mirror_register_file[SPSR_FIRQ] = state->Spsr[FIQBANK]; -#endif - /* Execute the next instruction. */ - if (state->NextInstr < PRIMEPIPE) { - decoded = state->decoded; - loaded = state->loaded; - pc = state->pc; - //chy 2006-04-12, for ICE debug - decoded_addr=state->decoded_addr; - loaded_addr=state->loaded_addr; - } - - do { - //print_func_name(state->pc); - /* Just keep going. */ - isize = INSN_SIZE; - - switch (state->NextInstr) { - case SEQ: - /* Advance the pipeline, and an S cycle. */ - state->Reg[15] += isize; - pc += isize; - instr = decoded; - //chy 2006-04-12, for ICE debug - have_bp = ARMul_ICE_debug(state,instr,decoded_addr); - decoded = loaded; - decoded_addr=loaded_addr; - //loaded = ARMul_LoadInstrS (state, pc + (isize * 2), - // isize); - loaded_addr=pc + (isize * 2); - if (have_bp) goto TEST_EMULATE; - break; - - case NONSEQ: - /* Advance the pipeline, and an N cycle. */ - state->Reg[15] += isize; - pc += isize; - instr = decoded; - //chy 2006-04-12, for ICE debug - have_bp=ARMul_ICE_debug(state,instr,decoded_addr); - decoded = loaded; - decoded_addr=loaded_addr; - //loaded = ARMul_LoadInstrN (state, pc + (isize * 2), - // isize); - loaded_addr=pc + (isize * 2); - NORMALCYCLE; - if (have_bp) goto TEST_EMULATE; - break; - - case PCINCEDSEQ: - /* Program counter advanced, and an S cycle. */ - pc += isize; - instr = decoded; - //chy 2006-04-12, for ICE debug - have_bp=ARMul_ICE_debug(state,instr,decoded_addr); - decoded = loaded; - decoded_addr=loaded_addr; - //loaded = ARMul_LoadInstrS (state, pc + (isize * 2), - // isize); - loaded_addr=pc + (isize * 2); - NORMALCYCLE; - if (have_bp) goto TEST_EMULATE; - break; - - case PCINCEDNONSEQ: - /* Program counter advanced, and an N cycle. */ - pc += isize; - instr = decoded; - //chy 2006-04-12, for ICE debug - have_bp=ARMul_ICE_debug(state,instr,decoded_addr); - decoded = loaded; - decoded_addr=loaded_addr; - //loaded = ARMul_LoadInstrN (state, pc + (isize * 2), - // isize); - loaded_addr=pc + (isize * 2); - NORMALCYCLE; - if (have_bp) goto TEST_EMULATE; - break; - - case RESUME: - /* The program counter has been changed. */ - pc = state->Reg[15]; -#ifndef MODE32 - pc = pc & R15PCBITS; -#endif - state->Reg[15] = pc + (isize * 2); - state->Aborted = 0; - //chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU> - state->AbortAddr = 1; - - instr = ARMul_LoadInstrN (state, pc, isize); - //instr = ARMul_ReLoadInstr (state, pc, isize); - //chy 2006-04-12, for ICE debug - have_bp=ARMul_ICE_debug(state,instr,pc); - //decoded = - // ARMul_ReLoadInstr (state, pc + isize, isize); - decoded_addr=pc+isize; - //loaded = ARMul_ReLoadInstr (state, pc + isize * 2, - // isize); - loaded_addr=pc + isize * 2; - NORMALCYCLE; - if (have_bp) goto TEST_EMULATE; - break; - - default: - /* The program counter has been changed. */ - pc = state->Reg[15]; -#ifndef MODE32 - pc = pc & R15PCBITS; -#endif - state->Reg[15] = pc + (isize * 2); - state->Aborted = 0; - //chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU> - state->AbortAddr = 1; - - instr = ARMul_LoadInstrN (state, pc, isize); - - //chy 2006-04-12, for ICE debug - have_bp=ARMul_ICE_debug(state,instr,pc); -#if 0 - decoded = - ARMul_LoadInstrS (state, pc + (isize), isize); -#endif - decoded_addr=pc+isize; -#if 0 - loaded = ARMul_LoadInstrS (state, pc + (isize * 2), - isize); -#endif - loaded_addr=pc + isize * 2; - NORMALCYCLE; - if (have_bp) goto TEST_EMULATE; - break; - } -#if 0 - int idx = 0; - printf("pc:%x\n", pc); - for (; idx < 17; idx ++) { - printf("R%d:%x\t", idx, state->Reg[idx]); - } - printf("\n"); -#endif - - instr = ARMul_LoadInstrN (state, pc, isize); - state->last_instr = state->CurrInstr; - state->CurrInstr = instr; - ARMul_Debug(state, pc, instr); -#if 0 - if((state->NumInstrs % 10000000) == 0) - printf("---|%p|--- %lld\n", pc, state->NumInstrs); - if(state->NumInstrs > (3000000000)) { - static int flag = 0; - if(pc == 0x8032ccc4) { - flag = 300; - } - if(flag) { - int idx = 0; - printf("------------------------------------\n"); - printf("pc:%x\n", pc); - for (; idx < 17; idx ++) { - printf("R%d:%x\t", idx, state->Reg[idx]); - } - printf("\nN:%d\t Z:%d\t C:%d\t V:%d\n", state->NFlag, state->ZFlag, state->CFlag, state->VFlag); - printf("\n"); - printf("------------------------------------\n"); - flag--; - } - } -#endif -#if DIFF_STATE - fprintf(state->state_log, "PC:0x%x\n", pc); - if (pc && (pc + 8) != state->Reg[15]) { - printf("lucky dog\n"); - printf("pc is %x, R15 is %x\n", pc, state->Reg[15]); - //exit(-1); - } - for (reg_index = 0; reg_index < 16; reg_index ++) { - if (state->Reg[reg_index] != mirror_register_file[reg_index]) { - fprintf(state->state_log, "R%d:0x%x\n", reg_index, state->Reg[reg_index]); - mirror_register_file[reg_index] = state->Reg[reg_index]; - } - } - if (state->Cpsr != mirror_register_file[CPSR_REG]) { - fprintf(state->state_log, "Cpsr:0x%x\n", state->Cpsr); - mirror_register_file[CPSR_REG] = state->Cpsr; - } - if (state->RegBank[SVCBANK][13] != mirror_register_file[R13_SVC]) { - fprintf(state->state_log, "R13_SVC:0x%x\n", state->RegBank[SVCBANK][13]); - mirror_register_file[R13_SVC] = state->RegBank[SVCBANK][13]; - } - if (state->RegBank[SVCBANK][14] != mirror_register_file[R14_SVC]) { - fprintf(state->state_log, "R14_SVC:0x%x\n", state->RegBank[SVCBANK][14]); - mirror_register_file[R14_SVC] = state->RegBank[SVCBANK][14]; - } - if (state->RegBank[ABORTBANK][13] != mirror_register_file[R13_ABORT]) { - fprintf(state->state_log, "R13_ABORT:0x%x\n", state->RegBank[ABORTBANK][13]); - mirror_register_file[R13_ABORT] = state->RegBank[ABORTBANK][13]; - } - if (state->RegBank[ABORTBANK][14] != mirror_register_file[R14_ABORT]) { - fprintf(state->state_log, "R14_ABORT:0x%x\n", state->RegBank[ABORTBANK][14]); - mirror_register_file[R14_ABORT] = state->RegBank[ABORTBANK][14]; - } - if (state->RegBank[UNDEFBANK][13] != mirror_register_file[R13_UNDEF]) { - fprintf(state->state_log, "R13_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][13]); - mirror_register_file[R13_UNDEF] = state->RegBank[UNDEFBANK][13]; - } - if (state->RegBank[UNDEFBANK][14] != mirror_register_file[R14_UNDEF]) { - fprintf(state->state_log, "R14_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][14]); - mirror_register_file[R14_UNDEF] = state->RegBank[UNDEFBANK][14]; - } - if (state->RegBank[IRQBANK][13] != mirror_register_file[R13_IRQ]) { - fprintf(state->state_log, "R13_IRQ:0x%x\n", state->RegBank[IRQBANK][13]); - mirror_register_file[R13_IRQ] = state->RegBank[IRQBANK][13]; - } - if (state->RegBank[IRQBANK][14] != mirror_register_file[R14_IRQ]) { - fprintf(state->state_log, "R14_IRQ:0x%x\n", state->RegBank[IRQBANK][14]); - mirror_register_file[R14_IRQ] = state->RegBank[IRQBANK][14]; - } - if (state->RegBank[FIQBANK][8] != mirror_register_file[R8_FIRQ]) { - fprintf(state->state_log, "R8_FIRQ:0x%x\n", state->RegBank[FIQBANK][8]); - mirror_register_file[R8_FIRQ] = state->RegBank[FIQBANK][8]; - } - if (state->RegBank[FIQBANK][9] != mirror_register_file[R9_FIRQ]) { - fprintf(state->state_log, "R9_FIRQ:0x%x\n", state->RegBank[FIQBANK][9]); - mirror_register_file[R9_FIRQ] = state->RegBank[FIQBANK][9]; - } - if (state->RegBank[FIQBANK][10] != mirror_register_file[R10_FIRQ]) { - fprintf(state->state_log, "R10_FIRQ:0x%x\n", state->RegBank[FIQBANK][10]); - mirror_register_file[R10_FIRQ] = state->RegBank[FIQBANK][10]; - } - if (state->RegBank[FIQBANK][11] != mirror_register_file[R11_FIRQ]) { - fprintf(state->state_log, "R11_FIRQ:0x%x\n", state->RegBank[FIQBANK][11]); - mirror_register_file[R11_FIRQ] = state->RegBank[FIQBANK][11]; - } - if (state->RegBank[FIQBANK][12] != mirror_register_file[R12_FIRQ]) { - fprintf(state->state_log, "R12_FIRQ:0x%x\n", state->RegBank[FIQBANK][12]); - mirror_register_file[R12_FIRQ] = state->RegBank[FIQBANK][12]; - } - if (state->RegBank[FIQBANK][13] != mirror_register_file[R13_FIRQ]) { - fprintf(state->state_log, "R13_FIRQ:0x%x\n", state->RegBank[FIQBANK][13]); - mirror_register_file[R13_FIRQ] = state->RegBank[FIQBANK][13]; - } - if (state->RegBank[FIQBANK][14] != mirror_register_file[R14_FIRQ]) { - fprintf(state->state_log, "R14_FIRQ:0x%x\n", state->RegBank[FIQBANK][14]); - mirror_register_file[R14_FIRQ] = state->RegBank[FIQBANK][14]; - } - if (state->Spsr[SVCBANK] != mirror_register_file[SPSR_SVC]) { - fprintf(state->state_log, "SPSR_SVC:0x%x\n", state->Spsr[SVCBANK]); - mirror_register_file[SPSR_SVC] = state->RegBank[SVCBANK]; - } - if (state->Spsr[ABORTBANK] != mirror_register_file[SPSR_ABORT]) { - fprintf(state->state_log, "SPSR_ABORT:0x%x\n", state->Spsr[ABORTBANK]); - mirror_register_file[SPSR_ABORT] = state->RegBank[ABORTBANK]; - } - if (state->Spsr[UNDEFBANK] != mirror_register_file[SPSR_UNDEF]) { - fprintf(state->state_log, "SPSR_UNDEF:0x%x\n", state->Spsr[UNDEFBANK]); - mirror_register_file[SPSR_UNDEF] = state->RegBank[UNDEFBANK]; - } - if (state->Spsr[IRQBANK] != mirror_register_file[SPSR_IRQ]) { - fprintf(state->state_log, "SPSR_IRQ:0x%x\n", state->Spsr[IRQBANK]); - mirror_register_file[SPSR_IRQ] = state->RegBank[IRQBANK]; - } - if (state->Spsr[FIQBANK] != mirror_register_file[SPSR_FIRQ]) { - fprintf(state->state_log, "SPSR_FIRQ:0x%x\n", state->Spsr[FIQBANK]); - mirror_register_file[SPSR_FIRQ] = state->RegBank[FIQBANK]; - } -#endif - -#if 0 - uint32_t alex = 0; - static int flagged = 0; - if ((flagged == 0) && (pc == 0xb224)) { - flagged++; - } - if ((flagged == 1) && (pc == 0x1a800)) { - flagged++; - } - if (flagged == 3) { - printf("---|%p|--- %x\n", pc, state->NumInstrs); - for (alex = 0; alex < 15; alex++) { - printf("R%02d % 8x\n", alex, state->Reg[alex]); - } - printf("R%02d % 8x\n", alex, state->Reg[alex] - 8); - printf("CPS %x%07x\n", (state->NFlag<<3 | state->ZFlag<<2 | state->CFlag<<1 | state->VFlag), state->Cpsr & 0xfffffff); - } else { - if (state->NumInstrs < 0x400000) { - //exit(-1); - } - } -#endif - - /*if (state->EventSet) - ARMul_EnvokeEvent (state);*/ - -#if 0 - /* do profiling for code coverage */ - if (skyeye_config.code_cov.prof_on) - cov_prof(EXEC_FLAG, pc); -#endif -//2003-07-11 chy: for test -#if 0 - if (skyeye_config.log.logon >= 1) { - if (state->NumInstrs >= skyeye_config.log.start && - state->NumInstrs <= skyeye_config.log.end) { - static int mybegin = 0; - static int myinstrnum = 0; - if (mybegin == 0) - mybegin = 1; -#if 0 - if (state->NumInstrs == 3695) { - printf ("***********SKYEYE: numinstr = 3695\n"); - } - static int mybeg2 = 0; - static int mybeg3 = 0; - static int mybeg4 = 0; - static int mybeg5 = 0; - - if (pc == 0xa0008000) { - //mybegin=1; - printf ("************SKYEYE: real vmlinux begin now numinstr is %llu ****************\n", state->NumInstrs); - } - - //chy 2003-09-02 test fiq - if (state->NumInstrs == 67347000) { - printf ("***********SKYEYE: numinstr = 67347000, begin log\n"); - mybegin = 1; - } - if (pc == 0xc00087b4) { //numinstr=67348714 - mybegin = 1; - printf ("************SKYEYE: test irq now numinstr is %llu ****************\n", state->NumInstrs); - } - if (pc == 0xc00087b8) { //in start_kernel::sti() - mybeg4 = 1; - printf ("************SKYEYE: startkerenl: sti now numinstr is %llu ********\n", state->NumInstrs); - } - /*if (pc==0xc001e4f4||pc==0xc001e4f8||pc==0xc001e4fc||pc==0xc001e500||pc==0xffff0004) { //MRA instr */ - if (pc == 0xc001e500) { //MRA instr - mybeg5 = 1; - printf ("************SKYEYE: MRA instr now numinstr is %llu ********\n", state->NumInstrs); - } - if (pc >= 0xc0000000 && mybeg2 == 0) { - mybeg2 = 1; - printf ("************SKYEYE: enable mmu&cache, now numinstr is %llu **************\n", state->NumInstrs); - SKYEYE_OUTREGS (stderr); - printf ("************************************************************************\n"); - } - //chy 2003-09-01 test after tlb-flush - if (pc == 0xc00261ac) { - //sleep(2); - mybeg3 = 1; - printf ("************SKYEYE: after tlb-flush numinstr is %llu ****************\n", state->NumInstrs); - } - if (mybeg3 == 1) { - SKYEYE_OUTREGS (skyeye_logfd); - SKYEYE_OUTMOREREGS (skyeye_logfd); - fprintf (skyeye_logfd, "\n"); - } -#endif - if (mybegin == 1) { - //fprintf(skyeye_logfd,"p %x,i %x,d %x,l %x,",pc,instr,decoded,loaded); - //chy for test 20050729 - /*if (state->NumInstrs>=3302294) { - if (pc==0x100c9d4 && instr==0xe1b0f00e){ - chy_debug(); - printf("*********************************************\n"); - printf("******SKYEYE N %llx :p %x,i %x\n SKYEYE******\n",state->NumInstrs,pc,instr); - printf("*********************************************\n"); - } - */ - if (skyeye_config.log.logon >= 1) - /* - fprintf (skyeye_logfd, - "N %llx :p %x,i %x,", - state->NumInstrs, pc, - #ifdef MODET - TFLAG ? instr & 0xffff : instr - #else - instr - #endif - ); - */ - fprintf(skyeye_logfd, "pc=0x%x,r3=0x%x\n", pc, state->Reg[3]); - if (skyeye_config.log.logon >= 2) - SKYEYE_OUTREGS (skyeye_logfd); - if (skyeye_config.log.logon >= 3) - SKYEYE_OUTMOREREGS - (skyeye_logfd); - //fprintf (skyeye_logfd, "\n"); - if (skyeye_config.log.length > 0) { - myinstrnum++; - if (myinstrnum >= - skyeye_config.log. - length) { - myinstrnum = 0; - fflush (skyeye_logfd); - fseek (skyeye_logfd, - 0L, SEEK_SET); - } - } - } - //SKYEYE_OUTREGS(skyeye_logfd); - //SKYEYE_OUTMOREREGS(skyeye_logfd); - } - } -#endif -#if 0 /* Enable this for a helpful bit of debugging when tracing is needed. */ - fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr); - if (instr == 0) - abort (); -#endif -#if 0 /* Enable this code to help track down stack alignment bugs. */ - { - static ARMword old_sp = -1; - - if (old_sp != state->Reg[13]) { - old_sp = state->Reg[13]; - fprintf (stderr, - "pc: %08x: SP set to %08x%s\n", - pc & ~1, old_sp, - (old_sp % 8) ? " [UNALIGNED!]" : ""); - } - } -#endif - /* Any exceptions ? */ - if (state->NresetSig == LOW) { - ARMul_Abort (state, ARMul_ResetV); - - /*added energy_prof statement by ksh in 2004-11-26 */ - //chy 2005-07-28 for standalone - //ARMul_do_energy(state,instr,pc); - break; - } else if (!state->NfiqSig && !FFLAG) { - ARMul_Abort (state, ARMul_FIQV); - /*added energy_prof statement by ksh in 2004-11-26 */ - //chy 2005-07-28 for standalone - //ARMul_do_energy(state,instr,pc); - break; - } else if (!state->NirqSig && !IFLAG) { - ARMul_Abort (state, ARMul_IRQV); - /*added energy_prof statement by ksh in 2004-11-26 */ - //chy 2005-07-28 for standalone - //ARMul_do_energy(state,instr,pc); - break; - } - -//teawater add for arm2x86 2005.04.26------------------------------------------- -#if 0 -// if (state->pc == 0xc011a868 || state->pc == 0xc011a86c) { - if (state->NumInstrs == 1671574 || state->NumInstrs == 1671573 || state->NumInstrs == 1671572 - || state->NumInstrs == 1671575) { - for (reg_index = 0; reg_index < 16; reg_index ++) { - printf("R%d:%x\t", reg_index, state->Reg[reg_index]); - } - printf("\n"); - } -#endif - if (state->tea_pc) { - int i; - - if (state->tea_reg_fd) { - fprintf (state->tea_reg_fd, "\n"); - for (i = 0; i < 15; i++) { - fprintf (state->tea_reg_fd, "%x,", - state->Reg[i]); - } - fprintf (state->tea_reg_fd, "%x,", pc); - state->Cpsr = ARMul_GetCPSR (state); - fprintf (state->tea_reg_fd, "%x\n", - state->Cpsr); - } else { - printf ("\n"); - for (i = 0; i < 15; i++) { - printf ("%x,", state->Reg[i]); - } - printf ("%x,", pc); - state->Cpsr = ARMul_GetCPSR (state); - printf ("%x\n", state->Cpsr); - } - } -//AJ2D-------------------------------------------------------------------------- - - /*if (state->CallDebug > 0) { - instr = ARMul_Debug (state, pc, instr); - if (state->Emulate < ONCE) { - state->NextInstr = RESUME; - break; - } - if (state->Debug) { - fprintf (stderr, - "sim: At %08lx Instr %08lx Mode %02lx\n", - pc, instr, state->Mode); - (void) fgetc (stdin); - } - } - else*/ - if (state->Emulate < ONCE) { - state->NextInstr = RESUME; - break; - } - //io_do_cycle (state); - state->NumInstrs++; -#if 0 - if (state->NumInstrs % 10000000 == 0) { - printf("10 MIPS instr have been executed\n"); - } -#endif - -#ifdef MODET - /* Provide Thumb instruction decoding. If the processor is in Thumb - mode, then we can simply decode the Thumb instruction, and map it - to the corresponding ARM instruction (by directly loading the - instr variable, and letting the normal ARM simulator - execute). There are some caveats to ensure that the correct - pipelined PC value is used when executing Thumb code, and also for - dealing with the BL instruction. */ - if (TFLAG) { - ARMword armOp = 0; - /* Check if in Thumb mode. */ - switch (ARMul_ThumbDecode(state, pc, instr, &armOp)) { - case t_undefined: - /* This is a Thumb instruction. */ - ARMul_UndefInstr (state, instr); - goto donext; - - case t_branch: - /* Already processed. */ - //pc = state->Reg[15] - 2; - //state->pc = state->Reg[15] - 2; //ichfly why do I need that - goto donext; - - case t_decoded: - /* ARM instruction available. */ - //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp); - - if (armOp == 0xDEADC0DE) { - LOG_ERROR(Core_ARM11, "Failed to decode thumb opcode %04X at %08X", instr, pc); - } - - instr = armOp; - - /* So continue instruction decoding. */ - break; - default: - break; - } - } -#endif - /* Check the condition codes. */ - if ((temp = TOPBITS (28)) == AL) { - /* Vile deed in the need for speed. */ - goto mainswitch; - } - - /* Check the condition code. */ - switch ((int) TOPBITS (28)) { - case AL: - temp = TRUE; - break; - case NV: - - /* shenoubang add for armv7 instr dmb 2012-3-11 */ - if (state->is_v7) { - if ((instr & 0x0fffff00) == 0x057ff000) { - switch((instr >> 4) & 0xf) { - case 4: /* dsb */ - case 5: /* dmb */ - case 6: /* isb */ - // TODO: do no implemented thes instr - goto donext; - } - } - } - /* dyf add for armv6 instruct CPS 2010.9.17 */ - if (state->is_v6) { - /* clrex do nothing here temporary */ - if (instr == 0xf57ff01f) { - //printf("clrex \n"); -#if 0 - int i; - for(i = 0; i < 128; i++) { - state->exclusive_tag_array[i] = 0xffffffff; - } -#endif - /* shenoubang 2012-3-14 refer the dyncom_interpreter */ - state->exclusive_tag_array[0] = 0xFFFFFFFF; - state->exclusive_access_state = 0; - goto donext; - } - - if (BITS(20, 27) == 0x10) { - if (BIT(19)) { - if (BIT(8)) { - if (BIT(18)) - state->Cpsr |= 1<<8; - else - state->Cpsr &= ~(1<<8); - } - if (BIT(7)) { - if (BIT(18)) - state->Cpsr |= 1<<7; - else - state->Cpsr &= ~(1<<7); - ASSIGNINT (state->Cpsr & INTBITS); - } - if (BIT(6)) { - if (BIT(18)) - state->Cpsr |= 1<<6; - else - state->Cpsr &= ~(1<<6); - ASSIGNINT (state->Cpsr & INTBITS); - } - } - if (BIT(17)) { - state->Cpsr |= BITS(0, 4); - printf("skyeye test state->Mode\n"); - if (state->Mode != (state->Cpsr & MODEBITS)) { - state->Mode = ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS); - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - } - } - goto donext; - } - } - if (state->is_v5) { - if (BITS (25, 27) == 5) { /* BLX(1) */ - ARMword dest; - - state->Reg[14] = pc + 4; - - /* Force entry into Thumb mode. */ - dest = pc + 8 + 1; - if (BIT (23)) - dest += (NEGBRANCH + - (BIT (24) << 1)); - else - dest += POSBRANCH + - (BIT (24) << 1); - - WriteR15Branch (state, dest); - goto donext; - } else if ((instr & 0xFC70F000) == 0xF450F000) { - /* The PLD instruction. Ignored. */ - goto donext; - } else if (((instr & 0xfe500f00) == 0xfc100100) - || ((instr & 0xfe500f00) == - 0xfc000100)) { - /* wldrw and wstrw are unconditional. */ - goto mainswitch; - } else { - /* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */ - ARMul_UndefInstr (state, instr); - } - } - temp = FALSE; - break; - case EQ: - temp = ZFLAG; - break; - case NE: - temp = !ZFLAG; - break; - case VS: - temp = VFLAG; - break; - case VC: - temp = !VFLAG; - break; - case MI: - temp = NFLAG; - break; - case PL: - temp = !NFLAG; - break; - case CS: - temp = CFLAG; - break; - case CC: - temp = !CFLAG; - break; - case HI: - temp = (CFLAG && !ZFLAG); - break; - case LS: - temp = (!CFLAG || ZFLAG); - break; - case GE: - temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); - break; - case LT: - temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); - break; - case GT: - temp = ((!NFLAG && !VFLAG && !ZFLAG) - || (NFLAG && VFLAG && !ZFLAG)); - break; - case LE: - temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) - || ZFLAG; - break; - } /* cc check */ - -//chy 2003-08-24 now #if 0 .... #endif process cp14, cp15.reg14, I disable it... - - - /* Actual execution of instructions begins here. */ - /* If the condition codes don't match, stop here. */ - if (temp) { -mainswitch: - - /* shenoubang sbfx and ubfx instr 2012-3-16 */ - if (state->is_v6) { - unsigned int m, lsb, width, Rd, Rn, data; - Rd = Rn = lsb = width = data = m = 0; - - //printf("helloworld\n"); - if ((((int) BITS (21, 27)) == 0x3f) && (((int) BITS (4, 6)) == 0x5)) { - m = (unsigned)BITS(7, 11); - width = (unsigned)BITS(16, 20); - Rd = (unsigned)BITS(12, 15); - Rn = (unsigned)BITS(0, 3); - if ((Rd == 15) || (Rn == 15)) { - ARMul_UndefInstr (state, instr); - } else if ((m + width) < 32) { - data = state->Reg[Rn]; - state->Reg[Rd] ^= state->Reg[Rd]; - state->Reg[Rd] = ((ARMword)(data << (31 -(m + width))) >> ((31 - (m + width)) + (m))); - //SKYEYE_LOG_IN_CLR(RED, "UBFX: In %s, line = %d, Reg_src[%d] = 0x%x, Reg_d[%d] = 0x%x, m = %d, width = %d, Rd = %d, Rn = %d\n", - // __FUNCTION__, __LINE__, Rn, data, Rd, state->Reg[Rd], m, width + 1, Rd, Rn); - goto donext; - } - } // ubfx instr - else if ((((int) BITS (21, 27)) == 0x3d) && (((int) BITS (4, 6)) == 0x5)) { - int tmp = 0; - Rd = BITS(12, 15); - Rn = BITS(0, 3); - lsb = BITS(7, 11); - width = BITS(16, 20); - if ((Rd == 15) || (Rn == 15)) { - ARMul_UndefInstr (state, instr); - } else if ((lsb + width) < 32) { - state->Reg[Rd] ^= state->Reg[Rd]; - data = state->Reg[Rn]; - tmp = (data << (32 - (lsb + width + 1))); - state->Reg[Rd] = (tmp >> (32 - (lsb + width + 1))); - //SKYEYE_LOG_IN_CLR(RED, "sbfx: In %s, line = %d, pc = 0x%x, instr = 0x%x,Rd = 0x%x, Rn = 0x%x, lsb = %d, width = %d, Rs[%d] = 0x%x, Rd[%d] = 0x%x\n", - // __func__, __LINE__, pc, instr, Rd, Rn, lsb, width + 1, Rn, state->Reg[Rn], Rd, state->Reg[Rd]); - goto donext; - } - } // sbfx instr - else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) { - //(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) - unsigned msb ,tmp_rn, tmp_rd, dst; - tmp_rd = tmp_rn = dst = 0; - Rd = BITS(12, 15); - Rn = BITS(0, 3); - lsb = BITS(7, 11); - msb = BITS(16, 20); //-V519 - if ((Rd == 15)) { - ARMul_UndefInstr (state, instr); - } else if ((Rn == 15)) { - data = state->Reg[Rd]; - tmp_rd = ((ARMword)(data << (31 - lsb)) >> (31 - lsb)); - dst = ((data >> msb) << (msb - lsb)); - dst = (dst << lsb) | tmp_rd; - /*SKYEYE_DBG("BFC instr: msb = %d, lsb = %d, Rd[%d] : 0x%x, dst = 0x%x\n", - msb, lsb, Rd, state->Reg[Rd], dst);*/ - goto donext; - } // bfc instr - else if (((msb >= lsb) && (msb < 32))) { - data = state->Reg[Rn]; - tmp_rn = ((ARMword)(data << (31 - (msb - lsb))) >> (31 - (msb - lsb))); - data = state->Reg[Rd]; - tmp_rd = ((ARMword)(data << (31 - lsb)) >> (31 - lsb)); - dst = ((data >> msb) << (msb - lsb)) | tmp_rn; - dst = (dst << lsb) | tmp_rd; - /*SKYEYE_DBG("BFI instr:msb = %d, lsb = %d, Rd[%d] : 0x%x, Rn[%d]: 0x%x, dst = 0x%x\n", - msb, lsb, Rd, state->Reg[Rd], Rn, state->Reg[Rn], dst);*/ - goto donext; - } // bfi instr - } - } - - switch ((int) BITS (20, 27)) { - /* Data Processing Register RHS Instructions. */ - - case 0x00: /* AND reg and MUL */ -#ifdef MODET - if (BITS (4, 11) == 0xB) { - /* STRH register offset, no write-back, down, post indexed. */ - SHDOWNWB (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif - if (BITS (4, 7) == 9) { - /* MUL */ - rhs = state->Reg[MULRHSReg]; - //if (MULLHSReg == MULDESTReg) { - if(0) { /* For armv6, the restriction is removed */ - UNDEF_MULDestEQOp1; - state->Reg[MULDESTReg] = 0; - } else if (MULDESTReg != 15) - state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs; - else - UNDEF_MULPCDest; - - for (dest = 0, temp = 0; dest < 32; - dest++) - if (rhs & (1L << dest)) - temp = dest; - - /* Mult takes this many/2 I cycles. */ - ARMul_Icycles (state, ARMul_MultTable[temp], 0L); - } else { - /* AND reg. */ - rhs = DPRegRHS; - dest = LHS & rhs; - WRITEDEST (dest); - } - break; - - case 0x01: /* ANDS reg and MULS */ -#ifdef MODET - if ((BITS (4, 11) & 0xF9) == 0x9) - /* LDR register offset, no write-back, down, post indexed. */ - LHPOSTDOWN (); - /* Fall through to rest of decoding. */ -#endif - if (BITS (4, 7) == 9) { - /* MULS */ - rhs = state->Reg[MULRHSReg]; - - //if (MULLHSReg == MULDESTReg) { - if(0) { - printf("Something in %d line\n", __LINE__); - UNDEF_WARNING; - UNDEF_MULDestEQOp1; - state->Reg[MULDESTReg] = 0; - CLEARN; - SETZ; - } else if (MULDESTReg != 15) { - dest = state->Reg[MULLHSReg] * rhs; - ARMul_NegZero (state, dest); - state->Reg[MULDESTReg] = dest; - } else - UNDEF_MULPCDest; - - for (dest = 0, temp = 0; dest < 32; - dest++) - if (rhs & (1L << dest)) - temp = dest; - - /* Mult takes this many/2 I cycles. */ - ARMul_Icycles (state, ARMul_MultTable[temp], 0L); - } else { - /* ANDS reg. */ - rhs = DPSRegRHS; - dest = LHS & rhs; - WRITESDEST (dest); - } - break; - - case 0x02: /* EOR reg and MLA */ -#ifdef MODET - if (BITS (4, 11) == 0xB) { - /* STRH register offset, write-back, down, post indexed. */ - SHDOWNWB (); - break; - } -#endif - if (BITS (4, 7) == 9) { /* MLA */ - rhs = state->Reg[MULRHSReg]; -#if 0 - if (MULLHSReg == MULDESTReg) { - UNDEF_MULDestEQOp1; - state->Reg[MULDESTReg] = state->Reg[MULACCReg]; - } else if (MULDESTReg != 15) { -#endif - if (MULDESTReg != 15) { - state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg]; - } else - UNDEF_MULPCDest; - - for (dest = 0, temp = 0; dest < 32; - dest++) - if (rhs & (1L << dest)) - temp = dest; - - /* Mult takes this many/2 I cycles. */ - ARMul_Icycles (state, ARMul_MultTable[temp], 0L); - } else { - rhs = DPRegRHS; - dest = LHS ^ rhs; - WRITEDEST (dest); - } - break; - - case 0x03: /* EORS reg and MLAS */ -#ifdef MODET - if ((BITS (4, 11) & 0xF9) == 0x9) - /* LDR register offset, write-back, down, post-indexed. */ - LHPOSTDOWN (); - /* Fall through to rest of the decoding. */ -#endif - if (BITS (4, 7) == 9) { - /* MLAS */ - rhs = state->Reg[MULRHSReg]; - //if (MULLHSReg == MULDESTReg) { - if (0) { - UNDEF_MULDestEQOp1; - dest = state->Reg[MULACCReg]; - ARMul_NegZero (state, dest); - state->Reg[MULDESTReg] = dest; - } else if (MULDESTReg != 15) { - dest = state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg]; - ARMul_NegZero (state, dest); - state->Reg[MULDESTReg] = dest; - } else - UNDEF_MULPCDest; - - for (dest = 0, temp = 0; dest < 32; - dest++) - if (rhs & (1L << dest)) - temp = dest; - - /* Mult takes this many/2 I cycles. */ - ARMul_Icycles (state, ARMul_MultTable[temp], 0L); - } else { - /* EORS Reg. */ - rhs = DPSRegRHS; - dest = LHS ^ rhs; - WRITESDEST (dest); - } - break; - - case 0x04: /* SUB reg */ - // Signifies UMAAL - if (state->is_v6 && BITS(4, 7) == 0x09) { - if (handle_v6_insn(state, instr)) - break; - } - -#ifdef MODET - if (BITS (4, 7) == 0xB) { - /* STRH immediate offset, no write-back, down, post indexed. */ - SHDOWNWB (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif - rhs = DPRegRHS; - dest = LHS - rhs; - WRITEDEST (dest); - break; - - case 0x05: /* SUBS reg */ -#ifdef MODET - if ((BITS (4, 7) & 0x9) == 0x9) - /* LDR immediate offset, no write-back, down, post indexed. */ - LHPOSTDOWN (); - /* Fall through to the rest of the instruction decoding. */ -#endif - lhs = LHS; - rhs = DPRegRHS; - dest = lhs - rhs; - - if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, lhs, rhs, dest); - ARMul_SubOverflow (state, lhs, rhs, dest); - } else { - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x06: /* RSB reg */ -#ifdef MODET - if (BITS (4, 7) == 0xB) { - /* STRH immediate offset, write-back, down, post indexed. */ - SHDOWNWB (); - break; - } -#endif - rhs = DPRegRHS; - dest = rhs - LHS; - WRITEDEST (dest); - break; - - case 0x07: /* RSBS reg */ -#ifdef MODET - if ((BITS (4, 7) & 0x9) == 0x9) - /* LDR immediate offset, write-back, down, post indexed. */ - LHPOSTDOWN (); - /* Fall through to remainder of instruction decoding. */ -#endif - lhs = LHS; - rhs = DPRegRHS; - dest = rhs - lhs; - - if ((rhs >= lhs) || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, rhs, lhs, dest); - ARMul_SubOverflow (state, rhs, lhs, dest); - } else { - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x08: /* ADD reg */ -#ifdef MODET - if (BITS (4, 11) == 0xB) { - /* STRH register offset, no write-back, up, post indexed. */ - SHUPWB (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif -#ifdef MODET - if (BITS (4, 7) == 0x9) { - /* MULL */ - /* 32x32 = 64 */ - ARMul_Icycles (state, Multiply64 (state, instr, LUNSIGNED, LDEFAULT), 0L); - break; - } -#endif - rhs = DPRegRHS; - dest = LHS + rhs; - WRITEDEST (dest); - break; - - case 0x09: /* ADDS reg */ -#ifdef MODET - if ((BITS (4, 11) & 0xF9) == 0x9) - /* LDR register offset, no write-back, up, post indexed. */ - LHPOSTUP (); - /* Fall through to remaining instruction decoding. */ -#endif -#ifdef MODET - if (BITS (4, 7) == 0x9) { - /* MULL */ - /* 32x32=64 */ - ARMul_Icycles (state, Multiply64 (state, instr, LUNSIGNED, LSCC), 0L); - break; - } -#endif - lhs = LHS; - rhs = DPRegRHS; - dest = lhs + rhs; - ASSIGNZ (dest == 0); - if ((lhs | rhs) >> 30) { - /* Possible C,V,N to set. */ - ASSIGNN (NEG (dest)); - ARMul_AddCarry (state, lhs, rhs, dest); - ARMul_AddOverflow (state, lhs, rhs, dest); - } else { - CLEARN; - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x0a: /* ADC reg */ -#ifdef MODET - if (BITS (4, 11) == 0xB) { - /* STRH register offset, write-back, up, post-indexed. */ - SHUPWB (); - break; - } - if (BITS (4, 7) == 0x9) { - /* MULL */ - /* 32x32=64 */ - ARMul_Icycles (state, MultiplyAdd64 (state, instr, LUNSIGNED, LDEFAULT), 0L); - break; - } -#endif - rhs = DPRegRHS; - dest = LHS + rhs + CFLAG; - WRITEDEST (dest); - break; - - case 0x0b: /* ADCS reg */ -#ifdef MODET - if ((BITS (4, 11) & 0xF9) == 0x9) - /* LDR register offset, write-back, up, post indexed. */ - LHPOSTUP (); - /* Fall through to remaining instruction decoding. */ - if (BITS (4, 7) == 0x9) { - /* MULL */ - /* 32x32=64 */ - ARMul_Icycles (state, MultiplyAdd64 (state, instr, LUNSIGNED, LSCC), 0L); - break; - } -#endif - lhs = LHS; - rhs = DPRegRHS; - dest = lhs + rhs + CFLAG; - ASSIGNZ (dest == 0); - if ((lhs | rhs) >> 30) { - /* Possible C,V,N to set. */ - ASSIGNN (NEG (dest)); - ARMul_AddCarry (state, lhs, rhs, dest); - ARMul_AddOverflow (state, lhs, rhs, dest); - } else { - CLEARN; - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x0c: /* SBC reg */ -#ifdef MODET - if (BITS (4, 7) == 0xB) { - /* STRH immediate offset, no write-back, up post indexed. */ - SHUPWB (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } - if (BITS (4, 7) == 0x9) { - /* MULL */ - /* 32x32=64 */ - ARMul_Icycles (state, Multiply64 (state, instr, LSIGNED, LDEFAULT), 0L); - break; - } -#endif - rhs = DPRegRHS; - dest = LHS - rhs - !CFLAG; - WRITEDEST (dest); - break; - - case 0x0d: /* SBCS reg */ -#ifdef MODET - if ((BITS (4, 7) & 0x9) == 0x9) - /* LDR immediate offset, no write-back, up, post indexed. */ - LHPOSTUP (); - - if (BITS (4, 7) == 0x9) { - /* MULL */ - /* 32x32=64 */ - ARMul_Icycles (state, Multiply64 (state, instr, LSIGNED, LSCC), 0L); - break; - } -#endif - lhs = LHS; - rhs = DPRegRHS; - dest = lhs - rhs - !CFLAG; - if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, lhs, rhs, dest); - ARMul_SubOverflow (state, lhs, rhs, dest); - } else { - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x0e: /* RSC reg */ -#ifdef MODET - if (BITS (4, 7) == 0xB) { - /* STRH immediate offset, write-back, up, post indexed. */ - SHUPWB (); - break; - } - - if (BITS (4, 7) == 0x9) { - /* MULL */ - /* 32x32=64 */ - ARMul_Icycles (state, MultiplyAdd64 (state, instr, LSIGNED, LDEFAULT), 0L); - break; - } -#endif - rhs = DPRegRHS; - dest = rhs - LHS - !CFLAG; - WRITEDEST (dest); - break; - - case 0x0f: /* RSCS reg */ -#ifdef MODET - if ((BITS (4, 7) & 0x9) == 0x9) - /* LDR immediate offset, write-back, up, post indexed. */ - LHPOSTUP (); - /* Fall through to remaining instruction decoding. */ - - if (BITS (4, 7) == 0x9) { - /* MULL */ - /* 32x32=64 */ - ARMul_Icycles (state, MultiplyAdd64 (state, instr, LSIGNED, LSCC), 0L); - break; - } -#endif - lhs = LHS; - rhs = DPRegRHS; - dest = rhs - lhs - !CFLAG; - - if ((rhs >= lhs) || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, rhs, lhs, dest); - ARMul_SubOverflow (state, rhs, lhs, dest); - } else { - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x10: /* TST reg and MRS CPSR and SWP word. */ - if (state->is_v5e) { - if (BIT (4) == 0 && BIT (7) == 1) { - /* ElSegundo SMLAxy insn. */ - ARMword op1 = state->Reg[BITS (0, 3)]; - ARMword op2 = state->Reg[BITS (8, 11)]; - ARMword Rn = state->Reg[BITS (12, 15)]; - - if (BIT (5)) - op1 >>= 16; - if (BIT (6)) - op2 >>= 16; - op1 &= 0xFFFF; - op2 &= 0xFFFF; - if (op1 & 0x8000) - op1 -= 65536; - if (op2 & 0x8000) - op2 -= 65536; - op1 *= op2; - //printf("SMLA_INST:BB,op1=0x%x, op2=0x%x. Rn=0x%x\n", op1, op2, Rn); - if (AddOverflow(op1, Rn, op1 + Rn)) - SETQ; - state->Reg[BITS (16, 19)] = op1 + Rn; - break; - } - - if (BITS (4, 11) == 5) { - /* ElSegundo QADD insn. */ - ARMword op1 = state->Reg[BITS (0, 3)]; - ARMword op2 = state->Reg[BITS (16, 19)]; - ARMword result = op1 + op2; - if (AddOverflow(op1, op2, result)) { - result = POS (result) ? 0x80000000 : 0x7fffffff; - SETQ; - } - state->Reg[BITS (12, 15)] = result; - break; - } - } -#ifdef MODET - if (BITS (4, 11) == 0xB) { - /* STRH register offset, no write-back, down, pre indexed. */ - SHPREDOWN (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif - if (BITS (4, 11) == 9) { - /* SWP */ - UNDEF_SWPPC; - temp = LHS; - BUSUSEDINCPCS; -#ifndef MODE32 - if (VECTORACCESS (temp) || ADDREXCEPT (temp)) { - INTERNALABORT (temp); - (void) ARMul_LoadWordN (state, temp); - (void) ARMul_LoadWordN (state, temp); - } else -#endif - dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]); - if (temp & 3) - DEST = ARMul_Align (state, temp, dest); - else - DEST = dest; - if (state->abortSig || state->Aborted) - TAKEABORT; - } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */ - UNDEF_MRSPC; - DEST = ARMul_GetCPSR(state); - } else { - UNDEF_Test; - } - break; - - case 0x11: /* TSTP reg */ -#ifdef MODET - if ((BITS (4, 11) & 0xF9) == 0x9) - /* LDR register offset, no write-back, down, pre indexed. */ - LHPREDOWN (); - /* Continue with remaining instruction decode. */ -#endif - if (DESTReg == 15) { - /* TSTP reg */ -#ifdef MODE32 - //chy 2006-02-15 if in user mode, can not set cpsr 0:23 - //from p165 of ARMARM book - state->Cpsr = GETSPSR (state->Bank); - ARMul_CPSRAltered (state); -#else - rhs = DPRegRHS; - temp = LHS & rhs; - SETR15PSR (temp); -#endif - } else { - /* TST reg */ - rhs = DPSRegRHS; - dest = LHS & rhs; - ARMul_NegZero (state, dest); - } - break; - - case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6). */ - - if (state->is_v5) { - if (BITS (4, 7) == 3) { - /* BLX(2) */ - ARMword temp; - - if (TFLAG) - temp = (pc + 2) | 1; - else - temp = pc + 4; - - WriteR15Branch (state, state->Reg[RHSReg]); - state->Reg[14] = temp; - break; - } - } - - if (state->is_v5e) { - if (BIT (4) == 0 && BIT (7) == 1 && (BIT (5) == 0 || BITS (12, 15) == 0)) { - /* ElSegundo SMLAWy/SMULWy insn. */ - unsigned long long op1 = state->Reg[BITS (0, 3)]; - unsigned long long op2 = state->Reg[BITS (8, 11)]; - unsigned long long result; - - if (BIT (6)) - op2 >>= 16; - if (op1 & 0x80000000) - op1 -= 1ULL << 32; - op2 &= 0xFFFF; - if (op2 & 0x8000) - op2 -= 65536; - result = (op1 * op2) >> 16; - - if (BIT (5) == 0) { - ARMword Rn = state->Reg[BITS(12, 15)]; - - if (AddOverflow((ARMword)result, Rn, (ARMword)(result + Rn))) - SETQ; - result += Rn; - } - state->Reg[BITS (16, 19)] = (ARMword)result; - break; - } - - if (BITS (4, 11) == 5) { - /* ElSegundo QSUB insn. */ - ARMword op1 = state->Reg[BITS (0, 3)]; - ARMword op2 = state->Reg[BITS (16, 19)]; - ARMword result = op1 - op2; - - if (SubOverflow - (op1, op2, result)) { - result = POS (result) ? 0x80000000 : 0x7fffffff; - SETQ; - } - - state->Reg[BITS (12, 15)] = result; - break; - } - } -#ifdef MODET - if (BITS (4, 11) == 0xB) { - /* STRH register offset, write-back, down, pre indexed. */ - SHPREDOWNWB (); - break; - } - if (BITS (4, 27) == 0x12FFF1) { - /* BX */ - WriteR15Branch (state, state->Reg[RHSReg]); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif - if (state->is_v5) { - if (BITS (4, 7) == 0x7) { - //ARMword value; - //extern int SWI_vector_installed; - - /* Hardware is allowed to optionally override this - instruction and treat it as a breakpoint. Since - this is a simulator not hardware, we take the position - that if a SWI vector was not installed, then an Abort - vector was probably not installed either, and so - normally this instruction would be ignored, even if an - Abort is generated. This is a bad thing, since GDB - uses this instruction for its breakpoints (at least in - Thumb mode it does). So intercept the instruction here - and generate a breakpoint SWI instead. */ - /* Force the next instruction to be refetched. */ - state->NextInstr = RESUME; - break; - } - } - if (DESTReg == 15) { - /* MSR reg to CPSR. */ - UNDEF_MSRPC; - temp = DPRegRHS; -#ifdef MODET - /* Don't allow TBIT to be set by MSR. */ - temp &= ~TBIT; -#endif - ARMul_FixCPSR (state, instr, temp); - } else - UNDEF_Test; - - break; - - case 0x13: /* TEQP reg */ -#ifdef MODET - if ((BITS (4, 11) & 0xF9) == 0x9) - /* LDR register offset, write-back, down, pre indexed. */ - LHPREDOWNWB (); - /* Continue with remaining instruction decode. */ -#endif - if (DESTReg == 15) { - /* TEQP reg */ -#ifdef MODE32 - state->Cpsr = GETSPSR (state->Bank); - ARMul_CPSRAltered (state); -#else - rhs = DPRegRHS; - temp = LHS ^ rhs; - SETR15PSR (temp); -#endif - } else { - /* TEQ Reg. */ - rhs = DPSRegRHS; - dest = LHS ^ rhs; - ARMul_NegZero (state, dest); - } - break; - - case 0x14: /* CMP reg and MRS SPSR and SWP byte. */ - if (state->is_v5e) { - if (BIT (4) == 0 && BIT (7) == 1) { - /* ElSegundo SMLALxy insn. */ - unsigned long long op1 = state->Reg[BITS (0, 3)]; - unsigned long long op2 = state->Reg[BITS (8, 11)]; - unsigned long long dest; - //unsigned long long result; - - if (BIT (5)) - op1 >>= 16; - if (BIT (6)) - op2 >>= 16; - op1 &= 0xFFFF; - if (op1 & 0x8000) - op1 -= 65536; - op2 &= 0xFFFF; - if (op2 & 0x8000) - op2 -= 65536; - - dest = (unsigned long long) state->Reg[BITS (16, 19)] << 32; - dest |= state->Reg[BITS (12, 15)]; - dest += op1 * op2; - state->Reg[BITS(12, 15)] = (ARMword)dest; - state->Reg[BITS(16, 19)] = (ARMword)(dest >> 32); - break; - } - - if (BITS (4, 11) == 5) { - /* ElSegundo QDADD insn. */ - ARMword op1 = state->Reg[BITS (0, 3)]; - ARMword op2 = state->Reg[BITS (16, 19)]; - ARMword op2d = op2 + op2; - ARMword result; - - if (AddOverflow - (op2, op2, op2d)) { - SETQ; - op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; - } - - result = op1 + op2d; - if (AddOverflow(op1, op2d, result)) { - SETQ; - result = POS (result) ? 0x80000000 : 0x7fffffff; - } - - state->Reg[BITS (12, 15)] = result; - break; - } - } -#ifdef MODET - if (BITS (4, 7) == 0xB) { - /* STRH immediate offset, no write-back, down, pre indexed. */ - SHPREDOWN (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif - if (BITS (4, 11) == 9) { - /* SWP */ - UNDEF_SWPPC; - temp = LHS; - BUSUSEDINCPCS; -#ifndef MODE32 - if (VECTORACCESS (temp) || ADDREXCEPT (temp)) { - INTERNALABORT (temp); - (void) ARMul_LoadByte (state, temp); - (void) ARMul_LoadByte (state, temp); - } else -#endif - DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]); - if (state->abortSig || state->Aborted) - TAKEABORT; - } else if ((BITS (0, 11) == 0) - && (LHSReg == 15)) { - /* MRS SPSR */ - UNDEF_MRSPC; - DEST = GETSPSR (state->Bank); - } else - UNDEF_Test; - - break; - - case 0x15: /* CMPP reg. */ -#ifdef MODET - if ((BITS (4, 7) & 0x9) == 0x9) - /* LDR immediate offset, no write-back, down, pre indexed. */ - LHPREDOWN (); - /* Continue with remaining instruction decode. */ -#endif - if (DESTReg == 15) { - /* CMPP reg. */ -#ifdef MODE32 - state->Cpsr = GETSPSR (state->Bank); - ARMul_CPSRAltered (state); -#else - rhs = DPRegRHS; - temp = LHS - rhs; - SETR15PSR (temp); -#endif - } else { - /* CMP reg. */ - lhs = LHS; - rhs = DPRegRHS; - dest = lhs - rhs; - ARMul_NegZero (state, dest); - if ((lhs >= rhs) - || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, lhs, rhs, dest); - ARMul_SubOverflow (state, lhs, rhs, dest); - } else { - CLEARC; - CLEARV; - } - } - break; - - case 0x16: /* CMN reg and MSR reg to SPSR */ - if (state->is_v5e) { - if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0) { - /* ElSegundo SMULxy insn. */ - ARMword op1 = state->Reg[BITS (0, 3)]; - ARMword op2 = state->Reg[BITS (8, 11)]; - ARMword Rn = state->Reg[BITS (12, 15)]; - - if (BIT (5)) - op1 >>= 16; - if (BIT (6)) - op2 >>= 16; - op1 &= 0xFFFF; - op2 &= 0xFFFF; - if (op1 & 0x8000) - op1 -= 65536; - if (op2 & 0x8000) - op2 -= 65536; - - state->Reg[BITS (16, 19)] = op1 * op2; - break; - } - - if (BITS (4, 11) == 5) { - /* ElSegundo QDSUB insn. */ - ARMword op1 = state->Reg[BITS (0, 3)]; - ARMword op2 = state->Reg[BITS (16, 19)]; - ARMword op2d = op2 + op2; - ARMword result; - - if (AddOverflow(op2, op2, op2d)) { - SETQ; - op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; - } - - result = op1 - op2d; - if (SubOverflow(op1, op2d, result)) { - SETQ; - result = POS (result) ? 0x80000000 : 0x7fffffff; - } - - state->Reg[BITS (12, 15)] = result; - break; - } - } - - if (state->is_v5) { - if (BITS (4, 11) == 0xF1 - && BITS (16, 19) == 0xF) { - /* ARM5 CLZ insn. */ - ARMword op1 = state->Reg[BITS (0, 3)]; - int result = 32; - - if (op1) - for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1) - result++; - state->Reg[BITS (12, 15)] = result; - break; - } - } - -#ifdef MODET - if (BITS (4, 7) == 0xB) { - /* STRH immediate offset, write-back, down, pre indexed. */ - SHPREDOWNWB (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif - if (DESTReg == 15) { - /* MSR */ - UNDEF_MSRPC; - /*ARMul_FixSPSR (state, instr, - DPRegRHS);*/ - } else { - UNDEF_Test; - } - break; - - case 0x17: /* CMNP reg */ -#ifdef MODET - if ((BITS (4, 7) & 0x9) == 0x9) - /* LDR immediate offset, write-back, down, pre indexed. */ - LHPREDOWNWB (); - /* Continue with remaining instruction decoding. */ -#endif - if (DESTReg == 15) { -#ifdef MODE32 - state->Cpsr = GETSPSR (state->Bank); - ARMul_CPSRAltered (state); -#else - rhs = DPRegRHS; - temp = LHS + rhs; - SETR15PSR (temp); -#endif - break; - } else { - /* CMN reg. */ - lhs = LHS; - rhs = DPRegRHS; - dest = lhs + rhs; - ASSIGNZ (dest == 0); - if ((lhs | rhs) >> 30) { - /* Possible C,V,N to set. */ - ASSIGNN (NEG (dest)); - ARMul_AddCarry (state, lhs, rhs, dest); - ARMul_AddOverflow (state, lhs, rhs, dest); - } else { - CLEARN; - CLEARC; - CLEARV; - } - } - break; - - case 0x18: /* ORR reg */ -#ifdef MODET - /* dyf add armv6 instr strex 2010.9.17 */ - if (state->is_v6) { - if (BITS (4, 7) == 0x9) - if (handle_v6_insn (state, instr)) - break; - } - - if (BITS (4, 11) == 0xB) { - /* STRH register offset, no write-back, up, pre indexed. */ - SHPREUP (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif - rhs = DPRegRHS; - dest = LHS | rhs; - WRITEDEST (dest); - break; - - case 0x19: /* ORRS reg */ -#ifdef MODET - /* dyf add armv6 instr ldrex */ - if (state->is_v6) { - if (BITS (4, 7) == 0x9) { - if (handle_v6_insn (state, instr)) - break; - } - } - if ((BITS (4, 11) & 0xF9) == 0x9) - /* LDR register offset, no write-back, up, pre indexed. */ - LHPREUP (); - /* Continue with remaining instruction decoding. */ -#endif - rhs = DPSRegRHS; - dest = LHS | rhs; - WRITESDEST (dest); - break; - - case 0x1a: /* MOV reg */ -#ifdef MODET - if (BITS (4, 11) == 0xB) { - /* STRH register offset, write-back, up, pre indexed. */ - SHPREUPWB (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } - if (BITS(4, 11) == 0xF9) { //strexd - u32 l = LHSReg; - - bool enter = false; - - if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr)&& - state->currentexvald == (u32)ARMul_ReadWord(state, state->currentexaddr + 4)) - enter = true; - - - //todo bug this and STREXD and LDREXD http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/CHDGJGGC.html - - - if (enter) { - ARMul_StoreWordN(state, LHS, state->Reg[RHSReg]); - ARMul_StoreWordN(state,LHS + 4 , state->Reg[RHSReg + 1]); - state->Reg[DESTReg] = 0; - } else { - state->Reg[DESTReg] = 1; - } - - break; - } -#endif - dest = DPRegRHS; - WRITEDEST (dest); - break; - - case 0x1B: /* MOVS reg */ -#ifdef MODET - /* ldrexd ichfly */ - if (BITS(0, 11) == 0xF9F) { //strexd - lhs = LHS; - - state->currentexaddr = lhs; - state->currentexval = (u32)ARMul_ReadWord(state, lhs); - state->currentexvald = (u32)ARMul_ReadWord(state, lhs + 4); - - state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs); - state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs + 4); - break; - } - - if ((BITS (4, 11) & 0xF9) == 0x9) - /* LDR register offset, write-back, up, pre indexed. */ - LHPREUPWB (); - /* Continue with remaining instruction decoding. */ - - - - -#endif - dest = DPSRegRHS; - WRITESDEST (dest); - break; - - case 0x1c: /* BIC reg */ -#ifdef MODET - /* dyf add for STREXB */ - if (state->is_v6) { - if (BITS (4, 7) == 0x9) { - if (handle_v6_insn (state, instr)) - break; - } - } - if (BITS (4, 7) == 0xB) { - /* STRH immediate offset, no write-back, up, pre indexed. */ - SHPREUP (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } else if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif - rhs = DPRegRHS; - dest = LHS & ~rhs; - WRITEDEST (dest); - break; - - case 0x1d: /* BICS reg */ -#ifdef MODET - /* ladsh P=1 U=1 W=0 L=1 S=1 H=1 */ - if (BITS(4, 7) == 0xF) { - temp = LHS + GetLS7RHS (state, instr); - LoadHalfWord (state, instr, temp, LSIGNED); - break; - - } - if (BITS (4, 7) == 0xb) { - /* LDRH immediate offset, no write-back, up, pre indexed. */ - temp = LHS + GetLS7RHS (state, instr); - LoadHalfWord (state, instr, temp, LUNSIGNED); - break; - } - if (BITS (4, 7) == 0xd) { - // alex-ykl fix: 2011-07-20 missing ldrsb instruction - temp = LHS + GetLS7RHS (state, instr); - LoadByte (state, instr, temp, LSIGNED); - break; - } - - /* Continue with instruction decoding. */ - /*if ((BITS (4, 7) & 0x9) == 0x9) */ - if ((BITS (4, 7)) == 0x9) { - /* ldrexb */ - if (state->is_v6) { - if (handle_v6_insn (state, instr)) - break; - } - /* LDR immediate offset, no write-back, up, pre indexed. */ - LHPREUP (); - - } - -#endif - rhs = DPSRegRHS; - dest = LHS & ~rhs; - WRITESDEST (dest); - break; - - case 0x1e: /* MVN reg */ -#ifdef MODET - if ((instr & 0x00000FF0) == 0x00000F90) { //if ((instr & 0x0FF00FF0) == 0x01e00f90) { //todo make that better ichfly - /* strexh ichfly */ - u32 l = LHSReg; - u32 r = RHSReg; - lhs = LHS; - - bool enter = false; - - if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true; - - - //StoreWord(state, lhs, RHS) - if (state->Aborted) { - TAKEABORT; - } - if (enter) { - ARMul_StoreHalfWord(state, lhs, RHS); - state->Reg[DESTReg] = 0; - } else { - state->Reg[DESTReg] = 1; - } - break; - } - if (BITS (4, 7) == 0xB) { - /* STRH immediate offset, write-back, up, pre indexed. */ - SHPREUPWB (); - break; - } - if (BITS (4, 7) == 0xD) { - Handle_Load_Double (state, instr); - break; - } - if (BITS (4, 7) == 0xF) { - Handle_Store_Double (state, instr); - break; - } -#endif - dest = ~DPRegRHS; - WRITEDEST (dest); - break; - - case 0x1f: /* MVNS reg */ -#ifdef MODET - - if ((instr & 0x00000FF0) == 0x00000F90) { //(instr & 0x0FF00FF0) == 0x01f00f90)//if ((instr & 0x0FF00FF0) == 0x01f00f90) { - /* ldrexh ichfly */ - lhs = LHS; - - state->currentexaddr = lhs; - state->currentexval = (u32)ARMul_LoadHalfWord(state, lhs); - - LoadHalfWord(state, instr, lhs,0); - break; - } - - if ((BITS (4, 7) & 0x9) == 0x9) - /* LDR immediate offset, write-back, up, pre indexed. */ - LHPREUPWB (); - /* Continue instruction decoding. */ -#endif - dest = ~DPSRegRHS; - WRITESDEST (dest); - break; - - - /* Data Processing Immediate RHS Instructions. */ - - case 0x20: /* AND immed */ - dest = LHS & DPImmRHS; - WRITEDEST (dest); - break; - - case 0x21: /* ANDS immed */ - DPSImmRHS; - dest = LHS & rhs; - WRITESDEST (dest); - break; - - case 0x22: /* EOR immed */ - dest = LHS ^ DPImmRHS; - WRITEDEST (dest); - break; - - case 0x23: /* EORS immed */ - DPSImmRHS; - dest = LHS ^ rhs; - WRITESDEST (dest); - break; - - case 0x24: /* SUB immed */ - dest = LHS - DPImmRHS; - WRITEDEST (dest); - break; - - case 0x25: /* SUBS immed */ - lhs = LHS; - rhs = DPImmRHS; - dest = lhs - rhs; - - if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, lhs, rhs, dest); - ARMul_SubOverflow (state, lhs, rhs, dest); - } else { - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x26: /* RSB immed */ - dest = DPImmRHS - LHS; - WRITEDEST (dest); - break; - - case 0x27: /* RSBS immed */ - lhs = LHS; - rhs = DPImmRHS; - dest = rhs - lhs; - - if ((rhs >= lhs) || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, rhs, lhs, dest); - ARMul_SubOverflow (state, rhs, lhs, dest); - } else { - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x28: /* ADD immed */ - dest = LHS + DPImmRHS; - WRITEDEST (dest); - break; - - case 0x29: /* ADDS immed */ - lhs = LHS; - rhs = DPImmRHS; - dest = lhs + rhs; - ASSIGNZ (dest == 0); - - if ((lhs | rhs) >> 30) { - /* Possible C,V,N to set. */ - ASSIGNN (NEG (dest)); - ARMul_AddCarry (state, lhs, rhs, dest); - ARMul_AddOverflow (state, lhs, rhs, dest); - } else { - CLEARN; - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x2a: /* ADC immed */ - dest = LHS + DPImmRHS + CFLAG; - WRITEDEST (dest); - break; - - case 0x2b: /* ADCS immed */ - lhs = LHS; - rhs = DPImmRHS; - dest = lhs + rhs + CFLAG; - ASSIGNZ (dest == 0); - if ((lhs | rhs) >> 30) { - /* Possible C,V,N to set. */ - ASSIGNN (NEG (dest)); - ARMul_AddCarry (state, lhs, rhs, dest); - ARMul_AddOverflow (state, lhs, rhs, dest); - } else { - CLEARN; - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x2c: /* SBC immed */ - dest = LHS - DPImmRHS - !CFLAG; - WRITEDEST (dest); - break; - - case 0x2d: /* SBCS immed */ - lhs = LHS; - rhs = DPImmRHS; - dest = lhs - rhs - !CFLAG; - if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, lhs, rhs, dest); - ARMul_SubOverflow (state, lhs, rhs, dest); - } else { - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x2e: /* RSC immed */ - dest = DPImmRHS - LHS - !CFLAG; - WRITEDEST (dest); - break; - - case 0x2f: /* RSCS immed */ - lhs = LHS; - rhs = DPImmRHS; - dest = rhs - lhs - !CFLAG; - if ((rhs >= lhs) || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, rhs, lhs, dest); - ARMul_SubOverflow (state, rhs, lhs, dest); - } else { - CLEARC; - CLEARV; - } - WRITESDEST (dest); - break; - - case 0x30: /* TST immed */ - /* shenoubang 2012-3-14*/ - if (state->is_v6) { /* movw, ARMV6, ARMv7 */ - dest ^= dest; - dest = BITS(16, 19); - dest = ((dest<<12) | BITS(0, 11)); - WRITEDEST(dest); - //SKYEYE_DBG("In %s, line = %d, pc = 0x%x, instr = 0x%x, R[0:11]: 0x%x, R[16:19]: 0x%x, R[%d]:0x%x\n", - // __func__, __LINE__, pc, instr, BITS(0, 11), BITS(16, 19), DESTReg, state->Reg[DESTReg]); - break; - } else { - UNDEF_Test; - break; - } - - case 0x31: /* TSTP immed */ - if (DESTReg == 15) { - /* TSTP immed. */ -#ifdef MODE32 - state->Cpsr = GETSPSR (state->Bank); - ARMul_CPSRAltered (state); -#else - temp = LHS & DPImmRHS; - SETR15PSR (temp); -#endif - } else { - /* TST immed. */ - DPSImmRHS; - dest = LHS & rhs; - ARMul_NegZero (state, dest); - } - break; - - case 0x32: /* TEQ immed and MSR immed to CPSR */ - if (DESTReg == 15) - /* MSR immed to CPSR. */ - ARMul_FixCPSR (state, instr, - DPImmRHS); - else - UNDEF_Test; - break; - - case 0x33: /* TEQP immed */ - if (DESTReg == 15) { - /* TEQP immed. */ -#ifdef MODE32 - state->Cpsr = GETSPSR (state->Bank); - ARMul_CPSRAltered (state); -#else - temp = LHS ^ DPImmRHS; - SETR15PSR (temp); -#endif - } else { - DPSImmRHS; /* TEQ immed */ - dest = LHS ^ rhs; - ARMul_NegZero (state, dest); - } - break; - - case 0x34: /* CMP immed */ - UNDEF_Test; - break; - - case 0x35: /* CMPP immed */ - if (DESTReg == 15) { - /* CMPP immed. */ -#ifdef MODE32 - state->Cpsr = GETSPSR (state->Bank); - ARMul_CPSRAltered (state); -#else - temp = LHS - DPImmRHS; - SETR15PSR (temp); -#endif - break; - } else { - /* CMP immed. */ - lhs = LHS; - rhs = DPImmRHS; - dest = lhs - rhs; - ARMul_NegZero (state, dest); - - if ((lhs >= rhs) || ((rhs | lhs) >> 31)) { - ARMul_SubCarry (state, lhs, rhs, dest); - ARMul_SubOverflow (state, lhs, rhs, dest); - } else { - CLEARC; - CLEARV; - } - } - break; - - case 0x36: /* CMN immed and MSR immed to SPSR */ - //if (DESTReg == 15) - /*ARMul0_FixSPSR (state, instr, - DPImmRHS);*/ - //else - UNDEF_Test; - break; - - case 0x37: /* CMNP immed. */ - if (DESTReg == 15) { - /* CMNP immed. */ -#ifdef MODE32 - state->Cpsr = GETSPSR (state->Bank); - ARMul_CPSRAltered (state); -#else - temp = LHS + DPImmRHS; - SETR15PSR (temp); -#endif - break; - } else { - /* CMN immed. */ - lhs = LHS; - rhs = DPImmRHS; - dest = lhs + rhs; - ASSIGNZ (dest == 0); - if ((lhs | rhs) >> 30) { - /* Possible C,V,N to set. */ - ASSIGNN (NEG (dest)); - ARMul_AddCarry (state, lhs, rhs, dest); - ARMul_AddOverflow (state, lhs, rhs, dest); - } else { - CLEARN; - CLEARC; - CLEARV; - } - } - break; - - case 0x38: /* ORR immed. */ - dest = LHS | DPImmRHS; - WRITEDEST (dest); - break; - - case 0x39: /* ORRS immed. */ - DPSImmRHS; - dest = LHS | rhs; - WRITESDEST (dest); - break; - - case 0x3a: /* MOV immed. */ - dest = DPImmRHS; - WRITEDEST (dest); - break; - - case 0x3b: /* MOVS immed. */ - DPSImmRHS; - WRITESDEST (rhs); - break; - - case 0x3c: /* BIC immed. */ - dest = LHS & ~DPImmRHS; - WRITEDEST (dest); - break; - - case 0x3d: /* BICS immed. */ - DPSImmRHS; - dest = LHS & ~rhs; - WRITESDEST (dest); - break; - - case 0x3e: /* MVN immed. */ - dest = ~DPImmRHS; - WRITEDEST (dest); - break; - - case 0x3f: /* MVNS immed. */ - DPSImmRHS; - WRITESDEST (~rhs); - break; - - - /* Single Data Transfer Immediate RHS Instructions. */ - - case 0x40: /* Store Word, No WriteBack, Post Dec, Immed. */ - lhs = LHS; - if (StoreWord (state, instr, lhs)) - LSBase = lhs - LSImmRHS; - break; - - case 0x41: /* Load Word, No WriteBack, Post Dec, Immed. */ - lhs = LHS; - if (LoadWord (state, instr, lhs)) - LSBase = lhs - LSImmRHS; - break; - - case 0x42: /* Store Word, WriteBack, Post Dec, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - lhs = LHS; - temp = lhs - LSImmRHS; - state->NtransSig = LOW; - if (StoreWord (state, instr, lhs)) - LSBase = temp; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x43: /* Load Word, WriteBack, Post Dec, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - lhs = LHS; - state->NtransSig = LOW; - if (LoadWord (state, instr, lhs)) - LSBase = lhs - LSImmRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x44: /* Store Byte, No WriteBack, Post Dec, Immed. */ - lhs = LHS; - if (StoreByte (state, instr, lhs)) - LSBase = lhs - LSImmRHS; - break; - - case 0x45: /* Load Byte, No WriteBack, Post Dec, Immed. */ - lhs = LHS; - if (LoadByte (state, instr, lhs, LUNSIGNED)) - LSBase = lhs - LSImmRHS; - break; - - case 0x46: /* Store Byte, WriteBack, Post Dec, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - lhs = LHS; - state->NtransSig = LOW; - if (StoreByte (state, instr, lhs)) - LSBase = lhs - LSImmRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x47: /* Load Byte, WriteBack, Post Dec, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - lhs = LHS; - state->NtransSig = LOW; - if (LoadByte (state, instr, lhs, LUNSIGNED)) - LSBase = lhs - LSImmRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x48: /* Store Word, No WriteBack, Post Inc, Immed. */ - lhs = LHS; - if (StoreWord (state, instr, lhs)) - LSBase = lhs + LSImmRHS; - break; - - case 0x49: /* Load Word, No WriteBack, Post Inc, Immed. */ - lhs = LHS; - if (LoadWord (state, instr, lhs)) - LSBase = lhs + LSImmRHS; - break; - - case 0x4a: /* Store Word, WriteBack, Post Inc, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - lhs = LHS; - state->NtransSig = LOW; - if (StoreWord (state, instr, lhs)) - LSBase = lhs + LSImmRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x4b: /* Load Word, WriteBack, Post Inc, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - lhs = LHS; - state->NtransSig = LOW; - if (LoadWord (state, instr, lhs)) - LSBase = lhs + LSImmRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x4c: /* Store Byte, No WriteBack, Post Inc, Immed. */ - lhs = LHS; - if (StoreByte (state, instr, lhs)) - LSBase = lhs + LSImmRHS; - break; - - case 0x4d: /* Load Byte, No WriteBack, Post Inc, Immed. */ - lhs = LHS; - if (LoadByte (state, instr, lhs, LUNSIGNED)) - LSBase = lhs + LSImmRHS; - break; - - case 0x4e: /* Store Byte, WriteBack, Post Inc, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - lhs = LHS; - state->NtransSig = LOW; - if (StoreByte (state, instr, lhs)) - LSBase = lhs + LSImmRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x4f: /* Load Byte, WriteBack, Post Inc, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - lhs = LHS; - state->NtransSig = LOW; - if (LoadByte (state, instr, lhs, LUNSIGNED)) - LSBase = lhs + LSImmRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - - case 0x50: /* Store Word, No WriteBack, Pre Dec, Immed. */ - (void) StoreWord (state, instr, LHS - LSImmRHS); - break; - - case 0x51: /* Load Word, No WriteBack, Pre Dec, Immed. */ - (void) LoadWord (state, instr, LHS - LSImmRHS); - break; - - case 0x52: /* Store Word, WriteBack, Pre Dec, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - temp = LHS - LSImmRHS; - if (StoreWord (state, instr, temp)) - LSBase = temp; - break; - - case 0x53: /* Load Word, WriteBack, Pre Dec, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - temp = LHS - LSImmRHS; - if (LoadWord (state, instr, temp)) - LSBase = temp; - break; - - case 0x54: /* Store Byte, No WriteBack, Pre Dec, Immed. */ - (void) StoreByte (state, instr, LHS - LSImmRHS); - break; - - case 0x55: /* Load Byte, No WriteBack, Pre Dec, Immed. */ - (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED); - break; - - case 0x56: /* Store Byte, WriteBack, Pre Dec, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - temp = LHS - LSImmRHS; - if (StoreByte (state, instr, temp)) - LSBase = temp; - break; - - case 0x57: /* Load Byte, WriteBack, Pre Dec, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - temp = LHS - LSImmRHS; - if (LoadByte (state, instr, temp, LUNSIGNED)) - LSBase = temp; - break; - - case 0x58: /* Store Word, No WriteBack, Pre Inc, Immed. */ - (void) StoreWord (state, instr, LHS + LSImmRHS); - break; - - case 0x59: /* Load Word, No WriteBack, Pre Inc, Immed. */ - (void) LoadWord (state, instr, LHS + LSImmRHS); - break; - - case 0x5a: /* Store Word, WriteBack, Pre Inc, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - temp = LHS + LSImmRHS; - if (StoreWord (state, instr, temp)) - LSBase = temp; - break; - - case 0x5b: /* Load Word, WriteBack, Pre Inc, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - temp = LHS + LSImmRHS; - if (LoadWord (state, instr, temp)) - LSBase = temp; - break; - - case 0x5c: /* Store Byte, No WriteBack, Pre Inc, Immed. */ - (void) StoreByte (state, instr, LHS + LSImmRHS); - break; - - case 0x5d: /* Load Byte, No WriteBack, Pre Inc, Immed. */ - (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED); - break; - - case 0x5e: /* Store Byte, WriteBack, Pre Inc, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - temp = LHS + LSImmRHS; - if (StoreByte (state, instr, temp)) - LSBase = temp; - break; - - case 0x5f: /* Load Byte, WriteBack, Pre Inc, Immed. */ - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - temp = LHS + LSImmRHS; - if (LoadByte (state, instr, temp, LUNSIGNED)) - LSBase = temp; - break; - - - /* Single Data Transfer Register RHS Instructions. */ - - case 0x60: /* Store Word, No WriteBack, Post Dec, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - if (StoreWord (state, instr, lhs)) - LSBase = lhs - LSRegRHS; - break; - - case 0x61: /* Load Word, No WriteBack, Post Dec, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - temp = lhs - LSRegRHS; - if (LoadWord (state, instr, lhs)) - LSBase = temp; - break; - - case 0x62: /* Store Word, WriteBack, Post Dec, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - state->NtransSig = LOW; - if (StoreWord (state, instr, lhs)) - LSBase = lhs - LSRegRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x63: /* Load Word, WriteBack, Post Dec, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - temp = lhs - LSRegRHS; - state->NtransSig = LOW; - if (LoadWord (state, instr, lhs)) - LSBase = temp; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x64: /* Store Byte, No WriteBack, Post Dec, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - if (StoreByte (state, instr, lhs)) - LSBase = lhs - LSRegRHS; - break; - - case 0x65: /* Load Byte, No WriteBack, Post Dec, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - temp = lhs - LSRegRHS; - if (LoadByte (state, instr, lhs, LUNSIGNED)) - LSBase = temp; - break; - - case 0x66: /* Store Byte, WriteBack, Post Dec, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - state->NtransSig = LOW; - if (StoreByte (state, instr, lhs)) - LSBase = lhs - LSRegRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x67: /* Load Byte, WriteBack, Post Dec, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 - && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - temp = lhs - LSRegRHS; - state->NtransSig = LOW; - if (LoadByte (state, instr, lhs, LUNSIGNED)) - LSBase = temp; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ - if ((instr & 0x70) == 0x10) { //pkhbt - u8 idest = BITS(12, 15); - u8 rfis = BITS(16, 19); - u8 rlast = BITS(0, 3); - u8 ishi = BITS(7,11); - state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000); - break; - } else if ((instr & 0x70) == 0x50) { //pkhtb - u8 rd_idx = BITS(12, 15); - u8 rn_idx = BITS(16, 19); - u8 rm_idx = BITS(0, 3); - u8 imm5 = BITS(7, 11) ? BITS(7, 11) : 31; - state->Reg[rd_idx] = ((static_cast<s32>(state->Reg[rm_idx]) >> imm5) & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000); - break; - } else if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 - && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - if (StoreWord (state, instr, lhs)) - LSBase = lhs + LSRegRHS; - break; - - case 0x69: /* Load Word, No WriteBack, Post Inc, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - temp = lhs + LSRegRHS; - if (LoadWord (state, instr, lhs)) - LSBase = temp; - break; - - case 0x6a: /* Store Word, WriteBack, Post Inc, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 - && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - state->NtransSig = LOW; - if (StoreWord (state, instr, lhs)) - LSBase = lhs + LSRegRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x6b: /* Load Word, WriteBack, Post Inc, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 - && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - temp = lhs + LSRegRHS; - state->NtransSig = LOW; - if (LoadWord (state, instr, lhs)) - LSBase = temp; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x6c: /* Store Byte, No WriteBack, Post Inc, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 - && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - if (StoreByte (state, instr, lhs)) - LSBase = lhs + LSRegRHS; - break; - - case 0x6d: /* Load Byte, No WriteBack, Post Inc, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - temp = lhs + LSRegRHS; - if (LoadByte (state, instr, lhs, LUNSIGNED)) - LSBase = temp; - break; - - case 0x6e: /* Store Byte, WriteBack, Post Inc, Reg. */ -#if 0 - if (state->is_v6) { - int Rm = 0; - /* utxb */ - if (BITS(15, 19) == 0xf && BITS(4, 7) == 0x7) { - - Rm = (RHS >> (8 * BITS(10, 11))) & 0xff; - DEST = Rm; - } - - } -#endif - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 - && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - state->NtransSig = LOW; - if (StoreByte (state, instr, lhs)) - LSBase = lhs + LSRegRHS; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - case 0x6f: /* Load Byte, WriteBack, Post Inc, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 - && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - lhs = LHS; - temp = lhs + LSRegRHS; - state->NtransSig = LOW; - if (LoadByte (state, instr, lhs, LUNSIGNED)) - LSBase = temp; - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - break; - - - case 0x70: /* Store Word, No WriteBack, Pre Dec, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - ARMul_UndefInstr (state, instr); - break; - } - (void) StoreWord (state, instr, LHS - LSRegRHS); - break; - - case 0x71: /* Load Word, No WriteBack, Pre Dec, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - (void) LoadWord (state, instr, LHS - LSRegRHS); - break; - - case 0x72: /* Store Word, WriteBack, Pre Dec, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - temp = LHS - LSRegRHS; - if (StoreWord (state, instr, temp)) - LSBase = temp; - break; - - case 0x73: /* Load Word, WriteBack, Pre Dec, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - temp = LHS - LSRegRHS; - if (LoadWord (state, instr, temp)) - LSBase = temp; - break; - - case 0x74: /* Store Byte, No WriteBack, Pre Dec, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - ARMul_UndefInstr (state, instr); - break; - } - (void) StoreByte (state, instr, LHS - LSRegRHS); - break; - - case 0x75: /* Load Byte, No WriteBack, Pre Dec, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - ARMul_UndefInstr (state, instr); - break; - } - (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED); - break; - - case 0x76: /* Store Byte, WriteBack, Pre Dec, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - temp = LHS - LSRegRHS; - if (StoreByte (state, instr, temp)) - LSBase = temp; - break; - - case 0x77: /* Load Byte, WriteBack, Pre Dec, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - temp = LHS - LSRegRHS; - if (LoadByte (state, instr, temp, LUNSIGNED)) - LSBase = temp; - break; - - case 0x78: /* Store Word, No WriteBack, Pre Inc, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - (void) StoreWord (state, instr, LHS + LSRegRHS); - break; - - case 0x79: /* Load Word, No WriteBack, Pre Inc, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - (void) LoadWord (state, instr, LHS + LSRegRHS); - break; - - case 0x7a: /* Store Word, WriteBack, Pre Inc, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - temp = LHS + LSRegRHS; - if (StoreWord (state, instr, temp)) - LSBase = temp; - break; - - case 0x7b: /* Load Word, WriteBack, Pre Inc, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - temp = LHS + LSRegRHS; - if (LoadWord (state, instr, temp)) - LSBase = temp; - break; - - case 0x7c: /* Store Byte, No WriteBack, Pre Inc, Reg. */ - if (BIT (4)) { -#ifdef MODE32 - if (state->is_v6 && handle_v6_insn (state, instr)) - break; -#endif - - ARMul_UndefInstr (state, instr); - break; - } - (void) StoreByte (state, instr, LHS + LSRegRHS); - break; - - case 0x7d: /* Load Byte, No WriteBack, Pre Inc, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED); - break; - - case 0x7e: /* Store Byte, WriteBack, Pre Inc, Reg. */ - if (BIT (4)) { - ARMul_UndefInstr (state, instr); - break; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - temp = LHS + LSRegRHS; - if (StoreByte (state, instr, temp)) - LSBase = temp; - break; - - case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */ - if (BIT (4)) { - LOG_DEBUG(Core_ARM11, "got unhandled special breakpoint"); - return 1; - } - UNDEF_LSRBaseEQOffWb; - UNDEF_LSRBaseEQDestWb; - UNDEF_LSRPCBaseWb; - UNDEF_LSRPCOffWb; - temp = LHS + LSRegRHS; - if (LoadByte (state, instr, temp, LUNSIGNED)) - LSBase = temp; - break; - - - /* Multiple Data Transfer Instructions. */ - - case 0x80: /* Store, No WriteBack, Post Dec. */ - STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L); - break; - - case 0x81: /* Load, No WriteBack, Post Dec. */ - LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L); - break; - - case 0x82: /* Store, WriteBack, Post Dec. */ - temp = LSBase - LSMNumRegs; - STOREMULT (instr, temp + 4L, temp); - break; - - case 0x83: /* Load, WriteBack, Post Dec. */ - temp = LSBase - LSMNumRegs; - LOADMULT (instr, temp + 4L, temp); - break; - - case 0x84: /* Store, Flags, No WriteBack, Post Dec. */ - STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L); - break; - - case 0x85: /* Load, Flags, No WriteBack, Post Dec. */ - LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L); - break; - - case 0x86: /* Store, Flags, WriteBack, Post Dec. */ - temp = LSBase - LSMNumRegs; - STORESMULT (instr, temp + 4L, temp); - break; - - case 0x87: /* Load, Flags, WriteBack, Post Dec. */ - temp = LSBase - LSMNumRegs; - LOADSMULT (instr, temp + 4L, temp); - break; - - case 0x88: /* Store, No WriteBack, Post Inc. */ - STOREMULT (instr, LSBase, 0L); - break; - - case 0x89: /* Load, No WriteBack, Post Inc. */ - LOADMULT (instr, LSBase, 0L); - break; - - case 0x8a: /* Store, WriteBack, Post Inc. */ - temp = LSBase; - STOREMULT (instr, temp, temp + LSMNumRegs); - break; - - case 0x8b: /* Load, WriteBack, Post Inc. */ - temp = LSBase; - LOADMULT (instr, temp, temp + LSMNumRegs); - break; - - case 0x8c: /* Store, Flags, No WriteBack, Post Inc. */ - STORESMULT (instr, LSBase, 0L); - break; - - case 0x8d: /* Load, Flags, No WriteBack, Post Inc. */ - LOADSMULT (instr, LSBase, 0L); - break; - - case 0x8e: /* Store, Flags, WriteBack, Post Inc. */ - temp = LSBase; - STORESMULT (instr, temp, temp + LSMNumRegs); - break; - - case 0x8f: /* Load, Flags, WriteBack, Post Inc. */ - temp = LSBase; - LOADSMULT (instr, temp, temp + LSMNumRegs); - break; - - case 0x90: /* Store, No WriteBack, Pre Dec. */ - STOREMULT (instr, LSBase - LSMNumRegs, 0L); - break; - - case 0x91: /* Load, No WriteBack, Pre Dec. */ - LOADMULT (instr, LSBase - LSMNumRegs, 0L); - break; - - case 0x92: /* Store, WriteBack, Pre Dec. */ - temp = LSBase - LSMNumRegs; - STOREMULT (instr, temp, temp); - break; - - case 0x93: /* Load, WriteBack, Pre Dec. */ - temp = LSBase - LSMNumRegs; - LOADMULT (instr, temp, temp); - break; - - case 0x94: /* Store, Flags, No WriteBack, Pre Dec. */ - STORESMULT (instr, LSBase - LSMNumRegs, 0L); - break; - - case 0x95: /* Load, Flags, No WriteBack, Pre Dec. */ - LOADSMULT (instr, LSBase - LSMNumRegs, 0L); - break; - - case 0x96: /* Store, Flags, WriteBack, Pre Dec. */ - temp = LSBase - LSMNumRegs; - STORESMULT (instr, temp, temp); - break; - - case 0x97: /* Load, Flags, WriteBack, Pre Dec. */ - temp = LSBase - LSMNumRegs; - LOADSMULT (instr, temp, temp); - break; - - case 0x98: /* Store, No WriteBack, Pre Inc. */ - STOREMULT (instr, LSBase + 4L, 0L); - break; - - case 0x99: /* Load, No WriteBack, Pre Inc. */ - LOADMULT (instr, LSBase + 4L, 0L); - break; - - case 0x9a: /* Store, WriteBack, Pre Inc. */ - temp = LSBase; - STOREMULT (instr, temp + 4L, temp + LSMNumRegs); - break; - - case 0x9b: /* Load, WriteBack, Pre Inc. */ - temp = LSBase; - LOADMULT (instr, temp + 4L, temp + LSMNumRegs); - break; - - case 0x9c: /* Store, Flags, No WriteBack, Pre Inc. */ - STORESMULT (instr, LSBase + 4L, 0L); - break; - - case 0x9d: /* Load, Flags, No WriteBack, Pre Inc. */ - LOADSMULT (instr, LSBase + 4L, 0L); - break; - - case 0x9e: /* Store, Flags, WriteBack, Pre Inc. */ - temp = LSBase; - STORESMULT (instr, temp + 4L, temp + LSMNumRegs); - break; - - case 0x9f: /* Load, Flags, WriteBack, Pre Inc. */ - temp = LSBase; - LOADSMULT (instr, temp + 4L, temp + LSMNumRegs); - break; - - - /* Branch forward. */ - case 0xa0: - case 0xa1: - case 0xa2: - case 0xa3: - case 0xa4: - case 0xa5: - case 0xa6: - case 0xa7: - state->Reg[15] = pc + 8 + POSBRANCH; - FLUSHPIPE; - break; - - - /* Branch backward. */ - case 0xa8: - case 0xa9: - case 0xaa: - case 0xab: - case 0xac: - case 0xad: - case 0xae: - case 0xaf: - state->Reg[15] = pc + 8 + NEGBRANCH; - FLUSHPIPE; - break; - - - /* Branch and Link forward. */ - case 0xb0: - case 0xb1: - case 0xb2: - case 0xb3: - case 0xb4: - case 0xb5: - case 0xb6: - case 0xb7: - - /* Put PC into Link. */ -#ifdef MODE32 - state->Reg[14] = pc + 4; -#else - state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE; -#endif - state->Reg[15] = pc + 8 + POSBRANCH; - FLUSHPIPE; - -#ifdef callstacker - memset(a, 0, 256); - aufloeser(a, state->Reg[15]); - printf("call %08X %08X %s(%08X %08X %08X %08X %08X %08X %08X)\n", state->Reg[14], state->Reg[15], a, state->Reg[0], state->Reg[1], state->Reg[2], state->Reg[3], mem_Read32(state->Reg[13]), mem_Read32(state->Reg[13] - 4),mem_Read32(state->Reg[13] - 8)); -#endif - - - break; - - - /* Branch and Link backward. */ - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: - case 0xbc: - case 0xbd: - case 0xbe: - case 0xbf: - /* Put PC into Link. */ -#ifdef MODE32 - state->Reg[14] = pc + 4; -#else - state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE; -#endif - state->Reg[15] = pc + 8 + NEGBRANCH; - FLUSHPIPE; - - -#ifdef callstacker - memset(a, 0, 256); - aufloeser(a, state->Reg[15]); - printf("call %08X %08X %s(%08X %08X %08X %08X %08X %08X %08X)\n", state->Reg[14], state->Reg[15], a, state->Reg[0], state->Reg[1], state->Reg[2], state->Reg[3], mem_Read32(state->Reg[13]), mem_Read32(state->Reg[13] - 4),mem_Read32(state->Reg[13] - 8)); -#endif - - - - break; - - - /* Co-Processor Data Transfers. */ - case 0xc4: - if ((instr & 0x0FF00FF0) == 0xC400B10) { //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0 - state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)]; - state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)]; - break; - } else if (state->is_v5) { - /* Reading from R15 is UNPREDICTABLE. */ - if (BITS (12, 15) == 15 || BITS (16, 19) == 15) - ARMul_UndefInstr (state, instr); - /* Is access to coprocessor 0 allowed ? */ - else if (!CP_ACCESS_ALLOWED(state, CPNum)) - ARMul_UndefInstr (state, instr); - else { - /* MCRR, ARMv5TE and up */ - ARMul_MCRR (state, instr, DEST, state->Reg[LHSReg]); - break; - } - } - /* Drop through. */ - - case 0xc0: /* Store , No WriteBack , Post Dec. */ - ARMul_STC (state, instr, LHS); - break; - - case 0xc5: - if ((instr & 0x00000FF0) == 0xB10) { //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0 - state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1]; - state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1]; - break; - } else if (state->is_v5) { - /* Writes to R15 are UNPREDICATABLE. */ - if (DESTReg == 15 || LHSReg == 15) - ARMul_UndefInstr (state, instr); - /* Is access to the coprocessor allowed ? */ - else if (!CP_ACCESS_ALLOWED(state, CPNum)) { - ARMul_UndefInstr(state, instr); - } else { - /* MRRC, ARMv5TE and up */ - ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg])); - break; - } - } - /* Drop through. */ - - case 0xc1: /* Load , No WriteBack , Post Dec. */ - ARMul_LDC (state, instr, LHS); - break; - - case 0xc2: - case 0xc6: /* Store , WriteBack , Post Dec. */ - lhs = LHS; - state->Base = lhs - LSCOff; - ARMul_STC (state, instr, lhs); - break; - - case 0xc3: - case 0xc7: /* Load , WriteBack , Post Dec. */ - lhs = LHS; - state->Base = lhs - LSCOff; - ARMul_LDC (state, instr, lhs); - break; - - case 0xc8: - case 0xcc: /* Store , No WriteBack , Post Inc. */ - ARMul_STC (state, instr, LHS); - break; - - case 0xc9: - case 0xcd: /* Load , No WriteBack , Post Inc. */ - ARMul_LDC (state, instr, LHS); - break; - - case 0xca: - case 0xce: /* Store , WriteBack , Post Inc. */ - lhs = LHS; - state->Base = lhs + LSCOff; - ARMul_STC (state, instr, LHS); - break; - - case 0xcb: - case 0xcf: /* Load , WriteBack , Post Inc. */ - lhs = LHS; - state->Base = lhs + LSCOff; - ARMul_LDC (state, instr, LHS); - break; - - case 0xd0: - case 0xd4: /* Store , No WriteBack , Pre Dec. */ - ARMul_STC (state, instr, LHS - LSCOff); - break; - - case 0xd1: - case 0xd5: /* Load , No WriteBack , Pre Dec. */ - ARMul_LDC (state, instr, LHS - LSCOff); - break; - - case 0xd2: - case 0xd6: /* Store , WriteBack , Pre Dec. */ - lhs = LHS - LSCOff; - state->Base = lhs; - ARMul_STC (state, instr, lhs); - break; - - case 0xd3: - case 0xd7: /* Load , WriteBack , Pre Dec. */ - lhs = LHS - LSCOff; - state->Base = lhs; - ARMul_LDC (state, instr, lhs); - break; - - case 0xd8: - case 0xdc: /* Store , No WriteBack , Pre Inc. */ - ARMul_STC (state, instr, LHS + LSCOff); - break; - - case 0xd9: - case 0xdd: /* Load , No WriteBack , Pre Inc. */ - ARMul_LDC (state, instr, LHS + LSCOff); - break; - - case 0xda: - case 0xde: /* Store , WriteBack , Pre Inc. */ - lhs = LHS + LSCOff; - state->Base = lhs; - ARMul_STC (state, instr, lhs); - break; - - case 0xdb: - case 0xdf: /* Load , WriteBack , Pre Inc. */ - lhs = LHS + LSCOff; - state->Base = lhs; - ARMul_LDC (state, instr, lhs); - break; - - - /* Co-Processor Register Transfers (MCR) and Data Ops. */ - - case 0xe2: - /*if (!CP_ACCESS_ALLOWED (state, CPNum)) { - ARMul_UndefInstr (state, instr); - break; - }*/ - - case 0xe0: - case 0xe4: - case 0xe6: - case 0xe8: - case 0xea: - case 0xec: - case 0xee: - if (BIT (4)) { - /* MCR. */ - if (DESTReg == 15) { - UNDEF_MCRPC; -#ifdef MODE32 - ARMul_MCR (state, instr, state->Reg[15] + isize); -#else - ARMul_MCR (state, instr, ECC | ER15INT | EMODE | ((state->Reg[15] + isize) & R15PCBITS)); -#endif - } else - ARMul_MCR (state, instr, DEST); - } else - /* CDP Part 1. */ - ARMul_CDP (state, instr); - break; - - - /* Co-Processor Register Transfers (MRC) and Data Ops. */ - case 0xe1: - case 0xe3: - case 0xe5: - case 0xe7: - case 0xe9: - case 0xeb: - case 0xed: - case 0xef: - if (BIT (4)) { - /* MRC */ - temp = ARMul_MRC (state, instr); - if (DESTReg == 15) { - ASSIGNN ((temp & NBIT) != 0); - ASSIGNZ ((temp & ZBIT) != 0); - ASSIGNC ((temp & CBIT) != 0); - ASSIGNV ((temp & VBIT) != 0); - } else - DEST = temp; - } else - /* CDP Part 2. */ - ARMul_CDP (state, instr); - break; - - - /* SWI instruction. */ - case 0xf0: - case 0xf1: - case 0xf2: - case 0xf3: - case 0xf4: - case 0xf5: - case 0xf6: - case 0xf7: - case 0xf8: - case 0xf9: - case 0xfa: - case 0xfb: - case 0xfc: - case 0xfd: - case 0xfe: - case 0xff: - //svc_Execute(state, BITS(0, 23)); - HLE::CallSVC(instr); - - break; - } - } - -#ifdef MODET -donext: -#endif - state->pc = pc; -#if 0 - /* shenoubang */ - instr_sum++; - int i, j; - i = j = 0; - if (instr_sum >= 7388648) { - //if (pc == 0xc0008ab4) { - // printf("instr_sum: %d\n", instr_sum); - // start_kernel : 0xc000895c - printf("--------------------------------------------------\n"); - for (i = 0; i < 16; i++) { - printf("[R%02d]:[0x%08x]\t", i, state->Reg[i]); - if ((i % 3) == 2) { - printf("\n"); - } - } - printf("[cpr]:[0x%08x]\t[spr0]:[0x%08x]\n", state->Cpsr, state->Spsr[0]); - for (j = 1; j < 7; j++) { - printf("[spr%d]:[0x%08x]\t", j, state->Spsr[j]); - if ((j % 4) == 3) { - printf("\n"); - } - } - printf("\n[PC]:[0x%08x]\t[INST]:[0x%08x]\t[COUNT]:[%d]\n", pc, instr, instr_sum); - printf("--------------------------------------------------\n"); - } -#endif - -#if 0 - fprintf(state->state_log, "PC:0x%x\n", pc); - for (reg_index = 0; reg_index < 16; reg_index ++) { - if (state->Reg[reg_index] != mirror_register_file[reg_index]) { - fprintf(state->state_log, "R%d:0x%x\n", reg_index, state->Reg[reg_index]); - mirror_register_file[reg_index] = state->Reg[reg_index]; - } - } - if (state->Cpsr != mirror_register_file[CPSR_REG]) { - fprintf(state->state_log, "Cpsr:0x%x\n", state->Cpsr); - mirror_register_file[CPSR_REG] = state->Cpsr; - } - if (state->RegBank[SVCBANK][13] != mirror_register_file[R13_SVC]) { - fprintf(state->state_log, "R13_SVC:0x%x\n", state->RegBank[SVCBANK][13]); - mirror_register_file[R13_SVC] = state->RegBank[SVCBANK][13]; - } - if (state->RegBank[SVCBANK][14] != mirror_register_file[R14_SVC]) { - fprintf(state->state_log, "R14_SVC:0x%x\n", state->RegBank[SVCBANK][14]); - mirror_register_file[R14_SVC] = state->RegBank[SVCBANK][14]; - } - if (state->RegBank[ABORTBANK][13] != mirror_register_file[R13_ABORT]) { - fprintf(state->state_log, "R13_ABORT:0x%x\n", state->RegBank[ABORTBANK][13]); - mirror_register_file[R13_ABORT] = state->RegBank[ABORTBANK][13]; - } - if (state->RegBank[ABORTBANK][14] != mirror_register_file[R14_ABORT]) { - fprintf(state->state_log, "R14_ABORT:0x%x\n", state->RegBank[ABORTBANK][14]); - mirror_register_file[R14_ABORT] = state->RegBank[ABORTBANK][14]; - } - if (state->RegBank[UNDEFBANK][13] != mirror_register_file[R13_UNDEF]) { - fprintf(state->state_log, "R13_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][13]); - mirror_register_file[R13_UNDEF] = state->RegBank[UNDEFBANK][13]; - } - if (state->RegBank[UNDEFBANK][14] != mirror_register_file[R14_UNDEF]) { - fprintf(state->state_log, "R14_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][14]); - mirror_register_file[R14_UNDEF] = state->RegBank[UNDEFBANK][14]; - } - if (state->RegBank[IRQBANK][13] != mirror_register_file[R13_IRQ]) { - fprintf(state->state_log, "R13_IRQ:0x%x\n", state->RegBank[IRQBANK][13]); - mirror_register_file[R13_IRQ] = state->RegBank[IRQBANK][13]; - } - if (state->RegBank[IRQBANK][14] != mirror_register_file[R14_IRQ]) { - fprintf(state->state_log, "R14_IRQ:0x%x\n", state->RegBank[IRQBANK][14]); - mirror_register_file[R14_IRQ] = state->RegBank[IRQBANK][14]; - } - if (state->RegBank[FIQBANK][8] != mirror_register_file[R8_FIRQ]) { - fprintf(state->state_log, "R8_FIRQ:0x%x\n", state->RegBank[FIQBANK][8]); - mirror_register_file[R8_FIRQ] = state->RegBank[FIQBANK][8]; - } - if (state->RegBank[FIQBANK][9] != mirror_register_file[R9_FIRQ]) { - fprintf(state->state_log, "R9_FIRQ:0x%x\n", state->RegBank[FIQBANK][9]); - mirror_register_file[R9_FIRQ] = state->RegBank[FIQBANK][9]; - } - if (state->RegBank[FIQBANK][10] != mirror_register_file[R10_FIRQ]) { - fprintf(state->state_log, "R10_FIRQ:0x%x\n", state->RegBank[FIQBANK][10]); - mirror_register_file[R10_FIRQ] = state->RegBank[FIQBANK][10]; - } - if (state->RegBank[FIQBANK][11] != mirror_register_file[R11_FIRQ]) { - fprintf(state->state_log, "R11_FIRQ:0x%x\n", state->RegBank[FIQBANK][11]); - mirror_register_file[R11_FIRQ] = state->RegBank[FIQBANK][11]; - } - if (state->RegBank[FIQBANK][12] != mirror_register_file[R12_FIRQ]) { - fprintf(state->state_log, "R12_FIRQ:0x%x\n", state->RegBank[FIQBANK][12]); - mirror_register_file[R12_FIRQ] = state->RegBank[FIQBANK][12]; - } - if (state->RegBank[FIQBANK][13] != mirror_register_file[R13_FIRQ]) { - fprintf(state->state_log, "R13_FIRQ:0x%x\n", state->RegBank[FIQBANK][13]); - mirror_register_file[R13_FIRQ] = state->RegBank[FIQBANK][13]; - } - if (state->RegBank[FIQBANK][14] != mirror_register_file[R14_FIRQ]) { - fprintf(state->state_log, "R14_FIRQ:0x%x\n", state->RegBank[FIQBANK][14]); - mirror_register_file[R14_FIRQ] = state->RegBank[FIQBANK][14]; - } - if (state->Spsr[SVCBANK] != mirror_register_file[SPSR_SVC]) { - fprintf(state->state_log, "SPSR_SVC:0x%x\n", state->Spsr[SVCBANK]); - mirror_register_file[SPSR_SVC] = state->RegBank[SVCBANK]; - } - if (state->Spsr[ABORTBANK] != mirror_register_file[SPSR_ABORT]) { - fprintf(state->state_log, "SPSR_ABORT:0x%x\n", state->Spsr[ABORTBANK]); - mirror_register_file[SPSR_ABORT] = state->RegBank[ABORTBANK]; - } - if (state->Spsr[UNDEFBANK] != mirror_register_file[SPSR_UNDEF]) { - fprintf(state->state_log, "SPSR_UNDEF:0x%x\n", state->Spsr[UNDEFBANK]); - mirror_register_file[SPSR_UNDEF] = state->RegBank[UNDEFBANK]; - } - if (state->Spsr[IRQBANK] != mirror_register_file[SPSR_IRQ]) { - fprintf(state->state_log, "SPSR_IRQ:0x%x\n", state->Spsr[IRQBANK]); - mirror_register_file[SPSR_IRQ] = state->RegBank[IRQBANK]; - } - if (state->Spsr[FIQBANK] != mirror_register_file[SPSR_FIRQ]) { - fprintf(state->state_log, "SPSR_FIRQ:0x%x\n", state->Spsr[FIQBANK]); - mirror_register_file[SPSR_FIRQ] = state->RegBank[FIQBANK]; - } - -#endif - -#ifdef NEED_UI_LOOP_HOOK - if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0) { - ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL; - ui_loop_hook (0); - } -#endif /* NEED_UI_LOOP_HOOK */ - - /*added energy_prof statement by ksh in 2004-11-26 */ - //chy 2005-07-28 for standalone - //ARMul_do_energy(state,instr,pc); -//teawater add for record reg value to ./reg.txt 2005.07.10--------------------- - if (state->tea_break_ok && pc == state->tea_break_addr) { - //ARMul_Debug (state, 0, 0); - state->tea_break_ok = 0; - } else { - state->tea_break_ok = 1; - } -//AJ2D-------------------------------------------------------------------------- -//chy 2006-04-14 for ctrl-c debug -#if 0 - if (debugmode) { - if (instr != ARMul_ABORTWORD) { - remote_interrupt_test_time++; - //chy 2006-04-14 2000 should be changed in skyeye_conf ???!!! - if (remote_interrupt_test_time >= 2000) { - remote_interrupt_test_time=0; - if (remote_interrupt()) { - //for test - //printf("SKYEYE: ICE_debug recv Ctrl_C\n"); - state->EndCondition = 0; - state->Emulate = STOP; - } - } - } - } -#endif - - /* jump out every time */ - //state->EndCondition = 0; - //state->Emulate = STOP; -//chy 2006-04-12 for ICE debug -TEST_EMULATE: - if (state->Emulate == ONCE) - state->Emulate = STOP; - //chy: 2003-08-23: should not use CHANGEMODE !!!! - /* If we have changed mode, allow the PC to advance before stopping. */ - // else if (state->Emulate == CHANGEMODE) - // continue; - else if (state->Emulate != RUN) - break; - - } - - while (state->NumInstrsToExecute); -exit: - state->decoded = decoded; - state->loaded = loaded; - state->pc = pc; - //chy 2006-04-12, for ICE debug - state->decoded_addr=decoded_addr; - state->loaded_addr=loaded_addr; - - return pc; - } - -//teawater add for arm2x86 2005.02.17------------------------------------------- - /*ywc 2005-04-01*/ -//#include "tb.h" -//#include "arm2x86_self.h" - - static volatile void (*gen_func) (void); -//static volatile ARMul_State *tmp_st; -//static volatile ARMul_State *save_st; - static volatile uint32_t tmp_st; - static volatile uint32_t save_st; - static volatile uint32_t save_T0; - static volatile uint32_t save_T1; - static volatile uint32_t save_T2; - -#ifdef MODE32 -#ifdef DBCT -//teawater change for debug function 2005.07.09--------------------------------- - ARMword - ARMul_Emulate32_dbct (ARMul_State * state) { - static int init = 0; - static FILE *fd; - - /*if (!init) { - - fd = fopen("./pc.txt", "w"); - if (!fd) { - exit(-1); - } - init = 1; - } */ - - state->Reg[15] += INSN_SIZE; - do { - /*if (skyeye_config.log.logon>=1) { - if (state->NumInstrs>=skyeye_config.log.start && state->NumInstrs<=skyeye_config.log.end) { - static int mybegin=0; - static int myinstrnum=0; - - if (mybegin==0) mybegin=1; - if (mybegin==1) { - state->Reg[15] -= INSN_SIZE; - if (skyeye_config.log.logon>=1) fprintf(skyeye_logfd,"N %llx :p %x,i %x,",state->NumInstrs, (state->Reg[15] - INSN_SIZE), instr); - if (skyeye_config.log.logon>=2) SKYEYE_OUTREGS(skyeye_logfd); - if (skyeye_config.log.logon>=3) SKYEYE_OUTMOREREGS(skyeye_logfd); - fprintf(skyeye_logfd,"\n"); - if (skyeye_config.log.length>0) { - myinstrnum++; - if (myinstrnum>=skyeye_config.log.length) { - myinstrnum=0; - fflush(skyeye_logfd); - fseek(skyeye_logfd,0L,SEEK_SET); - } - } - state->Reg[15] += INSN_SIZE; - } - } - } */ - state->trap = 0; - gen_func = - (void *) tb_find (state, state->Reg[15] - INSN_SIZE); - if (!gen_func) { - //fprintf(stderr, "SKYEYE: tb_find: Error in find the translate block.\n"); - //exit(-1); - //TRAP_INSN_ABORT - //TEA_OUT(printf("\n------------\npc:%x\n", state->Reg[15] - INSN_SIZE)); - //TEA_OUT(printf("TRAP_INSN_ABORT\n")); -//teawater add for xscale(arm v5) 2005.09.01------------------------------------ - /*XScale_set_fsr_far(state, ARMul_CP15_R5_MMU_EXCPT, state->Reg[15] - INSN_SIZE); - state->Reg[15] += INSN_SIZE; - ARMul_Abort(state, ARMul_PrefetchAbortV); - state->Reg[15] += INSN_SIZE; - goto next; */ - state->trap = TRAP_INSN_ABORT; - goto check; -//AJ2D-------------------------------------------------------------------------- - } - - save_st = (uint32_t) st; - save_T0 = T0; - save_T1 = T1; - save_T2 = T2; - tmp_st = (uint32_t) state; - wmb (); - st = (ARMul_State *) tmp_st; - gen_func (); - st = (ARMul_State *) save_st; - T0 = save_T0; - T1 = save_T1; - T2 = save_T2; - - /*if (state->trap != TRAP_OUT) { - state->tea_break_ok = 1; - } - if (state->trap <= TRAP_SET_R15) { - goto next; - } */ - //TEA_OUT(printf("\n------------\npc:%x\n", state->Reg[15] - INSN_SIZE)); -//teawater add check thumb 2005.07.21------------------------------------------- - /*if (TFLAG) { - state->Reg[15] -= 2; - return(state->Reg[15]); - } */ -//AJ2D-------------------------------------------------------------------------- - -//teawater add for xscale(arm v5) 2005.09.01------------------------------------ -check: -//AJ2D-------------------------------------------------------------------------- - switch (state->trap) { - case TRAP_RESET: { - //TEA_OUT(printf("TRAP_RESET\n")); - ARMul_Abort (state, ARMul_ResetV); - state->Reg[15] += INSN_SIZE; - } - break; - case TRAP_UNPREDICTABLE: { - //ARMul_Debug (state, 0, 0); - } - break; - case TRAP_INSN_UNDEF: { - //TEA_OUT(printf("TRAP_INSN_UNDEF\n")); - state->Reg[15] += INSN_SIZE; - ARMul_UndefInstr (state, 0); - state->Reg[15] += INSN_SIZE; - } - break; - case TRAP_SWI: { - //TEA_OUT(printf("TRAP_SWI\n")); - state->Reg[15] += INSN_SIZE; - ARMul_Abort (state, ARMul_SWIV); - state->Reg[15] += INSN_SIZE; - } - break; -//teawater add for xscale(arm v5) 2005.09.01------------------------------------ - case TRAP_INSN_ABORT: { - /*XScale_set_fsr_far (state, - ARMul_CP15_R5_MMU_EXCPT, - state->Reg[15] - - INSN_SIZE);*/ - state->Reg[15] += INSN_SIZE; - ARMul_Abort (state, ARMul_PrefetchAbortV); - state->Reg[15] += INSN_SIZE; - } - break; -//AJ2D-------------------------------------------------------------------------- - case TRAP_DATA_ABORT: { - //TEA_OUT(printf("TRAP_DATA_ABORT\n")); - state->Reg[15] += INSN_SIZE; - ARMul_Abort (state, ARMul_DataAbortV); - state->Reg[15] += INSN_SIZE; - } - break; - case TRAP_IRQ: { - //TEA_OUT(printf("TRAP_IRQ\n")); - state->Reg[15] += INSN_SIZE; - ARMul_Abort (state, ARMul_IRQV); - state->Reg[15] += INSN_SIZE; - } - break; - case TRAP_FIQ: { - //TEA_OUT(printf("TRAP_FIQ\n")); - state->Reg[15] += INSN_SIZE; - ARMul_Abort (state, ARMul_FIQV); - state->Reg[15] += INSN_SIZE; - } - break; - case TRAP_SETS_R15: { - //TEA_OUT(printf("TRAP_SETS_R15\n")); - /*if (state->Bank > 0) { - state->Cpsr = state->Spsr[state->Bank]; - ARMul_CPSRAltered (state); - } */ - WriteSR15 (state, state->Reg[15]); - } - break; - case TRAP_SET_CPSR: { - //TEA_OUT(printf("TRAP_SET_CPSR\n")); - //chy 2006-02-15 USERBANK=SYSTEMBANK=0 - //chy 2006-02-16 should use Mode to test - //if (state->Bank > 0) { - if (state->Mode != USER26MODE && state->Mode != USER32MODE) { - //ARMul_CPSRAltered (state); - } - state->Reg[15] += INSN_SIZE; - } - break; - case TRAP_OUT: { - //TEA_OUT(printf("TRAP_OUT\n")); - goto out; - } - break; - case TRAP_BREAKPOINT: { - //TEA_OUT(printf("TRAP_BREAKPOINT\n")); - state->Reg[15] -= INSN_SIZE; - if (!ARMul_OSHandleSWI - (state, SWI_Breakpoint)) { - ARMul_Abort (state, ARMul_SWIV); - } - state->Reg[15] += INSN_SIZE; - } - break; - } - -next: - if (state->Emulate == ONCE) { - state->Emulate = STOP; - break; - } else if (state->Emulate != RUN) { - break; - } - } while (!state->stop_simulator); - -out: - state->Reg[15] -= INSN_SIZE; - return (state->Reg[15]); - } -#endif -//AJ2D-------------------------------------------------------------------------- -#endif -//AJ2D-------------------------------------------------------------------------- - - /* This routine evaluates most Data Processing register RHS's with the S - bit clear. It is intended to be called from the macro DPRegRHS, which - filters the common case of an unshifted register with in line code. */ - - static ARMword - GetDPRegRHS (ARMul_State * state, ARMword instr) { - ARMword shamt, base; - - base = RHSReg; - if (BIT (4)) { - /* Shift amount in a register. */ - UNDEF_Shift; - INCPC; -#ifndef MODE32 - if (base == 15) - base = ECC | ER15INT | R15PC | EMODE; - else -#endif - base = state->Reg[base]; - ARMul_Icycles (state, 1, 0L); - shamt = state->Reg[BITS (8, 11)] & 0xff; - switch ((int) BITS (5, 6)) { - case LSL: - if (shamt == 0) - return (base); - else if (shamt >= 32) - return (0); - else - return (base << shamt); - case LSR: - if (shamt == 0) - return (base); - else if (shamt >= 32) - return (0); - else - return (base >> shamt); - case ASR: - if (shamt == 0) - return (base); - else if (shamt >= 32) - return ((ARMword) ((int) base >> 31L)); - else - return ((ARMword) - (( int) base >> (int) shamt)); - case ROR: - shamt &= 0x1f; - if (shamt == 0) - return (base); - else - return ((base << (32 - shamt)) | - (base >> shamt)); - } - } else { - /* Shift amount is a constant. */ -#ifndef MODE32 - if (base == 15) - base = ECC | ER15INT | R15PC | EMODE; - else -#endif - base = state->Reg[base]; - shamt = BITS (7, 11); - switch ((int) BITS (5, 6)) { - case LSL: - return (base << shamt); - case LSR: - if (shamt == 0) - return (0); - else - return (base >> shamt); - case ASR: - if (shamt == 0) - return ((ARMword) (( int) base >> 31L)); - else - return ((ARMword) - (( int) base >> (int) shamt)); - case ROR: - if (shamt == 0) - /* It's an RRX. */ - return ((base >> 1) | (CFLAG << 31)); - else - return ((base << (32 - shamt)) | - (base >> shamt)); - } - } - - return 0; - } - - /* This routine evaluates most Logical Data Processing register RHS's - with the S bit set. It is intended to be called from the macro - DPSRegRHS, which filters the common case of an unshifted register - with in line code. */ - - static ARMword - GetDPSRegRHS (ARMul_State * state, ARMword instr) { - ARMword shamt, base; - - base = RHSReg; - if (BIT (4)) { - /* Shift amount in a register. */ - UNDEF_Shift; - INCPC; -#ifndef MODE32 - if (base == 15) - base = ECC | ER15INT | R15PC | EMODE; - else -#endif - base = state->Reg[base]; - ARMul_Icycles (state, 1, 0L); - shamt = state->Reg[BITS (8, 11)] & 0xff; - switch ((int) BITS (5, 6)) { - case LSL: - if (shamt == 0) - return (base); - else if (shamt == 32) { - ASSIGNC (base & 1); - return (0); - } else if (shamt > 32) { - CLEARC; - return (0); - } else { - ASSIGNC ((base >> (32 - shamt)) & 1); - return (base << shamt); - } - case LSR: - if (shamt == 0) - return (base); - else if (shamt == 32) { - ASSIGNC (base >> 31); - return (0); - } else if (shamt > 32) { - CLEARC; - return (0); - } else { - ASSIGNC ((base >> (shamt - 1)) & 1); - return (base >> shamt); - } - case ASR: - if (shamt == 0) - return (base); - else if (shamt >= 32) { - ASSIGNC (base >> 31L); - return ((ARMword) (( int) base >> 31L)); - } else { - ASSIGNC ((ARMword) - (( int) base >> - (int) (shamt - 1)) & 1); - return ((ARMword) - ((int) base >> (int) shamt)); - } - case ROR: - if (shamt == 0) - return (base); - shamt &= 0x1f; - if (shamt == 0) { - ASSIGNC (base >> 31); - return (base); - } else { - ASSIGNC ((base >> (shamt - 1)) & 1); - return ((base << (32 - shamt)) | - (base >> shamt)); - } - } - } else { - /* Shift amount is a constant. */ -#ifndef MODE32 - if (base == 15) - base = ECC | ER15INT | R15PC | EMODE; - else -#endif - base = state->Reg[base]; - shamt = BITS (7, 11); - - switch ((int) BITS (5, 6)) { - case LSL: - ASSIGNC ((base >> (32 - shamt)) & 1); - return (base << shamt); - case LSR: - if (shamt == 0) { - ASSIGNC (base >> 31); - return (0); - } else { - ASSIGNC ((base >> (shamt - 1)) & 1); - return (base >> shamt); - } - case ASR: - if (shamt == 0) { - ASSIGNC (base >> 31L); - return ((ARMword) ((int) base >> 31L)); - } else { - ASSIGNC ((ARMword) - ((int) base >> - (int) (shamt - 1)) & 1); - return ((ARMword) - (( int) base >> (int) shamt)); - } - case ROR: - if (shamt == 0) { - /* It's an RRX. */ - shamt = CFLAG; - ASSIGNC (base & 1); - return ((base >> 1) | (shamt << 31)); - } else { - ASSIGNC ((base >> (shamt - 1)) & 1); - return ((base << (32 - shamt)) | - (base >> shamt)); - } - } - } - - return 0; - } - - /* This routine handles writes to register 15 when the S bit is not set. */ - - static void - WriteR15 (ARMul_State * state, ARMword src) { - /* The ARM documentation states that the two least significant bits - are discarded when setting PC, except in the cases handled by - WriteR15Branch() below. It's probably an oversight: in THUMB - mode, the second least significant bit should probably not be - discarded. */ -#ifdef MODET - if (TFLAG) - src &= 0xfffffffe; - else -#endif - src &= 0xfffffffc; - -#ifdef MODE32 - state->Reg[15] = src & PCBITS; -#else - state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE; - ARMul_R15Altered (state); -#endif - - FLUSHPIPE; - } - - /* This routine handles writes to register 15 when the S bit is set. */ - - static void - WriteSR15 (ARMul_State * state, ARMword src) { -#ifdef MODE32 - if (state->Bank > 0) { - state->Cpsr = state->Spsr[state->Bank]; - ARMul_CPSRAltered (state); - } -#ifdef MODET - if (TFLAG) - src &= 0xfffffffe; - else -#endif - src &= 0xfffffffc; - state->Reg[15] = src & PCBITS; -#else -#ifdef MODET - if (TFLAG) - /* ARMul_R15Altered would have to support it. */ - abort (); - else -#endif - src &= 0xfffffffc; - - if (state->Bank == USERBANK) - state->Reg[15] = - (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE; - else - state->Reg[15] = src; - - ARMul_R15Altered (state); -#endif - FLUSHPIPE; - } - - /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM - will switch to Thumb mode if the least significant bit is set. */ - - static void - WriteR15Branch (ARMul_State * state, ARMword src) { -#ifdef MODET - if (src & 1) { - /* Thumb bit. */ - SETT; - state->Reg[15] = src & 0xfffffffe; - } else { - CLEART; - state->Reg[15] = src & 0xfffffffc; - } - state->Cpsr = ARMul_GetCPSR (state); - FLUSHPIPE; -#else - WriteR15 (state, src); -#endif - } - - /* This routine evaluates most Load and Store register RHS's. It is - intended to be called from the macro LSRegRHS, which filters the - common case of an unshifted register with in line code. */ - - static ARMword - GetLSRegRHS (ARMul_State * state, ARMword instr) { - ARMword shamt, base; - - base = RHSReg; -#ifndef MODE32 - if (base == 15) - /* Now forbidden, but ... */ - base = ECC | ER15INT | R15PC | EMODE; - else -#endif - base = state->Reg[base]; - - shamt = BITS (7, 11); - switch ((int) BITS (5, 6)) { - case LSL: - return (base << shamt); - case LSR: - if (shamt == 0) - return (0); - else - return (base >> shamt); - case ASR: - if (shamt == 0) - return ((ARMword) (( int) base >> 31L)); - else - return ((ARMword) (( int) base >> (int) shamt)); - case ROR: - if (shamt == 0) - /* It's an RRX. */ - return ((base >> 1) | (CFLAG << 31)); - else - return ((base << (32 - shamt)) | (base >> shamt)); - default: - break; - } - return 0; - } - - /* This routine evaluates the ARM7T halfword and signed transfer RHS's. */ - - static ARMword - GetLS7RHS (ARMul_State * state, ARMword instr) { - if (BIT (22) == 0) { - /* Register. */ -#ifndef MODE32 - if (RHSReg == 15) - /* Now forbidden, but ... */ - return ECC | ER15INT | R15PC | EMODE; -#endif - return state->Reg[RHSReg]; - } - - /* Immediate. */ - return BITS (0, 3) | (BITS (8, 11) << 4); - } - - /* This function does the work of loading a word for a LDR instruction. */ -#define MEM_LOAD_LOG(description) if (skyeye_config.log.memlogon >= 1) { \ - fprintf(skyeye_logfd, \ - "m LOAD %s: N %llx :p %x :i %x :a %x :d %x\n", \ - description, state->NumInstrs, state->pc, instr, \ - address, dest); \ - } - -#define MEM_STORE_LOG(description) if (skyeye_config.log.memlogon >= 1) { \ - fprintf(skyeye_logfd, \ - "m STORE %s: N %llx :p %x :i %x :a %x :d %x\n", \ - description, state->NumInstrs, state->pc, instr, \ - address, DEST); \ - } - - - - static unsigned - LoadWord (ARMul_State * state, ARMword instr, ARMword address) { - ARMword dest; - - BUSUSEDINCPCS; -#ifndef MODE32 - if (ADDREXCEPT (address)) - INTERNALABORT (address); -#endif - - dest = ARMul_LoadWordN (state, address); - - if (state->Aborted) { - TAKEABORT; - return state->lateabtSig; - } - if (address & 3) - dest = ARMul_Align (state, address, dest); - WRITEDESTB (dest); - ARMul_Icycles (state, 1, 0L); - - //MEM_LOAD_LOG("WORD"); - - return (DESTReg != LHSReg); - } - -#ifdef MODET - /* This function does the work of loading a halfword. */ - - static unsigned - LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address, - int signextend) { - ARMword dest; - - BUSUSEDINCPCS; -#ifndef MODE32 - if (ADDREXCEPT (address)) - INTERNALABORT (address); -#endif - dest = ARMul_LoadHalfWord (state, address); - if (state->Aborted) { - TAKEABORT; - return state->lateabtSig; - } - UNDEF_LSRBPC; - if (signextend) - if (dest & 1 << (16 - 1)) - dest = (dest & ((1 << 16) - 1)) - (1 << 16); - - WRITEDEST (dest); - ARMul_Icycles (state, 1, 0L); - - //MEM_LOAD_LOG("HALFWORD"); - - return (DESTReg != LHSReg); - } - -#endif /* MODET */ - - /* This function does the work of loading a byte for a LDRB instruction. */ - - static unsigned - LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend) { - ARMword dest; - - BUSUSEDINCPCS; -#ifndef MODE32 - if (ADDREXCEPT (address)) - INTERNALABORT (address); -#endif - dest = ARMul_LoadByte (state, address); - if (state->Aborted) { - TAKEABORT; - return state->lateabtSig; - } - UNDEF_LSRBPC; - if (signextend) - if (dest & 1 << (8 - 1)) - dest = (dest & ((1 << 8) - 1)) - (1 << 8); - - WRITEDEST (dest); - ARMul_Icycles (state, 1, 0L); - - //MEM_LOAD_LOG("BYTE"); - - return (DESTReg != LHSReg); - } - - /* This function does the work of loading two words for a LDRD instruction. */ - - static void - Handle_Load_Double (ARMul_State * state, ARMword instr) { - ARMword dest_reg; - ARMword addr_reg; - ARMword write_back = BIT (21); - ARMword immediate = BIT (22); - ARMword add_to_base = BIT (23); - ARMword pre_indexed = BIT (24); - ARMword offset; - ARMword addr; - ARMword sum; - ARMword base; - ARMword value1; - ARMword value2; - - BUSUSEDINCPCS; - - /* If the writeback bit is set, the pre-index bit must be clear. */ - if (write_back && !pre_indexed) { - ARMul_UndefInstr (state, instr); - return; - } - - /* Extract the base address register. */ - addr_reg = LHSReg; - - /* Extract the destination register and check it. */ - dest_reg = DESTReg; - - /* Destination register must be even. */ - if ((dest_reg & 1) - /* Destination register cannot be LR. */ - || (dest_reg == 14)) { - ARMul_UndefInstr (state, instr); - return; - } - - /* Compute the base address. */ - base = state->Reg[addr_reg]; - - /* Compute the offset. */ - offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state-> - Reg[RHSReg]; - - /* Compute the sum of the two. */ - if (add_to_base) - sum = base + offset; - else - sum = base - offset; - - /* If this is a pre-indexed mode use the sum. */ - if (pre_indexed) - addr = sum; - else - addr = base; - - /* The address must be aligned on a 8 byte boundary. */ - /*if (addr & 0x7) { - #ifdef ABORTS - ARMul_DATAABORT (addr); - #else - ARMul_UndefInstr (state, instr); - #endif - return; - }*/ - /* Lets just forcibly align it for now */ - //addr = (addr + 7) & ~7; - - /* For pre indexed or post indexed addressing modes, - check that the destination registers do not overlap - the address registers. */ - if ((!pre_indexed || write_back) - && (addr_reg == dest_reg || addr_reg == dest_reg + 1)) { - ARMul_UndefInstr (state, instr); - return; - } - - /* Load the words. */ - value1 = ARMul_LoadWordN (state, addr); - value2 = ARMul_LoadWordN (state, addr + 4); - - /* Check for data aborts. */ - if (state->Aborted) { - TAKEABORT; - return; - } - - ARMul_Icycles (state, 2, 0L); - - /* Store the values. */ - state->Reg[dest_reg] = value1; - state->Reg[dest_reg + 1] = value2; - - /* Do the post addressing and writeback. */ - if (!pre_indexed) - addr = sum; - - if (!pre_indexed || write_back) - state->Reg[addr_reg] = addr; - } - - /* This function does the work of storing two words for a STRD instruction. */ - - static void - Handle_Store_Double (ARMul_State * state, ARMword instr) { - ARMword src_reg; - ARMword addr_reg; - ARMword write_back = BIT (21); - ARMword immediate = BIT (22); - ARMword add_to_base = BIT (23); - ARMword pre_indexed = BIT (24); - ARMword offset; - ARMword addr; - ARMword sum; - ARMword base; - - BUSUSEDINCPCS; - - /* If the writeback bit is set, the pre-index bit must be clear. */ - if (write_back && !pre_indexed) { - ARMul_UndefInstr (state, instr); - return; - } - - /* Extract the base address register. */ - addr_reg = LHSReg; - - /* Base register cannot be PC. */ - if (addr_reg == 15) { - ARMul_UndefInstr (state, instr); - return; - } - - /* Extract the source register. */ - src_reg = DESTReg; - - /* Source register must be even. */ - if (src_reg & 1) { - ARMul_UndefInstr (state, instr); - return; - } - - /* Compute the base address. */ - base = state->Reg[addr_reg]; - - /* Compute the offset. */ - offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state-> - Reg[RHSReg]; - - /* Compute the sum of the two. */ - if (add_to_base) - sum = base + offset; - else - sum = base - offset; - - /* If this is a pre-indexed mode use the sum. */ - if (pre_indexed) - addr = sum; - else - addr = base; - - /* The address must be aligned on a 8 byte boundary. */ - /*if (addr & 0x7) { - #ifdef ABORTS - ARMul_DATAABORT (addr); - #else - ARMul_UndefInstr (state, instr); - #endif - return; - }*/ - /* Lets just forcibly align it for now */ - //addr = (addr + 7) & ~7; - - /* For pre indexed or post indexed addressing modes, - check that the destination registers do not overlap - the address registers. */ - if ((!pre_indexed || write_back) - && (addr_reg == src_reg || addr_reg == src_reg + 1)) { - ARMul_UndefInstr (state, instr); - return; - } - - /* Load the words. */ - ARMul_StoreWordN (state, addr, state->Reg[src_reg]); - ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]); - - if (state->Aborted) { - TAKEABORT; - return; - } - - /* Do the post addressing and writeback. */ - if (!pre_indexed) - addr = sum; - - if (!pre_indexed || write_back) - state->Reg[addr_reg] = addr; - } - - /* This function does the work of storing a word from a STR instruction. */ - - static unsigned - StoreWord (ARMul_State * state, ARMword instr, ARMword address) { - //MEM_STORE_LOG("WORD"); - - BUSUSEDINCPCN; -#ifndef MODE32 - if (DESTReg == 15) - state->Reg[15] = ECC | ER15INT | R15PC | EMODE; -#endif -#ifdef MODE32 - ARMul_StoreWordN (state, address, DEST); -#else - if (VECTORACCESS (address) || ADDREXCEPT (address)) { - INTERNALABORT (address); - (void) ARMul_LoadWordN (state, address); - } else - ARMul_StoreWordN (state, address, DEST); -#endif - if (state->Aborted) { - TAKEABORT; - return state->lateabtSig; - } - - return TRUE; - } - -#ifdef MODET - /* This function does the work of storing a byte for a STRH instruction. */ - - static unsigned - StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address) { - //MEM_STORE_LOG("HALFWORD"); - - BUSUSEDINCPCN; - -#ifndef MODE32 - if (DESTReg == 15) - state->Reg[15] = ECC | ER15INT | R15PC | EMODE; -#endif - -#ifdef MODE32 - ARMul_StoreHalfWord (state, address, DEST); -#else - if (VECTORACCESS (address) || ADDREXCEPT (address)) { - INTERNALABORT (address); - (void) ARMul_LoadHalfWord (state, address); - } else - ARMul_StoreHalfWord (state, address, DEST); -#endif - - if (state->Aborted) { - TAKEABORT; - return state->lateabtSig; - } - return TRUE; - } - -#endif /* MODET */ - - /* This function does the work of storing a byte for a STRB instruction. */ - - static unsigned - StoreByte (ARMul_State * state, ARMword instr, ARMword address) { - //MEM_STORE_LOG("BYTE"); - - BUSUSEDINCPCN; -#ifndef MODE32 - if (DESTReg == 15) - state->Reg[15] = ECC | ER15INT | R15PC | EMODE; -#endif -#ifdef MODE32 - ARMul_StoreByte (state, address, DEST); -#else - if (VECTORACCESS (address) || ADDREXCEPT (address)) { - INTERNALABORT (address); - (void) ARMul_LoadByte (state, address); - } else - ARMul_StoreByte (state, address, DEST); -#endif - if (state->Aborted) { - TAKEABORT; - return state->lateabtSig; - } - //UNDEF_LSRBPC; - return TRUE; - } - - /* This function does the work of loading the registers listed in an LDM - instruction, when the S bit is clear. The code here is always increment - after, it's up to the caller to get the input address correct and to - handle base register modification. */ - - static void - LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase) { - ARMword dest, temp; - - //UNDEF_LSMNoRegs; - //UNDEF_LSMPCBase; - //UNDEF_LSMBaseInListWb; - BUSUSEDINCPCS; -#ifndef MODE32 - if (ADDREXCEPT (address)) - INTERNALABORT (address); -#endif - /*chy 2004-05-23 may write twice - if (BIT (21) && LHSReg != 15) - LSBase = WBBase; - */ - /* N cycle first. */ - for (temp = 0; !BIT (temp); temp++); - - dest = ARMul_LoadWordN (state, address); - - if (!state->abortSig && !state->Aborted) - state->Reg[temp++] = dest; - else if (!state->Aborted) { - //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); - state->Aborted = ARMul_DataAbortV; - } - /*chy 2004-05-23 chy goto end*/ - if (state->Aborted) - goto L_ldm_makeabort; - /* S cycles from here on. */ - for (; temp < 16; temp++) - if (BIT (temp)) { - /* Load this register. */ - address += 4; - dest = ARMul_LoadWordS (state, address); - - if (!state->abortSig && !state->Aborted) - state->Reg[temp] = dest; - else if (!state->Aborted) { - /*XScale_set_fsr_far (state, - ARMul_CP15_R5_ST_ALIGN, - address);*/ - state->Aborted = ARMul_DataAbortV; - } - /*chy 2004-05-23 chy goto end */ - if (state->Aborted) - goto L_ldm_makeabort; - - } - - if (BIT (15) && !state->Aborted) - /* PC is in the reg list. */ - WriteR15Branch (state, PC); - - /* To write back the final register. */ - /* ARMul_Icycles (state, 1, 0L);*/ - /*chy 2004-05-23, see below - if (state->Aborted) - { - if (BIT (21) && LHSReg != 15) - LSBase = WBBase; - - TAKEABORT; - } - */ - /*chy 2004-05-23 should compare the Abort Models*/ -L_ldm_makeabort: - /* To write back the final register. */ - ARMul_Icycles (state, 1, 0L); - - /* chy 2005-11-24, bug found by benjl@cse.unsw.edu.au, etc */ - /* - if (state->Aborted) - { - if (BIT (21) && LHSReg != 15) - if (!(state->abortSig && state->Aborted && state->lateabtSig == LOW)) - LSBase = WBBase; - TAKEABORT; - }else if (BIT (21) && LHSReg != 15) - LSBase = WBBase; - */ - if (state->Aborted) { - if (BIT (21) && LHSReg != 15) { - if (!(state->abortSig)) { - } - } - TAKEABORT; - } else if (BIT (21) && LHSReg != 15) { - LSBase = WBBase; - } - /* chy 2005-11-24, over */ - - } - - /* This function does the work of loading the registers listed in an LDM - instruction, when the S bit is set. The code here is always increment - after, it's up to the caller to get the input address correct and to - handle base register modification. */ - - static void - LoadSMult (ARMul_State * state, - ARMword instr, ARMword address, ARMword WBBase) { - ARMword dest, temp; - - //UNDEF_LSMNoRegs; - //UNDEF_LSMPCBase; - //UNDEF_LSMBaseInListWb; - - BUSUSEDINCPCS; - -#ifndef MODE32 - if (ADDREXCEPT (address)) - INTERNALABORT (address); -#endif - /* chy 2004-05-23, may write twice - if (BIT (21) && LHSReg != 15) - LSBase = WBBase; - */ - if (!BIT (15) && state->Bank != USERBANK) { - /* Temporary reg bank switch. */ - (void) ARMul_SwitchMode (state, state->Mode, USER26MODE); - UNDEF_LSMUserBankWb; - } - - /* N cycle first. */ - for (temp = 0; !BIT (temp); temp++); - - dest = ARMul_LoadWordN (state, address); - - if (!state->abortSig) - state->Reg[temp++] = dest; - else if (!state->Aborted) { - //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); - state->Aborted = ARMul_DataAbortV; - } - - /*chy 2004-05-23 chy goto end*/ - if (state->Aborted) - goto L_ldm_s_makeabort; - /* S cycles from here on. */ - for (; temp < 16; temp++) - if (BIT (temp)) { - /* Load this register. */ - address += 4; - dest = ARMul_LoadWordS (state, address); - - if (!state->abortSig && !state->Aborted) - state->Reg[temp] = dest; - else if (!state->Aborted) { - /*XScale_set_fsr_far (state, - ARMul_CP15_R5_ST_ALIGN, - address);*/ - state->Aborted = ARMul_DataAbortV; - } - /*chy 2004-05-23 chy goto end */ - if (state->Aborted) - goto L_ldm_s_makeabort; - } - - /*chy 2004-05-23 label of ldm_s_makeabort*/ -L_ldm_s_makeabort: - /*chy 2004-06-06 LSBase process should be here, not in the end of this function. Because ARMul_CPSRAltered maybe change R13(SP) R14(lr). If not, simulate INSTR ldmia sp!,[....pc]^ error.*/ - /*chy 2004-05-23 should compare the Abort Models*/ - if (state->Aborted) { - if (BIT (21) && LHSReg != 15) - if (! - (state->abortSig && state->Aborted - && state->lateabtSig == LOW)) - LSBase = WBBase; - TAKEABORT; - } else if (BIT (21) && LHSReg != 15) - LSBase = WBBase; - - if (BIT (15) && !state->Aborted) { - /* PC is in the reg list. */ -#ifdef MODE32 - //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode - if (state->Mode != USER26MODE && state->Mode != USER32MODE ) { - state->Cpsr = GETSPSR (state->Bank); - ARMul_CPSRAltered (state); - } - - WriteR15 (state, PC); -#else - //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode - if (state->Mode == USER26MODE || state->Mode == USER32MODE ) { - /* Protect bits in user mode. */ - ASSIGNN ((state->Reg[15] & NBIT) != 0); - ASSIGNZ ((state->Reg[15] & ZBIT) != 0); - ASSIGNC ((state->Reg[15] & CBIT) != 0); - ASSIGNV ((state->Reg[15] & VBIT) != 0); - } else - ARMul_R15Altered (state); - - FLUSHPIPE; -#endif - } - - //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode - if (!BIT (15) && state->Mode != USER26MODE - && state->Mode != USER32MODE ) - /* Restore the correct bank. */ - (void) ARMul_SwitchMode (state, USER26MODE, state->Mode); - - /* To write back the final register. */ - ARMul_Icycles (state, 1, 0L); - /* chy 2004-05-23, see below - if (state->Aborted) - { - if (BIT (21) && LHSReg != 15) - LSBase = WBBase; - - TAKEABORT; - } - */ - } - - /* This function does the work of storing the registers listed in an STM - instruction, when the S bit is clear. The code here is always increment - after, it's up to the caller to get the input address correct and to - handle base register modification. */ - - static void - StoreMult (ARMul_State * state, - ARMword instr, ARMword address, ARMword WBBase) { - ARMword temp; - - UNDEF_LSMNoRegs; - UNDEF_LSMPCBase; - UNDEF_LSMBaseInListWb; - - if (!TFLAG) - /* N-cycle, increment the PC and update the NextInstr state. */ - BUSUSEDINCPCN; - -#ifndef MODE32 - if (VECTORACCESS (address) || ADDREXCEPT (address)) - INTERNALABORT (address); - - if (BIT (15)) - PATCHR15; -#endif - - /* N cycle first. */ - for (temp = 0; !BIT (temp); temp++); - -#ifdef MODE32 - ARMul_StoreWordN (state, address, state->Reg[temp++]); -#else - if (state->Aborted) { - (void) ARMul_LoadWordN (state, address); - - /* Fake the Stores as Loads. */ - for (; temp < 16; temp++) - if (BIT (temp)) { - /* Save this register. */ - address += 4; - (void) ARMul_LoadWordS (state, address); - } - - if (BIT (21) && LHSReg != 15) - LSBase = WBBase; - TAKEABORT; - return; - } else - ARMul_StoreWordN (state, address, state->Reg[temp++]); -#endif - - if (state->abortSig && !state->Aborted) { - //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); - state->Aborted = ARMul_DataAbortV; - } - -//chy 2004-05-23, needn't store other when aborted - if (state->Aborted) - goto L_stm_takeabort; - - /* S cycles from here on. */ - for (; temp < 16; temp++) - if (BIT (temp)) { - /* Save this register. */ - address += 4; - - ARMul_StoreWordS (state, address, state->Reg[temp]); - - if (state->abortSig && !state->Aborted) { - /*XScale_set_fsr_far (state, - ARMul_CP15_R5_ST_ALIGN, - address);*/ - state->Aborted = ARMul_DataAbortV; - } - //chy 2004-05-23, needn't store other when aborted - if (state->Aborted) - goto L_stm_takeabort; - - } - -//chy 2004-05-23,should compare the Abort Models -L_stm_takeabort: - if (BIT (21) && LHSReg != 15) { - if (! - (state->abortSig && state->Aborted - && state->lateabtSig == LOW)) - LSBase = WBBase; - } - if (state->Aborted) - TAKEABORT; - } - - /* This function does the work of storing the registers listed in an STM - instruction when the S bit is set. The code here is always increment - after, it's up to the caller to get the input address correct and to - handle base register modification. */ - - static void - StoreSMult (ARMul_State * state, - ARMword instr, ARMword address, ARMword WBBase) { - ARMword temp; - - UNDEF_LSMNoRegs; - UNDEF_LSMPCBase; - UNDEF_LSMBaseInListWb; - - BUSUSEDINCPCN; - -#ifndef MODE32 - if (VECTORACCESS (address) || ADDREXCEPT (address)) - INTERNALABORT (address); - - if (BIT (15)) - PATCHR15; -#endif - - if (state->Bank != USERBANK) { - /* Force User Bank. */ - (void) ARMul_SwitchMode (state, state->Mode, USER26MODE); - UNDEF_LSMUserBankWb; - } - - for (temp = 0; !BIT (temp); temp++); /* N cycle first. */ - -#ifdef MODE32 - ARMul_StoreWordN (state, address, state->Reg[temp++]); -#else - if (state->Aborted) { - (void) ARMul_LoadWordN (state, address); - - for (; temp < 16; temp++) - /* Fake the Stores as Loads. */ - if (BIT (temp)) { - /* Save this register. */ - address += 4; - - (void) ARMul_LoadWordS (state, address); - } - - if (BIT (21) && LHSReg != 15) - LSBase = WBBase; - - TAKEABORT; - return; - } else - ARMul_StoreWordN (state, address, state->Reg[temp++]); -#endif - - if (state->abortSig && !state->Aborted) { - //XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); - state->Aborted = ARMul_DataAbortV; - } - -//chy 2004-05-23, needn't store other when aborted - if (state->Aborted) - goto L_stm_s_takeabort; - /* S cycles from here on. */ - for (; temp < 16; temp++) - if (BIT (temp)) { - /* Save this register. */ - address += 4; - - ARMul_StoreWordS (state, address, state->Reg[temp]); - - if (state->abortSig && !state->Aborted) { - /*XScale_set_fsr_far (state, - ARMul_CP15_R5_ST_ALIGN, - address);*/ - state->Aborted = ARMul_DataAbortV; - } - //chy 2004-05-23, needn't store other when aborted - if (state->Aborted) - goto L_stm_s_takeabort; - } - - //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode - if (state->Mode != USER26MODE && state->Mode != USER32MODE ) - /* Restore the correct bank. */ - (void) ARMul_SwitchMode (state, USER26MODE, state->Mode); - - -//chy 2004-05-23,should compare the Abort Models -L_stm_s_takeabort: - if (BIT (21) && LHSReg != 15) { - if (! - (state->abortSig && state->Aborted - && state->lateabtSig == LOW)) - LSBase = WBBase; - } - - if (state->Aborted) - TAKEABORT; - } - - /* This function does the work of adding two 32bit values - together, and calculating if a carry has occurred. */ - - static ARMword - Add32 (ARMword a1, ARMword a2, int *carry) { - ARMword result = (a1 + a2); - unsigned int uresult = (unsigned int) result; - unsigned int ua1 = (unsigned int) a1; - - /* If (result == RdLo) and (state->Reg[nRdLo] == 0), - or (result > RdLo) then we have no carry. */ - if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1)) - *carry = 1; - else - *carry = 0; - - return result; - } - - /* This function does the work of multiplying - two 32bit values to give a 64bit result. */ - - static unsigned - Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc) { - /* Operand register numbers. */ - int nRdHi, nRdLo, nRs, nRm; - ARMword RdHi = 0, RdLo = 0, Rm; - /* Cycle count. */ - int scount; - - nRdHi = BITS (16, 19); - nRdLo = BITS (12, 15); - nRs = BITS (8, 11); - nRm = BITS (0, 3); - - /* Needed to calculate the cycle count. */ - Rm = state->Reg[nRm]; - - /* Check for illegal operand combinations first. */ - if (nRdHi != 15 - && nRdLo != 15 - && nRs != 15 - //&& nRm != 15 && nRdHi != nRdLo && nRdHi != nRm && nRdLo != nRm) { - && nRm != 15 && nRdHi != nRdLo ) { - /* Intermediate results. */ - ARMword lo, mid1, mid2, hi; - int carry; - ARMword Rs = state->Reg[nRs]; - int sign = 0; - - if (msigned) { - /* Compute sign of result and adjust operands if necessary. */ - sign = (Rm ^ Rs) & 0x80000000; - - if (((signed int) Rm) < 0) - Rm = -Rm; - - if (((signed int) Rs) < 0) - Rs = -Rs; - } - - /* We can split the 32x32 into four 16x16 operations. This - ensures that we do not lose precision on 32bit only hosts. */ - lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF)); - mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF)); - mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF)); - hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF)); - - /* We now need to add all of these results together, taking - care to propogate the carries from the additions. */ - RdLo = Add32 (lo, (mid1 << 16), &carry); - RdHi = carry; - RdLo = Add32 (RdLo, (mid2 << 16), &carry); - RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + - ((mid2 >> 16) & 0xFFFF) + hi); - - if (sign) { - /* Negate result if necessary. */ - RdLo = ~RdLo; - RdHi = ~RdHi; - if (RdLo == 0xFFFFFFFF) { - RdLo = 0; - RdHi += 1; - } else - RdLo += 1; - } - - state->Reg[nRdLo] = RdLo; - state->Reg[nRdHi] = RdHi; - } else { - fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS, instr=0x%x\n", instr); - } - if (scc) - /* Ensure that both RdHi and RdLo are used to compute Z, - but don't let RdLo's sign bit make it to N. */ - ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF)); - - /* The cycle count depends on whether the instruction is a signed or - unsigned multiply, and what bits are clear in the multiplier. */ - if (msigned && (Rm & ((unsigned) 1 << 31))) - /* Invert the bits to make the check against zero. */ - Rm = ~Rm; - - if ((Rm & 0xFFFFFF00) == 0) - scount = 1; - else if ((Rm & 0xFFFF0000) == 0) - scount = 2; - else if ((Rm & 0xFF000000) == 0) - scount = 3; - else - scount = 4; - - return 2 + scount; - } - - /* This function does the work of multiplying two 32bit - values and adding a 64bit value to give a 64bit result. */ - - static unsigned - MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc) { - unsigned scount; - ARMword RdLo, RdHi; - int nRdHi, nRdLo; - int carry = 0; - - nRdHi = BITS (16, 19); - nRdLo = BITS (12, 15); - - RdHi = state->Reg[nRdHi]; - RdLo = state->Reg[nRdLo]; - - scount = Multiply64 (state, instr, msigned, LDEFAULT); - - RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry); - RdHi = (RdHi + state->Reg[nRdHi]) + carry; - - state->Reg[nRdLo] = RdLo; - state->Reg[nRdHi] = RdHi; - - if (scc) - /* Ensure that both RdHi and RdLo are used to compute Z, - but don't let RdLo's sign bit make it to N. */ - ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF)); - - /* Extra cycle for addition. */ - return scount + 1; - } - - /* Attempt to emulate an ARMv6 instruction. - Returns non-zero upon success. */ - - static int handle_v6_insn(ARMul_State* state, ARMword instr) { - switch (BITS(20, 27)) { - case 0x03: - printf ("Unhandled v6 insn: ldr\n"); - break; - case 0x04: // UMAAL - { - const u8 rm_idx = BITS(8, 11); - const u8 rn_idx = BITS(0, 3); - const u8 rd_lo_idx = BITS(12, 15); - const u8 rd_hi_idx = BITS(16, 19); - - const u32 rm_val = state->Reg[rm_idx]; - const u32 rn_val = state->Reg[rn_idx]; - const u32 rd_lo_val = state->Reg[rd_lo_idx]; - const u32 rd_hi_val = state->Reg[rd_hi_idx]; - - const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val; - - state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF); - state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF); - return 1; - } - break; - case 0x06: - printf ("Unhandled v6 insn: mls/str\n"); - break; - case 0x16: - printf ("Unhandled v6 insn: smi\n"); - break; - case 0x18: - if (BITS(4, 7) == 0x9) { - /* strex */ - u32 l = LHSReg; - u32 r = RHSReg; - u32 lhs = LHS; - - bool enter = false; - - if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true; - //StoreWord(state, lhs, RHS) - if (state->Aborted) { - TAKEABORT; - } - - if (enter) { - ARMul_StoreWordS(state, lhs, RHS); - state->Reg[DESTReg] = 0; - } - else { - state->Reg[DESTReg] = 1; - } - - return 1; - } - printf ("Unhandled v6 insn: strex\n"); - break; - case 0x19: - /* ldrex */ - if (BITS(4, 7) == 0x9) { - u32 lhs = LHS; - - state->currentexaddr = lhs; - state->currentexval = ARMul_ReadWord(state, lhs); - - LoadWord(state, instr, lhs); - return 1; - } - printf ("Unhandled v6 insn: ldrex\n"); - break; - case 0x1a: - printf ("Unhandled v6 insn: strexd\n"); - break; - case 0x1b: - printf ("Unhandled v6 insn: ldrexd\n"); - break; - case 0x1c: - if (BITS(4, 7) == 0x9) { - /* strexb */ - u32 lhs = LHS; - - bool enter = false; - - if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true; - - BUSUSEDINCPCN; - if (state->Aborted) { - TAKEABORT; - } - - - if (enter) { - ARMul_StoreByte(state, lhs, RHS); - state->Reg[DESTReg] = 0; - } - else { - state->Reg[DESTReg] = 1; - } - - //printf("In %s, strexb not implemented\n", __FUNCTION__); - UNDEF_LSRBPC; - /* WRITESDEST (dest); */ - return 1; - } - printf ("Unhandled v6 insn: strexb\n"); - break; - case 0x1d: - if ((BITS(4, 7)) == 0x9) { - /* ldrexb */ - u32 lhs = LHS; - LoadByte(state, instr, lhs, LUNSIGNED); - - state->currentexaddr = lhs; - state->currentexval = (u32)ARMul_ReadByte(state, lhs); - - //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); - //printf("ldrexb\n"); - //printf("instr is %x rm is %d\n", instr, BITS(16, 19)); - //exit(-1); - - //printf("In %s, ldrexb not implemented\n", __FUNCTION__); - return 1; - } - printf ("Unhandled v6 insn: ldrexb\n"); - break; - case 0x1e: - printf ("Unhandled v6 insn: strexh\n"); - break; - case 0x1f: - printf ("Unhandled v6 insn: ldrexh\n"); - break; - case 0x30: - printf ("Unhandled v6 insn: movw\n"); - break; - case 0x32: - printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n"); - break; - case 0x34: - printf ("Unhandled v6 insn: movt\n"); - break; - case 0x3f: - printf ("Unhandled v6 insn: rbit\n"); - break; - case 0x61: // SADD16, SASX, SSAX, and SSUB16 - if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 || - (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70) - { - const u8 rd_idx = BITS(12, 15); - const u8 rm_idx = BITS(0, 3); - const u8 rn_idx = BITS(16, 19); - const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF); - const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF); - const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF); - const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF); - - s32 lo_result; - s32 hi_result; - - // SADD16 - if ((instr & 0xFF0) == 0xf10) { - lo_result = (rn_lo + rm_lo); - hi_result = (rn_hi + rm_hi); - } - // SASX - else if ((instr & 0xFF0) == 0xf30) { - lo_result = (rn_lo - rm_hi); - hi_result = (rn_hi + rm_lo); - } - // SSAX - else if ((instr & 0xFF0) == 0xf50) { - lo_result = (rn_lo + rm_hi); - hi_result = (rn_hi - rm_lo); - } - // SSUB16 - else { - lo_result = (rn_lo - rm_lo); - hi_result = (rn_hi - rm_hi); - } - - state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); - - if (lo_result >= 0) { - state->GEFlag |= (1 << 16); - state->GEFlag |= (1 << 17); - } else { - state->GEFlag &= ~(1 << 16); - state->GEFlag &= ~(1 << 17); - } - - if (hi_result >= 0) { - state->GEFlag |= (1 << 18); - state->GEFlag |= (1 << 19); - } else { - state->GEFlag &= ~(1 << 18); - state->GEFlag &= ~(1 << 19); - } - - return 1; - } - // SADD8/SSUB8 - else if ((instr & 0xFF0) == 0xf90 || (instr & 0xFF0) == 0xff0) - { - const u8 rd_idx = BITS(12, 15); - const u8 rm_idx = BITS(0, 3); - const u8 rn_idx = BITS(16, 19); - const u32 rm_val = state->Reg[rm_idx]; - const u32 rn_val = state->Reg[rn_idx]; - - s32 lo_val1, lo_val2; - s32 hi_val1, hi_val2; - - // SADD8 - if ((instr & 0xFF0) == 0xf90) { - lo_val1 = (s32)(s8)(rn_val & 0xFF) + (s32)(s8)(rm_val & 0xFF); - lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) + (s32)(s8)((rm_val >> 8) & 0xFF); - hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) + (s32)(s8)((rm_val >> 16) & 0xFF); - hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) + (s32)(s8)((rm_val >> 24) & 0xFF); - } - // SSUB8 - else { - lo_val1 = (s32)(s8)(rn_val & 0xFF) - (s32)(s8)(rm_val & 0xFF); - lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) - (s32)(s8)((rm_val >> 8) & 0xFF); - hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) - (s32)(s8)((rm_val >> 16) & 0xFF); - hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) - (s32)(s8)((rm_val >> 24) & 0xFF); - } - - if (lo_val1 >= 0) - state->GEFlag |= (1 << 16); - else - state->GEFlag &= ~(1 << 16); - - if (lo_val2 >= 0) - state->GEFlag |= (1 << 17); - else - state->GEFlag &= ~(1 << 17); - - if (hi_val1 >= 0) - state->GEFlag |= (1 << 18); - else - state->GEFlag &= ~(1 << 18); - - if (hi_val2 >= 0) - state->GEFlag |= (1 << 19); - else - state->GEFlag &= ~(1 << 19); - - state->Reg[rd_idx] = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24)); - return 1; - } - else { - printf("Unhandled v6 insn: %08x", instr); - } - break; - case 0x62: // QADD16, QASX, QSAX, QSUB16, QADD8, and QSUB8 - { - const u8 op2 = BITS(5, 7); - - const u8 rd_idx = BITS(12, 15); - const u8 rn_idx = BITS(16, 19); - const u8 rm_idx = BITS(0, 3); - const u16 rm_lo = (state->Reg[rm_idx] & 0xFFFF); - const u16 rm_hi = ((state->Reg[rm_idx] >> 0x10) & 0xFFFF); - const u16 rn_lo = (state->Reg[rn_idx] & 0xFFFF); - const u16 rn_hi = ((state->Reg[rn_idx] >> 0x10) & 0xFFFF); - - u16 lo_result = 0; - u16 hi_result = 0; - - // QADD16 - if (op2 == 0x00) { - lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo); - hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi); - } - // QASX - else if (op2 == 0x01) { - lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi); - hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo); - } - // QSAX - else if (op2 == 0x02) { - lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi); - hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo); - } - // QSUB16 - else if (op2 == 0x03) { - lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo); - hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi); - } - // QADD8 - else if (op2 == 0x04) { - lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) | - ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8; - hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) | - ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8; - } - // QSUB8 - else if (op2 == 0x07) { - lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) | - ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8; - hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) | - ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8; - } - - state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); - return 1; - } - break; - case 0x63: - printf ("Unhandled v6 insn: shadd/shsub\n"); - break; - case 0x65: - { - u32 rd = (instr >> 12) & 0xF; - u32 rn = (instr >> 16) & 0xF; - u32 rm = (instr >> 0) & 0xF; - u32 from = state->Reg[rn]; - u32 to = state->Reg[rm]; - - if ((instr & 0xFF0) == 0xF10 || (instr & 0xFF0) == 0xF70) { // UADD16/USUB16 - u32 h1, h2; - state->Cpsr &= 0xfff0ffff; - if ((instr & 0x0F0) == 0x070) { // USUB16 - h1 = ((u16)from - (u16)to); - h2 = ((u16)(from >> 16) - (u16)(to >> 16)); - - if (!(h1 & 0xffff0000)) - state->GEFlag |= (3 << 16); - else - state->GEFlag &= ~(3 << 16); - - if (!(h2 & 0xffff0000)) - state->GEFlag |= (3 << 18); - else - state->GEFlag &= ~(3 << 18); - } - else { // UADD16 - h1 = ((u16)from + (u16)to); - h2 = ((u16)(from >> 16) + (u16)(to >> 16)); - - if (h1 & 0xffff0000) - state->GEFlag |= (3 << 16); - else - state->GEFlag &= ~(3 << 16); - - if (h2 & 0xffff0000) - state->GEFlag |= (3 << 18); - else - state->GEFlag &= ~(3 << 18); - } - - state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16)); - return 1; - } - else - if ((instr & 0xFF0) == 0xF90 || (instr & 0xFF0) == 0xFF0) { // UADD8/USUB8 - u32 b1, b2, b3, b4; - state->Cpsr &= 0xfff0ffff; - if ((instr & 0x0F0) == 0x0F0) { // USUB8 - b1 = ((u8)from - (u8)to); - b2 = ((u8)(from >> 8) - (u8)(to >> 8)); - b3 = ((u8)(from >> 16) - (u8)(to >> 16)); - b4 = ((u8)(from >> 24) - (u8)(to >> 24)); - - if (!(b1 & 0xffffff00)) - state->GEFlag |= (1 << 16); - else - state->GEFlag &= ~(1 << 16); - - if (!(b2 & 0xffffff00)) - state->GEFlag |= (1 << 17); - else - state->GEFlag &= ~(1 << 17); - - if (!(b3 & 0xffffff00)) - state->GEFlag |= (1 << 18); - else - state->GEFlag &= ~(1 << 18); - - if (!(b4 & 0xffffff00)) - state->GEFlag |= (1 << 19); - else - state->GEFlag &= ~(1 << 19); - } - else { // UADD8 - b1 = ((u8)from + (u8)to); - b2 = ((u8)(from >> 8) + (u8)(to >> 8)); - b3 = ((u8)(from >> 16) + (u8)(to >> 16)); - b4 = ((u8)(from >> 24) + (u8)(to >> 24)); - - if (b1 & 0xffffff00) - state->GEFlag |= (1 << 16); - else - state->GEFlag &= ~(1 << 16); - - if (b2 & 0xffffff00) - state->GEFlag |= (1 << 17); - else - state->GEFlag &= ~(1 << 17); - - if (b3 & 0xffffff00) - state->GEFlag |= (1 << 18); - else - state->GEFlag &= ~(1 << 18); - - if (b4 & 0xffffff00) - state->GEFlag |= (1 << 19); - else - state->GEFlag &= ~(1 << 19); - } - - state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); - return 1; - } - } - printf("Unhandled v6 insn: uasx/usax\n"); - break; - case 0x66: // UQADD16, UQASX, UQSAX, UQSUB16, UQADD8, and UQSUB8 - { - const u8 rd_idx = BITS(12, 15); - const u8 rm_idx = BITS(0, 3); - const u8 rn_idx = BITS(16, 19); - const u8 op2 = BITS(5, 7); - const u32 rm_val = state->Reg[rm_idx]; - const u32 rn_val = state->Reg[rn_idx]; - - u16 lo_val = 0; - u16 hi_val = 0; - - // UQADD16 - if (op2 == 0x00) { - lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); - hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); - } - // UQASX - else if (op2 == 0x01) { - lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); - hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); - } - // UQSAX - else if (op2 == 0x02) { - lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); - hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); - } - // UQSUB16 - else if (op2 == 0x03) { - lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF); - hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); - } - // UQADD8 - else if (op2 == 0x04) { - lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) | - ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8; - hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) | - ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8; - } - // UQSUB8 - else { - lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) | - ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8; - hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) | - ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8; - } - - state->Reg[rd_idx] = ((lo_val & 0xFFFF) | hi_val << 16); - return 1; - } - break; - case 0x67: // UHADD16, UHASX, UHSAX, UHSUB16, UHADD8, and UHSUB8. - { - const u8 op2 = BITS(5, 7); - - const u8 rm_idx = BITS(0, 3); - const u8 rn_idx = BITS(16, 19); - const u8 rd_idx = BITS(12, 15); - - const u32 rm_val = state->Reg[rm_idx]; - const u32 rn_val = state->Reg[rn_idx]; - - if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) - { - u32 lo_val = 0; - u32 hi_val = 0; - - // UHADD16 - if (op2 == 0x00) { - lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); - hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); - } - // UHASX - else if (op2 == 0x01) { - lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); - hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); - } - // UHSAX - else if (op2 == 0x02) { - lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); - hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); - } - // UHSUB16 - else if (op2 == 0x03) { - lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); - hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); - } - - lo_val >>= 1; - hi_val >>= 1; - - state->Reg[rd_idx] = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); - return 1; - } - else if (op2 == 0x04 || op2 == 0x07) { - u32 sum1; - u32 sum2; - u32 sum3; - u32 sum4; - - // UHADD8 - if (op2 == 0x04) { - sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); - sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); - sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); - sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); - } - // UHSUB8 - else { - sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); - sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); - sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); - sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); - } - - sum1 >>= 1; - sum2 >>= 1; - sum3 >>= 1; - sum4 >>= 1; - - state->Reg[rd_idx] = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24); - return 1; - } - } - break; - case 0x68: - { - u32 rd = (instr >> 12) & 0xF; - u32 rn = (instr >> 16) & 0xF; - u32 rm = (instr >> 0) & 0xF; - u32 from = state->Reg[rn]; - u32 to = state->Reg[rm]; - u32 cpsr = ARMul_GetCPSR(state); - if ((instr & 0xFF0) == 0xFB0) { // SEL - u32 result; - if (cpsr & (1 << 16)) - result = from & 0xff; - else - result = to & 0xff; - if (cpsr & (1 << 17)) - result |= from & 0x0000ff00; - else - result |= to & 0x0000ff00; - if (cpsr & (1 << 18)) - result |= from & 0x00ff0000; - else - result |= to & 0x00ff0000; - if (cpsr & (1 << 19)) - result |= from & 0xff000000; - else - result |= to & 0xff000000; - state->Reg[rd] = result; - return 1; - } - } - printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); - break; - - case 0x6a: // SSAT, SSAT16, SXTB, and SXTAB - { - const u8 op2 = BITS(5, 7); - - // SSAT16 - if (op2 == 0x01) { - const u8 rd_idx = BITS(12, 15); - const u8 rn_idx = BITS(0, 3); - const u8 num_bits = BITS(16, 19) + 1; - const s16 min = -(0x8000 >> (16 - num_bits)); - const s16 max = (0x7FFF >> (16 - num_bits)); - s16 rn_lo = (state->Reg[rn_idx]); - s16 rn_hi = (state->Reg[rn_idx] >> 16); - - if (rn_lo > max) { - rn_lo = max; - SETQ; - } else if (rn_lo < min) { - rn_lo = min; - SETQ; - } - - if (rn_hi > max) { - rn_hi = max; - SETQ; - } else if (rn_hi < min) { - rn_hi = min; - SETQ; - } - - state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16); - return 1; - } - else if (op2 == 0x03) { - const u8 rotation = BITS(10, 11) * 8; - u32 rm = ((state->Reg[BITS(0, 3)] >> rotation) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotation)) & 0xFF) & 0xFF); - if (rm & 0x80) - rm |= 0xffffff00; - - // SXTB, otherwise SXTAB - if (BITS(16, 19) == 0xf) - state->Reg[BITS(12, 15)] = rm; - else - state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm; - - return 1; - } - else { - printf("Unimplemented op: SSAT"); - } - } - break; - - case 0x6b: // REV, REV16, SXTH, and SXTAH - { - const u8 op2 = BITS(5, 7); - - // REV - if (op2 == 0x01) { - DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); - return 1; - } - // REV16 - else if (op2 == 0x05) { - DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8); - return 1; - } - else if (op2 == 0x03) { - const u8 rotate = BITS(10, 11) * 8; - - u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF); - if (rm & 0x8000) - rm |= 0xffff0000; - - // SXTH, otherwise SXTAH - if (BITS(16, 19) == 15) - state->Reg[BITS(12, 15)] = rm; - else - state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm; - - return 1; - } - } - break; - - case 0x6c: // UXTB16 and UXTAB16 - { - const u8 rm_idx = BITS(0, 3); - const u8 rn_idx = BITS(16, 19); - const u8 rd_idx = BITS(12, 15); - const u32 rm_val = state->Reg[rm_idx]; - const u32 rn_val = state->Reg[rn_idx]; - const u32 rotation = BITS(10, 11) * 8; - const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); - - // UXTB16 - if ((instr & 0xf03f0) == 0xf0070) { - state->Reg[rd_idx] = rotated_rm & 0x00FF00FF; - } - else { // UXTAB16 - const u8 lo_rotated = (rotated_rm & 0xFF); - const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated; - - const u8 hi_rotated = (rotated_rm >> 16) & 0xFF; - const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated; - - state->Reg[rd_idx] = ((hi_result << 16) | (lo_result & 0xFFFF)); - } - - return 1; - } - break; - case 0x6e: // USAT, USAT16, UXTB, and UXTAB - { - const u8 op2 = BITS(5, 7); - - // USAT16 - if (op2 == 0x01) { - const u8 rd_idx = BITS(12, 15); - const u8 rn_idx = BITS(0, 3); - const u8 num_bits = BITS(16, 19); - const s16 max = 0xFFFF >> (16 - num_bits); - s16 rn_lo = (state->Reg[rn_idx]); - s16 rn_hi = (state->Reg[rn_idx] >> 16); - - if (max < rn_lo) { - rn_lo = max; - SETQ; - } else if (rn_lo < 0) { - rn_lo = 0; - SETQ; - } - - if (max < rn_hi) { - rn_hi = max; - SETQ; - } else if (rn_hi < 0) { - rn_hi = 0; - SETQ; - } - - state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF); - return 1; - } - else if (op2 == 0x03) { - const u8 rotate = BITS(10, 11) * 8; - const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF); - - if (BITS(16, 19) == 0xf) - /* UXTB */ - state->Reg[BITS(12, 15)] = rm; - else - /* UXTAB */ - state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm; - - return 1; - } - else { - printf("Unimplemented op: USAT"); - } - } - break; - - case 0x6f: // UXTH, UXTAH, and REVSH. - { - const u8 op2 = BITS(5, 7); - - // REVSH - if (op2 == 0x05) { - DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8); - if (DEST & 0x8000) - DEST |= 0xffff0000; - return 1; - } - // UXTH and UXTAH - else if (op2 == 0x03) { - const u8 rotate = BITS(10, 11) * 8; - const ARMword rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF); - - // UXTH - if (BITS(16, 19) == 0xf) { - state->Reg[BITS(12, 15)] = rm; - } - // UXTAH - else { - state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm; - } - - return 1; - } - } - case 0x70: - // ichfly - // SMUAD, SMUSD, SMLAD, and SMLSD - if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 || - (instr & 0xd0) == 0x10 || (instr & 0xd0) == 0x50) - { - const u8 rd_idx = BITS(16, 19); - const u8 rn_idx = BITS(0, 3); - const u8 rm_idx = BITS(8, 11); - const u8 ra_idx = BITS(12, 15); - const bool do_swap = (BIT(5) == 1); - - u32 rm_val = state->Reg[rm_idx]; - const u32 rn_val = state->Reg[rn_idx]; - - if (do_swap) - rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); - - const s16 rm_lo = (rm_val & 0xFFFF); - const s16 rm_hi = ((rm_val >> 16) & 0xFFFF); - const s16 rn_lo = (rn_val & 0xFFFF); - const s16 rn_hi = ((rn_val >> 16) & 0xFFFF); - - const u32 product1 = (rn_lo * rm_lo); - const u32 product2 = (rn_hi * rm_hi); - - // SMUAD and SMLAD - if (BIT(6) == 0) { - state->Reg[rd_idx] = product1 + product2; - - if (BITS(12, 15) != 15) { - state->Reg[rd_idx] += state->Reg[ra_idx]; - if (ARMul_AddOverflowQ(product1 + product2, state->Reg[ra_idx])) - SETQ; - } - - if (ARMul_AddOverflowQ(product1, product2)) - SETQ; - } - // SMUSD and SMLSD - else { - state->Reg[rd_idx] = product1 - product2; - - if (BITS(12, 15) != 15) { - state->Reg[rd_idx] += state->Reg[ra_idx]; - - if (ARMul_AddOverflowQ(product1 - product2, state->Reg[ra_idx])) - SETQ; - } - } - - return 1; - } - break; - case 0x74: // SMLALD and SMLSLD - { - const u8 rm_idx = BITS(8, 11); - const u8 rn_idx = BITS(0, 3); - const u8 rdlo_idx = BITS(12, 15); - const u8 rdhi_idx = BITS(16, 19); - const bool do_swap = (BIT(5) == 1); - - const u32 rdlo_val = state->Reg[rdlo_idx]; - const u32 rdhi_val = state->Reg[rdhi_idx]; - const u32 rn_val = state->Reg[rn_idx]; - u32 rm_val = state->Reg[rm_idx]; - - if (do_swap) - rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); - - const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF); - const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF); - s64 result; - - // SMLALD - if (BIT(6) == 0) { - result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); - } - // SMLSLD - else { - result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); - } - - state->Reg[rdlo_idx] = (result & 0xFFFFFFFF); - state->Reg[rdhi_idx] = ((result >> 32) & 0xFFFFFFFF); - return 1; - } - break; - case 0x75: // SMMLA, SMMUL, and SMMLS - { - const u8 rm_idx = BITS(8, 11); - const u8 rn_idx = BITS(0, 3); - const u8 ra_idx = BITS(12, 15); - const u8 rd_idx = BITS(16, 19); - const bool do_round = (BIT(5) == 1); - - const u32 rm_val = state->Reg[rm_idx]; - const u32 rn_val = state->Reg[rn_idx]; - - // Assume SMMUL by default. - s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val; - - if (ra_idx != 15) { - const u32 ra_val = state->Reg[ra_idx]; - - // SMMLA, otherwise SMMLS - if (BIT(6) == 0) - result += ((s64)ra_val << 32); - else - result = ((s64)ra_val << 32) - result; - } - - if (do_round) - result += 0x80000000; - - state->Reg[rd_idx] = ((result >> 32) & 0xFFFFFFFF); - return 1; - } - break; - case 0x78: - if (BITS(20, 24) == 0x18) - { - const u8 rm_idx = BITS(8, 11); - const u8 rn_idx = BITS(0, 3); - const u8 rd_idx = BITS(16, 19); - - const u32 rm_val = state->Reg[rm_idx]; - const u32 rn_val = state->Reg[rn_idx]; - - const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF); - const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF); - const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF); - const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF); - - u32 finalDif = (diff1 + diff2 + diff3 + diff4); - - // Op is USADA8 if true. - const u8 ra_idx = BITS(12, 15); - if (ra_idx != 15) - finalDif += state->Reg[ra_idx]; - - state->Reg[rd_idx] = finalDif; - return 1; - } - break; - case 0x7a: - printf ("Unhandled v6 insn: usbfx\n"); - break; - case 0x7c: - printf ("Unhandled v6 insn: bfc/bfi\n"); - break; - case 0x84: - printf ("Unhandled v6 insn: srs\n"); - break; - default: - break; - } - printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27)); - return 0; - }
\ No newline at end of file diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp index 03bca2870..a52d14960 100644 --- a/src/core/arm/interpreter/arminit.cpp +++ b/src/core/arm/interpreter/arminit.cpp @@ -15,8 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -//#include <unistd.h> - #include "core/arm/skyeye_common/armdefs.h" #include "core/arm/skyeye_common/armemu.h" @@ -24,87 +22,46 @@ * Definitions for the emulator architecture * \***************************************************************************/ -void ARMul_EmulateInit (void); -ARMul_State *ARMul_NewState (ARMul_State * state); -void ARMul_Reset (ARMul_State * state); -ARMword ARMul_DoCycle (ARMul_State * state); -unsigned ARMul_DoCoPro (ARMul_State * state); -ARMword ARMul_DoProg (ARMul_State * state); -ARMword ARMul_DoInstr (ARMul_State * state); -void ARMul_Abort (ARMul_State * state, ARMword address); +void ARMul_EmulateInit(); +ARMul_State* ARMul_NewState(ARMul_State* state); +void ARMul_Reset (ARMul_State* state); unsigned ARMul_MultTable[32] = { 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16 }; -ARMword ARMul_ImmedTable[4096]; /* immediate DP LHS values */ -char ARMul_BitList[256]; /* number of bits in a byte table */ - -//chy 2006-02-22 add test debugmode -extern int debugmode; -extern int remote_interrupt( void ); - - -void arm_dyncom_Abort(ARMul_State * state, ARMword vector) -{ - ARMul_Abort(state, vector); -} - - -/* ahe-ykl : the following code to initialize user mode - code is architecture dependent and probably model dependant. */ - -/*#include "skyeye_arch.h" -#include "skyeye_pref.h" -#include "skyeye_exec_info.h" -#include "bank_defs.h"*/ -//#include "armcpu.h" -//#include "skyeye_callback.h" - -/* - ARM_CPU_State* cpu = get_current_cpu(); - arm_core_t* core = &cpu->core[0]; - - uint32_t sp = info->initial_sp; +ARMword ARMul_ImmedTable[4096]; // immediate DP LHS values +char ARMul_BitList[256]; // number of bits in a byte table - core->Cpsr = 0x10; // User mode -// FIXME: may need to add thumb -core->Reg[13] = sp; -core->Reg[10] = info->start_data; -core->Reg[0] = 0; -bus_read(32, sp + 4, &(core->Reg[1])); -bus_read(32, sp + 8, &(core->Reg[2])); -*/ /***************************************************************************\ * Call this routine once to set up the emulator's tables. * \***************************************************************************/ - -void -ARMul_EmulateInit (void) +void ARMul_EmulateInit() { unsigned int i, j; - for (i = 0; i < 4096; i++) { /* the values of 12 bit dp rhs's */ + // the values of 12 bit dp rhs's + for (i = 0; i < 4096; i++) { ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL); } - for (i = 0; i < 256; ARMul_BitList[i++] = 0); /* how many bits in LSM */ + // how many bits in LSM + for (i = 0; i < 256; ARMul_BitList[i++] = 0); for (j = 1; j < 256; j <<= 1) for (i = 0; i < 256; i++) if ((i & j) > 0) ARMul_BitList[i]++; + // you always need 4 times these values for (i = 0; i < 256; i++) - ARMul_BitList[i] *= 4; /* you always need 4 times these values */ + ARMul_BitList[i] *= 4; } /***************************************************************************\ * Returns a new instantiation of the ARMulator's state * \***************************************************************************/ - -ARMul_State * -ARMul_NewState (ARMul_State *state) +ARMul_State* ARMul_NewState(ARMul_State* state) { unsigned i, j; @@ -120,7 +77,6 @@ ARMul_NewState (ARMul_State *state) state->Spsr[i] = 0; state->Mode = 0; - state->CallDebug = FALSE; state->Debug = FALSE; state->VectorCatch = 0; state->Aborted = FALSE; @@ -128,34 +84,6 @@ ARMul_NewState (ARMul_State *state) state->Inted = 3; state->LastInted = 3; - state->CommandLine = NULL; - - state->EventSet = 0; - state->Now = 0; - state->EventPtr = - (struct EventNode **) malloc ((unsigned) EVENTLISTSIZE * - sizeof (struct EventNode *)); -#if DIFF_STATE - state->state_log = fopen("/data/state.log", "w"); - printf("create pc log file.\n"); -#endif - if (state->EventPtr == NULL) { - printf ("SKYEYE: ARMul_NewState malloc state->EventPtr error\n"); - exit(-1); - //skyeye_exit (-1); - } - for (i = 0; i < EVENTLISTSIZE; i++) - *(state->EventPtr + i) = NULL; -#if SAVE_LOG - state->state_log = fopen("/tmp/state.log", "w"); - printf("create pc log file.\n"); -#else -#if DIFF_LOG - state->state_log = fopen("/tmp/state.log", "r"); - printf("loaded pc log file.\n"); -#endif -#endif - #ifdef ARM61 state->prog32Sig = LOW; state->data32Sig = LOW; @@ -167,29 +95,14 @@ ARMul_NewState (ARMul_State *state) state->lateabtSig = HIGH; state->bigendSig = LOW; - //chy:2003-08-19 - state->LastTime = 0; - state->CP14R0_CCD = -1; - - /* ahe-ykl: common function for interpret and dyncom */ - /*sky_pref_t *pref = get_skyeye_pref(); - if (pref->user_mode_sim) - register_callback(arm_user_mode_init, Bootmach_callback); - */ - - memset(&state->exclusive_tag_array[0], 0xFF, sizeof(state->exclusive_tag_array[0]) * 128); - state->exclusive_access_state = 0; - //state->cpu = (cpu_config_t *) malloc (sizeof (cpu_config_t)); - //state->mem_bank = (mem_config_t *) malloc (sizeof (mem_config_t)); - return (state); + return state; } /***************************************************************************\ * Call this routine to set ARMulator to model a certain processor * \***************************************************************************/ -void -ARMul_SelectProcessor (ARMul_State * state, unsigned properties) +void ARMul_SelectProcessor(ARMul_State* state, unsigned properties) { if (properties & ARM_Fix26_Prop) { state->prog32Sig = LOW; @@ -198,27 +111,16 @@ ARMul_SelectProcessor (ARMul_State * state, unsigned properties) state->prog32Sig = HIGH; state->data32Sig = HIGH; } - /* 2004-05-09 chy - below line sould be in skyeye_mach_XXX.c 's XXX_mach_init function - */ - // state->lateabtSig = HIGH; - - - state->is_v4 = - (properties & (ARM_v4_Prop | ARM_v5_Prop)) ? HIGH : LOW; - state->is_v5 = (properties & ARM_v5_Prop) ? HIGH : LOW; - state->is_v5e = (properties & ARM_v5e_Prop) ? HIGH : LOW; - state->is_XScale = (properties & ARM_XScale_Prop) ? HIGH : LOW; - state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) ? HIGH : LOW; - /* state->is_v6 = LOW */; - /* jeff.du 2010-08-05 */ - state->is_v6 = (properties & ARM_v6_Prop) ? HIGH : LOW; - state->is_ep9312 = (properties & ARM_ep9312_Prop) ? HIGH : LOW; - //chy 2005-09-19 - state->is_pxa27x = (properties & ARM_PXA27X_Prop) ? HIGH : LOW; - /* shenoubang 2012-3-11 */ - state->is_v7 = (properties & ARM_v7_Prop) ? HIGH : LOW; + state->is_v4 = (properties & (ARM_v4_Prop | ARM_v5_Prop)) != 0; + state->is_v5 = (properties & ARM_v5_Prop) != 0; + state->is_v5e = (properties & ARM_v5e_Prop) != 0; + state->is_XScale = (properties & ARM_XScale_Prop) != 0; + state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) != 0; + state->is_v6 = (properties & ARM_v6_Prop) != 0; + state->is_ep9312 = (properties & ARM_ep9312_Prop) != 0; + state->is_pxa27x = (properties & ARM_PXA27X_Prop) != 0; + state->is_v7 = (properties & ARM_v7_Prop) != 0; /* Only initialse the coprocessor support once we know what kind of chip we are dealing with. */ @@ -229,11 +131,8 @@ ARMul_SelectProcessor (ARMul_State * state, unsigned properties) /***************************************************************************\ * Call this routine to set up the initial machine state (or perform a RESET * \***************************************************************************/ - -void -ARMul_Reset (ARMul_State * state) +void ARMul_Reset(ARMul_State* state) { - //fprintf(stderr,"armul_reset 0: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); state->NextInstr = 0; if (state->prog32Sig) { state->Reg[15] = 0; @@ -244,15 +143,13 @@ ARMul_Reset (ARMul_State * state) state->Cpsr = INTBITS | SVC26MODE; state->Mode = SVC26MODE; } - //fprintf(stderr,"armul_reset 1: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); - //ARMul_CPSRAltered (state); + state->Bank = SVCBANK; FLUSHPIPE; state->EndCondition = 0; state->ErrorCode = 0; - //fprintf(stderr,"armul_reset 2: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); state->NresetSig = HIGH; state->NfiqSig = HIGH; state->NirqSig = HIGH; @@ -261,266 +158,4 @@ ARMul_Reset (ARMul_State * state) state->AbortAddr = 1; state->NumInstrs = 0; - state->NumNcycles = 0; - state->NumScycles = 0; - state->NumIcycles = 0; - state->NumCcycles = 0; - state->NumFcycles = 0; - - //fprintf(stderr,"armul_reset 3: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); - //mmu_reset (state); - //fprintf(stderr,"armul_reset 4: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); - - //mem_reset (state); /* move to memory/ram.c */ - - //fprintf(stderr,"armul_reset 5: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode); - /*remove later. walimis 03.7.17 */ - //io_reset(state); - //lcd_disable(state); - - /*ywc 2005-04-07 move from ARMul_NewState , because skyeye_config.no_dbct will - *be configured in skyeye_option_init and it is called after ARMul_NewState*/ - state->tea_break_ok = 0; - state->tea_break_addr = 0; - state->tea_pc = 0; -#ifdef DBCT - if (!skyeye_config.no_dbct) { - //teawater add for arm2x86 2005.02.14------------------------------------------- - if (arm2x86_init (state)) { - printf ("SKYEYE: arm2x86_init error\n"); - //skyeye_exit (-1); - } - //AJ2D-------------------------------------------------------------------------- - } -#endif -} - - -/***************************************************************************\ -* Emulate the execution of an entire program. Start the correct emulator * -* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * -* address of the last instruction that is executed. * -\***************************************************************************/ - -//teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- -#ifdef DBCT_TEST_SPEED -static ARMul_State *dbct_test_speed_state = NULL; -static void -dbct_test_speed_sig(int signo) -{ - printf("\n0x%llx %llu\n", dbct_test_speed_state->instr_count, dbct_test_speed_state->instr_count); - exit(0); - //skyeye_exit(0); -} -#endif //DBCT_TEST_SPEED -//AJ2D-------------------------------------------------------------------------- - -ARMword -ARMul_DoProg (ARMul_State * state) -{ - ARMword pc = 0; - - /* - * 2007-01-24 removed the term-io functions by Anthony Lee, - * moved to "device/uart/skyeye_uart_stdio.c". - */ - -//teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- -#ifdef DBCT_TEST_SPEED - { - if (!dbct_test_speed_state) { - //init timer - struct itimerval value; - struct sigaction act; - - dbct_test_speed_state = state; - state->instr_count = 0; - act.sa_handler = dbct_test_speed_sig; - act.sa_flags = SA_RESTART; - //cygwin don't support ITIMER_VIRTUAL or ITIMER_PROF -#ifndef __CYGWIN__ - if (sigaction(SIGVTALRM, &act, NULL) == -1) { -#else - if (sigaction(SIGALRM, &act, NULL) == -1) { -#endif //__CYGWIN__ - fprintf(stderr, "init timer error.\n"); - exit(-1); - //skyeye_exit(-1); - } - if (skyeye_config.dbct_test_speed_sec) { - value.it_value.tv_sec = skyeye_config.dbct_test_speed_sec; - } else { - value.it_value.tv_sec = DBCT_TEST_SPEED_SEC; - } - printf("dbct_test_speed_sec = %ld\n", value.it_value.tv_sec); - value.it_value.tv_usec = 0; - value.it_interval.tv_sec = 0; - value.it_interval.tv_usec = 0; -#ifndef __CYGWIN__ - if (setitimer(ITIMER_VIRTUAL, &value, NULL) == -1) { -#else - if (setitimer(ITIMER_REAL, &value, NULL) == -1) { -#endif //__CYGWIN__ - fprintf(stderr, "init timer error.\n"); - //skyeye_exit(-1); - } - } - } -#endif //DBCT_TEST_SPEED -//AJ2D-------------------------------------------------------------------------- - state->Emulate = RUN; - while (state->Emulate != STOP) { - state->Emulate = RUN; - - /*ywc 2005-03-31 */ - if (state->prog32Sig && ARMul_MODE32BIT) { -#ifdef DBCT - if (skyeye_config.no_dbct) { - pc = ARMul_Emulate32 (state); - } else { - pc = ARMul_Emulate32_dbct (state); - } -#else - pc = ARMul_Emulate32 (state); -#endif - } - - else { - //pc = ARMul_Emulate26 (state); - } - //chy 2006-02-22, should test debugmode first - //chy 2006-04-14, put below codes in ARMul_Emulate -#if 0 - if(debugmode) - if(remote_interrupt()) - state->Emulate = STOP; -#endif - } - - /* - * 2007-01-24 removed the term-io functions by Anthony Lee, - * moved to "device/uart/skyeye_uart_stdio.c". - */ - - return (pc); -} - -/***************************************************************************\ -* Emulate the execution of one instruction. Start the correct emulator * -* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * -* address of the instruction that is executed. * -\***************************************************************************/ - -ARMword -ARMul_DoInstr (ARMul_State * state) -{ - ARMword pc = 0; - - state->Emulate = ONCE; - - /*ywc 2005-03-31 */ - if (state->prog32Sig && ARMul_MODE32BIT) { -#ifdef DBCT - if (skyeye_config.no_dbct) { - pc = ARMul_Emulate32 (state); - } else { -//teawater add compile switch for DBCT GDB RSP function 2005.10.21-------------- -#ifndef DBCT_GDBRSP - printf("DBCT GDBRSP function switch is off.\n"); - printf("To use this function, open \"#define DBCT_GDBRSP\" in arch/arm/common/armdefs.h & recompile skyeye.\n"); - skyeye_exit(-1); -#endif //DBCT_GDBRSP -//AJ2D-------------------------------------------------------------------------- - pc = ARMul_Emulate32_dbct (state); - } -#else - pc = ARMul_Emulate32 (state); -#endif - } - - //else - //pc = ARMul_Emulate26 (state); - - return (pc); -} - -/***************************************************************************\ -* This routine causes an Abort to occur, including selecting the correct * -* mode, register bank, and the saving of registers. Call with the * -* appropriate vector's memory address (0,4,8 ....) * -\***************************************************************************/ - -void -ARMul_Abort (ARMul_State * state, ARMword vector) -{ - ARMword temp; - int isize = INSN_SIZE; - int esize = (TFLAG ? 0 : 4); - int e2size = (TFLAG ? -4 : 0); - - state->Aborted = FALSE; - - if (state->prog32Sig) - if (ARMul_MODE26BIT) - temp = R15PC; - else - temp = state->Reg[15]; - else - temp = R15PC | ECC | ER15INT | EMODE; - - switch (vector) { - case ARMul_ResetV: /* RESET */ - SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE, - 0); - break; - case ARMul_UndefinedInstrV: /* Undefined Instruction */ - SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE, - isize); - break; - case ARMul_SWIV: /* Software Interrupt */ - SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE, - isize); - break; - case ARMul_PrefetchAbortV: /* Prefetch Abort */ - state->AbortAddr = 1; - SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, - esize); - break; - case ARMul_DataAbortV: /* Data Abort */ - SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, - e2size); - break; - case ARMul_AddrExceptnV: /* Address Exception */ - SETABORT (IBIT, SVC26MODE, isize); - break; - case ARMul_IRQV: /* IRQ */ - //chy 2003-09-02 the if sentence seems no use -#if 0 - if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp) - || (temp & ARMul_CP13_R0_IRQ)) -#endif - SETABORT (IBIT, - state->prog32Sig ? IRQ32MODE : IRQ26MODE, - esize); - break; - case ARMul_FIQV: /* FIQ */ - //chy 2003-09-02 the if sentence seems no use -#if 0 - if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp) - || (temp & ARMul_CP13_R0_FIQ)) -#endif - SETABORT (INTBITS, - state->prog32Sig ? FIQ32MODE : FIQ26MODE, - esize); - break; - } - - if (ARMul_MODE32BIT) { - /*if (state->mmu.control & CONTROL_VECTOR) - vector += 0xffff0000; //for v4 high exception address*/ - if (state->vector_remap_flag) - vector += state->vector_remap_addr; /* support some remap function in LPC processor */ - ARMul_SetR15 (state, vector); - } else - ARMul_SetR15 (state, R15CCINTMODE | vector); } diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index 68ac2a0ce..fd90fb0a4 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp @@ -20,402 +20,29 @@ #include "core/arm/disassembler/arm_disasm.h" #include "core/mem_map.h" - -static ARMword ModeToBank (ARMword); -static void EnvokeList (ARMul_State *, unsigned int, unsigned int); - -struct EventNode { - /* An event list node. */ - unsigned (*func) (ARMul_State *); /* The function to call. */ - struct EventNode *next; -}; - -/* This routine returns the value of a register from a mode. */ - -ARMword -ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg) -{ - mode &= MODEBITS; - if (mode != state->Mode) - return (state->RegBank[ModeToBank ((ARMword) mode)][reg]); - else - return (state->Reg[reg]); -} - -/* This routine sets the value of a register for a mode. */ - -void -ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value) -{ - mode &= MODEBITS; - if (mode != state->Mode) - state->RegBank[ModeToBank ((ARMword) mode)][reg] = value; - else - state->Reg[reg] = value; -} - -/* This routine returns the value of the PC, mode independently. */ - -ARMword -ARMul_GetPC (ARMul_State * state) -{ - if (state->Mode > SVC26MODE) - return state->Reg[15]; - else - return R15PC; -} - -/* This routine returns the value of the PC, mode independently. */ - -ARMword -ARMul_GetNextPC (ARMul_State * state) -{ - if (state->Mode > SVC26MODE) - return state->Reg[15] + INSN_SIZE; - else - return (state->Reg[15] + INSN_SIZE) & R15PCBITS; -} - -/* This routine sets the value of the PC. */ - -void -ARMul_SetPC (ARMul_State * state, ARMword value) -{ - if (ARMul_MODE32BIT) - state->Reg[15] = value & PCBITS; - else - state->Reg[15] = R15CCINTMODE | (value & R15PCBITS); - FLUSHPIPE; -} - -/* This routine returns the value of register 15, mode independently. */ - -ARMword -ARMul_GetR15 (ARMul_State * state) -{ - if (state->Mode > SVC26MODE) - return (state->Reg[15]); - else - return (R15PC | ECC | ER15INT | EMODE); -} - -/* This routine sets the value of Register 15. */ - -void -ARMul_SetR15 (ARMul_State * state, ARMword value) -{ - if (ARMul_MODE32BIT) - state->Reg[15] = value & PCBITS; - else { - state->Reg[15] = value; - ARMul_R15Altered (state); - } - FLUSHPIPE; -} - -/* This routine returns the value of the CPSR. */ - -ARMword -ARMul_GetCPSR (ARMul_State * state) -{ - //chy 2003-08-20: below is from gdb20030716, maybe isn't suitable for system simulator - //return (CPSR | state->Cpsr); for gdb20030716 - return (CPSR); //had be tested in old skyeye with gdb5.0-5.3 -} - -/* This routine sets the value of the CPSR. */ - -void -ARMul_SetCPSR (ARMul_State * state, ARMword value) -{ - state->Cpsr = value; - ARMul_CPSRAltered (state); -} - -/* This routine does all the nasty bits involved in a write to the CPSR, - including updating the register bank, given a MSR instruction. */ - -void -ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs) -{ - state->Cpsr = ARMul_GetCPSR (state); - //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode - if (state->Mode != USER26MODE && state->Mode != USER32MODE ) { - /* In user mode, only write flags. */ - if (BIT (16)) - SETPSR_C (state->Cpsr, rhs); - if (BIT (17)) - SETPSR_X (state->Cpsr, rhs); - if (BIT (18)) - SETPSR_S (state->Cpsr, rhs); - } - if (BIT (19)) - SETPSR_F (state->Cpsr, rhs); - ARMul_CPSRAltered (state); -} - -/* Get an SPSR from the specified mode. */ - -ARMword -ARMul_GetSPSR (ARMul_State * state, ARMword mode) -{ - ARMword bank = ModeToBank (mode & MODEBITS); - - if (!BANK_CAN_ACCESS_SPSR (bank)) - return ARMul_GetCPSR (state); - - return state->Spsr[bank]; -} - -/* This routine does a write to an SPSR. */ - -void -ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value) -{ - ARMword bank = ModeToBank (mode & MODEBITS); - - if (BANK_CAN_ACCESS_SPSR (bank)) - state->Spsr[bank] = value; -} - -/* This routine does a write to the current SPSR, given an MSR instruction. */ - -void -ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs) -{ - if (BANK_CAN_ACCESS_SPSR (state->Bank)) { - if (BIT (16)) - SETPSR_C (state->Spsr[state->Bank], rhs); - if (BIT (17)) - SETPSR_X (state->Spsr[state->Bank], rhs); - if (BIT (18)) - SETPSR_S (state->Spsr[state->Bank], rhs); - if (BIT (19)) - SETPSR_F (state->Spsr[state->Bank], rhs); - } -} - -/* This routine updates the state of the emulator after the Cpsr has been - changed. Both the processor flags and register bank are updated. */ - -void -ARMul_CPSRAltered (ARMul_State * state) -{ - ARMword oldmode; - - if (state->prog32Sig == LOW) - state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS); - - oldmode = state->Mode; - - /*if (state->Mode != (state->Cpsr & MODEBITS)) { - state->Mode = - ARMul_SwitchMode (state, state->Mode, - state->Cpsr & MODEBITS); - - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - }*/ - //state->Cpsr &= ~MODEBITS; - - ASSIGNINT (state->Cpsr & INTBITS); - //state->Cpsr &= ~INTBITS; - ASSIGNN ((state->Cpsr & NBIT) != 0); - //state->Cpsr &= ~NBIT; - ASSIGNZ ((state->Cpsr & ZBIT) != 0); - //state->Cpsr &= ~ZBIT; - ASSIGNC ((state->Cpsr & CBIT) != 0); - //state->Cpsr &= ~CBIT; - ASSIGNV ((state->Cpsr & VBIT) != 0); - //state->Cpsr &= ~VBIT; - ASSIGNQ ((state->Cpsr & QBIT) != 0); - //state->Cpsr &= ~QBIT; - state->GEFlag = (state->Cpsr & 0x000F0000); -#ifdef MODET - ASSIGNT ((state->Cpsr & TBIT) != 0); - //state->Cpsr &= ~TBIT; -#endif - - if (oldmode > SVC26MODE) { - if (state->Mode <= SVC26MODE) { - state->Emulate = CHANGEMODE; - state->Reg[15] = ECC | ER15INT | EMODE | R15PC; - } - } else { - if (state->Mode > SVC26MODE) { - state->Emulate = CHANGEMODE; - state->Reg[15] = R15PC; - } else - state->Reg[15] = ECC | ER15INT | EMODE | R15PC; - } -} - -/* This routine updates the state of the emulator after register 15 has - been changed. Both the processor flags and register bank are updated. - This routine should only be called from a 26 bit mode. */ - -void -ARMul_R15Altered (ARMul_State * state) -{ - if (state->Mode != R15MODE) { - state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE); - state->NtransSig = (state->Mode & 3) ? HIGH : LOW; - } - - if (state->Mode > SVC26MODE) - state->Emulate = CHANGEMODE; - - ASSIGNR15INT (R15INT); - - ASSIGNN ((state->Reg[15] & NBIT) != 0); - ASSIGNZ ((state->Reg[15] & ZBIT) != 0); - ASSIGNC ((state->Reg[15] & CBIT) != 0); - ASSIGNV ((state->Reg[15] & VBIT) != 0); -} - -/* This routine controls the saving and restoring of registers across mode - changes. The regbank matrix is largely unused, only rows 13 and 14 are - used across all modes, 8 to 14 are used for FIQ, all others use the USER - column. It's easier this way. old and new parameter are modes numbers. - Notice the side effect of changing the Bank variable. */ - -ARMword -ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode) -{ - unsigned i; - ARMword oldbank; - ARMword newbank; - static int revision_value = 53; - - oldbank = ModeToBank (oldmode); - newbank = state->Bank = ModeToBank (newmode); - - /* Do we really need to do it? */ - if (oldbank != newbank) { - if (oldbank == 3 && newbank == 2) { - //printf("icounter is %d PC is %x MODE CHANGED : %d --> %d\n", state->NumInstrs, state->pc, oldbank, newbank); - if (state->NumInstrs >= 5832487) { -// printf("%d, ", state->NumInstrs + revision_value); -// printf("revision_value : %d\n", revision_value); - revision_value ++; - } - } - /* Save away the old registers. */ - switch (oldbank) { - case USERBANK: - case IRQBANK: - case SVCBANK: - case ABORTBANK: - case UNDEFBANK: - if (newbank == FIQBANK) - for (i = 8; i < 13; i++) - state->RegBank[USERBANK][i] = - state->Reg[i]; - state->RegBank[oldbank][13] = state->Reg[13]; - state->RegBank[oldbank][14] = state->Reg[14]; - break; - case FIQBANK: - for (i = 8; i < 15; i++) - state->RegBank[FIQBANK][i] = state->Reg[i]; - break; - case DUMMYBANK: - for (i = 8; i < 15; i++) - state->RegBank[DUMMYBANK][i] = 0; - break; - default: - abort (); - } - - /* Restore the new registers. */ - switch (newbank) { - case USERBANK: - case IRQBANK: - case SVCBANK: - case ABORTBANK: - case UNDEFBANK: - if (oldbank == FIQBANK) - for (i = 8; i < 13; i++) - state->Reg[i] = - state->RegBank[USERBANK][i]; - state->Reg[13] = state->RegBank[newbank][13]; - state->Reg[14] = state->RegBank[newbank][14]; - break; - case FIQBANK: - for (i = 8; i < 15; i++) - state->Reg[i] = state->RegBank[FIQBANK][i]; - break; - case DUMMYBANK: - for (i = 8; i < 15; i++) - state->Reg[i] = 0; - break; - default: - abort (); - } - } - - return newmode; -} - -/* Given a processor mode, this routine returns the - register bank that will be accessed in that mode. */ - -static ARMword -ModeToBank (ARMword mode) -{ - static ARMword bankofmode[] = { - USERBANK, FIQBANK, IRQBANK, SVCBANK, - DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, - DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, - DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, - USERBANK, FIQBANK, IRQBANK, SVCBANK, - DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK, - DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK, - DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK - }; - - if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0]))) - return DUMMYBANK; - - return bankofmode[mode]; -} - -/* Returns the register number of the nth register in a reg list. */ - -unsigned -ARMul_NthReg (ARMword instr, unsigned number) +// Unsigned sum of absolute difference +u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) { - unsigned bit, upto; + if (left > right) + return left - right; - for (bit = 0, upto = 0; upto <= number; bit++) - if (BIT (bit)) - upto++; - - return (bit - 1); + return right - left; } -/* Unsigned sum of absolute difference */ -u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) +// Add with carry, indicates if a carry-out or signed overflow occurred. +u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred) { - if (left > right) - return left - right; + u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in; + s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in; + u64 result = (unsigned_sum & 0xFFFFFFFF); - return right - left; -} + if (carry_out_occurred) + *carry_out_occurred = (result != unsigned_sum); -/* Assigns the N and Z flags depending on the value of result. */ + if (overflow_occurred) + *overflow_occurred = ((s64)(s32)result != signed_sum); -void -ARMul_NegZero (ARMul_State * state, ARMword result) -{ - if (NEG (result)) { - SETN; - CLEARZ; - } else if (result == 0) { - CLEARN; - SETZ; - } else { - CLEARN; - CLEARZ; - } + return (u32)result; } // Compute whether an addition of A and B, giving RESULT, overflowed. @@ -432,23 +59,6 @@ bool SubOverflow(ARMword a, ARMword b, ARMword result) (POS(a) && NEG(b) && NEG(result))); } -/* Assigns the C flag after an addition of a and b to give result. */ - -void -ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result) -{ - ASSIGNC ((NEG (a) && NEG (b)) || - (NEG (a) && POS (result)) || (NEG (b) && POS (result))); -} - -/* Assigns the V flag after an addition of a and b to give result. */ - -void -ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) -{ - ASSIGNV (AddOverflow (a, b, result)); -} - // Returns true if the Q flag should be set as a result of overflow. bool ARMul_AddOverflowQ(ARMword a, ARMword b) { @@ -459,24 +69,7 @@ bool ARMul_AddOverflowQ(ARMword a, ARMword b) return false; } -/* Assigns the C flag after an subtraction of a and b to give result. */ - -void -ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result) -{ - ASSIGNC ((NEG (a) && POS (b)) || - (NEG (a) && POS (result)) || (POS (b) && POS (result))); -} - -/* Assigns the V flag after an subtraction of a and b to give result. */ - -void -ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) -{ - ASSIGNV (SubOverflow (a, b, result)); -} - -/* 8-bit signed saturated addition */ +// 8-bit signed saturated addition u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) { u8 result = left + right; @@ -491,7 +84,7 @@ u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) return result; } -/* 8-bit signed saturated subtraction */ +// 8-bit signed saturated subtraction u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) { u8 result = left - right; @@ -506,7 +99,7 @@ u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) return result; } -/* 16-bit signed saturated addition */ +// 16-bit signed saturated addition u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) { u16 result = left + right; @@ -521,7 +114,7 @@ u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) return result; } -/* 16-bit signed saturated subtraction */ +// 16-bit signed saturated subtraction u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) { u16 result = left - right; @@ -536,7 +129,7 @@ u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) return result; } -/* 8-bit unsigned saturated addition */ +// 8-bit unsigned saturated addition u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) { u8 result = left + right; @@ -547,7 +140,7 @@ u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) return result; } -/* 16-bit unsigned saturated addition */ +// 16-bit unsigned saturated addition u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) { u16 result = left + right; @@ -558,7 +151,7 @@ u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) return result; } -/* 8-bit unsigned saturated subtraction */ +// 8-bit unsigned saturated subtraction u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) { if (left <= right) @@ -567,7 +160,7 @@ u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) return left - right; } -/* 16-bit unsigned saturated subtraction */ +// 16-bit unsigned saturated subtraction u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) { if (left <= right) @@ -611,517 +204,3 @@ u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred) *saturation_occurred = false; return (u32)value; } - -/* This function does the work of generating the addresses used in an - LDC instruction. The code here is always post-indexed, it's up to the - caller to get the input address correct and to handle base register - modification. It also handles the Busy-Waiting. */ - -void -ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address) -{ - unsigned cpab; - ARMword data; - - UNDEF_LSCPCBaseWb; - //printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address); - /*chy 2004-05-23 should update this function in the future,should concern dataabort*/ -// chy 2004-05-25 , fix it now,so needn't printf -// printf("SKYEYE ARMul_LDC, should update this function!!!!!\n"); - //exit(-1); - - //if (!CP_ACCESS_ALLOWED (state, CPNum)) { - if (!state->LDC[CPNum]) { - /* - printf - ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n", - CPNum, instr, address); - */ - ARMul_UndefInstr (state, instr); - return; - } - - /*if (ADDREXCEPT (address)) - INTERNALABORT (address);*/ - - cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0); - while (cpab == ARMul_BUSY) { - ARMul_Icycles (state, 1, 0); - - if (IntPending (state)) { - cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, - instr, 0); - return; - } else - cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, - 0); - } - if (cpab == ARMul_CANT) { - /* - printf - ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n", - CPNum, instr, address); - */ - CPTAKEABORT; - return; - } - - cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0); - data = ARMul_LoadWordN (state, address); - //chy 2004-05-25 - if (state->abortSig || state->Aborted) - goto L_ldc_takeabort; - - BUSUSEDINCPCN; -//chy 2004-05-25 - /* - if (BIT (21)) - LSBase = state->Base; - */ - - cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); - - while (cpab == ARMul_INC) { - address += 4; - data = ARMul_LoadWordN (state, address); - //chy 2004-05-25 - if (state->abortSig || state->Aborted) - goto L_ldc_takeabort; - - cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); - } - -//chy 2004-05-25 -L_ldc_takeabort: - if (BIT (21)) { - if (! - ((state->abortSig || state->Aborted) - && state->lateabtSig == LOW)) - LSBase = state->Base; - } - - if (state->abortSig || state->Aborted) - TAKEABORT; -} - -/* This function does the work of generating the addresses used in an - STC instruction. The code here is always post-indexed, it's up to the - caller to get the input address correct and to handle base register - modification. It also handles the Busy-Waiting. */ - -void -ARMul_STC (ARMul_State * state, ARMword instr, ARMword address) -{ - unsigned cpab; - ARMword data; - - UNDEF_LSCPCBaseWb; - - //printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address); - /*chy 2004-05-23 should update this function in the future,should concern dataabort */ -// skyeye_instr_debug=0;printf("SKYEYE debug end!!!!\n"); -// chy 2004-05-25 , fix it now,so needn't printf -// printf("SKYEYE ARMul_STC, should update this function!!!!!\n"); - - //exit(-1); - //if (!CP_ACCESS_ALLOWED (state, CPNum)) { - if (!state->STC[CPNum]) { - /* - printf - ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr, CPnum is %x, instr %x, addr %x\n", - CPNum, instr, address); - */ - ARMul_UndefInstr (state, instr); - return; - } - - /*if (ADDREXCEPT (address) || VECTORACCESS (address)) - INTERNALABORT (address);*/ - - cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data); - while (cpab == ARMul_BUSY) { - ARMul_Icycles (state, 1, 0); - if (IntPending (state)) { - cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, - instr, 0); - return; - } else - cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, - &data); - } - - if (cpab == ARMul_CANT) { - /* - printf - ("SKYEYE ARMul_STC,CANT, undefinstr, CPnum is %x, instr %x, addr %x\n", - CPNum, instr, address); - */ - CPTAKEABORT; - return; - } - /*#ifndef MODE32 - if (ADDREXCEPT (address) || VECTORACCESS (address)) - INTERNALABORT (address); - #endif*/ - BUSUSEDINCPCN; -//chy 2004-05-25 - /* - if (BIT (21)) - LSBase = state->Base; - */ - cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); - ARMul_StoreWordN (state, address, data); - //chy 2004-05-25 - if (state->abortSig || state->Aborted) - goto L_stc_takeabort; - - while (cpab == ARMul_INC) { - address += 4; - cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); - ARMul_StoreWordN (state, address, data); - //chy 2004-05-25 - if (state->abortSig || state->Aborted) - goto L_stc_takeabort; - } -//chy 2004-05-25 -L_stc_takeabort: - if (BIT (21)) { - if (! - ((state->abortSig || state->Aborted) - && state->lateabtSig == LOW)) - LSBase = state->Base; - } - - if (state->abortSig || state->Aborted) - TAKEABORT; -} - -/* This function does the Busy-Waiting for an MCR instruction. */ - -void -ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) -{ - unsigned cpab; - int cm = BITS(0, 3) & 0xf; - int cp = BITS(5, 7) & 0x7; - int rd = BITS(12, 15) & 0xf; - int cn = BITS(16, 19) & 0xf; - int cpopc = BITS(21, 23) & 0x7; - - if (CPNum == 15 && source == 0) //Cache flush - { - return; - } - - //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source); - //if (!CP_ACCESS_ALLOWED (state, CPNum)) { - if (!state->MCR[CPNum]) { - //chy 2004-07-19 should fix in the future ????!!!! - LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x",CPNum, source); - ARMul_UndefInstr (state, instr); - return; - } - - //DEBUG("SKYEYE ARMul_MCR p%d, %d, r%d, c%d, c%d, %d\n", CPNum, cpopc, rd, cn, cm, cp); - //DEBUG("plutoo: MCR not implemented\n"); - //exit(1); - //return; - - cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source); - - while (cpab == ARMul_BUSY) { - ARMul_Icycles (state, 1, 0); - - if (IntPending (state)) { - cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, - instr, 0); - return; - } else - cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, - source); - } - - if (cpab == ARMul_CANT) { - LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x", instr, CPNum, source); //ichfly todo - //ARMul_Abort (state, ARMul_UndefinedInstrV); - } else { - BUSUSEDINCPCN; - ARMul_Ccycles (state, 1, 0); - } -} - -/* This function does the Busy-Waiting for an MCRR instruction. */ - -void -ARMul_MCRR (ARMul_State * state, ARMword instr, ARMword source1, ARMword source2) -{ - unsigned cpab; - - //if (!CP_ACCESS_ALLOWED (state, CPNum)) { - if (!state->MCRR[CPNum]) { - ARMul_UndefInstr (state, instr); - return; - } - - cpab = (state->MCRR[CPNum]) (state, ARMul_FIRST, instr, source1, source2); - - while (cpab == ARMul_BUSY) { - ARMul_Icycles (state, 1, 0); - - if (IntPending (state)) { - cpab = (state->MCRR[CPNum]) (state, ARMul_INTERRUPT, - instr, 0, 0); - return; - } else - cpab = (state->MCRR[CPNum]) (state, ARMul_BUSY, instr, - source1, source2); - } - if (cpab == ARMul_CANT) { - printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x, source %x %x\n", __FUNCTION__, CPNum, instr, source1, source2); - ARMul_Abort (state, ARMul_UndefinedInstrV); - } else { - BUSUSEDINCPCN; - ARMul_Ccycles (state, 1, 0); - } -} - -/* This function does the Busy-Waiting for an MRC instruction. */ - -ARMword ARMul_MRC (ARMul_State * state, ARMword instr) -{ - int cm = BITS(0, 3) & 0xf; - int cp = BITS(5, 7) & 0x7; - int rd = BITS(12, 15) & 0xf; - int cn = BITS(16, 19) & 0xf; - int cpopc = BITS(21, 23) & 0x7; - - if (cn == 13 && cm == 0 && cp == 3) { //c13,c0,3; returns CPU svc buffer - ARMword result = Memory::KERNEL_MEMORY_VADDR; - - if (result != -1) { - return result; - } - } - - //DEBUG("SKYEYE ARMul_MRC p%d, %d, r%d, c%d, c%d, %d\n", CPNum, cpopc, rd, cn, cm, cp); - //DEBUG("plutoo: MRC not implemented\n"); - //return; - - unsigned cpab; - ARMword result = 0; - - //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr); - //if (!CP_ACCESS_ALLOWED (state, CPNum)) { - if (!state->MRC[CPNum]) { - //chy 2004-07-19 should fix in the future????!!!! - LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x", CPNum, instr); - ARMul_UndefInstr (state, instr); - return -1; - } - - cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result); - while (cpab == ARMul_BUSY) { - ARMul_Icycles (state, 1, 0); - if (IntPending (state)) { - cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, - instr, 0); - return (0); - } else - cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, - &result); - } - if (cpab == ARMul_CANT) { - printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr); - ARMul_Abort (state, ARMul_UndefinedInstrV); - /* Parent will destroy the flags otherwise. */ - result = ECC; - } else { - BUSUSEDINCPCN; - ARMul_Ccycles (state, 1, 0); - ARMul_Icycles (state, 1, 0); - } - - return result; -} - -/* This function does the Busy-Waiting for an MRRC instruction. (to verify) */ - -void -ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2) -{ - unsigned cpab; - ARMword result1 = 0; - ARMword result2 = 0; - - //if (!CP_ACCESS_ALLOWED (state, CPNum)) { - if (!state->MRRC[CPNum]) { - ARMul_UndefInstr (state, instr); - return; - } - - cpab = (state->MRRC[CPNum]) (state, ARMul_FIRST, instr, &result1, &result2); - while (cpab == ARMul_BUSY) { - ARMul_Icycles (state, 1, 0); - if (IntPending (state)) { - cpab = (state->MRRC[CPNum]) (state, ARMul_INTERRUPT, - instr, 0, 0); - return; - } else - cpab = (state->MRRC[CPNum]) (state, ARMul_BUSY, instr, - &result1, &result2); - } - if (cpab == ARMul_CANT) { - printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x\n", __FUNCTION__, CPNum, instr); - ARMul_Abort (state, ARMul_UndefinedInstrV); - } else { - BUSUSEDINCPCN; - ARMul_Ccycles (state, 1, 0); - ARMul_Icycles (state, 1, 0); - } - - *dest1 = result1; - *dest2 = result2; -} - -/* This function does the Busy-Waiting for an CDP instruction. */ - -void -ARMul_CDP (ARMul_State * state, ARMword instr) -{ - unsigned cpab; - - //if (!CP_ACCESS_ALLOWED (state, CPNum)) { - if (!state->CDP[CPNum]) { - ARMul_UndefInstr (state, instr); - return; - } - cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr); - while (cpab == ARMul_BUSY) { - ARMul_Icycles (state, 1, 0); - if (IntPending (state)) { - cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, - instr); - return; - } else - cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr); - } - if (cpab == ARMul_CANT) - ARMul_Abort (state, ARMul_UndefinedInstrV); - else - BUSUSEDN; -} - -/* This function handles Undefined instructions, as CP isntruction. */ - -void -ARMul_UndefInstr (ARMul_State * state, ARMword instr) -{ - std::string disasm = ARM_Disasm::Disassemble(state->pc, instr); - LOG_ERROR(Core_ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr); - ARMul_Abort (state, ARMul_UndefinedInstrV); -} - -/* Return TRUE if an interrupt is pending, FALSE otherwise. */ - -unsigned -IntPending (ARMul_State * state) -{ - /* Any exceptions. */ - if (state->NresetSig == LOW) { - ARMul_Abort (state, ARMul_ResetV); - return TRUE; - } else if (!state->NfiqSig && !FFLAG) { - ARMul_Abort (state, ARMul_FIQV); - return TRUE; - } else if (!state->NirqSig && !IFLAG) { - ARMul_Abort (state, ARMul_IRQV); - return TRUE; - } - - return FALSE; -} - -/* Align a word access to a non word boundary. */ - -ARMword -ARMul_Align (ARMul_State* state, ARMword address, ARMword data) -{ - /* This code assumes the address is really unaligned, - as a shift by 32 is undefined in C. */ - - address = (address & 3) << 3; /* Get the word address. */ - return ((data >> address) | (data << (32 - address))); /* rot right */ -} - -/* This routine is used to call another routine after a certain number of - cycles have been executed. The first parameter is the number of cycles - delay before the function is called, the second argument is a pointer - to the function. A delay of zero doesn't work, just call the function. */ - -void -ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay, - unsigned (*what) (ARMul_State *)) -{ - unsigned int when; - struct EventNode *event; - - if (state->EventSet++ == 0) - state->Now = ARMul_Time (state); - when = (state->Now + delay) % EVENTLISTSIZE; - event = (struct EventNode *) malloc (sizeof (struct EventNode)); - if (!event) { - printf ("SKYEYE:ARMul_ScheduleEvent: malloc event error\n"); - exit(-1); - //skyeye_exit (-1); - } - event->func = what; - event->next = *(state->EventPtr + when); - *(state->EventPtr + when) = event; -} - -/* This routine is called at the beginning of - every cycle, to envoke scheduled events. */ - -void -ARMul_EnvokeEvent (ARMul_State * state) -{ - static unsigned int then; - - then = state->Now; - state->Now = ARMul_Time (state) % EVENTLISTSIZE; - if (then < state->Now) - /* Schedule events. */ - EnvokeList (state, then, state->Now); - else if (then > state->Now) { - /* Need to wrap around the list. */ - EnvokeList (state, then, EVENTLISTSIZE - 1L); - EnvokeList (state, 0L, state->Now); - } -} - -/* Envokes all the entries in a range. */ - -static void -EnvokeList (ARMul_State * state, unsigned int from, unsigned int to) -{ - for (; from <= to; from++) { - struct EventNode *anevent; - - anevent = *(state->EventPtr + from); - while (anevent) { - (anevent->func) (state); - state->EventSet--; - anevent = anevent->next; - } - *(state->EventPtr + from) = NULL; - } -} - -/* This routine is returns the number of clock ticks since the last reset. */ - -unsigned int -ARMul_Time (ARMul_State * state) -{ - return (state->NumScycles + state->NumNcycles + - state->NumIcycles + state->NumCcycles + state->NumFcycles); -} diff --git a/src/core/arm/interpreter/armvirt.cpp b/src/core/arm/interpreter/armvirt.cpp deleted file mode 100644 index 7845d1042..000000000 --- a/src/core/arm/interpreter/armvirt.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator. - Copyright (C) 1994 Advanced RISC Machines Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This file contains a complete ARMulator memory model, modelling a -"virtual memory" system. A much simpler model can be found in armfast.c, -and that model goes faster too, but has a fixed amount of memory. This -model's memory has 64K pages, allocated on demand from a 64K entry page -table. The routines PutWord and GetWord implement this. Pages are never -freed as they might be needed again. A single area of memory may be -defined to generate aborts. */ - -#include "core/arm/skyeye_common/armdefs.h" -#include "core/arm/skyeye_common/armemu.h" - -#include "core/mem_map.h" - -#define dumpstack 1 -#define dumpstacksize 0x10 -#define maxdmupaddr 0x0033a850 - -/*ARMword ARMul_GetCPSR (ARMul_State * state) { -return 0; -} -ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode) { -return 0; -} -void ARMul_SetCPSR (ARMul_State * state, ARMword value) { - -} -void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value) { - -}*/ - -void ARMul_Icycles(ARMul_State * state, unsigned number, ARMword address) { -} - -void ARMul_Ccycles(ARMul_State * state, unsigned number, ARMword address) { -} - -ARMword ARMul_LoadInstrS(ARMul_State * state, ARMword address, ARMword isize) { - state->NumScycles++; - -#ifdef HOURGLASS - if ((state->NumScycles & HOURGLASS_RATE) == 0) { - HOURGLASS; - } -#endif - if (isize == 2) - return (u16)Memory::Read16(address); - else - return (u32)Memory::Read32(address); -} - -ARMword ARMul_LoadInstrN(ARMul_State * state, ARMword address, ARMword isize) { - state->NumNcycles++; - - if (isize == 2) - return (u16)Memory::Read16(address); - else - return (u32)Memory::Read32(address); -} - -ARMword ARMul_ReLoadInstr(ARMul_State * state, ARMword address, ARMword isize) { - ARMword data; - - if ((isize == 2) && (address & 0x2)) { - ARMword lo; - lo = (u16)Memory::Read16(address); - return lo; - } - - data = (u32)Memory::Read32(address); - return data; -} - -ARMword ARMul_ReadWord(ARMul_State * state, ARMword address) { - ARMword data; - data = Memory::Read32(address); - return data; -} - -ARMword ARMul_LoadWordS(ARMul_State * state, ARMword address) { - state->NumScycles++; - return ARMul_ReadWord(state, address); -} - -ARMword ARMul_LoadWordN(ARMul_State * state, ARMword address) { - state->NumNcycles++; - return ARMul_ReadWord(state, address); -} - -ARMword ARMul_LoadHalfWord(ARMul_State * state, ARMword address) { - state->NumNcycles++; - return (u16)Memory::Read16(address);; -} - -ARMword ARMul_ReadByte(ARMul_State * state, ARMword address) { - return (u8)Memory::Read8(address); -} - -ARMword ARMul_LoadByte(ARMul_State * state, ARMword address) { - state->NumNcycles++; - return ARMul_ReadByte(state, address); -} - -void ARMul_StoreHalfWord(ARMul_State * state, ARMword address, ARMword data) { - state->NumNcycles++; - Memory::Write16(address, data); -} - -void ARMul_StoreByte(ARMul_State * state, ARMword address, ARMword data) { - state->NumNcycles++; - ARMul_WriteByte(state, address, data); -} - -ARMword ARMul_SwapWord(ARMul_State * state, ARMword address, ARMword data) { - ARMword temp; - state->NumNcycles++; - temp = ARMul_ReadWord(state, address); - state->NumNcycles++; - Memory::Write32(address, data); - return temp; -} - -ARMword ARMul_SwapByte(ARMul_State * state, ARMword address, ARMword data) { - ARMword temp; - temp = ARMul_LoadByte(state, address); - Memory::Write8(address, data); - return temp; -} - -void ARMul_WriteWord(ARMul_State * state, ARMword address, ARMword data) { - Memory::Write32(address, data); -} - -void ARMul_WriteByte(ARMul_State * state, ARMword address, ARMword data) -{ - Memory::Write8(address, data); -} - -void ARMul_StoreWordS(ARMul_State * state, ARMword address, ARMword data) -{ - state->NumScycles++; - ARMul_WriteWord(state, address, data); -} - -void ARMul_StoreWordN(ARMul_State * state, ARMword address, ARMword data) -{ - state->NumNcycles++; - ARMul_WriteWord(state, address, data); -} diff --git a/src/core/arm/interpreter/thumbemu.cpp b/src/core/arm/interpreter/thumbemu.cpp deleted file mode 100644 index 9cf80672d..000000000 --- a/src/core/arm/interpreter/thumbemu.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/* thumbemu.c -- Thumb instruction emulation. - Copyright (C) 1996, Cygnus Software Technologies Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* We can provide simple Thumb simulation by decoding the Thumb -instruction into its corresponding ARM instruction, and using the -existing ARM simulator. */ - -#include "core/arm/skyeye_common/skyeye_defs.h" - -#ifndef MODET /* required for the Thumb instruction support */ -#if 1 -#error "MODET needs to be defined for the Thumb world to work" -#else -#define MODET (1) -#endif -#endif - -#include "core/arm/skyeye_common/armdefs.h" -#include "core/arm/skyeye_common/armemu.h" -#include "core/arm/skyeye_common/armos.h" - - -/* Decode a 16bit Thumb instruction. The instruction is in the low - 16-bits of the tinstr field, with the following Thumb instruction - held in the high 16-bits. Passing in two Thumb instructions allows - easier simulation of the special dual BL instruction. */ - -tdstate -ARMul_ThumbDecode ( - ARMul_State *state, - ARMword pc, - ARMword tinstr, - ARMword *ainstr) -{ - tdstate valid = t_decoded; /* default assumes a valid instruction */ - ARMword next_instr; - - if (state->bigendSig) { - next_instr = tinstr & 0xFFFF; - tinstr >>= 16; - } - else { - next_instr = tinstr >> 16; - tinstr &= 0xFFFF; - } - -#if 1 /* debugging to catch non updates */ - *ainstr = 0xDEADC0DE; -#endif - - switch ((tinstr & 0xF800) >> 11) { - case 0: /* LSL */ - case 1: /* LSR */ - case 2: /* ASR */ - /* Format 1 */ - *ainstr = 0xE1B00000 /* base opcode */ - | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */ - |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */ - |((tinstr & 0x0038) >> 3) /* Rs */ - |((tinstr & 0x0007) << 12); /* Rd */ - break; - case 3: /* ADD/SUB */ - /* Format 2 */ - { - ARMword subset[4] = { - 0xE0900000, /* ADDS Rd,Rs,Rn */ - 0xE0500000, /* SUBS Rd,Rs,Rn */ - 0xE2900000, /* ADDS Rd,Rs,#imm3 */ - 0xE2500000 /* SUBS Rd,Rs,#imm3 */ - }; - /* It is quicker indexing into a table, than performing switch - or conditionals: */ - *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */ - |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */ - |((tinstr & 0x0038) << (16 - 3)) /* Rs */ - |((tinstr & 0x0007) << (12 - 0)); /* Rd */ - } - break; - case 4: /* MOV */ - case 5: /* CMP */ - case 6: /* ADD */ - case 7: /* SUB */ - /* Format 3 */ - { - ARMword subset[4] = { - 0xE3B00000, /* MOVS Rd,#imm8 */ - 0xE3500000, /* CMP Rd,#imm8 */ - 0xE2900000, /* ADDS Rd,Rd,#imm8 */ - 0xE2500000, /* SUBS Rd,Rd,#imm8 */ - }; - *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */ - |((tinstr & 0x00FF) >> 0) /* imm8 */ - |((tinstr & 0x0700) << (16 - 8)) /* Rn */ - |((tinstr & 0x0700) << (12 - 8)); /* Rd */ - } - break; - case 8: /* Arithmetic and high register transfers */ - /* TODO: Since the subsets for both Format 4 and Format 5 - instructions are made up of different ARM encodings, we could - save the following conditional, and just have one large - subset. */ - if ((tinstr & (1 << 10)) == 0) { - /* Format 4 */ - enum OpcodeType { t_norm, t_shift, t_neg, t_mul }; - struct ThumbOpcode { - ARMword opcode; - OpcodeType otype; - }; - - ThumbOpcode subset[16] = { - { - 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */ - { - 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */ - { - 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */ - { - 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */ - { - 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */ - { - 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */ - { - 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */ - { - 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */ - { - 0xE1100000, t_norm}, /* TST Rd,Rs */ - { - 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */ - { - 0xE1500000, t_norm}, /* CMP Rd,Rs */ - { - 0xE1700000, t_norm}, /* CMN Rd,Rs */ - { - 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */ - { - 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */ - { - 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */ - { - 0xE1F00000, t_norm} /* MVNS Rd,Rs */ - }; - *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */ - switch (subset[(tinstr & 0x03C0) >> 6].otype) { - case t_norm: - *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */ - |((tinstr & 0x0007) << 12) /* Rd */ - |((tinstr & 0x0038) >> 3); /* Rs */ - break; - case t_shift: - *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ - |((tinstr & 0x0007) >> 0) /* Rm */ - |((tinstr & 0x0038) << (8 - 3)); /* Rs */ - break; - case t_neg: - *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)); /* Rn */ - break; - case t_mul: - *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */ - |((tinstr & 0x0007) << 8) /* Rs */ - |((tinstr & 0x0038) >> 3); /* Rm */ - break; - } - } - else { - /* Format 5 */ - ARMword Rd = ((tinstr & 0x0007) >> 0); - ARMword Rs = ((tinstr & 0x0038) >> 3); - if (tinstr & (1 << 7)) - Rd += 8; - if (tinstr & (1 << 6)) - Rs += 8; - switch ((tinstr & 0x03C0) >> 6) { - case 0x1: /* ADD Rd,Rd,Hs */ - case 0x2: /* ADD Hd,Hd,Rs */ - case 0x3: /* ADD Hd,Hd,Hs */ - *ainstr = 0xE0800000 /* base */ - | (Rd << 16) /* Rn */ - |(Rd << 12) /* Rd */ - |(Rs << 0); /* Rm */ - break; - case 0x5: /* CMP Rd,Hs */ - case 0x6: /* CMP Hd,Rs */ - case 0x7: /* CMP Hd,Hs */ - *ainstr = 0xE1500000 /* base */ - | (Rd << 16) /* Rn */ - |(Rd << 12) /* Rd */ - |(Rs << 0); /* Rm */ - break; - case 0x9: /* MOV Rd,Hs */ - case 0xA: /* MOV Hd,Rs */ - case 0xB: /* MOV Hd,Hs */ - *ainstr = 0xE1A00000 /* base */ - | (Rd << 16) /* Rn */ - |(Rd << 12) /* Rd */ - |(Rs << 0); /* Rm */ - break; - case 0xC: /* BX Rs */ - case 0xD: /* BX Hs */ - *ainstr = 0xE12FFF10 /* base */ - | ((tinstr & 0x0078) >> 3); /* Rd */ - break; - case 0x0: /* UNDEFINED */ - case 0x4: /* UNDEFINED */ - case 0x8: /* UNDEFINED */ - valid = t_undefined; - break; - case 0xE: /* BLX */ - case 0xF: /* BLX */ - if (state->is_v5) { - *ainstr = 0xE1200030 /* base */ - |(Rs << 0); /* Rm */ - } else { - valid = t_undefined; - } - break; - } - } - break; - case 9: /* LDR Rd,[PC,#imm8] */ - /* Format 6 */ - *ainstr = 0xE59F0000 /* base */ - | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ - |((tinstr & 0x00FF) << (2 - 0)); /* off8 */ - break; - case 10: - case 11: - /* TODO: Format 7 and Format 8 perform the same ARM encoding, so - the following could be merged into a single subset, saving on - the following boolean: */ - if ((tinstr & (1 << 9)) == 0) { - /* Format 7 */ - ARMword subset[4] = { - 0xE7800000, /* STR Rd,[Rb,Ro] */ - 0xE7C00000, /* STRB Rd,[Rb,Ro] */ - 0xE7900000, /* LDR Rd,[Rb,Ro] */ - 0xE7D00000 /* LDRB Rd,[Rb,Ro] */ - }; - *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ - |((tinstr & 0x0007) << (12 - 0)) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)) /* Rb */ - |((tinstr & 0x01C0) >> 6); /* Ro */ - } - else { - /* Format 8 */ - ARMword subset[4] = { - 0xE18000B0, /* STRH Rd,[Rb,Ro] */ - 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */ - 0xE19000B0, /* LDRH Rd,[Rb,Ro] */ - 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */ - }; - *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ - |((tinstr & 0x0007) << (12 - 0)) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)) /* Rb */ - |((tinstr & 0x01C0) >> 6); /* Ro */ - } - break; - case 12: /* STR Rd,[Rb,#imm5] */ - case 13: /* LDR Rd,[Rb,#imm5] */ - case 14: /* STRB Rd,[Rb,#imm5] */ - case 15: /* LDRB Rd,[Rb,#imm5] */ - /* Format 9 */ - { - ARMword subset[4] = { - 0xE5800000, /* STR Rd,[Rb,#imm5] */ - 0xE5900000, /* LDR Rd,[Rb,#imm5] */ - 0xE5C00000, /* STRB Rd,[Rb,#imm5] */ - 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */ - }; - /* The offset range defends on whether we are transferring a - byte or word value: */ - *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */ - |((tinstr & 0x0007) << (12 - 0)) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)) /* Rb */ - |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */ - } - break; - case 16: /* STRH Rd,[Rb,#imm5] */ - case 17: /* LDRH Rd,[Rb,#imm5] */ - /* Format 10 */ - *ainstr = ((tinstr & (1 << 11)) /* base */ - ? 0xE1D000B0 /* LDRH */ - : 0xE1C000B0) /* STRH */ - |((tinstr & 0x0007) << (12 - 0)) /* Rd */ - |((tinstr & 0x0038) << (16 - 3)) /* Rb */ - |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */ - |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */ - break; - case 18: /* STR Rd,[SP,#imm8] */ - case 19: /* LDR Rd,[SP,#imm8] */ - /* Format 11 */ - *ainstr = ((tinstr & (1 << 11)) /* base */ - ? 0xE59D0000 /* LDR */ - : 0xE58D0000) /* STR */ - |((tinstr & 0x0700) << (12 - 8)) /* Rd */ - |((tinstr & 0x00FF) << 2); /* off8 */ - break; - case 20: /* ADD Rd,PC,#imm8 */ - case 21: /* ADD Rd,SP,#imm8 */ - /* Format 12 */ - if ((tinstr & (1 << 11)) == 0) { - /* NOTE: The PC value used here should by word aligned */ - /* We encode shift-left-by-2 in the rotate immediate field, - so no shift of off8 is needed. */ - *ainstr = 0xE28F0F00 /* base */ - | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ - |(tinstr & 0x00FF); /* off8 */ - } - else { - /* We encode shift-left-by-2 in the rotate immediate field, - so no shift of off8 is needed. */ - *ainstr = 0xE28D0F00 /* base */ - | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ - |(tinstr & 0x00FF); /* off8 */ - } - break; - case 22: - case 23: - if ((tinstr & 0x0F00) == 0x0000) { - /* Format 13 */ - /* NOTE: The instruction contains a shift left of 2 - equivalent (implemented as ROR #30): */ - *ainstr = ((tinstr & (1 << 7)) /* base */ - ? 0xE24DDF00 /* SUB */ - : 0xE28DDF00) /* ADD */ - |(tinstr & 0x007F); /* off7 */ - } - else if ((tinstr & 0x0F00) == 0x0e00) - *ainstr = 0xEF000000 | SWI_Breakpoint; - else { - /* Format 14 */ - ARMword subset[4] = { - 0xE92D0000, /* STMDB sp!,{rlist} */ - 0xE92D4000, /* STMDB sp!,{rlist,lr} */ - 0xE8BD0000, /* LDMIA sp!,{rlist} */ - 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */ - }; - *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */ - |(tinstr & 0x00FF); /* mask8 */ - } - break; - case 24: /* STMIA */ - case 25: /* LDMIA */ - /* Format 15 */ - *ainstr = ((tinstr & (1 << 11)) /* base */ - ? 0xE8B00000 /* LDMIA */ - : 0xE8A00000) /* STMIA */ - |((tinstr & 0x0700) << (16 - 8)) /* Rb */ - |(tinstr & 0x00FF); /* mask8 */ - break; - case 26: /* Bcc */ - case 27: /* Bcc/SWI */ - if ((tinstr & 0x0F00) == 0x0F00) { - if (tinstr == (ARMul_ABORTWORD & 0xffff) && - state->AbortAddr == pc) { - *ainstr = ARMul_ABORTWORD; - break; - } - /* Format 17 : SWI */ - *ainstr = 0xEF000000; - /* Breakpoint must be handled specially. */ - if ((tinstr & 0x00FF) == 0x18) - *ainstr |= ((tinstr & 0x00FF) << 16); - /* New breakpoint value. See gdb/arm-tdep.c */ - else if ((tinstr & 0x00FF) == 0xFE) - *ainstr |= SWI_Breakpoint; - else - *ainstr |= (tinstr & 0x00FF); - } - else if ((tinstr & 0x0F00) != 0x0E00) { - /* Format 16 */ - int doit = FALSE; - /* TODO: Since we are doing a switch here, we could just add - the SWI and undefined instruction checks into this - switch to same on a couple of conditionals: */ - switch ((tinstr & 0x0F00) >> 8) { - case EQ: - doit = ZFLAG; - break; - case NE: - doit = !ZFLAG; - break; - case VS: - doit = VFLAG; - break; - case VC: - doit = !VFLAG; - break; - case MI: - doit = NFLAG; - break; - case PL: - doit = !NFLAG; - break; - case CS: - doit = CFLAG; - break; - case CC: - doit = !CFLAG; - break; - case HI: - doit = (CFLAG && !ZFLAG); - break; - case LS: - doit = (!CFLAG || ZFLAG); - break; - case GE: - doit = ((!NFLAG && !VFLAG) - || (NFLAG && VFLAG)); - break; - case LT: - doit = ((NFLAG && !VFLAG) - || (!NFLAG && VFLAG)); - break; - case GT: - doit = ((!NFLAG && !VFLAG && !ZFLAG) - || (NFLAG && VFLAG && !ZFLAG)); - break; - case LE: - doit = ((NFLAG && !VFLAG) - || (!NFLAG && VFLAG)) || ZFLAG; - break; - } - if (doit) { - state->Reg[15] = (pc + 4 - + (((tinstr & 0x7F) << 1) - | ((tinstr & (1 << 7)) ? - 0xFFFFFF00 : 0))); - FLUSHPIPE; - } - valid = t_branch; - } - else /* UNDEFINED : cc=1110(AL) uses different format */ - valid = t_undefined; - break; - case 28: /* B */ - /* Format 18 */ - state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1) - | ((tinstr & (1 << 10)) ? - 0xFFFFF800 : 0))); - FLUSHPIPE; - valid = t_branch; - break; - case 29: - if(tinstr & 0x1) - valid = t_undefined; - else{ - /* BLX 1 for armv5t and above */ - ARMword tmp = (pc + 2); - state->Reg[15] = - (state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC; - state->Reg[14] = (tmp | 1); - CLEART; - LOG_DEBUG(Core_ARM11, "After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x", state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1); - valid = t_branch; - FLUSHPIPE; - } - break; - case 30: /* BL instruction 1 */ - /* Format 19 */ - /* There is no single ARM instruction equivalent for this Thumb - instruction. To keep the simulation simple (from the user - perspective) we check if the following instruction is the - second half of this BL, and if it is we simulate it - immediately. */ - state->Reg[14] = state->Reg[15] - + (((tinstr & 0x07FF) << 12) - | ((tinstr & (1 << 10)) ? 0xFF800000 : 0)); - valid = t_branch; /* in-case we don't have the 2nd half */ - //tinstr = next_instr; /* move the instruction down */ - //if (((tinstr & 0xF800) >> 11) != 31) - // break; /* exit, since not correct instruction */ - /* else we fall through to process the second half of the BL */ - //pc += 2; /* point the pc at the 2nd half */ - state->Reg[15] = pc + 2; - FLUSHPIPE; - break; - case 31: /* BL instruction 2 */ - /* Format 19 */ - /* There is no single ARM instruction equivalent for this - instruction. Also, it should only ever be matched with the - fmt19 "BL instruction 1" instruction. However, we do allow - the simulation of it on its own, with undefined results if - r14 is not suitably initialised. */ - { - ARMword tmp = (pc + 2); - state->Reg[15] = - (state->Reg[14] + ((tinstr & 0x07FF) << 1)); - state->Reg[14] = (tmp | 1); - valid = t_branch; - FLUSHPIPE; - } - break; - } - - return valid; -} diff --git a/src/core/arm/skyeye_common/arm_regformat.h b/src/core/arm/skyeye_common/arm_regformat.h index 4dac1a8bf..997874764 100644 --- a/src/core/arm/skyeye_common/arm_regformat.h +++ b/src/core/arm/skyeye_common/arm_regformat.h @@ -1,7 +1,6 @@ -#ifndef __ARM_REGFORMAT_H__ -#define __ARM_REGFORMAT_H__ +#pragma once -enum arm_regno{ +enum { R0 = 0, R1, R2, @@ -20,7 +19,7 @@ enum arm_regno{ R15, //PC, CPSR_REG, SPSR_REG, -#if 1 + PHYS_PC, R13_USR, R14_USR, @@ -95,11 +94,9 @@ enum arm_regno{ VFP_FPSID = VFP_BASE, VFP_FPSCR, VFP_FPEXC, -#endif + MAX_REG_NUM, }; #define CP15(idx) (idx - CP15_BASE) #define VFP_OFFSET(x) (x - VFP_BASE) - -#endif diff --git a/src/core/arm/skyeye_common/armcpu.h b/src/core/arm/skyeye_common/armcpu.h deleted file mode 100644 index 2b756c5bc..000000000 --- a/src/core/arm/skyeye_common/armcpu.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * arm - * armcpu.h - * - * Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ARM_CPU_H__ -#define __ARM_CPU_H__ - -#include <stddef.h> -#include <stdio.h> - -#include "core/arm/skyeye_common/armdefs.h" - -typedef struct ARM_CPU_State_s { - ARMul_State * core; - uint32_t core_num; - /* The core id that boot from - */ - uint32_t boot_core_id; -}ARM_CPU_State; - -//static ARM_CPU_State* get_current_cpu(){ -// machine_config_t* mach = get_current_mach(); -// /* Casting a conf_obj_t to ARM_CPU_State type */ -// ARM_CPU_State* cpu = (ARM_CPU_State*)mach->cpu_data->obj; -// -// return cpu; -//} - -/** -* @brief Get the core instance boot from -* -* @return -*/ -//static ARMul_State* get_boot_core(){ -// ARM_CPU_State* cpu = get_current_cpu(); -// return &cpu->core[cpu->boot_core_id]; -//} -/** -* @brief Get the instance of running core -* -* @return the core instance -*/ -//static ARMul_State* get_current_core(){ -// /* Casting a conf_obj_t to ARM_CPU_State type */ -// int id = Common::CurrentThreadId(); -// /* If thread is not in running mode, we should give the boot core */ -// if(get_thread_state(id) != Running_state){ -// return get_boot_core(); -// } -// /* Judge if we are running in paralell or sequenial */ -// if(thread_exist(id)){ -// conf_object_t* conf_obj = get_current_exec_priv(id); -// return (ARMul_State*)get_cast_conf_obj(conf_obj, "arm_core_t"); -// } -// -// return NULL; -//} - -#define CURRENT_CORE get_current_core() - -#endif - diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index 1b2cef451..778868783 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h @@ -15,8 +15,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _ARMDEFS_H_ -#define _ARMDEFS_H_ +#pragma once #include <cerrno> #include <csignal> @@ -33,20 +32,8 @@ #include "core/arm/skyeye_common/armmmu.h" #include "core/arm/skyeye_common/skyeye_defs.h" -#if EMU_PLATFORM == PLATFORM_LINUX -#include <sys/time.h> -#include <unistd.h> -#endif - -#if 0 -#if 0 -#define DIFF_STATE 1 -#define __FOLLOW_MODE__ 0 -#else -#define DIFF_STATE 0 -#define __FOLLOW_MODE__ 1 -#endif -#endif +#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) +#define BIT(s, n) ((s >> (n)) & 1) #ifndef FALSE #define FALSE 0 @@ -58,13 +45,6 @@ #define LOWHIGH 1 #define HIGHLOW 2 -//#define DBCT_TEST_SPEED -#define DBCT_TEST_SPEED_SEC 10 - -#define ARM_BYTE_TYPE 0 -#define ARM_HALFWORD_TYPE 1 -#define ARM_WORD_TYPE 2 - //the define of cachetype #define NONCACHE 0 #define DATACACHE 1 @@ -73,18 +53,11 @@ #define POS(i) ( (~(i)) >> 31 ) #define NEG(i) ( (i) >> 31 ) -#ifndef __STDC__ -typedef char *VoidStar; -#endif - typedef u64 ARMdword; // must be 64 bits wide typedef u32 ARMword; // must be 32 bits wide typedef u16 ARMhword; // must be 16 bits wide typedef u8 ARMbyte; // must be 8 bits wide typedef struct ARMul_State ARMul_State; -typedef struct ARMul_io ARMul_io; -typedef struct ARMul_Energy ARMul_Energy; - typedef unsigned ARMul_CPInits(ARMul_State* state); typedef unsigned ARMul_CPExits(ARMul_State* state); @@ -98,158 +71,72 @@ typedef unsigned ARMul_CDPs(ARMul_State* state, unsigned type, ARMword instr); typedef unsigned ARMul_CPReads(ARMul_State* state, unsigned reg, ARMword* value); typedef unsigned ARMul_CPWrites(ARMul_State* state, unsigned reg, ARMword value); - -//added by ksh,2004-3-5 -struct ARMul_io -{ - ARMword *instr; // to display the current interrupt state - ARMword *net_flag; // to judge if network is enabled - ARMword *net_int; // netcard interrupt - - //ywc,2004-04-01 - ARMword *ts_int; - ARMword *ts_is_enable; - ARMword *ts_addr_begin; - ARMword *ts_addr_end; - ARMword *ts_buffer; -}; - -/* added by ksh,2004-11-26,some energy profiling */ -struct ARMul_Energy -{ - int energy_prof; /* <tktan> BUG200103282109 : for energy profiling */ - int enable_func_energy; /* <tktan> BUG200105181702 */ - char *func_energy; - int func_display; /* <tktan> BUG200103311509 : for function call display */ - int func_disp_start; /* <tktan> BUG200104191428 : to start func profiling */ - char *start_func; /* <tktan> BUG200104191428 */ - - FILE *outfile; /* <tktan> BUG200105201531 : direct console to file */ - long long tcycle, pcycle; - float t_energy; - void *cur_task; /* <tktan> BUG200103291737 */ - long long t_mem_cycle, t_idle_cycle, t_uart_cycle; - long long p_mem_cycle, p_idle_cycle, p_uart_cycle; - long long p_io_update_tcycle; - /*record CCCR,to get current core frequency */ - ARMword cccr; -}; -#if 0 -#define MAX_BANK 8 -#define MAX_STR 1024 - -typedef struct mem_bank -{ - ARMword (*read_byte) (ARMul_State* state, ARMword addr); - void (*write_byte) (ARMul_State* state, ARMword addr, ARMword data); - ARMword (*read_halfword) (ARMul_State* state, ARMword addr); - void (*write_halfword) (ARMul_State* state, ARMword addr, ARMword data); - ARMword (*read_word) (ARMul_State* state, ARMword addr); - void (*write_word) (ARMul_State* state, ARMword addr, ARMword data); - unsigned int addr, len; - char filename[MAX_STR]; - unsigned type; //chy 2003-09-21: maybe io,ram,rom -} mem_bank_t; -typedef struct -{ - int bank_num; - int current_num; /*current num of bank */ - mem_bank_t mem_banks[MAX_BANK]; -} mem_config_t; -#endif #define VFP_REG_NUM 64 struct ARMul_State { - ARMword Emulate; /* to start and stop emulation */ - unsigned EndCondition; /* reason for stopping */ - unsigned ErrorCode; /* type of illegal instruction */ + ARMword Emulate; // To start and stop emulation + unsigned EndCondition; // Reason for stopping + unsigned ErrorCode; // Type of illegal instruction - /* Order of the following register should not be modified */ - ARMword Reg[16]; /* the current register file */ - ARMword Cpsr; /* the current psr */ + // Order of the following register should not be modified + ARMword Reg[16]; // The current register file + ARMword Cpsr; // The current PSR ARMword Spsr_copy; ARMword phys_pc; ARMword Reg_usr[2]; - ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ - ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */ - ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */ - ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */ - ARMword Reg_firq[7]; /* R8---R14 FIRQ */ - ARMword Spsr[7]; /* the exception psr's */ - ARMword Mode; /* the current mode */ - ARMword Bank; /* the current register bank */ - ARMword exclusive_tag; /* the address for which the local monitor is in exclusive access mode */ + ARMword Reg_svc[2]; // R13_SVC R14_SVC + ARMword Reg_abort[2]; // R13_ABORT R14_ABORT + ARMword Reg_undef[2]; // R13 UNDEF R14 UNDEF + ARMword Reg_irq[2]; // R13_IRQ R14_IRQ + ARMword Reg_firq[7]; // R8---R14 FIRQ + ARMword Spsr[7]; // The exception psr's + ARMword Mode; // The current mode + ARMword Bank; // The current register bank + ARMword exclusive_tag; // The address for which the local monitor is in exclusive access mode ARMword exclusive_state; ARMword exclusive_result; ARMword CP15[VFP_BASE - CP15_BASE]; - ARMword VFP[3]; /* FPSID, FPSCR, and FPEXC */ - /* VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31). - VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31), - and only 32 singleword registers are accessible (S0-S31). */ + ARMword VFP[3]; // FPSID, FPSCR, and FPEXC + // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31). + // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31), + // and only 32 singleword registers are accessible (S0-S31). ARMword ExtReg[VFP_REG_NUM]; /* ---- End of the ordered registers ---- */ - ARMword RegBank[7][16]; /* all the registers */ - //chy:2003-08-19, used in arm xscale - /* 40 bit accumulator. We always keep this 64 bits wide, - and move only 40 bits out of it in an MRA insn. */ - ARMdword Accumulator; - - ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; /* dummy flags for speed */ - unsigned long long int icounter, debug_icounter, kernel_icounter; - unsigned int shifter_carry_out; - //ARMword translate_pc; - - /* add armv6 flags dyf:2010-08-09 */ + ARMword RegBank[7][16]; // all the registers + + ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed + unsigned int shifter_carry_out; + + // Add armv6 flags dyf:2010-08-09 ARMword GEFlag, EFlag, AFlag, QFlag; - //chy:2003-08-19, used in arm v5e|xscale - ARMword SFlag; + #ifdef MODET - ARMword TFlag; /* Thumb state */ + ARMword TFlag; // Thumb state #endif - ARMword instr, pc, temp; /* saved register state */ - ARMword loaded, decoded; /* saved pipeline state */ - //chy 2006-04-12 for ICE breakpoint - ARMword loaded_addr, decoded_addr; /* saved pipeline state addr*/ - unsigned int NumScycles, NumNcycles, NumIcycles, NumCcycles, NumFcycles; /* emulated cycles used */ - unsigned long long NumInstrs; /* the number of instructions executed */ - unsigned NumInstrsToExecute; - ARMword currentexaddr; - ARMword currentexval; - ARMword currentexvald; - ARMword servaddr; + unsigned long long NumInstrs; // The number of instructions executed + unsigned NumInstrsToExecute; unsigned NextInstr; - unsigned VectorCatch; /* caught exception mask */ - unsigned CallDebug; /* set to call the debugger */ - unsigned CanWatch; /* set by memory interface if its willing to suffer the - overhead of checking for watchpoints on each memory - access */ - unsigned int StopHandle; - - char *CommandLine; /* Command Line from ARMsd */ - - ARMul_CPInits *CPInit[16]; /* coprocessor initialisers */ - ARMul_CPExits *CPExit[16]; /* coprocessor finalisers */ - ARMul_LDCs *LDC[16]; /* LDC instruction */ - ARMul_STCs *STC[16]; /* STC instruction */ - ARMul_MRCs *MRC[16]; /* MRC instruction */ - ARMul_MCRs *MCR[16]; /* MCR instruction */ - ARMul_MRRCs *MRRC[16]; /* MRRC instruction */ - ARMul_MCRRs *MCRR[16]; /* MCRR instruction */ - ARMul_CDPs *CDP[16]; /* CDP instruction */ - ARMul_CPReads *CPRead[16]; /* Read CP register */ - ARMul_CPWrites *CPWrite[16]; /* Write CP register */ - unsigned char *CPData[16]; /* Coprocessor data */ - unsigned char const *CPRegWords[16]; /* map of coprocessor register sizes */ - - unsigned EventSet; /* the number of events in the queue */ - unsigned int Now; /* time to the nearest cycle */ - struct EventNode **EventPtr; /* the event list */ - - unsigned Debug; /* show instructions as they are executed */ - unsigned NresetSig; /* reset the processor */ + unsigned VectorCatch; // Caught exception mask + + ARMul_CPInits* CPInit[16]; // Coprocessor initialisers + ARMul_CPExits* CPExit[16]; // Coprocessor finalisers + ARMul_LDCs* LDC[16]; // LDC instruction + ARMul_STCs* STC[16]; // STC instruction + ARMul_MRCs* MRC[16]; // MRC instruction + ARMul_MCRs* MCR[16]; // MCR instruction + ARMul_MRRCs* MRRC[16]; // MRRC instruction + ARMul_MCRRs* MCRR[16]; // MCRR instruction + ARMul_CDPs* CDP[16]; // CDP instruction + ARMul_CPReads* CPRead[16]; // Read CP register + ARMul_CPWrites* CPWrite[16]; // Write CP register + unsigned char* CPData[16]; // Coprocessor data + unsigned char const* CPRegWords[16]; // Map of coprocessor register sizes + + unsigned Debug; // Show instructions as they are executed + unsigned NresetSig; // Reset the processor unsigned NfiqSig; unsigned NirqSig; @@ -293,223 +180,130 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) */ unsigned lateabtSig; - ARMword Vector; /* synthesize aborts in cycle modes */ - ARMword Aborted; /* sticky flag for aborts */ - ARMword Reseted; /* sticky flag for Reset */ - ARMword Inted, LastInted; /* sticky flags for interrupts */ - ARMword Base; /* extra hand for base writeback */ - ARMword AbortAddr; /* to keep track of Prefetch aborts */ - - const struct Dbg_HostosInterface *hostif; - - int verbose; /* non-zero means print various messages like the banner */ - - int mmu_inited; - //mem_state_t mem; - /*remove io_state to skyeye_mach_*.c files */ - //io_state_t io; - /* point to a interrupt pending register. now for skyeye-ne2k.c - * later should move somewhere. e.g machine_config_t*/ - - - //chy: 2003-08-11, for different arm core type - unsigned is_v4; /* Are we emulating a v4 architecture (or higher) ? */ - unsigned is_v5; /* Are we emulating a v5 architecture ? */ - unsigned is_v5e; /* Are we emulating a v5e architecture ? */ - unsigned is_v6; /* Are we emulating a v6 architecture ? */ - unsigned is_v7; /* Are we emulating a v7 architecture ? */ - unsigned is_XScale; /* Are we emulating an XScale architecture ? */ - unsigned is_iWMMXt; /* Are we emulating an iWMMXt co-processor ? */ - unsigned is_ep9312; /* Are we emulating a Cirrus Maverick co-processor ? */ - //chy 2005-09-19 - unsigned is_pxa27x; /* Are we emulating a Intel PXA27x co-processor ? */ - //chy: seems only used in xscale's CP14 - unsigned int LastTime; /* Value of last call to ARMul_Time() */ - ARMword CP14R0_CCD; /* used to count 64 clock cycles with CP14 R0 bit 3 set */ - - - //added by ksh:for handle different machs io 2004-3-5 - ARMul_io mach_io; - - /*added by ksh,2004-11-26,some energy profiling*/ - ARMul_Energy energy; - - //teawater add for next_dis 2004.10.27----------------------- - int disassemble; - - - //teawater add for arm2x86 2005.02.15------------------------------------------- - u32 trap; - u32 tea_break_addr; - u32 tea_break_ok; - int tea_pc; - - //teawater add for arm2x86 2005.07.05------------------------------------------- - //arm_arm A2-18 - int abort_model; //0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model - - //teawater change for return if running tb dirty 2005.07.09--------------------- - void *tb_now; - - - //teawater add for record reg value to ./reg.txt 2005.07.10--------------------- - FILE *tea_reg_fd; - - - /*added by ksh in 2005-10-1*/ - cpu_config_t *cpu; - //mem_config_t *mem_bank; - - /* added LPC remap function */ - int vector_remap_flag; - u32 vector_remap_addr; - u32 vector_remap_size; - - u32 step; - u32 cycle; - int stop_simulator; - conf_object_t *dyncom_cpu; -//teawater add DBCT_TEST_SPEED 2005.10.04--------------------------------------- -#ifdef DBCT_TEST_SPEED - uint64_t instr_count; -#endif //DBCT_TEST_SPEED -// FILE * state_log; -//diff log -//#if DIFF_STATE - FILE * state_log; -//#endif - /* monitored memory for exclusice access */ - ARMword exclusive_tag_array[128]; - /* 1 means exclusive access and 0 means open access */ - ARMword exclusive_access_state; - - memory_space_intf space; + ARMword Vector; // Synthesize aborts in cycle modes + ARMword Aborted; // Sticky flag for aborts + ARMword Reseted; // Sticky flag for Reset + ARMword Inted, LastInted; // Sticky flags for interrupts + ARMword Base; // Extra hand for base writeback + ARMword AbortAddr; // To keep track of Prefetch aborts + + // For differentiating ARM core emulaiton. + bool is_v4; // Are we emulating a v4 architecture (or higher)? + bool is_v5; // Are we emulating a v5 architecture? + bool is_v5e; // Are we emulating a v5e architecture? + bool is_v6; // Are we emulating a v6 architecture? + bool is_v7; // Are we emulating a v7 architecture? + bool is_XScale; // Are we emulating an XScale architecture? + bool is_iWMMXt; // Are we emulating an iWMMXt co-processor? + bool is_ep9312; // Are we emulating a Cirrus Maverick co-processor? + bool is_pxa27x; // Are we emulating a Intel PXA27x co-processor? + + // ARM_ARM A2-18 + // 0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model + int abort_model; + + // Added by ksh in 2005-10-1 + cpu_config_t* cpu; + u32 CurrInstr; - u32 last_pc; /* the last pc executed */ - u32 last_instr; /* the last inst executed */ + u32 last_pc; // The last PC executed + u32 last_instr; // The last instruction executed u32 WriteAddr[17]; u32 WriteData[17]; u32 WritePc[17]; u32 CurrWrite; }; -#define DIFF_WRITE 0 typedef ARMul_State arm_core_t; -#define ResetPin NresetSig -#define FIQPin NfiqSig -#define IRQPin NirqSig -#define AbortPin abortSig -#define TransPin NtransSig -#define BigEndPin bigendSig -#define Prog32Pin prog32Sig -#define Data32Pin data32Sig -#define LateAbortPin lateabtSig /***************************************************************************\ * Types of ARM we know about * \***************************************************************************/ -/* The bitflags */ -#define ARM_Fix26_Prop 0x01 -#define ARM_Nexec_Prop 0x02 -#define ARM_Debug_Prop 0x10 -#define ARM_Isync_Prop ARM_Debug_Prop -#define ARM_Lock_Prop 0x20 -#define ARM_v4_Prop 0x40 -#define ARM_v5_Prop 0x80 -#define ARM_v6_Prop 0xc0 - -#define ARM_v5e_Prop 0x100 -#define ARM_XScale_Prop 0x200 -#define ARM_ep9312_Prop 0x400 -#define ARM_iWMMXt_Prop 0x800 -#define ARM_PXA27X_Prop 0x1000 -#define ARM_v7_Prop 0x2000 - -/* ARM2 family */ -#define ARM2 (ARM_Fix26_Prop) -#define ARM2as ARM2 -#define ARM61 ARM2 -#define ARM3 ARM2 - -#ifdef ARM60 /* previous definition in armopts.h */ -#undef ARM60 -#endif - -/* ARM6 family */ -#define ARM6 (ARM_Lock_Prop) -#define ARM60 ARM6 -#define ARM600 ARM6 -#define ARM610 ARM6 -#define ARM620 ARM6 - - -/***************************************************************************\ -* Macros to extract instruction fields * -\***************************************************************************/ - -#define BIT(n) ( (ARMword)(instr>>(n))&1) /* bit n of instruction */ -#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) ) /* bits m to n of instr */ -#define TOPBITS(n) (instr >> (n)) /* bits 31 to n of instr */ +enum { + ARM_Fix26_Prop = 0x01, + ARM_Nexec_Prop = 0x02, + ARM_Debug_Prop = 0x10, + ARM_Isync_Prop = ARM_Debug_Prop, + ARM_Lock_Prop = 0x20, + ARM_v4_Prop = 0x40, + ARM_v5_Prop = 0x80, + ARM_v6_Prop = 0xc0, + + ARM_v5e_Prop = 0x100, + ARM_XScale_Prop = 0x200, + ARM_ep9312_Prop = 0x400, + ARM_iWMMXt_Prop = 0x800, + ARM_PXA27X_Prop = 0x1000, + ARM_v7_Prop = 0x2000, + + // ARM2 family + ARM2 = ARM_Fix26_Prop, + ARM2as = ARM2, + ARM61 = ARM2, + ARM3 = ARM2, + + // ARM6 family + ARM6 = ARM_Lock_Prop, + ARM60 = ARM6, + ARM600 = ARM6, + ARM610 = ARM6, + ARM620 = ARM6 +}; /***************************************************************************\ * The hardware vector addresses * \***************************************************************************/ -#define ARMResetV 0L -#define ARMUndefinedInstrV 4L -#define ARMSWIV 8L -#define ARMPrefetchAbortV 12L -#define ARMDataAbortV 16L -#define ARMAddrExceptnV 20L -#define ARMIRQV 24L -#define ARMFIQV 28L -#define ARMErrorV 32L /* This is an offset, not an address ! */ - -#define ARMul_ResetV ARMResetV -#define ARMul_UndefinedInstrV ARMUndefinedInstrV -#define ARMul_SWIV ARMSWIV -#define ARMul_PrefetchAbortV ARMPrefetchAbortV -#define ARMul_DataAbortV ARMDataAbortV -#define ARMul_AddrExceptnV ARMAddrExceptnV -#define ARMul_IRQV ARMIRQV -#define ARMul_FIQV ARMFIQV +enum { + ARMResetV = 0, + ARMUndefinedInstrV = 4, + ARMSWIV = 8, + ARMPrefetchAbortV = 12, + ARMDataAbortV = 16, + ARMAddrExceptnV = 20, + ARMIRQV = 24, + ARMFIQV = 28, + ARMErrorV = 32, // This is an offset, not an address! + + ARMul_ResetV = ARMResetV, + ARMul_UndefinedInstrV = ARMUndefinedInstrV, + ARMul_SWIV = ARMSWIV, + ARMul_PrefetchAbortV = ARMPrefetchAbortV, + ARMul_DataAbortV = ARMDataAbortV, + ARMul_AddrExceptnV = ARMAddrExceptnV, + ARMul_IRQV = ARMIRQV, + ARMul_FIQV = ARMFIQV +}; /***************************************************************************\ * Mode and Bank Constants * \***************************************************************************/ -#define USER26MODE 0L -#define FIQ26MODE 1L -#define IRQ26MODE 2L -#define SVC26MODE 3L -#define USER32MODE 16L -#define FIQ32MODE 17L -#define IRQ32MODE 18L -#define SVC32MODE 19L -#define ABORT32MODE 23L -#define UNDEF32MODE 27L -//chy 2006-02-15 add system32 mode -#define SYSTEM32MODE 31L - -#define ARM32BITMODE (state->Mode > 3) -#define ARM26BITMODE (state->Mode <= 3) -#define ARMMODE (state->Mode) -#define ARMul_MODEBITS 0x1fL -#define ARMul_MODE32BIT ARM32BITMODE -#define ARMul_MODE26BIT ARM26BITMODE - -#define USERBANK 0 -#define FIQBANK 1 -#define IRQBANK 2 -#define SVCBANK 3 -#define ABORTBANK 4 -#define UNDEFBANK 5 -#define DUMMYBANK 6 -#define SYSTEMBANK USERBANK -#define BANK_CAN_ACCESS_SPSR(bank) \ - ((bank) != USERBANK && (bank) != SYSTEMBANK && (bank) != DUMMYBANK) +enum { + USER26MODE = 0, + FIQ26MODE = 1, + IRQ26MODE = 2, + SVC26MODE = 3, + USER32MODE = 16, + FIQ32MODE = 17, + IRQ32MODE = 18, + SVC32MODE = 19, + ABORT32MODE = 23, + UNDEF32MODE = 27, + SYSTEM32MODE = 31 +}; +enum { + USERBANK = 0, + FIQBANK = 1, + IRQBANK = 2, + SVCBANK = 3, + ABORTBANK = 4, + UNDEFBANK = 5, + DUMMYBANK = 6, + SYSTEMBANK = USERBANK +}; /***************************************************************************\ * Definitons of things in the emulator * @@ -522,166 +316,55 @@ extern void ARMul_Reset(ARMul_State* state); #ifdef __cplusplus } #endif -extern ARMul_State *ARMul_NewState(ARMul_State* state); -extern ARMword ARMul_DoProg(ARMul_State* state); -extern ARMword ARMul_DoInstr(ARMul_State* state); -/***************************************************************************\ -* Definitons of things for event handling * -\***************************************************************************/ - -extern void ARMul_ScheduleEvent(ARMul_State* state, unsigned int delay, unsigned(*func) ()); -extern void ARMul_EnvokeEvent(ARMul_State* state); -extern unsigned int ARMul_Time(ARMul_State* state); - -/***************************************************************************\ -* Useful support routines * -\***************************************************************************/ - -extern ARMword ARMul_GetReg (ARMul_State* state, unsigned mode, unsigned reg); -extern void ARMul_SetReg (ARMul_State* state, unsigned mode, unsigned reg, ARMword value); -extern ARMword ARMul_GetPC(ARMul_State* state); -extern ARMword ARMul_GetNextPC(ARMul_State* state); -extern void ARMul_SetPC(ARMul_State* state, ARMword value); -extern ARMword ARMul_GetR15(ARMul_State* state); -extern void ARMul_SetR15(ARMul_State* state, ARMword value); - -extern ARMword ARMul_GetCPSR(ARMul_State* state); -extern void ARMul_SetCPSR(ARMul_State* state, ARMword value); -extern ARMword ARMul_GetSPSR(ARMul_State* state, ARMword mode); -extern void ARMul_SetSPSR(ARMul_State* state, ARMword mode, ARMword value); - -/***************************************************************************\ -* Definitons of things to handle aborts * -\***************************************************************************/ - -extern void ARMul_Abort(ARMul_State* state, ARMword address); -#ifdef MODET -#define ARMul_ABORTWORD (state->TFlag ? 0xefffdfff : 0xefffffff) /* SWI -1 */ -#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \ - state->AbortAddr = (address & (state->TFlag ? ~1L : ~3L)) -#else -#define ARMul_ABORTWORD 0xefffffff /* SWI -1 */ -#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \ - state->AbortAddr = (address & ~3L) -#endif -#define ARMul_DATAABORT(address) state->abortSig = HIGH ; \ - state->Aborted = ARMul_DataAbortV ; -#define ARMul_CLEARABORT state->abortSig = LOW - -/***************************************************************************\ -* Definitons of things in the memory interface * -\***************************************************************************/ - -extern unsigned ARMul_MemoryInit(ARMul_State* state, unsigned int initmemsize); -extern void ARMul_MemoryExit(ARMul_State* state); - -extern ARMword ARMul_LoadInstrS(ARMul_State* state, ARMword address, ARMword isize); -extern ARMword ARMul_LoadInstrN(ARMul_State* state, ARMword address, ARMword isize); -#ifdef __cplusplus -extern "C" { -#endif -extern ARMword ARMul_ReLoadInstr(ARMul_State* state, ARMword address, ARMword isize); -#ifdef __cplusplus - } -#endif -extern ARMword ARMul_LoadWordS(ARMul_State* state, ARMword address); -extern ARMword ARMul_LoadWordN(ARMul_State* state, ARMword address); -extern ARMword ARMul_LoadHalfWord(ARMul_State* state, ARMword address); -extern ARMword ARMul_LoadByte(ARMul_State* state, ARMword address); - -extern void ARMul_StoreWordS(ARMul_State* state, ARMword address, ARMword data); -extern void ARMul_StoreWordN(ARMul_State* state, ARMword address, ARMword data); -extern void ARMul_StoreHalfWord(ARMul_State* state, ARMword address, ARMword data); -extern void ARMul_StoreByte(ARMul_State* state, ARMword address, ARMword data); - -extern ARMword ARMul_SwapWord(ARMul_State* state, ARMword address, ARMword data); -extern ARMword ARMul_SwapByte(ARMul_State* state, ARMword address, ARMword data); - -extern void ARMul_Icycles(ARMul_State* state, unsigned number, ARMword address); -extern void ARMul_Ccycles(ARMul_State* state, unsigned number, ARMword address); - -extern ARMword ARMul_ReadWord(ARMul_State* state, ARMword address); -extern ARMword ARMul_ReadByte(ARMul_State* state, ARMword address); -extern void ARMul_WriteWord(ARMul_State* state, ARMword address, ARMword data); -extern void ARMul_WriteByte(ARMul_State* state, ARMword address, ARMword data); - -extern ARMword ARMul_MemAccess(ARMul_State* state, ARMword, ARMword, - ARMword, ARMword, ARMword, ARMword, ARMword, - ARMword, ARMword, ARMword); +extern ARMul_State* ARMul_NewState(ARMul_State* state); /***************************************************************************\ * Definitons of things in the co-processor interface * \***************************************************************************/ -#define ARMul_FIRST 0 -#define ARMul_TRANSFER 1 -#define ARMul_BUSY 2 -#define ARMul_DATA 3 -#define ARMul_INTERRUPT 4 -#define ARMul_DONE 0 -#define ARMul_CANT 1 -#define ARMul_INC 3 - -#define ARMul_CP13_R0_FIQ 0x1 -#define ARMul_CP13_R0_IRQ 0x2 -#define ARMul_CP13_R8_PMUS 0x1 - -#define ARMul_CP14_R0_ENABLE 0x0001 -#define ARMul_CP14_R0_CLKRST 0x0004 -#define ARMul_CP14_R0_CCD 0x0008 -#define ARMul_CP14_R0_INTEN0 0x0010 -#define ARMul_CP14_R0_INTEN1 0x0020 -#define ARMul_CP14_R0_INTEN2 0x0040 -#define ARMul_CP14_R0_FLAG0 0x0100 -#define ARMul_CP14_R0_FLAG1 0x0200 -#define ARMul_CP14_R0_FLAG2 0x0400 -#define ARMul_CP14_R10_MOE_IB 0x0004 -#define ARMul_CP14_R10_MOE_DB 0x0008 -#define ARMul_CP14_R10_MOE_BT 0x000c -#define ARMul_CP15_R1_ENDIAN 0x0080 -#define ARMul_CP15_R1_ALIGN 0x0002 -#define ARMul_CP15_R5_X 0x0400 -#define ARMul_CP15_R5_ST_ALIGN 0x0001 -#define ARMul_CP15_R5_IMPRE 0x0406 -#define ARMul_CP15_R5_MMU_EXCPT 0x0400 -#define ARMul_CP15_DBCON_M 0x0100 -#define ARMul_CP15_DBCON_E1 0x000c -#define ARMul_CP15_DBCON_E0 0x0003 - -extern unsigned ARMul_CoProInit(ARMul_State* state); -extern void ARMul_CoProExit(ARMul_State* state); -extern void ARMul_CoProAttach (ARMul_State* state, unsigned number, - ARMul_CPInits* init, ARMul_CPExits* exit, - ARMul_LDCs* ldc, ARMul_STCs* stc, - ARMul_MRCs* mrc, ARMul_MCRs* mcr, - ARMul_MRRCs* mrrc, ARMul_MCRRs* mcrr, - ARMul_CDPs* cdp, - ARMul_CPReads* read, ARMul_CPWrites* write); -extern void ARMul_CoProDetach(ARMul_State* state, unsigned number); +enum { + ARMul_FIRST = 0, + ARMul_TRANSFER = 1, + ARMul_BUSY = 2, + ARMul_DATA = 3, + ARMul_INTERRUPT = 4, + ARMul_DONE = 0, + ARMul_CANT = 1, + ARMul_INC = 3 +}; + +enum { + ARMul_CP13_R0_FIQ = 0x1, + ARMul_CP13_R0_IRQ = 0x2, + ARMul_CP13_R8_PMUS = 0x1, + + ARMul_CP14_R0_ENABLE = 0x0001, + ARMul_CP14_R0_CLKRST = 0x0004, + ARMul_CP14_R0_CCD = 0x0008, + ARMul_CP14_R0_INTEN0 = 0x0010, + ARMul_CP14_R0_INTEN1 = 0x0020, + ARMul_CP14_R0_INTEN2 = 0x0040, + ARMul_CP14_R0_FLAG0 = 0x0100, + ARMul_CP14_R0_FLAG1 = 0x0200, + ARMul_CP14_R0_FLAG2 = 0x0400, + ARMul_CP14_R10_MOE_IB = 0x0004, + ARMul_CP14_R10_MOE_DB = 0x0008, + ARMul_CP14_R10_MOE_BT = 0x000c, + ARMul_CP15_R1_ENDIAN = 0x0080, + ARMul_CP15_R1_ALIGN = 0x0002, + ARMul_CP15_R5_X = 0x0400, + ARMul_CP15_R5_ST_ALIGN = 0x0001, + ARMul_CP15_R5_IMPRE = 0x0406, + ARMul_CP15_R5_MMU_EXCPT = 0x0400, + ARMul_CP15_DBCON_M = 0x0100, + ARMul_CP15_DBCON_E1 = 0x000c, + ARMul_CP15_DBCON_E0 = 0x0003 +}; /***************************************************************************\ * Definitons of things in the host environment * \***************************************************************************/ -extern unsigned ARMul_OSInit(ARMul_State* state); -extern void ARMul_OSExit(ARMul_State* state); - -#ifdef __cplusplus - extern "C" { -#endif - -extern unsigned ARMul_OSHandleSWI(ARMul_State* state, ARMword number); -#ifdef __cplusplus -} -#endif - - -extern ARMword ARMul_OSLastErrorP(ARMul_State* state); - -extern ARMword ARMul_Debug(ARMul_State* state, ARMword pc, ARMword instr); -extern unsigned ARMul_OSException(ARMul_State* state, ARMword vector, ARMword pc); -extern int rdi_log; - enum ConditionCode { EQ = 0, NE = 1, @@ -701,100 +384,12 @@ enum ConditionCode { NV = 15, }; -#ifndef NFLAG -#define NFLAG state->NFlag -#endif //NFLAG - -#ifndef ZFLAG -#define ZFLAG state->ZFlag -#endif //ZFLAG - -#ifndef CFLAG -#define CFLAG state->CFlag -#endif //CFLAG - -#ifndef VFLAG -#define VFLAG state->VFlag -#endif //VFLAG - -#ifndef IFLAG -#define IFLAG (state->IFFlags >> 1) -#endif //IFLAG - -#ifndef FFLAG -#define FFLAG (state->IFFlags & 1) -#endif //FFLAG - -#ifndef IFFLAGS -#define IFFLAGS state->IFFlags -#endif //VFLAG - -#define FLAG_MASK 0xf0000000 -#define NBIT_SHIFT 31 -#define ZBIT_SHIFT 30 -#define CBIT_SHIFT 29 -#define VBIT_SHIFT 28 - -#define SKYEYE_OUTREGS(fd) { fprintf ((fd), "R %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,C %x,S %x,%x,%x,%x,%x,%x,%x,M %x,B %x,E %x,I %x,P %x,T %x,L %x,D %x,",\ - state->Reg[0],state->Reg[1],state->Reg[2],state->Reg[3], \ - state->Reg[4],state->Reg[5],state->Reg[6],state->Reg[7], \ - state->Reg[8],state->Reg[9],state->Reg[10],state->Reg[11], \ - state->Reg[12],state->Reg[13],state->Reg[14],state->Reg[15], \ - state->Cpsr, state->Spsr[0], state->Spsr[1], state->Spsr[2],\ - state->Spsr[3],state->Spsr[4], state->Spsr[5], state->Spsr[6],\ - state->Mode,state->Bank,state->ErrorCode,state->instr,state->pc,\ - state->temp,state->loaded,state->decoded);} - -#define SKYEYE_OUTMOREREGS(fd) { fprintf ((fd),"\ -RUs %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ -RF %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ -RI %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ -RS %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ -RA %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\ -RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\ - state->RegBank[0][0],state->RegBank[0][1],state->RegBank[0][2],state->RegBank[0][3], \ - state->RegBank[0][4],state->RegBank[0][5],state->RegBank[0][6],state->RegBank[0][7], \ - state->RegBank[0][8],state->RegBank[0][9],state->RegBank[0][10],state->RegBank[0][11], \ - state->RegBank[0][12],state->RegBank[0][13],state->RegBank[0][14],state->RegBank[0][15], \ - state->RegBank[1][0],state->RegBank[1][1],state->RegBank[1][2],state->RegBank[1][3], \ - state->RegBank[1][4],state->RegBank[1][5],state->RegBank[1][6],state->RegBank[1][7], \ - state->RegBank[1][8],state->RegBank[1][9],state->RegBank[1][10],state->RegBank[1][11], \ - state->RegBank[1][12],state->RegBank[1][13],state->RegBank[1][14],state->RegBank[1][15], \ - state->RegBank[2][0],state->RegBank[2][1],state->RegBank[2][2],state->RegBank[2][3], \ - state->RegBank[2][4],state->RegBank[2][5],state->RegBank[2][6],state->RegBank[2][7], \ - state->RegBank[2][8],state->RegBank[2][9],state->RegBank[2][10],state->RegBank[2][11], \ - state->RegBank[2][12],state->RegBank[2][13],state->RegBank[2][14],state->RegBank[2][15], \ - state->RegBank[3][0],state->RegBank[3][1],state->RegBank[3][2],state->RegBank[3][3], \ - state->RegBank[3][4],state->RegBank[3][5],state->RegBank[3][6],state->RegBank[3][7], \ - state->RegBank[3][8],state->RegBank[3][9],state->RegBank[3][10],state->RegBank[3][11], \ - state->RegBank[3][12],state->RegBank[3][13],state->RegBank[3][14],state->RegBank[3][15], \ - state->RegBank[4][0],state->RegBank[4][1],state->RegBank[4][2],state->RegBank[4][3], \ - state->RegBank[4][4],state->RegBank[4][5],state->RegBank[4][6],state->RegBank[4][7], \ - state->RegBank[4][8],state->RegBank[4][9],state->RegBank[4][10],state->RegBank[4][11], \ - state->RegBank[4][12],state->RegBank[4][13],state->RegBank[4][14],state->RegBank[4][15], \ - state->RegBank[5][0],state->RegBank[5][1],state->RegBank[5][2],state->RegBank[5][3], \ - state->RegBank[5][4],state->RegBank[5][5],state->RegBank[5][6],state->RegBank[5][7], \ - state->RegBank[5][8],state->RegBank[5][9],state->RegBank[5][10],state->RegBank[5][11], \ - state->RegBank[5][12],state->RegBank[5][13],state->RegBank[5][14],state->RegBank[5][15] \ - );} - - -#define SA1110 0x6901b110 -#define SA1100 0x4401a100 -#define PXA250 0x69052100 -#define PXA270 0x69054110 -//#define PXA250 0x69052903 -// 0x69052903; //PXA250 B1 from intel 278522-001.pdf - extern bool AddOverflow(ARMword, ARMword, ARMword); extern bool SubOverflow(ARMword, ARMword, ARMword); -extern void ARMul_UndefInstr(ARMul_State*, ARMword); -extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword); -extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword); -extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...); extern void ARMul_SelectProcessor(ARMul_State*, unsigned); +extern u32 AddWithCarry(u32, u32, u32, bool*, bool*); extern bool ARMul_AddOverflowQ(ARMword, ARMword); extern u8 ARMul_SignedSaturatedAdd8(u8, u8); @@ -809,8 +404,3 @@ extern u16 ARMul_UnsignedSaturatedSub16(u16, u16); extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8); extern u32 ARMul_SignedSatQ(s32, u8, bool*); extern u32 ARMul_UnsignedSatQ(s32, u8, bool*); - -#define DIFF_LOG 0 -#define SAVE_LOG 0 - -#endif /* _ARMDEFS_H_ */ diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h index 1dfcc635a..6071d447b 100644 --- a/src/core/arm/skyeye_common/armemu.h +++ b/src/core/arm/skyeye_common/armemu.h @@ -14,20 +14,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __ARMEMU_H__ -#define __ARMEMU_H__ +#pragma once #include "core/arm/skyeye_common/armdefs.h" -//#include "skyeye.h" - -//extern ARMword isize; - -/* Shift Opcodes. */ -#define LSL 0 -#define LSR 1 -#define ASR 2 -#define ROR 3 /* Macros to twiddle the status flags and mode. */ #define NBIT ((unsigned)1L << 31) @@ -42,73 +32,6 @@ #define R15FBIT (1L << 26) #define R15IFBITS (3L << 26) -#ifdef MODET /* Thumb support. */ -/* ??? This bit is actually in the low order bit of the PC in the hardware. - It isn't clear if the simulator needs to model that or not. */ -#define TBIT (1L << 5) -#define TFLAG state->TFlag -#define SETT state->TFlag = 1 -#define CLEART state->TFlag = 0 -#define ASSIGNT(res) state->TFlag = res -#define INSN_SIZE (TFLAG ? 2 : 4) -#else -#define INSN_SIZE 4 -#endif - -/*add armv6 CPSR feature*/ -#define EFLAG state->EFlag -#define SETE state->EFlag = 1 -#define CLEARE state->EFlag = 0 -#define ASSIGNE(res) state->NFlag = res - -#define AFLAG state->AFlag -#define SETA state->AFlag = 1 -#define CLEARA state->AFlag = 0 -#define ASSIGNA(res) state->NFlag = res - -#define QFLAG state->QFlag -#define SETQ state->QFlag = 1 -#define CLEARQ state->AFlag = 0 -#define ASSIGNQ(res) state->QFlag = res - -/* add end */ - -#define NFLAG state->NFlag -#define SETN state->NFlag = 1 -#define CLEARN state->NFlag = 0 -#define ASSIGNN(res) state->NFlag = res - -#define ZFLAG state->ZFlag -#define SETZ state->ZFlag = 1 -#define CLEARZ state->ZFlag = 0 -#define ASSIGNZ(res) state->ZFlag = res - -#define CFLAG state->CFlag -#define SETC state->CFlag = 1 -#define CLEARC state->CFlag = 0 -#define ASSIGNC(res) state->CFlag = res - -#define VFLAG state->VFlag -#define SETV state->VFlag = 1 -#define CLEARV state->VFlag = 0 -#define ASSIGNV(res) state->VFlag = res - -#define SFLAG state->SFlag -#define SETS state->SFlag = 1 -#define CLEARS state->SFlag = 0 -#define ASSIGNS(res) state->SFlag = res - -#define IFLAG (state->IFFlags >> 1) -#define FFLAG (state->IFFlags & 1) -#define IFFLAGS state->IFFlags -#define ASSIGNINT(res) state->IFFlags = (((res) >> 6) & 3) -#define ASSIGNR15INT(res) state->IFFlags = (((res) >> 26) & 3) ; - -#define PSR_FBITS (0xff000000L) -#define PSR_SBITS (0x00ff0000L) -#define PSR_XBITS (0x0000ff00L) -#define PSR_CBITS (0x000000ffL) - #if defined MODE32 || defined MODET #define CCBITS (0xf8000000L) #else @@ -132,7 +55,6 @@ #define R15PCBITS (0x03fffffcL) #endif -#define R15PCMODEBITS (0x03ffffffL) #define R15MODEBITS (0x3L) #ifdef MODE32 @@ -153,106 +75,7 @@ #define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS)) #define R15MODE (state->Reg[15] & R15MODEBITS) -#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (QFLAG << 27)) -#define EINT (IFFLAGS << 6) -#define ER15INT (IFFLAGS << 26) -#define EMODE (state->Mode) -#define EGEBITS (state->GEFlag & 0x000F0000) - -#ifdef MODET -#define CPSR (ECC | EGEBITS | (EFLAG << 9) | (AFLAG << 8) | EINT | (TFLAG << 5) | EMODE) -#else -#define CPSR (ECC | EINT | EMODE) -#endif - -#ifdef MODE32 -#define PATCHR15 -#else -#define PATCHR15 state->Reg[15] = ECC | ER15INT | EMODE | R15PC -#endif - -#define GETSPSR(bank) (ARMul_GetSPSR (state, EMODE)) -#define SETPSR_F(d,s) d = ((d) & ~PSR_FBITS) | ((s) & PSR_FBITS) -#define SETPSR_S(d,s) d = ((d) & ~PSR_SBITS) | ((s) & PSR_SBITS) -#define SETPSR_X(d,s) d = ((d) & ~PSR_XBITS) | ((s) & PSR_XBITS) -#define SETPSR_C(d,s) d = ((d) & ~PSR_CBITS) | ((s) & PSR_CBITS) - -#define SETR15PSR(s) \ - do \ - { \ - if (state->Mode == USER26MODE) \ - { \ - state->Reg[15] = ((s) & CCBITS) | R15PC | ER15INT | EMODE; \ - ASSIGNN ((state->Reg[15] & NBIT) != 0); \ - ASSIGNZ ((state->Reg[15] & ZBIT) != 0); \ - ASSIGNC ((state->Reg[15] & CBIT) != 0); \ - ASSIGNV ((state->Reg[15] & VBIT) != 0); \ - } \ - else \ - { \ - state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS)); \ - ARMul_R15Altered (state); \ - } \ - } \ - while (0) - -#define SETABORT(i, m, d) \ - do \ - { \ - int SETABORT_mode = (m); \ - \ - ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state)); \ - ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT)) \ - | (i) | SETABORT_mode)); \ - state->Reg[14] = temp - (d); \ - } \ - while (0) - -#ifndef MODE32 -#define VECTORS 0x20 -#define LEGALADDR 0x03ffffff -#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig) -#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig) -#endif - -#define INTERNALABORT(address) \ - do \ - { \ - if (address < VECTORS) \ - state->Aborted = ARMul_DataAbortV; \ - else \ - state->Aborted = ARMul_AddrExceptnV; \ - } \ - while (0) - -#ifdef MODE32 -#define TAKEABORT ARMul_Abort (state, ARMul_DataAbortV) -#else -#define TAKEABORT \ - do \ - { \ - if (state->Aborted == ARMul_AddrExceptnV) \ - ARMul_Abort (state, ARMul_AddrExceptnV); \ - else \ - ARMul_Abort (state, ARMul_DataAbortV); \ - } \ - while (0) -#endif - -#define CPTAKEABORT \ - do \ - { \ - if (!state->Aborted) \ - ARMul_Abort (state, ARMul_UndefinedInstrV); \ - else if (state->Aborted == ARMul_AddrExceptnV) \ - ARMul_Abort (state, ARMul_AddrExceptnV); \ - else \ - ARMul_Abort (state, ARMul_DataAbortV); \ - } \ - while (0); - - -/* Different ways to start the next instruction. */ +// Different ways to start the next instruction. #define SEQ 0 #define NONSEQ 1 #define PCINCEDSEQ 2 @@ -260,352 +83,23 @@ #define PRIMEPIPE 4 #define RESUME 8 -/************************************/ -/* shenoubang 2012-3-11 */ -/* for armv7 DBG DMB DSB instr*/ -/************************************/ -#define MBReqTypes_Writes 0 -#define MBReqTypes_All 1 - -#define NORMALCYCLE state->NextInstr = 0 -#define BUSUSEDN state->NextInstr |= 1 /* The next fetch will be an N cycle. */ -#define BUSUSEDINCPCS \ - do \ - { \ - if (! state->is_v4) \ - { \ - /* A standard PC inc and an S cycle. */ \ - state->Reg[15] += INSN_SIZE; \ - state->NextInstr = (state->NextInstr & 0xff) | 2; \ - } \ - } \ - while (0) - -#define BUSUSEDINCPCN \ - do \ - { \ - if (state->is_v4) \ - BUSUSEDN; \ - else \ - { \ - /* A standard PC inc and an N cycle. */ \ - state->Reg[15] += INSN_SIZE; \ - state->NextInstr |= 3; \ - } \ - } \ - while (0) - -#define INCPC \ - do \ - { \ - /* A standard PC inc. */ \ - state->Reg[15] += INSN_SIZE; \ - state->NextInstr |= 2; \ - } \ - while (0) - #define FLUSHPIPE state->NextInstr |= PRIMEPIPE -/* Cycle based emulation. */ - -#define OUTPUTCP(i,a,b) -#define NCYCLE -#define SCYCLE -#define ICYCLE -#define CCYCLE -#define NEXTCYCLE(c) - -/* Macros to extract parts of instructions. */ -#define DESTReg (BITS (12, 15)) -#define LHSReg (BITS (16, 19)) -#define RHSReg (BITS ( 0, 3)) - -#define DEST (state->Reg[DESTReg]) - -#ifdef MODE32 -#ifdef MODET -#define LHS ((LHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[LHSReg])) -#define RHS ((RHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[RHSReg])) -#else -#define LHS (state->Reg[LHSReg]) -#define RHS (state->Reg[RHSReg]) -#endif -#else -#define LHS ((LHSReg == 15) ? R15PC : (state->Reg[LHSReg])) -#define RHS ((RHSReg == 15) ? R15PC : (state->Reg[RHSReg])) -#endif - -#define MULDESTReg (BITS (16, 19)) -#define MULLHSReg (BITS ( 0, 3)) -#define MULRHSReg (BITS ( 8, 11)) -#define MULACCReg (BITS (12, 15)) - -#define DPImmRHS (ARMul_ImmedTable[BITS(0, 11)]) -#define DPSImmRHS temp = BITS(0,11) ; \ - rhs = ARMul_ImmedTable[temp] ; \ - if (temp > 255) /* There was a shift. */ \ - ASSIGNC (rhs >> 31) ; - -#ifdef MODE32 -#define DPRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \ - : GetDPRegRHS (state, instr)) -#define DPSRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \ - : GetDPSRegRHS (state, instr)) -#else -#define DPRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \ - : GetDPRegRHS (state, instr)) -#define DPSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \ - : GetDPSRegRHS (state, instr)) -#endif - -#define LSBase state->Reg[LHSReg] -#define LSImmRHS (BITS(0,11)) - -#ifdef MODE32 -#define LSRegRHS ((BITS (4, 11) == 0) ? state->Reg[RHSReg] \ - : GetLSRegRHS (state, instr)) -#else -#define LSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \ - : GetLSRegRHS (state, instr)) -#endif - -#define LSMNumRegs ((ARMword) ARMul_BitList[BITS (0, 7)] + \ - (ARMword) ARMul_BitList[BITS (8, 15)] ) -#define LSMBaseFirst ((LHSReg == 0 && BIT (0)) || \ - (BIT (LHSReg) && BITS (0, LHSReg - 1) == 0)) - -#define SWAPSRC (state->Reg[RHSReg]) - -#define LSCOff (BITS (0, 7) << 2) -#define CPNum BITS (8, 11) - -/* Determine if access to coprocessor CP is permitted. - The XScale has a register in CP15 which controls access to CP0 - CP13. */ -//chy 2003-09-03, new CP_ACCESS_ALLOWED -/* -#define CP_ACCESS_ALLOWED(STATE, CP) \ - ( ((CP) >= 14) \ - || (! (STATE)->is_XScale) \ - || (read_cp15_reg (15, 0, 1) & (1 << (CP)))) -*/ -#define CP_ACCESS_ALLOWED(STATE, CP) \ - ( ((CP) >= 14) ) \ - -/* Macro to rotate n right by b bits. */ +// Macro to rotate n right by b bits. #define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b)))) -/* Macros to store results of instructions. */ -#define WRITEDEST(d) \ - do \ - { \ - if (DESTReg == 15) \ - WriteR15 (state, d); \ - else \ - DEST = d; \ - } \ - while (0) - -#define WRITESDEST(d) \ - do \ - { \ - if (DESTReg == 15) \ - WriteSR15 (state, d); \ - else \ - { \ - DEST = d; \ - ARMul_NegZero (state, d); \ - } \ - } \ - while (0) - -#define WRITEDESTB(d) \ - do \ - { \ - if (DESTReg == 15){ \ - WriteR15Branch (state, d); \ - } \ - else{ \ - DEST = d; \ - } \ - } \ - while (0) - -#define BYTETOBUS(data) ((data & 0xff) | \ - ((data & 0xff) << 8) | \ - ((data & 0xff) << 16) | \ - ((data & 0xff) << 24)) - -#define BUSTOBYTE(address, data) \ - do \ - { \ - if (state->bigendSig) \ - temp = (data >> (((address ^ 3) & 3) << 3)) & 0xff; \ - else \ - temp = (data >> ((address & 3) << 3)) & 0xff; \ - } \ - while (0) - -#define LOADMULT(instr, address, wb) LoadMult (state, instr, address, wb) -#define LOADSMULT(instr, address, wb) LoadSMult (state, instr, address, wb) -#define STOREMULT(instr, address, wb) StoreMult (state, instr, address, wb) -#define STORESMULT(instr, address, wb) StoreSMult (state, instr, address, wb) - -#define POSBRANCH ((instr & 0x7fffff) << 2) -#define NEGBRANCH ((0xff000000 |(instr & 0xffffff)) << 2) - - -/* Values for Emulate. */ -#define STOP 0 /* stop */ -#define CHANGEMODE 1 /* change mode */ -#define ONCE 2 /* execute just one interation */ -#define RUN 3 /* continuous execution */ - -/* Stuff that is shared across modes. */ -extern unsigned ARMul_MultTable[]; /* Number of I cycles for a mult. */ -extern ARMword ARMul_ImmedTable[]; /* Immediate DP LHS values. */ -extern char ARMul_BitList[]; /* Number of bits in a byte table. */ - -#define EVENTLISTSIZE 1024L - -/* Thumb support. */ -typedef enum -{ - t_undefined, /* Undefined Thumb instruction. */ - t_decoded, /* Instruction decoded to ARM equivalent. */ - t_branch /* Thumb branch (already processed). */ -} -tdstate; - -/********************************************************************************* - * Check all the possible undef or unpredict behavior, Some of them probably is - * out-of-updated with the newer ISA. - * -- Michael.Kang - ********************************************************************************/ -#define UNDEF_WARNING LOG_WARNING(Core_ARM11, "undefined or unpredicted behavior for arm instruction."); - -/* Macros to scrutinize instructions. */ -#define UNDEF_Test UNDEF_WARNING -//#define UNDEF_Test - -//#define UNDEF_Shift UNDEF_WARNING -#define UNDEF_Shift - -//#define UNDEF_MSRPC UNDEF_WARNING -#define UNDEF_MSRPC - -//#define UNDEF_MRSPC UNDEF_WARNING -#define UNDEF_MRSPC +// Values for Emulate. +#define STOP 0 // stop +#define CHANGEMODE 1 // change mode +#define ONCE 2 // execute just one interation +#define RUN 3 // continuous execution -#define UNDEF_MULPCDest UNDEF_WARNING -//#define UNDEF_MULPCDest +// Stuff that is shared across modes. +extern unsigned ARMul_MultTable[]; // Number of I cycles for a mult. +extern ARMword ARMul_ImmedTable[]; // Immediate DP LHS values. +extern char ARMul_BitList[]; // Number of bits in a byte table. -#define UNDEF_MULDestEQOp1 UNDEF_WARNING -//#define UNDEF_MULDestEQOp1 - -//#define UNDEF_LSRBPC UNDEF_WARNING -#define UNDEF_LSRBPC - -//#define UNDEF_LSRBaseEQOffWb UNDEF_WARNING -#define UNDEF_LSRBaseEQOffWb - -//#define UNDEF_LSRBaseEQDestWb UNDEF_WARNING -#define UNDEF_LSRBaseEQDestWb - -//#define UNDEF_LSRPCBaseWb UNDEF_WARNING -#define UNDEF_LSRPCBaseWb - -//#define UNDEF_LSRPCOffWb UNDEF_WARNING -#define UNDEF_LSRPCOffWb - -//#define UNDEF_LSMNoRegs UNDEF_WARNING -#define UNDEF_LSMNoRegs - -//#define UNDEF_LSMPCBase UNDEF_WARNING -#define UNDEF_LSMPCBase - -//#define UNDEF_LSMUserBankWb UNDEF_WARNING -#define UNDEF_LSMUserBankWb - -//#define UNDEF_LSMBaseInListWb UNDEF_WARNING -#define UNDEF_LSMBaseInListWb - -#define UNDEF_SWPPC UNDEF_WARNING -//#define UNDEF_SWPPC - -#define UNDEF_CoProHS UNDEF_WARNING -//#define UNDEF_CoProHS - -#define UNDEF_MCRPC UNDEF_WARNING -//#define UNDEF_MCRPC - -//#define UNDEF_LSCPCBaseWb UNDEF_WARNING -#define UNDEF_LSCPCBaseWb - -#define UNDEF_UndefNotBounced UNDEF_WARNING -//#define UNDEF_UndefNotBounced - -#define UNDEF_ShortInt UNDEF_WARNING -//#define UNDEF_ShortInt - -#define UNDEF_IllegalMode UNDEF_WARNING -//#define UNDEF_IllegalMode - -#define UNDEF_Prog32SigChange UNDEF_WARNING -//#define UNDEF_Prog32SigChange - -#define UNDEF_Data32SigChange UNDEF_WARNING -//#define UNDEF_Data32SigChange - -/* Prototypes for exported functions. */ -extern unsigned ARMul_NthReg (ARMword, unsigned); - -/* Prototypes for exported functions. */ -#ifdef __cplusplus - extern "C" { -#endif -extern ARMword ARMul_Emulate26 (ARMul_State *); -extern ARMword ARMul_Emulate32 (ARMul_State *); -#ifdef __cplusplus - } -#endif -extern unsigned IntPending (ARMul_State *); -extern void ARMul_CPSRAltered (ARMul_State *); -extern void ARMul_R15Altered (ARMul_State *); -extern ARMword ARMul_GetPC (ARMul_State *); -extern ARMword ARMul_GetNextPC (ARMul_State *); -extern ARMword ARMul_GetR15 (ARMul_State *); -extern ARMword ARMul_GetCPSR (ARMul_State *); -extern void ARMul_EnvokeEvent (ARMul_State *); -extern unsigned int ARMul_Time (ARMul_State *); -extern void ARMul_NegZero (ARMul_State *, ARMword); -extern void ARMul_SetPC (ARMul_State *, ARMword); -extern void ARMul_SetR15 (ARMul_State *, ARMword); -extern void ARMul_SetCPSR (ARMul_State *, ARMword); -extern ARMword ARMul_GetSPSR (ARMul_State *, ARMword); -extern void ARMul_Abort26 (ARMul_State *, ARMword); -extern void ARMul_Abort32 (ARMul_State *, ARMword); -extern ARMword ARMul_MRC (ARMul_State *, ARMword); -extern void ARMul_MRRC (ARMul_State *, ARMword, ARMword *, ARMword *); -extern void ARMul_CDP (ARMul_State *, ARMword); -extern void ARMul_LDC (ARMul_State *, ARMword, ARMword); -extern void ARMul_STC (ARMul_State *, ARMword, ARMword); -extern void ARMul_MCR (ARMul_State *, ARMword, ARMword); -extern void ARMul_MCRR (ARMul_State *, ARMword, ARMword, ARMword); -extern void ARMul_SetSPSR (ARMul_State *, ARMword, ARMword); -extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword); -extern ARMword ARMul_Align (ARMul_State *, ARMword, ARMword); -extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword); -extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword); -extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword); -extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword); -extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword); -extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword); -extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *); -extern ARMword ARMul_GetReg (ARMul_State *, unsigned, unsigned); -extern void ARMul_SetReg (ARMul_State *, unsigned, unsigned, ARMword); -extern void ARMul_ScheduleEvent (ARMul_State *, unsigned int, - unsigned (*)(ARMul_State *)); -/* Coprocessor support functions. */ +// Coprocessor support functions. extern unsigned ARMul_CoProInit (ARMul_State *); extern void ARMul_CoProExit (ARMul_State *); extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *, @@ -613,21 +107,3 @@ extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *, ARMul_MRCs *, ARMul_MCRs *, ARMul_MRRCs *, ARMul_MCRRs *, ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *); extern void ARMul_CoProDetach (ARMul_State *, unsigned); -extern ARMword read_cp15_reg (unsigned, unsigned, unsigned); - -extern unsigned DSPLDC4 (ARMul_State *, unsigned, ARMword, ARMword); -extern unsigned DSPMCR4 (ARMul_State *, unsigned, ARMword, ARMword); -extern unsigned DSPMRC4 (ARMul_State *, unsigned, ARMword, ARMword *); -extern unsigned DSPSTC4 (ARMul_State *, unsigned, ARMword, ARMword *); -extern unsigned DSPCDP4 (ARMul_State *, unsigned, ARMword); -extern unsigned DSPMCR5 (ARMul_State *, unsigned, ARMword, ARMword); -extern unsigned DSPMRC5 (ARMul_State *, unsigned, ARMword, ARMword *); -extern unsigned DSPLDC5 (ARMul_State *, unsigned, ARMword, ARMword); -extern unsigned DSPSTC5 (ARMul_State *, unsigned, ARMword, ARMword *); -extern unsigned DSPCDP5 (ARMul_State *, unsigned, ARMword); -extern unsigned DSPMCR6 (ARMul_State *, unsigned, ARMword, ARMword); -extern unsigned DSPMRC6 (ARMul_State *, unsigned, ARMword, ARMword *); -extern unsigned DSPCDP6 (ARMul_State *, unsigned, ARMword); - - -#endif diff --git a/src/core/arm/skyeye_common/armmmu.h b/src/core/arm/skyeye_common/armmmu.h index 30858f9ba..6e54142ee 100644 --- a/src/core/arm/skyeye_common/armmmu.h +++ b/src/core/arm/skyeye_common/armmmu.h @@ -18,19 +18,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _ARMMMU_H_ -#define _ARMMMU_H_ +#pragma once - -#define WORD_SHT 2 -#define WORD_SIZE (1<<WORD_SHT) -/* The MMU is accessible with MCR and MRC operations to copro 15: */ - -#define MMU_COPRO (15) - -/* Register numbers in the MMU: */ - -typedef enum mmu_regnum_t +// Register numbers in the MMU +enum { MMU_ID = 0, MMU_CONTROL = 1, @@ -44,94 +35,22 @@ typedef enum mmu_regnum_t MMU_TLB_LOCKDOWN = 10, MMU_PID = 13, - /*MMU_V4 */ + // MMU_V4 MMU_V4_CACHE_OPS = 7, MMU_V4_TLB_OPS = 8, - /*MMU_V3 */ + // MMU_V3 MMU_V3_FLUSH_TLB = 5, MMU_V3_FLUSH_TLB_ENTRY = 6, MMU_V3_FLUSH_CACHE = 7, - /*MMU Intel SA-1100 */ + // MMU Intel SA-1100 MMU_SA_RB_OPS = 9, MMU_SA_DEBUG = 14, MMU_SA_CP15_R15 = 15, - //chy 2003-08-24 - /*Intel xscale CP15 */ + + // Intel xscale CP15 XSCALE_CP15_CACHE_TYPE = 0, XSCALE_CP15_AUX_CONTROL = 1, XSCALE_CP15_COPRO_ACCESS = 15, - -} mmu_regnum_t; - -/* Bits in the control register */ - -#define CONTROL_MMU (1<<0) -#define CONTROL_ALIGN_FAULT (1<<1) -#define CONTROL_CACHE (1<<2) -#define CONTROL_DATA_CACHE (1<<2) -#define CONTROL_WRITE_BUFFER (1<<3) -#define CONTROL_BIG_ENDIAN (1<<7) -#define CONTROL_SYSTEM (1<<8) -#define CONTROL_ROM (1<<9) -#define CONTROL_UNDEFINED (1<<10) -#define CONTROL_BRANCH_PREDICT (1<<11) -#define CONTROL_INSTRUCTION_CACHE (1<<12) -#define CONTROL_VECTOR (1<<13) -#define CONTROL_RR (1<<14) -#define CONTROL_L4 (1<<15) -#define CONTROL_XP (1<<23) -#define CONTROL_EE (1<<25) - -/*Macro defines for MMU state*/ -#define MMU_CTL (state->mmu.control) -#define MMU_Enabled (state->mmu.control & CONTROL_MMU) -#define MMU_Disabled (!(MMU_Enabled)) -#define MMU_Aligned (state->mmu.control & CONTROL_ALIGN_FAULT) - -#define MMU_ICacheEnabled (MMU_CTL & CONTROL_INSTRUCTION_CACHE) -#define MMU_ICacheDisabled (!(MMU_ICacheDisabled)) - -#define MMU_DCacheEnabled (MMU_CTL & CONTROL_DATA_CACHE) -#define MMU_DCacheDisabled (!(MMU_DCacheEnabled)) - -#define MMU_CacheEnabled (MMU_CTL & CONTROL_CACHE) -#define MMU_CacheDisabled (!(MMU_CacheEnabled)) - -#define MMU_WBEnabled (MMU_CTL & CONTROL_WRITE_BUFFER) -#define MMU_WBDisabled (!(MMU_WBEnabled)) - -/*virt_addr exchange according to CP15.R13(process id virtul mapping)*/ -#define PID_VA_MAP_MASK 0xfe000000 -//#define mmu_pid_va_map(va) ({\ -// ARMword ret; \ -// if ((va) & PID_VA_MAP_MASK)\ -// ret = (va); \ -// else \ -// ret = ((va) | (state->mmu.process_id & PID_VA_MAP_MASK));\ -// ret;\ -//}) -#define mmu_pid_va_map(va) ((va) & PID_VA_MAP_MASK) ? (va) : ((va) | (state->mmu.process_id & PID_VA_MAP_MASK)) - -/* FS[3:0] in the fault status register: */ - -typedef enum fault_t -{ - NO_FAULT = 0x0, - ALIGNMENT_FAULT = 0x1, - - SECTION_TRANSLATION_FAULT = 0x5, - PAGE_TRANSLATION_FAULT = 0x7, - SECTION_DOMAIN_FAULT = 0x9, - PAGE_DOMAIN_FAULT = 0xB, - SECTION_PERMISSION_FAULT = 0xD, - SUBPAGE_PERMISSION_FAULT = 0xF, - - /* defined by skyeye */ - TLB_READ_MISS = 0x30, - TLB_WRITE_MISS = 0x40, - -} fault_t; - -#endif /* _ARMMMU_H_ */ +}; diff --git a/src/core/arm/skyeye_common/armos.h b/src/core/arm/skyeye_common/armos.h index ffdadcd1c..1217a728b 100644 --- a/src/core/arm/skyeye_common/armos.h +++ b/src/core/arm/skyeye_common/armos.h @@ -1,38 +1,24 @@ /* armos.h -- ARMulator OS definitions: ARM6 Instruction Emulator. Copyright (C) 1994 Advanced RISC Machines Ltd. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include <stdint.h> + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ -#if FAST_MEMORY -/* in user mode, mmap_base will be on initial brk, - set at the first mmap request */ -#define mmap_base -1 -#else -#define mmap_base 0x50000000 -#endif -static long mmap_next_base = mmap_base; - -//static mmap_area_t* new_mmap_area(int sim_addr, int len); -static char mmap_mem_write(short size, int addr, uint32_t value); -static char mmap_mem_read(short size, int addr, uint32_t * value); - -/***************************************************************************\ -* SWI numbers * -\***************************************************************************/ +// +// SWI Numbers +// #define SWI_Syscall 0x0 #define SWI_Exit 0x1 @@ -44,8 +30,8 @@ static char mmap_mem_read(short size, int addr, uint32_t * value); #define SWI_Rename 0x26 #define SWI_Break 0x11 -#define SWI_Times 0x2b -#define SWI_Brk 0x2d +#define SWI_Times 0x2b +#define SWI_Brk 0x2d #define SWI_Mmap 0x5a #define SWI_Munmap 0x5b @@ -56,76 +42,13 @@ static char mmap_mem_read(short size, int addr, uint32_t * value); #define SWI_GetEUID32 0xc9 #define SWI_GetEGID32 0xca -#define SWI_ExitGroup 0xf8 - -#if 0 -#define SWI_Time 0xd -#define SWI_Clock 0x61 -#define SWI_Time 0x63 -#define SWI_Remove 0x64 -#define SWI_Rename 0x65 -#define SWI_Flen 0x6c -#endif +#define SWI_ExitGroup 0xf8 -#define SWI_Uname 0x7a -#define SWI_Fcntl 0xdd -#define SWI_Fstat64 0xc5 +#define SWI_Uname 0x7a +#define SWI_Fcntl 0xdd +#define SWI_Fstat64 0xc5 #define SWI_Gettimeofday 0x4e #define SWI_Set_tls 0xf0005 #define SWI_Breakpoint 0x180000 /* see gdb's tm-arm.h */ -/***************************************************************************\ -* SWI structures * -\***************************************************************************/ - -/* Arm binaries (for now) only support 32 bit, and expect to receive - 32-bit compliant structure in return of a systen call. Because - we use host system calls to emulate system calls, the returned - structure can be 32-bit compliant or 64-bit compliant, depending - on the OS running skyeye. Therefore, we need a fixed size structure - adapted to arm.*/ - -/* Borrowed from qemu */ -struct target_stat64 { - unsigned short st_dev; - unsigned char __pad0[10]; - uint32_t __st_ino; - unsigned int st_mode; - unsigned int st_nlink; - uint32_t st_uid; - uint32_t st_gid; - unsigned short st_rdev; - unsigned char __pad3[10]; - unsigned char __pad31[4]; - long long st_size; - uint32_t st_blksize; - unsigned char __pad32[4]; - uint32_t st_blocks; - uint32_t __pad4; - uint32_t st32_atime; - uint32_t __pad5; - uint32_t st32_mtime; - uint32_t __pad6; - uint32_t st32_ctime; - uint32_t __pad7; - unsigned long long st_ino; -};// __attribute__((packed)); - -struct target_tms32 { - uint32_t tms_utime; - uint32_t tms_stime; - uint32_t tms_cutime; - uint32_t tms_cstime; -}; - -struct target_timeval32 { - uint32_t tv_sec; /* seconds */ - uint32_t tv_usec; /* microseconds */ -}; - -struct target_timezone32 { - int32_t tz_minuteswest; /* minutes west of Greenwich */ - int32_t tz_dsttime; /* type of DST correction */ -}; - diff --git a/src/core/arm/skyeye_common/skyeye_defs.h b/src/core/arm/skyeye_common/skyeye_defs.h index d4088383f..6648e9d66 100644 --- a/src/core/arm/skyeye_common/skyeye_defs.h +++ b/src/core/arm/skyeye_common/skyeye_defs.h @@ -1,5 +1,4 @@ -#ifndef CORE_ARM_SKYEYE_DEFS_H_ -#define CORE_ARM_SKYEYE_DEFS_H_ +#pragma once #include "common/common.h" @@ -8,21 +7,15 @@ typedef struct { - const char *cpu_arch_name; /*cpu architecture version name.e.g. armv4t */ - const char *cpu_name; /*cpu name. e.g. arm7tdmi or arm720t */ - u32 cpu_val; /*CPU value; also call MMU ID or processor id;see - ARM Architecture Reference Manual B2-6 */ - u32 cpu_mask; /*cpu_val's mask. */ - u32 cachetype; /*this cpu has what kind of cache */ + const char *cpu_arch_name; /* CPU architecture version name.e.g. armv4t */ + const char *cpu_name; /* CPU name. e.g. arm7tdmi or arm720t */ + u32 cpu_val; /*CPU value; also call MMU ID or processor id;see + ARM Architecture Reference Manual B2-6 */ + u32 cpu_mask; /* cpu_val's mask. */ + u32 cachetype; /* this CPU has what kind of cache */ } cpu_config_t; -typedef struct conf_object_s{ - char* objname; - void* obj; - char* class_name; -}conf_object_t; - -typedef enum{ +typedef enum { /* No exception */ No_exp = 0, /* Memory allocation exception */ @@ -44,70 +37,21 @@ typedef enum{ /* Unknown exception */ Unknown_exp -}exception_t; +} exception_t; typedef enum { Align = 0, UnAlign -}align_t; +} align_t; typedef enum { Little_endian = 0, Big_endian -}endian_t; -//typedef int exception_t; +} endian_t; -typedef enum{ +typedef enum { Phys_addr = 0, Virt_addr -}addr_type_t; - -typedef exception_t(*read_byte_t)(conf_object_t* target, u32 addr, void *buf, size_t count); -typedef exception_t(*write_byte_t)(conf_object_t* target, u32 addr, const void *buf, size_t count); - -typedef struct memory_space{ - conf_object_t* conf_obj; - read_byte_t read; - write_byte_t write; -}memory_space_intf; - - -/* - * a running instance for a specific archteciture. - */ -typedef struct generic_arch_s -{ - char* arch_name; - void (*init) (void); - void (*reset) (void); - void (*step_once) (void); - void (*set_pc)(u32 addr); - u32 (*get_pc)(void); - u32 (*get_step)(void); - //chy 2004-04-15 - //int (*ICE_write_byte) (u32 addr, uint8_t v); - //int (*ICE_read_byte)(u32 addr, uint8_t *pv); - u32 (*get_regval_by_id)(int id); - u32 (*get_regnum)(void); - char* (*get_regname_by_id)(int id); - exception_t (*set_regval_by_id)(int id, u32 value); - /* - * read a data by virtual address. - */ - exception_t (*mmu_read)(short size, u32 addr, u32 * value); - /* - * write a data by a virtual address. - */ - exception_t (*mmu_write)(short size, u32 addr, u32 value); - /** - * get a signal from external - */ - //exception_t (*signal)(interrupt_signal_t* signal); - - endian_t endianess; - align_t alignment; -} generic_arch_t; +} addr_type_t; typedef u32 addr_t; - -#endif diff --git a/src/core/arm/skyeye_common/skyeye_types.h b/src/core/arm/skyeye_common/skyeye_types.h deleted file mode 100644 index fc7d8d922..000000000 --- a/src/core/arm/skyeye_common/skyeye_types.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - skyeye_types.h - some data types definition for skyeye debugger - Copyright (C) 2003 Skyeye Develop Group - for help please send mail to <skyeye-developer@lists.sf.linuxforum.net> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ -/* - * 12/16/2006 Michael.Kang <blackfin.kang@gmail.com> - */ - -#pragma once - -#include <cstdint> - -typedef uint32_t address_t; -typedef uint32_t physical_address_t; -typedef uint32_t generic_address_t; diff --git a/src/core/arm/skyeye_common/vfp/asm_vfp.h b/src/core/arm/skyeye_common/vfp/asm_vfp.h index f4ab34fd4..e113eaf29 100644 --- a/src/core/arm/skyeye_common/vfp/asm_vfp.h +++ b/src/core/arm/skyeye_common/vfp/asm_vfp.h @@ -5,6 +5,8 @@ * First, the standard VFP set. */ +#pragma once + #define FPSID cr0 #define FPSCR cr1 #define MVFR1 cr6 diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp index 10d640f37..563247c78 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.cpp +++ b/src/core/arm/skyeye_common/vfp/vfp.cpp @@ -20,16 +20,11 @@ /* Note: this file handles interface with arm core and vfp registers */ -/* Opens debug for classic interpreter only */ -//#define DEBUG - #include "common/common.h" #include "core/arm/skyeye_common/armdefs.h" #include "core/arm/skyeye_common/vfp/vfp.h" -#define DEBUG DBG - //ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */ unsigned VFPInit(ARMul_State* state) @@ -48,12 +43,12 @@ unsigned VFPInit(ARMul_State* state) unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value) { /* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ - int CoProc = BITS (8, 11); /* 10 or 11 */ - int OPC_1 = BITS (21, 23); - int Rt = BITS (12, 15); - int CRn = BITS (16, 19); - int CRm = BITS (0, 3); - int OPC_2 = BITS (5, 7); + int CoProc = BITS(instr, 8, 11); /* 10 or 11 */ + int OPC_1 = BITS(instr, 21, 23); + int Rt = BITS(instr, 12, 15); + int CRn = BITS(instr, 16, 19); + int CRm = BITS(instr, 0, 3); + int OPC_2 = BITS(instr, 5, 7); /* TODO check access permission */ @@ -65,7 +60,7 @@ unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value) { /* VMOV r to s */ /* Transfering Rt is not mandatory, as the value of interest is pointed by value */ - VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value); + VMOVBRS(state, BIT(instr, 20), Rt, BIT(instr, 7)|CRn<<1, value); return ARMul_DONE; } @@ -75,7 +70,7 @@ unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value) return ARMul_DONE; } } - DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", + LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); return ARMul_CANT; @@ -84,12 +79,12 @@ unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value) unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value) { /* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */ - int CoProc = BITS (8, 11); /* 10 or 11 */ - int OPC_1 = BITS (21, 23); - int Rt = BITS (12, 15); - int CRn = BITS (16, 19); - int CRm = BITS (0, 3); - int OPC_2 = BITS (5, 7); + int CoProc = BITS(instr, 8, 11); /* 10 or 11 */ + int OPC_1 = BITS(instr, 21, 23); + int Rt = BITS(instr, 12, 15); + int CRn = BITS(instr, 16, 19); + int CRm = BITS(instr, 0, 3); + int OPC_2 = BITS(instr, 5, 7); /* TODO check access permission */ @@ -100,7 +95,7 @@ unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value) { /* VMOV s to r */ /* Transfering Rt is not mandatory, as the value of interest is pointed by value */ - VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value); + VMOVBRS(state, BIT(instr, 20), Rt, BIT(instr, 7)|CRn<<1, &value); return ARMul_DONE; } @@ -122,7 +117,7 @@ unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value) return ARMul_DONE; } } - DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", + LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2); return ARMul_CANT; @@ -131,28 +126,28 @@ unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value) unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* value2) { /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ - int CoProc = BITS (8, 11); /* 10 or 11 */ - int OPC_1 = BITS (4, 7); - int Rt = BITS (12, 15); - int Rt2 = BITS (16, 19); - int CRm = BITS (0, 3); + int CoProc = BITS(instr, 8, 11); /* 10 or 11 */ + int OPC_1 = BITS(instr, 4, 7); + int Rt = BITS(instr, 12, 15); + int Rt2 = BITS(instr, 16, 19); + int CRm = BITS(instr, 0, 3); if (CoProc == 10 || CoProc == 11) { if (CoProc == 10 && (OPC_1 & 0xD) == 1) { - VMOVBRRSS(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2); + VMOVBRRSS(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, value1, value2); return ARMul_DONE; } if (CoProc == 11 && (OPC_1 & 0xD) == 1) { /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */ - VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2); + VMOVBRRD(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, value1, value2); return ARMul_DONE; } } - DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", + LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", instr, CoProc, OPC_1, Rt, Rt2, CRm); return ARMul_CANT; @@ -161,11 +156,11 @@ unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 value2) { /* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */ - int CoProc = BITS (8, 11); /* 10 or 11 */ - int OPC_1 = BITS (4, 7); - int Rt = BITS (12, 15); - int Rt2 = BITS (16, 19); - int CRm = BITS (0, 3); + int CoProc = BITS(instr, 8, 11); /* 10 or 11 */ + int OPC_1 = BITS(instr, 4, 7); + int Rt = BITS(instr, 12, 15); + int Rt2 = BITS(instr, 16, 19); + int CRm = BITS(instr, 0, 3); /* TODO check access permission */ @@ -175,18 +170,18 @@ unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 v { if (CoProc == 10 && (OPC_1 & 0xD) == 1) { - VMOVBRRSS(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2); + VMOVBRRSS(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, &value1, &value2); return ARMul_DONE; } if (CoProc == 11 && (OPC_1 & 0xD) == 1) { /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */ - VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2); + VMOVBRRD(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, &value1, &value2); return ARMul_DONE; } } - DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", + LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", instr, CoProc, OPC_1, Rt, Rt2, CRm); return ARMul_CANT; @@ -195,30 +190,30 @@ unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 v unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value) { /* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */ - int CoProc = BITS (8, 11); /* 10 or 11 */ - int CRd = BITS (12, 15); - int Rn = BITS (16, 19); - int imm8 = BITS (0, 7); - int P = BIT(24); - int U = BIT(23); - int D = BIT(22); - int W = BIT(21); + int CoProc = BITS(instr, 8, 11); /* 10 or 11 */ + int CRd = BITS(instr, 12, 15); + int Rn = BITS(instr, 16, 19); + int imm8 = BITS(instr, 0, 7); + int P = BIT(instr, 24); + int U = BIT(instr, 23); + int D = BIT(instr, 22); + int W = BIT(instr, 21); /* TODO check access permission */ /* VSTM */ if ( (P|U|D|W) == 0 ) { - DEBUG("In %s, UNDEFINED\n", __FUNCTION__); + LOG_ERROR(Core_ARM11, "In %s, UNDEFINED\n", __FUNCTION__); exit(-1); } if (CoProc == 10 || CoProc == 11) { #if 1 if (P == 0 && U == 0 && W == 0) { - DEBUG("VSTM Related encodings\n"); + LOG_ERROR(Core_ARM11, "VSTM Related encodings\n"); exit(-1); } if (P == U && W == 1) { - DEBUG("UNDEFINED\n"); + LOG_ERROR(Core_ARM11, "UNDEFINED\n"); exit(-1); } #endif @@ -235,7 +230,7 @@ unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value) return VSTM(state, type, instr, value); } - DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", + LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", instr, CoProc, CRd, Rn, imm8, P, U, D, W); return ARMul_CANT; @@ -244,19 +239,19 @@ unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value) unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value) { /* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */ - int CoProc = BITS (8, 11); /* 10 or 11 */ - int CRd = BITS (12, 15); - int Rn = BITS (16, 19); - int imm8 = BITS (0, 7); - int P = BIT(24); - int U = BIT(23); - int D = BIT(22); - int W = BIT(21); + int CoProc = BITS(instr, 8, 11); /* 10 or 11 */ + int CRd = BITS(instr, 12, 15); + int Rn = BITS(instr, 16, 19); + int imm8 = BITS(instr, 0, 7); + int P = BIT(instr, 24); + int U = BIT(instr, 23); + int D = BIT(instr, 22); + int W = BIT(instr, 21); /* TODO check access permission */ if ( (P|U|D|W) == 0 ) { - DEBUG("In %s, UNDEFINED\n", __FUNCTION__); + LOG_ERROR(Core_ARM11, "In %s, UNDEFINED\n", __FUNCTION__); exit(-1); } if (CoProc == 10 || CoProc == 11) @@ -273,7 +268,7 @@ unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value) return VLDM(state, type, instr, value); } - DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", + LOG_WARNING(Core_ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", instr, CoProc, CRd, Rn, imm8, P, U, D, W); return ARMul_CANT; @@ -282,57 +277,12 @@ unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value) unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr) { /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */ - int CoProc = BITS (8, 11); /* 10 or 11 */ - int OPC_1 = BITS (20, 23); - int CRd = BITS (12, 15); - int CRn = BITS (16, 19); - int CRm = BITS (0, 3); - int OPC_2 = BITS (5, 7); - - //ichfly - /*if ((instr & 0x0FBF0FD0) == 0x0EB70AC0) //vcvt.f64.f32 d8, s16 (s is bit 0-3 and LSB bit 22) (d is bit 12 - 15 MSB is Bit 6) - { - struct vfp_double vdd; - struct vfp_single vsd; - int dn = BITS(12, 15) + (BIT(22) << 4); - int sd = (BITS(0, 3) << 1) + BIT(5); - s32 n = vfp_get_float(state, sd); - vfp_single_unpack(&vsd, n); - if (vsd.exponent & 0x80) - { - vdd.exponent = (vsd.exponent&~0x80) | 0x400; - } - else - { - vdd.exponent = vsd.exponent | 0x380; - } - vdd.sign = vsd.sign; - vdd.significand = (u64)(vsd.significand & ~0xC0000000) << 32; // I have no idea why but the 2 uppern bits are not from the significand - vfp_put_double(state, vfp_double_pack(&vdd), dn); - return ARMul_DONE; - } - if ((instr & 0x0FBF0FD0) == 0x0EB70BC0) //vcvt.f32.f64 s15, d6 - { - struct vfp_double vdd; - struct vfp_single vsd; - int sd = BITS(0, 3) + (BIT(5) << 4); - int dn = (BITS(12, 15) << 1) + BIT(22); - vfp_double_unpack(&vdd, vfp_get_double(state, sd)); - if (vdd.exponent & 0x400) //todo if the exponent is to low or to high for this convert - { - vsd.exponent = (vdd.exponent) | 0x80; - } - else - { - vsd.exponent = vdd.exponent & ~0x80; - } - vsd.exponent &= 0xFF; - // vsd.exponent = vdd.exponent >> 3; - vsd.sign = vdd.sign; - vsd.significand = ((u64)(vdd.significand ) >> 32)& ~0xC0000000; - vfp_put_float(state, vfp_single_pack(&vsd), dn); - return ARMul_DONE; - }*/ + int CoProc = BITS(instr, 8, 11); /* 10 or 11 */ + int OPC_1 = BITS(instr, 20, 23); + int CRd = BITS(instr, 12, 15); + int CRn = BITS(instr, 16, 19); + int CRm = BITS(instr, 0, 3); + int OPC_2 = BITS(instr, 5, 7); /* TODO check access permission */ @@ -340,44 +290,17 @@ unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr) if (CoProc == 10 || CoProc == 11) { - if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 0) - DBG("VMLA :\n"); - - if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 2) - DBG("VMLS :\n"); - - if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 2) - DBG("VNMLA :\n"); - - if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 0) - DBG("VNMLS :\n"); - - if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 2) - DBG("VNMUL :\n"); - - if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 0) - DBG("VMUL :\n"); - - if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 0) - DBG("VADD :\n"); - - if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 2) - DBG("VSUB :\n"); - - if ((OPC_1 & 0xB) == 0xA && (OPC_2 & 0x2) == 0) - DBG("VDIV :\n"); - - if ((OPC_1 & 0xB) == 0xB && BITS(4, 7) == 0) + if ((OPC_1 & 0xB) == 0xB && BITS(instr, 4, 7) == 0) { - unsigned int single = BIT(8) == 0; - unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4); + unsigned int single = BIT(instr, 8) == 0; + unsigned int d = (single ? BITS(instr, 12,15)<<1 | BIT(instr, 22) : BITS(instr, 12,15) | BIT(instr, 22)<<4); unsigned int imm; - instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */ + instr = BITS(instr, 16, 19) << 4 | BITS(instr, 0, 3); // FIXME dirty workaround to get a correct imm if (single) - imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19; + imm = BIT(instr, 7)<<31 | (BIT(instr, 6)==0)<<30 | (BIT(instr, 6) ? 0x1f : 0)<<25 | BITS(instr, 0, 5)<<19; else - imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16; + imm = BIT(instr, 7)<<31 | (BIT(instr, 6)==0)<<30 | (BIT(instr, 6) ? 0xff : 0)<<22 | BITS(instr, 0, 5)<<16; VMOVI(state, single, d, imm); return ARMul_DONE; @@ -385,37 +308,13 @@ unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr) if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x6) == 0x2) { - unsigned int single = BIT(8) == 0; - unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4); - unsigned int m = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);; + unsigned int single = BIT(instr, 8) == 0; + unsigned int d = (single ? BITS(instr, 12,15)<<1 | BIT(instr, 22) : BITS(instr, 12,15) | BIT(instr, 22)<<4); + unsigned int m = (single ? BITS(instr, 0, 3)<<1 | BIT(instr, 5) : BITS(instr, 0, 3) | BIT(instr, 5)<<4); VMOVR(state, single, d, m); return ARMul_DONE; } - if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x7) == 6) - DBG("VABS :\n"); - - if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 2) - DBG("VNEG :\n"); - - if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 6) - DBG("VSQRT :\n"); - - if ((OPC_1 & 0xB) == 0xB && CRn == 4 && (OPC_2 & 0x2) == 2) - DBG("VCMP(1) :\n"); - - if ((OPC_1 & 0xB) == 0xB && CRn == 5 && (OPC_2 & 0x2) == 2 && CRm == 0) - DBG("VCMP(2) :\n"); - - if ((OPC_1 & 0xB) == 0xB && CRn == 7 && (OPC_2 & 0x6) == 6) - DBG("VCVT(BDS) :\n"); - - if ((OPC_1 & 0xB) == 0xB && CRn >= 0xA && (OPC_2 & 0x2) == 2) - DBG("VCVT(BFF) :\n"); - - if ((OPC_1 & 0xB) == 0xB && CRn > 7 && (OPC_2 & 0x2) == 2) - DBG("VCVT(BFI) :\n"); - int exceptions = 0; if (CoProc == 10) exceptions = vfp_single_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); @@ -426,40 +325,33 @@ unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr) return ARMul_DONE; } - DEBUG("Can't identify %x\n", instr); + LOG_WARNING(Core_ARM11, "Can't identify %x\n", instr); return ARMul_CANT; } - /* ----------- MRC ------------ */ void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value) { - DBG("VMOV(BRS) :\n"); if (to_arm) { - DBG("\tr%d <= s%d=[%x]\n", t, n, state->ExtReg[n]); *value = state->ExtReg[n]; } else { - DBG("\ts%d <= r%d=[%x]\n", n, t, *value); state->ExtReg[n] = *value; } } void VMRS(ARMul_State* state, ARMword reg, ARMword Rt, ARMword* value) { - DBG("VMRS :"); if (reg == 1) { if (Rt != 15) { *value = state->VFP[VFP_OFFSET(VFP_FPSCR)]; - DBG("\tr%d <= fpscr[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSCR)]); } else { *value = state->VFP[VFP_OFFSET(VFP_FPSCR)] ; - DBG("\tflags <= fpscr[%1xxxxxxxx]\n", state->VFP[VFP_OFFSET(VFP_FPSCR)]>>28); } } else @@ -468,54 +360,46 @@ void VMRS(ARMul_State* state, ARMword reg, ARMword Rt, ARMword* value) { case 0: *value = state->VFP[VFP_OFFSET(VFP_FPSID)]; - DBG("\tr%d <= fpsid[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSID)]); break; case 6: /* MVFR1, VFPv3 only ? */ - DBG("\tr%d <= MVFR1 unimplemented\n", Rt); + LOG_TRACE(Core_ARM11, "\tr%d <= MVFR1 unimplemented\n", Rt); break; case 7: /* MVFR0, VFPv3 only? */ - DBG("\tr%d <= MVFR0 unimplemented\n", Rt); + LOG_TRACE(Core_ARM11, "\tr%d <= MVFR0 unimplemented\n", Rt); break; case 8: *value = state->VFP[VFP_OFFSET(VFP_FPEXC)]; - DBG("\tr%d <= fpexc[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPEXC)]); break; default: - DBG("\tSUBARCHITECTURE DEFINED\n"); + LOG_TRACE(Core_ARM11, "\tSUBARCHITECTURE DEFINED\n"); break; } } } void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2) { - DBG("VMOV(BRRD) :\n"); if (to_arm) { - DBG("\tr[%d-%d] <= s[%d-%d]=[%x-%x]\n", t2, t, n*2+1, n*2, state->ExtReg[n*2+1], state->ExtReg[n*2]); *value2 = state->ExtReg[n*2+1]; *value1 = state->ExtReg[n*2]; } else { - DBG("\ts[%d-%d] <= r[%d-%d]=[%x-%x]\n", n*2+1, n*2, t2, t, *value2, *value1); state->ExtReg[n*2+1] = *value2; state->ExtReg[n*2] = *value1; } } void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2) { - DBG("VMOV(BRRSS) :\n"); if (to_arm) { - DBG("\tr[%d-%d] <= s[%d-%d]=[%x-%x]\n", t2, t, n+1, n, state->ExtReg[n+1], state->ExtReg[n]); *value1 = state->ExtReg[n+0]; *value2 = state->ExtReg[n+1]; } else { - DBG("\ts[%d-%d] <= r[%d-%d]=[%x-%x]\n", n+1, n, t2, t, *value2, *value1); state->ExtReg[n+0] = *value1; state->ExtReg[n+1] = *value2; } @@ -526,12 +410,10 @@ void VMSR(ARMul_State* state, ARMword reg, ARMword Rt) { if (reg == 1) { - DBG("VMSR :\tfpscr <= r%d=[%x]\n", Rt, state->Reg[Rt]); state->VFP[VFP_OFFSET(VFP_FPSCR)] = state->Reg[Rt]; } else if (reg == 8) { - DBG("VMSR :\tfpexc <= r%d=[%x]\n", Rt, state->Reg[Rt]); state->VFP[VFP_OFFSET(VFP_FPEXC)] = state->Reg[Rt]; } } @@ -550,13 +432,11 @@ int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value) static int single_reg, add, d, n, imm32, regs; if (type == ARMul_FIRST) { - single_reg = BIT(8) == 0; /* Double precision */ - add = BIT(23); /* */ - imm32 = BITS(0,7)<<2; /* may not be used */ - d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - n = BITS(16, 19); /* destination register */ - - DBG("VSTR :\n"); + single_reg = BIT(instr, 8) == 0; // Double precision + add = BIT(instr, 23); + imm32 = BITS(instr, 0,7)<<2; // may not be used + d = single_reg ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); /* Base register */ + n = BITS(instr, 16, 19); // destination register i = 0; regs = 1; @@ -568,7 +448,6 @@ int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value) if (single_reg) { *value = state->ExtReg[d+i]; - DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d+i]); i++; if (i < regs) return ARMul_INC; @@ -579,7 +458,6 @@ int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value) { /* FIXME Careful of endianness, may need to rework this */ *value = state->ExtReg[d*2+i]; - DBG("\taddr[?] <= s[%d]=[%x]\n", d*2+i, state->ExtReg[d*2+i]); i++; if (i < regs*2) return ARMul_INC; @@ -593,18 +471,15 @@ int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value) int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value) { static int i = 0; - static int single_regs, add, wback, d, n, imm32, regs; + static int single_regs, d, imm32, regs; if (type == ARMul_FIRST) { - single_regs = BIT(8) == 0; /* Single precision */ - d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - imm32 = BITS(0,7)<<2; /* may not be used */ - regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */ + single_regs = BIT(instr, 8) == 0; // Single precision + d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register + imm32 = BITS(instr, 0,7)<<2; // may not be used + regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 1, 7); // FSTMX if regs is odd - DBG("VPUSH :\n"); - DBG("\tsp[%x]", state->Reg[R13]); state->Reg[R13] = state->Reg[R13] - imm32; - DBG("=>[%x]\n", state->Reg[R13]); i = 0; @@ -615,7 +490,6 @@ int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value) if (single_regs) { *value = state->ExtReg[d + i]; - DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]); i++; if (i < regs) return ARMul_INC; @@ -626,7 +500,6 @@ int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value) { /* FIXME Careful of endianness, may need to rework this */ *value = state->ExtReg[d*2 + i]; - DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]); i++; if (i < regs*2) return ARMul_INC; @@ -643,19 +516,16 @@ int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value) static int single_regs, add, wback, d, n, imm32, regs; if (type == ARMul_FIRST) { - single_regs = BIT(8) == 0; /* Single precision */ - add = BIT(23); /* */ - wback = BIT(21); /* write-back */ - d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - n = BITS(16, 19); /* destination register */ - imm32 = BITS(0,7) * 4; /* may not be used */ - regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */ - - DBG("VSTM :\n"); + single_regs = BIT(instr, 8) == 0; // Single precision + add = BIT(instr, 23); + wback = BIT(instr, 21); // write-back + d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register + n = BITS(instr, 16, 19); // destination register + imm32 = BITS(instr, 0,7) * 4; // may not be used + regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 0, 7)>>1; // FSTMX if regs is odd if (wback) { state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32); - DBG("\twback r%d[%x]\n", n, state->Reg[n]); } i = 0; @@ -667,7 +537,6 @@ int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value) if (single_regs) { *value = state->ExtReg[d + i]; - DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]); i++; if (i < regs) return ARMul_INC; @@ -678,7 +547,6 @@ int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value) { /* FIXME Careful of endianness, may need to rework this */ *value = state->ExtReg[d*2 + i]; - DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]); i++; if (i < regs*2) return ARMul_INC; @@ -694,18 +562,15 @@ int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value) int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value) { static int i = 0; - static int single_regs, add, wback, d, n, imm32, regs; + static int single_regs, d, imm32, regs; if (type == ARMul_FIRST) { - single_regs = BIT(8) == 0; /* Single precision */ - d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - imm32 = BITS(0,7)<<2; /* may not be used */ - regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */ + single_regs = BIT(instr, 8) == 0; // Single precision + d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register + imm32 = BITS(instr, 0, 7)<<2; // may not be used + regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 1, 7); // FLDMX if regs is odd - DBG("VPOP :\n"); - DBG("\tsp[%x]", state->Reg[R13]); state->Reg[R13] = state->Reg[R13] + imm32; - DBG("=>[%x]\n", state->Reg[R13]); i = 0; @@ -720,7 +585,6 @@ int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value) if (single_regs) { state->ExtReg[d + i] = value; - DBG("\ts%d <= [%x]\n", d + i, value); i++; if (i < regs) return ARMul_INC; @@ -731,7 +595,6 @@ int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value) { /* FIXME Careful of endianness, may need to rework this */ state->ExtReg[d*2 + i] = value; - DBG("\ts%d <= [%x]\n", d*2 + i, value); i++; if (i < regs*2) return ARMul_INC; @@ -748,17 +611,15 @@ int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value) static int single_reg, add, d, n, imm32, regs; if (type == ARMul_FIRST) { - single_reg = BIT(8) == 0; /* Double precision */ - add = BIT(23); /* */ - imm32 = BITS(0,7)<<2; /* may not be used */ - d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - n = BITS(16, 19); /* destination register */ - - DBG("VLDR :\n"); + single_reg = BIT(instr, 8) == 0; // Double precision + add = BIT(instr, 23); + imm32 = BITS(instr, 0, 7)<<2; // may not be used + d = single_reg ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register + n = BITS(instr, 16, 19); // destination register i = 0; regs = 1; - + return ARMul_DONE; } else if (type == ARMul_TRANSFER) @@ -770,7 +631,6 @@ int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value) if (single_reg) { state->ExtReg[d+i] = value; - DBG("\ts%d <= [%x]\n", d+i, value); i++; if (i < regs) return ARMul_INC; @@ -781,7 +641,6 @@ int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value) { /* FIXME Careful of endianness, may need to rework this */ state->ExtReg[d*2+i] = value; - DBG("\ts[%d] <= [%x]\n", d*2+i, value); i++; if (i < regs*2) return ARMul_INC; @@ -798,19 +657,16 @@ int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value) static int single_regs, add, wback, d, n, imm32, regs; if (type == ARMul_FIRST) { - single_regs = BIT(8) == 0; /* Single precision */ - add = BIT(23); /* */ - wback = BIT(21); /* write-back */ - d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */ - n = BITS(16, 19); /* destination register */ - imm32 = BITS(0,7) * 4; /* may not be used */ - regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */ - - DBG("VLDM :\n"); - + single_regs = BIT(instr, 8) == 0; // Single precision + add = BIT(instr, 23); + wback = BIT(instr, 21); // write-back + d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register + n = BITS(instr, 16, 19); // destination register + imm32 = BITS(instr, 0, 7) * 4; // may not be used + regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 0, 7)>>1; // FLDMX if regs is odd + if (wback) { state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32); - DBG("\twback r%d[%x]\n", n, state->Reg[n]); } i = 0; @@ -822,7 +678,6 @@ int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value) if (single_regs) { state->ExtReg[d + i] = value; - DBG("\ts%d <= [%x] addr[?]\n", d+i, state->ExtReg[d + i]); i++; if (i < regs) return ARMul_INC; @@ -833,7 +688,6 @@ int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value) { /* FIXME Careful of endianness, may need to rework this */ state->ExtReg[d*2 + i] = value; - DBG("\ts[%d] <= [%x] addr[?]\n", d*2 + i, state->ExtReg[d*2 + i]); i++; if (i < regs*2) return ARMul_INC; @@ -841,41 +695,33 @@ int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value) return ARMul_DONE; } } - + return -1; } /* ----------- CDP ------------ */ void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm) { - DBG("VMOV(I) :\n"); - if (single) { - DBG("\ts%d <= [%x]\n", d, imm); state->ExtReg[d] = imm; } else { /* Check endian please */ - DBG("\ts[%d-%d] <= [%x-%x]\n", d*2+1, d*2, imm, 0); state->ExtReg[d*2+1] = imm; state->ExtReg[d*2] = 0; } } void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m) { - DBG("VMOV(R) :\n"); - if (single) { - DBG("\ts%d <= s%d[%x]\n", d, m, state->ExtReg[m]); state->ExtReg[d] = state->ExtReg[m]; } else { /* Check endian please */ - DBG("\ts[%d-%d] <= s[%d-%d][%x-%x]\n", d*2+1, d*2, m*2+1, m*2, state->ExtReg[m*2+1], state->ExtReg[m*2]); state->ExtReg[d*2+1] = state->ExtReg[m*2+1]; state->ExtReg[d*2] = state->ExtReg[m*2]; } @@ -884,27 +730,26 @@ void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m) /* Miscellaneous functions */ int32_t vfp_get_float(arm_core_t* state, unsigned int reg) { - DEBUG("VFP get float: s%d=[%08x]\n", reg, state->ExtReg[reg]); + LOG_TRACE(Core_ARM11, "VFP get float: s%d=[%08x]\n", reg, state->ExtReg[reg]); return state->ExtReg[reg]; } void vfp_put_float(arm_core_t* state, int32_t val, unsigned int reg) { - DEBUG("VFP put float: s%d <= [%08x]\n", reg, val); + LOG_TRACE(Core_ARM11, "VFP put float: s%d <= [%08x]\n", reg, val); state->ExtReg[reg] = val; } uint64_t vfp_get_double(arm_core_t* state, unsigned int reg) { - uint64_t result; - result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2]; - DEBUG("VFP get double: s[%d-%d]=[%016llx]\n", reg*2+1, reg*2, result); + uint64_t result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2]; + LOG_TRACE(Core_ARM11, "VFP get double: s[%d-%d]=[%016llx]\n", reg * 2 + 1, reg * 2, result); return result; } void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg) { - DEBUG("VFP put double: s[%d-%d] <= [%08x-%08x]\n", reg*2+1, reg*2, (uint32_t) (val>>32), (uint32_t) (val & 0xffffffff)); + LOG_TRACE(Core_ARM11, "VFP put double: s[%d-%d] <= [%08x-%08x]\n", reg * 2 + 1, reg * 2, (uint32_t)(val >> 32), (uint32_t)(val & 0xffffffff)); state->ExtReg[reg*2] = (uint32_t) (val & 0xffffffff); state->ExtReg[reg*2+1] = (uint32_t) (val>>32); } @@ -914,12 +759,10 @@ void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg) */ void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpscr) { - int si_code = 0; - - vfpdebug("VFP: raising exceptions %08x\n", exceptions); + LOG_TRACE(Core_ARM11, "VFP: raising exceptions %08x\n", exceptions); if (exceptions == VFP_EXCEPTION_ERROR) { - DEBUG("unhandled bounce %x\n", inst); + LOG_TRACE(Core_ARM11, "unhandled bounce %x\n", inst); exit(-1); return; } diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h index 539fb0131..09c7520db 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.h +++ b/src/core/arm/skyeye_common/vfp/vfp.h @@ -1,4 +1,4 @@ -/* +/* vfp/vfp.h - ARM VFPv3 emulation unit - vfp interface Copyright (C) 2003 Skyeye Develop Group for help please send mail to <skyeye-developer@lists.gro.clinux.org> @@ -18,18 +18,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __VFP_H__ -#define __VFP_H__ - -#define DBG(...) //DEBUG_LOG(ARM11, __VA_ARGS__) - -#define vfpdebug //printf +#pragma once #include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */ -#define VFP_DEBUG_TRANSLATE DBG("in func %s, %x\n", __FUNCTION__, inst); -#define VFP_DEBUG_UNIMPLEMENTED(x) printf("in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1); -#define VFP_DEBUG_UNTESTED(x) printf("in func %s, " #x " untested\n", __FUNCTION__); +#define VFP_DEBUG_UNIMPLEMENTED(x) LOG_ERROR(Core_ARM11, "in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1); +#define VFP_DEBUG_UNTESTED(x) LOG_TRACE(Core_ARM11, "in func %s, " #x " untested\n", __FUNCTION__); #define CHECK_VFP_ENABLED #define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); //if (ret == -1) {printf("VFP CDP FAILURE %x\n", inst_cream->instr); exit(-1);} @@ -114,5 +108,3 @@ int VLDR(ARMul_State * state, int type, ARMword instr, ARMword value); #ifdef __cplusplus } #endif - -#endif diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h index b1949603a..dec36c692 100644 --- a/src/core/arm/skyeye_common/vfp/vfp_helper.h +++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h @@ -30,8 +30,7 @@ * published by the Free Software Foundation. */ -#ifndef __VFP_HELPER_H__ -#define __VFP_HELPER_H__ +#pragma once /* Custom edit */ @@ -44,7 +43,6 @@ #define pr_info //printf #define pr_debug //printf -static u32 fls(ARMword x); #define do_div(n, base) {n/=base;} /* From vfpinstr.h */ @@ -502,7 +500,7 @@ struct op { u32 flags; }; -static u32 fls(ARMword x) +static inline u32 fls(ARMword x) { int r = 32; @@ -536,5 +534,3 @@ u32 vfp_double_normaliseroundintern(ARMul_State* state, struct vfp_double *vd, u u32 vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *vdm, u32 fpscr); u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *vdm, u32 fpscr); u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, struct vfp_double* dm, u32 fpscr); - -#endif diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp index a9df490ba..15a5d1265 100644 --- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp @@ -50,7 +50,7 @@ * this code that are retained. * =========================================================================== */ - + #include "core/arm/skyeye_common/vfp/vfp.h" #include "core/arm/skyeye_common/vfp/vfp_helper.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" @@ -63,7 +63,7 @@ static struct vfp_double vfp_double_default_qnan = { static void vfp_double_dump(const char *str, struct vfp_double *d) { - pr_debug("VFP: %s: sign=%d exponent=%d significand=%016llx\n", + LOG_TRACE(Core_ARM11, "VFP: %s: sign=%d exponent=%d significand=%016llx\n", str, d->sign != 0, d->exponent, d->significand); } @@ -155,7 +155,7 @@ u32 vfp_double_normaliseroundintern(ARMul_State* state, struct vfp_double *vd, u else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vd->sign != 0)) incr = (1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1; - pr_debug("VFP: rounding increment = 0x%08llx\n", incr); + LOG_TRACE(Core_ARM11, "VFP: rounding increment = 0x%08llx\n", incr); /* * Is our rounding going to overflow? @@ -281,7 +281,7 @@ u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vd->sign != 0)) incr = (1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1; - pr_debug("VFP: rounding increment = 0x%08llx\n", incr); + LOG_TRACE(Core_ARM11, "VFP: rounding increment = 0x%08llx\n", incr); /* * Is our rounding going to overflow? @@ -336,7 +336,7 @@ pack: vfp_double_dump("pack: final", vd); { s64 d = vfp_double_pack(vd); - pr_debug("VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func, + LOG_TRACE(Core_ARM11, "VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func, dd, d, exceptions); vfp_put_double(state, d, dd); } @@ -393,28 +393,28 @@ vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn, */ static u32 vfp_double_fabs(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_put_double(state, vfp_double_packed_abs(vfp_get_double(state, dm)), dd); return 0; } static u32 vfp_double_fcpy(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_put_double(state, vfp_get_double(state, dm), dd); return 0; } static u32 vfp_double_fneg(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_put_double(state, vfp_double_packed_negate(vfp_get_double(state, dm)), dd); return 0; } static u32 vfp_double_fsqrt(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_double vdm, vdd, *vdp; int ret, tm; @@ -508,7 +508,7 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u s64 d, m; u32 ret = 0; - pr_debug("In %s, state=0x%x, fpscr=0x%x\n", __FUNCTION__, state, fpscr); + LOG_TRACE(Core_ARM11, "In %s, state=0x%x, fpscr=0x%x\n", __FUNCTION__, state, fpscr); m = vfp_get_double(state, dm); if (vfp_double_packed_exponent(m) == 2047 && vfp_double_packed_mantissa(m)) { ret |= FPSCR_C | FPSCR_V; @@ -563,32 +563,32 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u ret |= FPSCR_C; } } - pr_debug("In %s, state=0x%x, ret=0x%x\n", __FUNCTION__, state, ret); + LOG_TRACE(Core_ARM11, "In %s, state=0x%x, ret=0x%x\n", __FUNCTION__, state, ret); return ret; } static u32 vfp_double_fcmp(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_compare(state, dd, 0, dm, fpscr); } static u32 vfp_double_fcmpe(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_compare(state, dd, 1, dm, fpscr); } static u32 vfp_double_fcmpz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_compare(state, dd, 0, VFP_REG_ZERO, fpscr); } static u32 vfp_double_fcmpez(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_compare(state, dd, 1, VFP_REG_ZERO, fpscr); } @@ -598,7 +598,7 @@ u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, struct vfp_double* int tm; u32 exceptions = 0; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); tm = vfp_double_type(dm); @@ -642,7 +642,7 @@ static u32 vfp_double_fcvts(ARMul_State* state, int sd, int unused, int dm, u32 int tm; u32 exceptions = 0; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_double_unpack(&vdm, vfp_get_double(state, dm)); tm = vfp_double_type(&vdm); @@ -684,7 +684,7 @@ static u32 vfp_double_fuito(ARMul_State* state, int dd, int unused, int dm, u32 struct vfp_double vdm; u32 m = vfp_get_float(state, dm); - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vdm.sign = 0; vdm.exponent = 1023 + 63 - 1; vdm.significand = (u64)m; @@ -697,7 +697,7 @@ static u32 vfp_double_fsito(ARMul_State* state, int dd, int unused, int dm, u32 struct vfp_double vdm; u32 m = vfp_get_float(state, dm); - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vdm.sign = (m & 0x80000000) >> 16; vdm.exponent = 1023 + 63 - 1; vdm.significand = vdm.sign ? -m : m; @@ -712,7 +712,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 int rmode = fpscr & FPSCR_RMODE_MASK; int tm; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_double_unpack(&vdm, vfp_get_double(state, dm)); /* @@ -773,7 +773,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 } } - pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + LOG_TRACE(Core_ARM11, "VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); vfp_put_float(state, d, sd); @@ -782,7 +782,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 static u32 vfp_double_ftouiz(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_double_ftoui(state, sd, unused, dm, FPSCR_ROUND_TOZERO); } @@ -793,7 +793,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 int rmode = fpscr & FPSCR_RMODE_MASK; int tm; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_double_unpack(&vdm, vfp_get_double(state, dm)); vfp_double_dump("VDM", &vdm); @@ -850,7 +850,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 } } - pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + LOG_TRACE(Core_ARM11, "VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); vfp_put_float(state, (s32)d, sd); @@ -859,7 +859,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 static u32 vfp_double_ftosiz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_double_ftosi(state, dd, unused, dm, FPSCR_ROUND_TOZERO); } @@ -894,9 +894,6 @@ static struct op fops_ext[] = { { vfp_double_ftosiz, OP_SCALAR }, //0x0000001B - FEXT_FTOSIZ }; - - - static u32 vfp_double_fadd_nonnumber(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *vdm, u32 fpscr) @@ -946,7 +943,7 @@ u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,struct vfp_dou if (vdn->significand & (1ULL << 63) || vdm->significand & (1ULL << 63)) { - pr_info("VFP: bad FP values in %s\n", __func__); + LOG_INFO(Core_ARM11, "VFP: bad FP values in %s\n", __func__); vfp_double_dump("VDN", vdn); vfp_double_dump("VDM", vdm); } @@ -1018,7 +1015,7 @@ vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *t = vdn; vdn = vdm; vdm = t; - pr_debug("VFP: swapping M <-> N\n"); + LOG_TRACE(Core_ARM11, "VFP: swapping M <-> N\n"); } vdd->sign = vdn->sign ^ vdm->sign; @@ -1099,7 +1096,7 @@ vfp_double_multiply_accumulate(ARMul_State* state, int dd, int dn, int dm, u32 f */ static u32 vfp_double_fmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, 0, "fmac"); } @@ -1108,7 +1105,7 @@ static u32 vfp_double_fmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr */ static u32 vfp_double_fnmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_MULTIPLY, "fnmac"); } @@ -1117,7 +1114,7 @@ static u32 vfp_double_fnmac(ARMul_State* state, int dd, int dn, int dm, u32 fpsc */ static u32 vfp_double_fmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_SUBTRACT, "fmsc"); } @@ -1126,7 +1123,7 @@ static u32 vfp_double_fmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr */ static u32 vfp_double_fnmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); } @@ -1138,7 +1135,7 @@ static u32 vfp_double_fmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr struct vfp_double vdd, vdn, vdm; u32 exceptions; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_double_unpack(&vdn, vfp_get_double(state, dn)); if (vdn.exponent == 0 && vdn.significand) vfp_double_normalise_denormal(&vdn); @@ -1159,7 +1156,7 @@ static u32 vfp_double_fnmul(ARMul_State* state, int dd, int dn, int dm, u32 fpsc struct vfp_double vdd, vdn, vdm; u32 exceptions; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_double_unpack(&vdn, vfp_get_double(state, dn)); if (vdn.exponent == 0 && vdn.significand) vfp_double_normalise_denormal(&vdn); @@ -1182,7 +1179,7 @@ static u32 vfp_double_fadd(ARMul_State* state, int dd, int dn, int dm, u32 fpscr struct vfp_double vdd, vdn, vdm; u32 exceptions; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_double_unpack(&vdn, vfp_get_double(state, dn)); if (vdn.exponent == 0 && vdn.significand) vfp_double_normalise_denormal(&vdn); @@ -1204,7 +1201,7 @@ static u32 vfp_double_fsub(ARMul_State* state, int dd, int dn, int dm, u32 fpscr struct vfp_double vdd, vdn, vdm; u32 exceptions; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_double_unpack(&vdn, vfp_get_double(state, dn)); if (vdn.exponent == 0 && vdn.significand) vfp_double_normalise_denormal(&vdn); @@ -1232,7 +1229,7 @@ static u32 vfp_double_fdiv(ARMul_State* state, int dd, int dn, int dm, u32 fpscr u32 exceptions = 0; int tm, tn; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vfp_double_unpack(&vdn, vfp_get_double(state, dn)); vfp_double_unpack(&vdm, vfp_get_double(state, dm)); @@ -1357,7 +1354,7 @@ u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr) unsigned int vecitr, veclen, vecstride; struct op *fop; - pr_debug("In %s\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "In %s\n", __FUNCTION__); vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)); fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)]; @@ -1388,7 +1385,7 @@ u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr) else veclen = fpscr & FPSCR_LENGTH_MASK; - pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, + LOG_TRACE(Core_ARM11, "VFP: vecstride=%u veclen=%u\n", vecstride, (veclen >> FPSCR_LENGTH_BIT) + 1); if (!fop->fn) { @@ -1400,18 +1397,18 @@ u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr) u32 except; char type; - type = fop->flags & OP_SD ? 's' : 'd'; + type = (fop->flags & OP_SD) ? 's' : 'd'; if (op == FOP_EXT) - pr_debug("VFP: itr%d (%c%u) = op[%u] (d%u)\n", + LOG_TRACE(Core_ARM11, "VFP: itr%d (%c%u) = op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, type, dest, dn, dm); else - pr_debug("VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n", + LOG_TRACE(Core_ARM11, "VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, type, dest, dn, FOP_TO_IDX(op), dm); except = fop->fn(state, dest, dn, dm, fpscr); - pr_debug("VFP: itr%d: exceptions=%08x\n", + LOG_TRACE(Core_ARM11, "VFP: itr%d: exceptions=%08x\n", vecitr >> FPSCR_LENGTH_BIT, except); exceptions |= except; diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp index 2c1218c30..1bdbfec8e 100644 --- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp @@ -21,14 +21,12 @@ typedef struct _vmla_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst)); vmla_inst *inst_cream = (vmla_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -43,8 +41,6 @@ VMLA_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VMLA :\n"); - vmla_inst *inst_cream = (vmla_inst *)inst_base->component; int ret; @@ -70,7 +66,6 @@ DYNCOM_FILL_ACTION(vmla), int DYNCOM_TAG(vmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -78,7 +73,6 @@ int DYNCOM_TAG(vmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int m; int n; @@ -124,7 +118,7 @@ int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ mm = FPBITCAST64(mm); tmp = FPADD(mm,tmp); mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); - nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); + nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); LETFPS(2*d ,FPBITCAST32(nn)); LETFPS(d*2 + 1 , FPBITCAST32(mm)); } @@ -144,14 +138,12 @@ typedef struct _vmls_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst)); vmls_inst *inst_cream = (vmls_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -166,8 +158,6 @@ VMLS_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VMLS :\n"); - vmls_inst *inst_cream = (vmls_inst *)inst_base->component; int ret; @@ -193,7 +183,6 @@ DYNCOM_FILL_ACTION(vmls), int DYNCOM_TAG(vmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -201,7 +190,7 @@ int DYNCOM_TAG(vmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int m; int n; @@ -247,10 +236,10 @@ int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ mm = FPBITCAST64(mm); tmp = FPADD(mm,tmp); mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); - nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); + nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); LETFPS(2*d ,FPBITCAST32(nn)); LETFPS(d*2 + 1 , FPBITCAST32(mm)); - } + } return No_exp; } #endif @@ -267,14 +256,12 @@ typedef struct _vnmla_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst)); vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -289,8 +276,6 @@ VNMLA_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VNMLA :\n"); - vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; int ret; @@ -317,7 +302,6 @@ DYNCOM_FILL_ACTION(vnmla), int DYNCOM_TAG(vnmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -325,7 +309,7 @@ int DYNCOM_TAG(vnmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int m; int n; @@ -370,7 +354,7 @@ int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ mm = OR(SHL(nn,CONST64(32)),mm); mm = FPBITCAST64(mm); tmp = FPADD(FPNEG64(mm),tmp); - mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); + mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); LETFPS(2*d ,FPBITCAST32(nn)); LETFPS(d*2 + 1 , FPBITCAST32(mm)); @@ -392,14 +376,12 @@ typedef struct _vnmls_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst)); vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -414,8 +396,6 @@ VNMLS_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VNMLS :\n"); - vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; int ret; @@ -441,7 +421,7 @@ DYNCOM_FILL_ACTION(vnmls), int DYNCOM_TAG(vnmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -449,7 +429,7 @@ int DYNCOM_TAG(vnmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int m; int n; @@ -495,10 +475,10 @@ int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ mm = FPBITCAST64(mm); tmp = FPADD(FPNEG64(mm),tmp); mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); - nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); + nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); LETFPS(2*d ,FPBITCAST32(nn)); LETFPS(d*2 + 1 , FPBITCAST32(mm)); - } + } return No_exp; } #endif @@ -515,14 +495,12 @@ typedef struct _vnmul_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst)); vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -537,8 +515,6 @@ VNMUL_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VNMUL :\n"); - vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; int ret; @@ -564,15 +540,15 @@ DYNCOM_FILL_ACTION(vnmul), int DYNCOM_TAG(vnmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; -} +} #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int m; int n; @@ -608,7 +584,7 @@ int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ tmp = FPMUL(nn,mm); tmp = FPNEG64(tmp); mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32))); - nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); + nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff))); LETFPS(2*d ,FPBITCAST32(nn)); LETFPS(d*2 + 1 , FPBITCAST32(mm)); } @@ -616,7 +592,6 @@ int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ } #endif - /* ----------------------------------------------------------------------- */ /* VMUL */ /* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */ @@ -629,14 +604,12 @@ typedef struct _vmul_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst)); vmul_inst *inst_cream = (vmul_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -651,8 +624,6 @@ VMUL_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VMUL :\n"); - vmul_inst *inst_cream = (vmul_inst *)inst_base->component; int ret; @@ -678,7 +649,6 @@ DYNCOM_FILL_ACTION(vmul), int DYNCOM_TAG(vmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -686,8 +656,7 @@ int DYNCOM_TAG(vmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - //printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int m; int n; @@ -728,7 +697,7 @@ int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi64 = ZEXT64(hi); lo64 = ZEXT64(lo); v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value *n0 = FPBITCAST64(v64); + Value *n0 = FPBITCAST64(v64); tmp = FPMUL(n0,m0); Value *val64 = IBITCAST64(tmp); hi = LSHR(val64,CONST64(32)); @@ -736,7 +705,7 @@ int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi = TRUNC32(hi); lo = TRUNC32(lo); hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); + lo = FPBITCAST32(lo); LETFPS(2*d ,lo); LETFPS(d*2 + 1 , hi); } @@ -756,14 +725,12 @@ typedef struct _vadd_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst)); vadd_inst *inst_cream = (vadd_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -778,8 +745,6 @@ VADD_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VADD :\n"); - vadd_inst *inst_cream = (vadd_inst *)inst_base->component; int ret; @@ -805,7 +770,7 @@ DYNCOM_FILL_ACTION(vadd), int DYNCOM_TAG(vadd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -813,7 +778,7 @@ int DYNCOM_TAG(vadd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int m; int n; @@ -849,7 +814,7 @@ int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi64 = ZEXT64(hi); lo64 = ZEXT64(lo); v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value *n0 = FPBITCAST64(v64); + Value *n0 = FPBITCAST64(v64); tmp = FPADD(n0,m0); Value *val64 = IBITCAST64(tmp); hi = LSHR(val64,CONST64(32)); @@ -857,7 +822,7 @@ int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi = TRUNC32(hi); lo = TRUNC32(lo); hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); + lo = FPBITCAST32(lo); LETFPS(2*d ,lo); LETFPS(d*2 + 1 , hi); } @@ -877,14 +842,12 @@ typedef struct _vsub_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst)); vsub_inst *inst_cream = (vsub_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -899,8 +862,6 @@ VSUB_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VSUB :\n"); - vsub_inst *inst_cream = (vsub_inst *)inst_base->component; int ret; @@ -932,7 +893,7 @@ int DYNCOM_TAG(vsub)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr); + LOG_TRACE(Core_ARM11, "\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr); //arch_arm_undef(cpu, bb, instr); int m; int n; @@ -968,7 +929,7 @@ int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi64 = ZEXT64(hi); lo64 = ZEXT64(lo); v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value *n0 = FPBITCAST64(v64); + Value *n0 = FPBITCAST64(v64); tmp = FPSUB(n0,m0); Value *val64 = IBITCAST64(tmp); hi = LSHR(val64,CONST64(32)); @@ -976,10 +937,10 @@ int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi = TRUNC32(hi); lo = TRUNC32(lo); hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); + lo = FPBITCAST32(lo); LETFPS(2*d ,lo); LETFPS(d*2 + 1 , hi); - } + } return No_exp; } #endif @@ -996,14 +957,12 @@ typedef struct _vdiv_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst)); vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -1018,8 +977,6 @@ VDIV_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VDIV :\n"); - vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; int ret; @@ -1045,7 +1002,7 @@ DYNCOM_FILL_ACTION(vdiv), int DYNCOM_TAG(vdiv)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -1053,7 +1010,7 @@ int DYNCOM_TAG(vdiv)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int m; int n; @@ -1089,7 +1046,7 @@ int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi64 = ZEXT64(hi); lo64 = ZEXT64(lo); v64 = OR(SHL(hi64,CONST64(32)),lo64); - Value *n0 = FPBITCAST64(v64); + Value *n0 = FPBITCAST64(v64); tmp = FPDIV(n0,m0); Value *val64 = IBITCAST64(tmp); hi = LSHR(val64,CONST64(32)); @@ -1097,10 +1054,10 @@ int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi = TRUNC32(hi); lo = TRUNC32(lo); hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); + lo = FPBITCAST32(lo); LETFPS(2*d ,lo); LETFPS(d*2 + 1 , hi); - } + } return No_exp; } #endif @@ -1119,18 +1076,16 @@ typedef struct _vmovi_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst)); vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3); if (inst_cream->single) inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19; @@ -1163,14 +1118,14 @@ DYNCOM_FILL_ACTION(vmovi), int DYNCOM_TAG(vmovi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int single = (BIT(8) == 0); int d; @@ -1210,19 +1165,17 @@ typedef struct _vmovr_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst)); vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); - inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4); + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); + inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4); return inst_base; } #endif @@ -1251,7 +1204,6 @@ int DYNCOM_TAG(vmovr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t { int instr_size = INSTR_SIZE; arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); if(instr >> 28 != 0xe) *tag |= TAG_CONDITIONAL; @@ -1260,7 +1212,6 @@ int DYNCOM_TAG(vmovr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s VMOV \n", __FUNCTION__); int single = BIT(8) == 0; int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4); @@ -1294,9 +1245,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst)); vabs_inst *inst_cream = (vabs_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -1311,8 +1262,6 @@ VABS_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VABS :\n"); - vabs_inst *inst_cream = (vabs_inst *)inst_base->component; int ret; @@ -1338,7 +1287,6 @@ DYNCOM_FILL_ACTION(vabs), int DYNCOM_TAG(vabs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -1346,7 +1294,6 @@ int DYNCOM_TAG(vabs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int single = BIT(8) == 0; int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); @@ -1376,7 +1323,7 @@ int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi = TRUNC32(hi); lo = TRUNC32(lo); hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); + lo = FPBITCAST32(lo); LETFPS(2*d ,lo); LETFPS(d*2 + 1 , hi); } @@ -1400,9 +1347,9 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index) arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst)); vneg_inst *inst_cream = (vneg_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -1417,8 +1364,6 @@ VNEG_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VNEG :\n"); - vneg_inst *inst_cream = (vneg_inst *)inst_base->component; int ret; @@ -1444,7 +1389,7 @@ DYNCOM_FILL_ACTION(vneg), int DYNCOM_TAG(vneg)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -1452,7 +1397,7 @@ int DYNCOM_TAG(vneg)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int single = BIT(8) == 0; int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15)); @@ -1482,7 +1427,7 @@ int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ hi = TRUNC32(hi); lo = TRUNC32(lo); hi = FPBITCAST32(hi); - lo = FPBITCAST32(lo); + lo = FPBITCAST32(lo); LETFPS(2*d ,lo); LETFPS(d*2 + 1 , hi); } @@ -1502,14 +1447,12 @@ typedef struct _vsqrt_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst)); vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -1524,8 +1467,6 @@ VSQRT_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VSQRT :\n"); - vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; int ret; @@ -1551,7 +1492,7 @@ DYNCOM_FILL_ACTION(vsqrt), int DYNCOM_TAG(vsqrt)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -1559,7 +1500,7 @@ int DYNCOM_TAG(vsqrt)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int dp_op = (BIT(8) == 1); int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; @@ -1572,7 +1513,7 @@ int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ v = OR(v,tmp); v = FPSQRT(FPBITCAST64(v)); tmp = TRUNC32(LSHR(IBITCAST64(v),CONST64(32))); - v = TRUNC32(AND(IBITCAST64(v),CONST64( 0xffffffff))); + v = TRUNC32(AND(IBITCAST64(v),CONST64( 0xffffffff))); LETFPS(2 * d , FPBITCAST32(v)); LETFPS(2 * d + 1, FPBITCAST32(tmp)); }else { @@ -1597,14 +1538,12 @@ typedef struct _vcmp_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst)); vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -1619,8 +1558,6 @@ VCMP_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VCMP(1) :\n"); - vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; int ret; @@ -1653,7 +1590,7 @@ int DYNCOM_TAG(vcmp)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int dp_op = (BIT(8) == 1); int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; @@ -1675,7 +1612,7 @@ int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ v = OR(v,tmp); z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1)); n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1)); - c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); + c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1)); v1 = tmp; c = OR(c,tmp); @@ -1683,14 +1620,14 @@ int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ z = SHL(ZEXT32(z),CONST32(30)); c = SHL(ZEXT32(c),CONST32(29)); v1 = SHL(ZEXT32(v1),CONST(28)); - nzcv = OR(OR(OR(n,z),c),v1); + nzcv = OR(OR(OR(n,z),c),v1); v = R(VFP_FPSCR); tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); LET(VFP_FPSCR,tmp); }else { z = FPCMP_OEQ(FR32(d),FR32(m)); n = FPCMP_OLT(FR32(d),FR32(m)); - c = FPCMP_OGE(FR32(d),FR32(m)); + c = FPCMP_OGE(FR32(d),FR32(m)); tmp = FPCMP_UNO(FR32(d),FR32(m)); c = OR(c,tmp); v1 = tmp; @@ -1698,7 +1635,7 @@ int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ z = SHL(ZEXT32(z),CONST32(30)); c = SHL(ZEXT32(c),CONST32(29)); v1 = SHL(ZEXT32(v1),CONST(28)); - nzcv = OR(OR(OR(n,z),c),v1); + nzcv = OR(OR(OR(n,z),c),v1); v = R(VFP_FPSCR); tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); LET(VFP_FPSCR,tmp); @@ -1719,14 +1656,12 @@ typedef struct _vcmp2_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst)); vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -1741,8 +1676,6 @@ VCMP2_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VCMP(2) :\n"); - vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; int ret; @@ -1775,7 +1708,7 @@ int DYNCOM_TAG(vcmp2)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int dp_op = (BIT(8) == 1); int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1; @@ -1795,7 +1728,7 @@ int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ v = OR(v,tmp); z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1)); n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1)); - c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); + c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1)); tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1)); v1 = tmp; c = OR(c,tmp); @@ -1803,7 +1736,7 @@ int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ z = SHL(ZEXT32(z),CONST32(30)); c = SHL(ZEXT32(c),CONST32(29)); v1 = SHL(ZEXT32(v1),CONST(28)); - nzcv = OR(OR(OR(n,z),c),v1); + nzcv = OR(OR(OR(n,z),c),v1); v = R(VFP_FPSCR); tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); LET(VFP_FPSCR,tmp); @@ -1812,7 +1745,7 @@ int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ v1 = FPBITCAST32(v1); z = FPCMP_OEQ(FR32(d),v1); n = FPCMP_OLT(FR32(d),v1); - c = FPCMP_OGE(FR32(d),v1); + c = FPCMP_OGE(FR32(d),v1); tmp = FPCMP_UNO(FR32(d),v1); c = OR(c,tmp); v1 = tmp; @@ -1820,7 +1753,7 @@ int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ z = SHL(ZEXT32(z),CONST32(30)); c = SHL(ZEXT32(c),CONST32(29)); v1 = SHL(ZEXT32(v1),CONST(28)); - nzcv = OR(OR(OR(n,z),c),v1); + nzcv = OR(OR(OR(n,z),c),v1); v = R(VFP_FPSCR); tmp = OR(nzcv,AND(v,CONST32(0x0fffffff))); LET(VFP_FPSCR,tmp); @@ -1841,14 +1774,12 @@ typedef struct _vcvtbds_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst)); vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); @@ -1863,8 +1794,6 @@ VCVTBDS_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VCVT(BDS) :\n"); - vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; int ret; @@ -1897,7 +1826,7 @@ int DYNCOM_TAG(vcvtbds)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_ #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is executed out.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int dp_op = (BIT(8) == 1); int d = dp_op ? BITS(12,15) << 1 | BIT(22) : BIT(22) << 4 | BITS(12,15); @@ -1911,7 +1840,7 @@ int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) tmp = ZEXT64(IBITCAST32(FR32(2 * m))); v1 = OR(v,tmp); tmp = FPTRUNC(32,FPBITCAST64(v1)); - LETFPS(d,tmp); + LETFPS(d,tmp); }else { v = FR32(m); tmp = FPEXT(64,v); @@ -1937,7 +1866,7 @@ typedef struct _vcvtbff_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF); + VFP_DEBUG_UNTESTED(VCVTBFF); arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst)); vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; @@ -1959,8 +1888,6 @@ VCVTBFF_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VCVT(BFF) :\n"); - vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; int ret; @@ -1986,14 +1913,14 @@ DYNCOM_FILL_ACTION(vcvtbff), int DYNCOM_TAG(vcvtbff)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); arch_arm_undef(cpu, bb, instr); return No_exp; } @@ -2011,20 +1938,17 @@ typedef struct _vcvtbfi_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst)); vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; - return inst_base; } #endif @@ -2034,8 +1958,6 @@ VCVTBFI_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - DBG("VCVT(BFI) :\n"); - vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; int ret; @@ -2061,8 +1983,7 @@ DYNCOM_FILL_ACTION(vcvtbfi), int DYNCOM_TAG(vcvtbfi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -2070,17 +1991,17 @@ int DYNCOM_TAG(vcvtbfi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_ #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); unsigned int opc2 = BITS(16,18); - int to_integer = ((opc2 >> 2) == 1); + int to_integer = ((opc2 >> 2) == 1); int dp_op = (BIT(8) == 1); unsigned int op = BIT(7); int m,d; Value* v; Value* hi; Value* lo; - Value* v64; + Value* v64; if(to_integer){ d = BIT(22) | (BITS(12,15) << 1); if(dp_op) @@ -2092,15 +2013,15 @@ int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) if(dp_op) d = BITS(12,15) | BIT(22) << 4; else - d = BIT(22) | BITS(12,15) << 1; + d = BIT(22) | BITS(12,15) << 1; } if(to_integer){ if(dp_op){ lo = FR32(m * 2); - hi = FR32(m * 2 + 1); + hi = FR32(m * 2 + 1); hi = ZEXT64(IBITCAST32(hi)); lo = ZEXT64(IBITCAST32(lo)); - v64 = OR(SHL(hi,CONST64(32)),lo); + v64 = OR(SHL(hi,CONST64(32)),lo); if(BIT(16)){ v = FPTOSI(32,FPBITCAST64(v64)); } @@ -2112,7 +2033,6 @@ int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) }else { v = FR32(m); if(BIT(16)){ - v = FPTOSI(32,v); } else @@ -2120,10 +2040,10 @@ int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) LETFPS(d,FPBITCAST32(v)); } }else { - if(dp_op){ + if(dp_op){ v = IBITCAST32(FR32(m)); if(BIT(7)) - v64 = SITOFP(64,v); + v64 = SITOFP(64,v); else v64 = UITOFP(64,v); v = IBITCAST64(v64); @@ -2149,7 +2069,7 @@ int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc) * @param cpu * @param instr * -* @return +* @return */ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){ int dp_operation = BIT(8); @@ -2183,19 +2103,17 @@ typedef struct _vmovbrs_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst)); vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->to_arm = BIT(inst, 20) == 1; - inst_cream->t = BITS(inst, 12, 15); - inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1; + inst_cream->to_arm = BIT(inst, 20) == 1; + inst_cream->t = BITS(inst, 12, 15); + inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1; return inst_base; } @@ -2224,26 +2142,22 @@ DYNCOM_FILL_ACTION(vmovbrs), int DYNCOM_TAG(vmovbrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("VMOV(BRS) :\n"); int to_arm = BIT(20) == 1; int t = BITS(12, 15); int n = BIT(7) | BITS(16, 19)<<1; if (to_arm) { - DBG("\tr%d <= s%d\n", t, n); LET(t, IBITCAST32(FR32(n))); } else { - DBG("\ts%d <= r%d\n", n, t); LETFPS(n, FPBITCAST32(R(t))); } return No_exp; @@ -2263,18 +2177,16 @@ typedef struct _vmsr_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst)); vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->reg = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->reg = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); return inst_base; } @@ -2306,7 +2218,6 @@ DYNCOM_FILL_ACTION(vmsr), int DYNCOM_TAG(vmsr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -2314,11 +2225,9 @@ int DYNCOM_TAG(vmsr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); - DBG("VMSR :"); if(RD == 15) { - printf("in %s is not implementation.\n", __FUNCTION__); + LOG_ERROR(Core_ARM11, "in %s is not implementation.\n", __FUNCTION__); exit(-1); } @@ -2328,7 +2237,6 @@ int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ if (reg == 1) { LET(VFP_FPSCR, R(Rt)); - DBG("\tflags <= fpscr\n"); } else { @@ -2336,10 +2244,8 @@ int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ { case 8: LET(VFP_FPEXC, R(Rt)); - DBG("\tfpexc <= r%d \n", Rt); break; default: - DBG("\tSUBARCHITECTURE DEFINED\n"); break; } } @@ -2362,14 +2268,12 @@ typedef struct _vmovbrc_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst)); vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; @@ -2405,14 +2309,14 @@ DYNCOM_FILL_ACTION(vmovbrc), int DYNCOM_TAG(vmovbrc)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); arch_arm_undef(cpu, bb, instr); return No_exp; } @@ -2431,18 +2335,16 @@ typedef struct _vmrs_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst)); vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->reg = BITS(inst, 16, 19); - inst_cream->Rt = BITS(inst, 12, 15); + inst_cream->reg = BITS(inst, 16, 19); + inst_cream->Rt = BITS(inst, 12, 15); return inst_base; } @@ -2458,46 +2360,39 @@ VMRS_INST: vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; - DBG("VMRS :"); - if (inst_cream->reg == 1) /* FPSCR */ { if (inst_cream->Rt != 15) - { + { cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSCR)]; - DBG("\tr%d <= fpscr[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); } else - { + { cpu->NFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 31) & 1; cpu->ZFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 30) & 1; cpu->CFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 29) & 1; cpu->VFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 28) & 1; - DBG("\tflags <= fpscr[%1xxxxxxxx]\n", cpu->VFP[VFP_OFFSET(VFP_FPSCR)]>>28); } - } + } else { switch (inst_cream->reg) { case 0: cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSID)]; - DBG("\tr%d <= fpsid[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSID)]); break; case 6: /* MVFR1, VFPv3 only ? */ - DBG("\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt); + LOG_TRACE(Core_ARM11, "\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt); break; case 7: /* MVFR0, VFPv3 only? */ - DBG("\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt); + LOG_TRACE(Core_ARM11, "\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt); break; case 8: cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPEXC)]; - DBG("\tr%d <= fpexc[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPEXC)]); break; default: - DBG("\tSUBARCHITECTURE DEFINED\n"); break; } } @@ -2516,8 +2411,6 @@ DYNCOM_FILL_ACTION(vmrs), int DYNCOM_TAG(vmrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); - DBG("\t\tin %s .\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; @@ -2525,25 +2418,21 @@ int DYNCOM_TAG(vmrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); Value *data = NULL; int reg = BITS(16, 19);; int Rt = BITS(12, 15); - DBG("VMRS : reg=%d, Rt=%d\n", reg, Rt); if (reg == 1) { if (Rt != 15) { LET(Rt, R(VFP_FPSCR)); - DBG("\tr%d <= fpscr\n", Rt); } else { //LET(Rt, R(VFP_FPSCR)); update_cond_from_fpscr(cpu, instr, bb, pc); - DBG("In %s, \tflags <= fpscr\n", __FUNCTION__); } } else @@ -2552,22 +2441,19 @@ int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ { case 0: LET(Rt, R(VFP_FPSID)); - DBG("\tr%d <= fpsid\n", Rt); break; case 6: /* MVFR1, VFPv3 only ? */ - DBG("\tr%d <= MVFR1 unimplemented\n", Rt); + LOG_TRACE(Core_ARM11, "\tr%d <= MVFR1 unimplemented\n", Rt); break; case 7: /* MVFR0, VFPv3 only? */ - DBG("\tr%d <= MVFR0 unimplemented\n", Rt); + LOG_TRACE(Core_ARM11, "\tr%d <= MVFR0 unimplemented\n", Rt); break; case 8: LET(Rt, R(VFP_FPEXC)); - DBG("\tr%d <= fpexc\n", Rt); break; default: - DBG("\tSUBARCHITECTURE DEFINED\n"); break; } } @@ -2591,14 +2477,12 @@ typedef struct _vmovbcr_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst)); vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; @@ -2634,14 +2518,14 @@ DYNCOM_FILL_ACTION(vmovbcr), int DYNCOM_TAG(vmovbcr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); return instr_size; } #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); + LOG_TRACE(Core_ARM11, "\t\tin %s instruction is not implemented.\n", __FUNCTION__); arch_arm_undef(cpu, bb, instr); return No_exp; } @@ -2667,20 +2551,18 @@ typedef struct _vmovbrrss_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst)); vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->to_arm = BIT(inst, 20) == 1; - inst_cream->t = BITS(inst, 12, 15); - inst_cream->t2 = BITS(inst, 16, 19); - inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5); + inst_cream->to_arm = BIT(inst, 20) == 1; + inst_cream->t = BITS(inst, 12, 15); + inst_cream->t2 = BITS(inst, 16, 19); + inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5); return inst_base; } @@ -2751,20 +2633,18 @@ typedef struct _vmovbrrd_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst)); vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; - inst_cream->to_arm = BIT(inst, 20) == 1; - inst_cream->t = BITS(inst, 12, 15); - inst_cream->t2 = BITS(inst, 16, 19); - inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3); + inst_cream->to_arm = BIT(inst, 20) == 1; + inst_cream->t = BITS(inst, 12, 15); + inst_cream->t2 = BITS(inst, 16, 19); + inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3); return inst_base; } @@ -2777,7 +2657,7 @@ VMOVBRRD_INST: vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; - VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, + VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); } cpu->Reg[15] += GET_INST_SIZE(cpu); @@ -2794,7 +2674,6 @@ DYNCOM_FILL_ACTION(vmovbrrd), int DYNCOM_TAG(vmovbrrd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); if(instr >> 28 != 0xe) *tag |= TAG_CONDITIONAL; @@ -2803,7 +2682,6 @@ int DYNCOM_TAG(vmovbrrd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int to_arm = BIT(20) == 1; int t = BITS(12, 15); @@ -2841,21 +2719,19 @@ typedef struct _vstr_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst)); vstr_inst *inst_cream = (vstr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); + inst_cream->add = BIT(inst, 23); inst_cream->imm32 = BITS(inst, 0,7) << 2; inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); + inst_cream->n = BITS(inst, 16, 19); return inst_base; } @@ -2896,7 +2772,6 @@ int DYNCOM_TAG(vstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * { int instr_size = INSTR_SIZE; arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); *tag |= TAG_NEW_BB; if(instr >> 28 != 0xe) *tag |= TAG_CONDITIONAL; @@ -2907,14 +2782,13 @@ int DYNCOM_TAG(vstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ int single = BIT(8) == 0; - int add = BIT(23); + int add = BIT(23); int imm32 = BITS(0,7) << 2; int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); - int n = BITS(16, 19); + int n = BITS(16, 19); Value* base = (n == 15) ? ADD(AND(R(n), CONST(0xFFFFFFFC)), CONST(8)): R(n); Value* Addr = add ? ADD(base, CONST(imm32)) : SUB(base, CONST(imm32)); - DBG("VSTR :\n"); //if(single) // bb = arch_check_mm(cpu, bb, Addr, 4, 0, cpu->dyncom_engine->bb_trap); //else @@ -2951,14 +2825,12 @@ typedef struct _vpush_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst)); vpush_inst *inst_cream = (vpush_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->single = BIT(inst, 8) == 0; @@ -2974,13 +2846,12 @@ VPUSH_INST: { if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - int i; vpush_inst *inst_cream = (vpush_inst *)inst_base->component; addr = cpu->Reg[R13] - inst_cream->imm32; - for (i = 0; i < inst_cream->regs; i++) + for (int i = 0; i < inst_cream->regs; i++) { if (inst_cream->single) { @@ -3010,7 +2881,6 @@ int DYNCOM_TAG(vpush)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t { int instr_size = INSTR_SIZE; arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); *tag |= TAG_NEW_BB; if(instr >> 28 != 0xe) *tag |= TAG_CONDITIONAL; @@ -3025,15 +2895,14 @@ int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ int imm32 = BITS(0, 7)<<2; int regs = (single ? BITS(0, 7) : BITS(1, 7)); - DBG("\t\tin %s \n", __FUNCTION__); Value* Addr = SUB(R(13), CONST(imm32)); //if(single) // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap); //else // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap); //Value* phys_addr; - int i; - for (i = 0; i < regs; i++) + + for (int i = 0; i < regs; i++) { if (single) { @@ -3079,14 +2948,12 @@ typedef struct _vstm_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst)); vstm_inst *inst_cream = (vstm_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->single = BIT(inst, 8) == 0; @@ -3106,13 +2973,11 @@ VSTM_INST: /* encoding 1 */ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - int i; - vstm_inst *inst_cream = (vstm_inst *)inst_base->component; addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); - for (i = 0; i < inst_cream->regs; i++) + for (int i = 0; i < inst_cream->regs; i++) { if (inst_cream->single) { @@ -3127,10 +2992,9 @@ VSTM_INST: /* encoding 1 */ } } if (inst_cream->wback){ - cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : + cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : cpu->Reg[inst_cream->n] - inst_cream->imm32); } - } cpu->Reg[15] += 4; INC_PC(sizeof(vstm_inst)); @@ -3147,10 +3011,8 @@ DYNCOM_FILL_ACTION(vstm), int DYNCOM_TAG(vstm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); *tag |= TAG_NEW_BB; if(instr >> 28 != 0xe) *tag |= TAG_CONDITIONAL; @@ -3170,30 +3032,26 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ int regs = single ? BITS(0, 7) : BITS(1, 7); Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32))); - DBG("VSTM \n"); //if(single) // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap); //else // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap); - int i; + int i; Value* phys_addr; for (i = 0; i < regs; i++) { if (single) { - //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); /* if R(i) is R15? */ //memory_write(cpu, bb, Addr, RSPR(d + i), 32); memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32); bb = cpu->dyncom_engine->bb; - //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); Addr = ADD(Addr, CONST(4)); } else { - //Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32); memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32); @@ -3203,16 +3061,14 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32); memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32); bb = cpu->dyncom_engine->bb; - //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); //addr += 8; Addr = ADD(Addr, CONST(8)); } } if (wback){ - //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 : + //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 : // cpu->Reg[n] - imm32); LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32)))); - DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32); } return No_exp; } @@ -3232,14 +3088,12 @@ typedef struct _vpop_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst)); vpop_inst *inst_cream = (vpop_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->single = BIT(inst, 8) == 0; @@ -3256,14 +3110,13 @@ VPOP_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - int i; unsigned int value1, value2; vpop_inst *inst_cream = (vpop_inst *)inst_base->component; addr = cpu->Reg[R13]; - for (i = 0; i < inst_cream->regs; i++) + for (int i = 0; i < inst_cream->regs; i++) { if (inst_cream->single) { @@ -3296,11 +3149,9 @@ DYNCOM_FILL_ACTION(vpop), int DYNCOM_TAG(vpop)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); /* Should check if PC is destination register */ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); *tag |= TAG_NEW_BB; if(instr >> 28 != 0xe) *tag |= TAG_CONDITIONAL; @@ -3310,7 +3161,6 @@ int DYNCOM_TAG(vpop)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t * #endif #ifdef VFP_DYNCOM_TRANS int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ - DBG("\t\tin %s instruction .\n", __FUNCTION__); //arch_arm_undef(cpu, bb, instr); int single = BIT(8) == 0; int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4)); @@ -3320,15 +3170,13 @@ int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ int i; unsigned int value1, value2; - DBG("VPOP :\n"); - Value* Addr = R(13); Value* val; //if(single) // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); //else // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); - //Value* phys_addr; + //Value* phys_addr; for (i = 0; i < regs; i++) { if (single) @@ -3374,21 +3222,19 @@ typedef struct _vldr_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst)); vldr_inst *inst_cream = (vldr_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); + inst_cream->add = BIT(inst, 23); inst_cream->imm32 = BITS(inst, 0,7) << 2; inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); + inst_cream->n = BITS(inst, 16, 19); return inst_base; } @@ -3432,11 +3278,9 @@ DYNCOM_FILL_ACTION(vldr), int DYNCOM_TAG(vldr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); /* Should check if PC is destination register */ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); *tag |= TAG_NEW_BB; if(instr >> 28 != 0xe) *tag |= TAG_CONDITIONAL; @@ -3454,7 +3298,6 @@ int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ int imm32 = BITS(0, 7)<<2; int regs = (single ? BITS(0, 7) : BITS(1, 7)); Value* base = R(n); - DBG("\t\tin %s .\n", __FUNCTION__); if(n == 15){ base = ADD(AND(base, CONST(0xFFFFFFFC)), CONST(8)); } @@ -3506,14 +3349,12 @@ typedef struct _vldm_inst { #ifdef VFP_INTERPRETER_TRANS ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index) { - VFP_DEBUG_TRANSLATE; - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst)); vldm_inst *inst_cream = (vldm_inst *)inst_base->component; - inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = NON_BRANCH; + inst_base->cond = BITS(inst, 28, 31); + inst_base->idx = index; + inst_base->br = NON_BRANCH; inst_base->load_r15 = 0; inst_cream->single = BIT(inst, 8) == 0; @@ -3533,13 +3374,11 @@ VLDM_INST: if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - int i; - vldm_inst *inst_cream = (vldm_inst *)inst_base->component; addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32); - for (i = 0; i < inst_cream->regs; i++) + for (int i = 0; i < inst_cream->regs; i++) { if (inst_cream->single) { @@ -3554,11 +3393,9 @@ VLDM_INST: } } if (inst_cream->wback){ - cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : + cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : cpu->Reg[inst_cream->n] - inst_cream->imm32); - DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]); } - } cpu->Reg[15] += GET_INST_SIZE(cpu); INC_PC(sizeof(vldm_inst)); @@ -3574,10 +3411,8 @@ DYNCOM_FILL_ACTION(vldm), int DYNCOM_TAG(vldm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc) { int instr_size = INSTR_SIZE; - //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__); //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc); arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc); - DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc); *tag |= TAG_NEW_BB; if(instr >> 28 != 0xe) *tag |= TAG_CONDITIONAL; @@ -3601,15 +3436,13 @@ int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ //else // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap); - DBG("VLDM \n"); - int i; + int i; //Value* phys_addr; Value* val; for (i = 0; i < regs; i++) { if (single) { - //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); /* if R(i) is R15? */ memory_read(cpu, bb, Addr, 0, 32); @@ -3617,7 +3450,6 @@ int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); //LETS(d + i, val); LETFPS(d + i, FPBITCAST32(val)); - //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); Addr = ADD(Addr, CONST(4)); } else @@ -3632,16 +3464,14 @@ int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){ LETFPS((d + i) * 2 + 1, FPBITCAST32(val)); //Memory::Write(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); - //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); //addr += 8; Addr = ADD(Addr, CONST(8)); } } if (wback){ - //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 : + //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 : // cpu->Reg[n] - imm32); LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32)))); - DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32); } return No_exp; } diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp index 08d0d719f..b7872bdc4 100644 --- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp @@ -959,70 +959,34 @@ vfp_single_multiply(struct vfp_single *vsd, struct vfp_single *vsn, struct vfp_s static u32 vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr, u32 negate, const char *func) { - - { - struct vfp_single vsd, vsp, vsn, vsm; - u32 exceptions; - s32 v; - - - - v = vfp_get_float(state, sn); - pr_debug("VFP: s%u = %08x\n", sn, v); - vfp_single_unpack(&vsn, v); - if (vsn.exponent == 0 && vsn.significand) - vfp_single_normalise_denormal(&vsn); - - vfp_single_unpack(&vsm, m); - if (vsm.exponent == 0 && vsm.significand) - vfp_single_normalise_denormal(&vsm); - - exceptions = vfp_single_multiply(&vsp, &vsn, &vsm, fpscr); - - if (negate & NEG_MULTIPLY) - vsp.sign = vfp_sign_negate(vsp.sign); - - v = vfp_get_float(state, sd); - pr_debug("VFP: s%u = %08x\n", sd, v); - vfp_single_unpack(&vsn, v); - if (negate & NEG_SUBTRACT) - vsn.sign = vfp_sign_negate(vsn.sign); - - exceptions |= vfp_single_add(&vsd, &vsn, &vsp, fpscr); - - return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, func); - } - - struct vfp_double vsd, vsp, vsn, vsm; + vfp_single vsd, vsp, vsn, vsm; u32 exceptions; s32 v; - s64 vd; - s64 md; v = vfp_get_float(state, sn); - vd = vfp_single_to_doubleintern(state, v, fpscr); - vfp_double_unpack(&vsn, vd); + pr_debug("VFP: s%u = %08x\n", sn, v); + vfp_single_unpack(&vsn, v); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); + + vfp_single_unpack(&vsm, m); + if (vsm.exponent == 0 && vsm.significand) + vfp_single_normalise_denormal(&vsm); - md = vfp_single_to_doubleintern(state, m, fpscr); - vfp_double_unpack(&vsm, md); + exceptions = vfp_single_multiply(&vsp, &vsn, &vsm, fpscr); - exceptions = vfp_double_multiply(&vsp, &vsn, &vsm, fpscr); if (negate & NEG_MULTIPLY) vsp.sign = vfp_sign_negate(vsp.sign); v = vfp_get_float(state, sd); - vd = vfp_single_to_doubleintern(state, v, fpscr); - vfp_double_unpack(&vsn, vd); - + pr_debug("VFP: s%u = %08x\n", sd, v); + vfp_single_unpack(&vsn, v); if (negate & NEG_SUBTRACT) vsn.sign = vfp_sign_negate(vsn.sign); - exceptions |= vfp_double_add(&vsd, &vsn, &vsp, fpscr); - - s64 debug = vfp_double_pack(&vsd); - - return vfp_double_fcvtsinterncutting(state, sd, &vsd, fpscr); + exceptions |= vfp_single_add(&vsd, &vsn, &vsp, fpscr); + return vfp_single_normaliseround(state, sd, &vsd, fpscr, exceptions, func); } /* @@ -1326,7 +1290,7 @@ u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr) u32 except; char type; - type = fop->flags & OP_DD ? 'd' : 's'; + type = (fop->flags & OP_DD) ? 'd' : 's'; if (op == FOP_EXT) pr_debug("VFP: itr%d (%c%u) = op[%u] (s%u=%08x)\n", vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, |
