diff options
Diffstat (limited to 'ARMInterpreter_ALU.cpp')
| -rw-r--r-- | ARMInterpreter_ALU.cpp | 134 | 
1 files changed, 133 insertions, 1 deletions
diff --git a/ARMInterpreter_ALU.cpp b/ARMInterpreter_ALU.cpp index 46f8107..eae671f 100644 --- a/ARMInterpreter_ALU.cpp +++ b/ARMInterpreter_ALU.cpp @@ -749,7 +749,57 @@ s32 T_ASR_IMM(ARM* cpu)      return C_S(1);  } -// +s32 T_ADD_REG_(ARM* cpu) +{ +    u32 a = cpu->R[(cpu->CurInstr >> 3) & 0x7]; +    u32 b = cpu->R[(cpu->CurInstr >> 6) & 0x7]; +    u32 res = a + b; +    cpu->R[cpu->CurInstr & 0x7] = res; +    cpu->SetNZCV(res & 0x80000000, +                 !res, +                 CARRY_ADD(a, b), +                 OVERFLOW_ADD(a, b, res)); +    return C_S(1); +} + +s32 T_SUB_REG_(ARM* cpu) +{ +    u32 a = cpu->R[(cpu->CurInstr >> 3) & 0x7]; +    u32 b = cpu->R[(cpu->CurInstr >> 6) & 0x7]; +    u32 res = a - b; +    cpu->R[cpu->CurInstr & 0x7] = res; +    cpu->SetNZCV(res & 0x80000000, +                 !res, +                 CARRY_SUB(a, b), +                 OVERFLOW_SUB(a, b, res)); +    return C_S(1); +} + +s32 T_ADD_IMM_(ARM* cpu) +{ +    u32 a = cpu->R[(cpu->CurInstr >> 3) & 0x7]; +    u32 b = (cpu->CurInstr >> 6) & 0x7; +    u32 res = a + b; +    cpu->R[cpu->CurInstr & 0x7] = res; +    cpu->SetNZCV(res & 0x80000000, +                 !res, +                 CARRY_ADD(a, b), +                 OVERFLOW_ADD(a, b, res)); +    return C_S(1); +} + +s32 T_SUB_IMM_(ARM* cpu) +{ +    u32 a = cpu->R[(cpu->CurInstr >> 3) & 0x7]; +    u32 b = (cpu->CurInstr >> 6) & 0x7; +    u32 res = a - b; +    cpu->R[cpu->CurInstr & 0x7] = res; +    cpu->SetNZCV(res & 0x80000000, +                 !res, +                 CARRY_SUB(a, b), +                 OVERFLOW_SUB(a, b, res)); +    return C_S(1); +}  s32 T_MOV_IMM(ARM* cpu)  { @@ -997,4 +1047,86 @@ s32 T_MVN_REG(ARM* cpu)  } +s32 T_ADD_HIREG(ARM* cpu) +{ +    u32 rd = (cpu->CurInstr & 0x7) | ((cpu->CurInstr >> 4) & 0x8); +    u32 rs = (cpu->CurInstr >> 3) & 0xF; + +    u32 a = cpu->R[rd]; +    u32 b = cpu->R[rs]; + +    if (rd == 15) +    { +        cpu->JumpTo(a + b); +        return C_S(2) + C_N(1); +    } +    else +    { +        cpu->R[rd] = a + b; +        return C_S(1); +    } +} + +s32 T_CMP_HIREG(ARM* cpu) +{ +    u32 rd = (cpu->CurInstr & 0x7) | ((cpu->CurInstr >> 4) & 0x8); +    u32 rs = (cpu->CurInstr >> 3) & 0xF; + +    u32 a = cpu->R[rd]; +    u32 b = cpu->R[rs]; +    u32 res = a - b; + +    cpu->SetNZCV(res & 0x80000000, +                 !res, +                 CARRY_SUB(a, b), +                 OVERFLOW_SUB(a, b, res)); +    return C_S(1); +} + +s32 T_MOV_HIREG(ARM* cpu) +{ +    u32 rd = (cpu->CurInstr & 0x7) | ((cpu->CurInstr >> 4) & 0x8); +    u32 rs = (cpu->CurInstr >> 3) & 0xF; + +    if (rd == 15) +    { +        cpu->JumpTo(cpu->R[rs]); +        return C_S(2) + C_N(1); +    } +    else +    { +        cpu->R[rd] = cpu->R[rs]; +        return C_S(1); +    } +} + + +s32 T_ADD_PCREL(ARM* cpu) +{ +    u32 val = cpu->R[15] = ~2; +    val += ((cpu->CurInstr & 0xFF) << 2); +    cpu->R[(cpu->CurInstr >> 8) & 0x7] = val; +    return C_S(1); +} + +s32 T_ADD_SPREL(ARM* cpu) +{ +    u32 val = cpu->R[13]; +    val += ((cpu->CurInstr & 0xFF) << 2); +    cpu->R[(cpu->CurInstr >> 8) & 0x7] = val; +    return C_S(1); +} + +s32 T_ADD_SP(ARM* cpu) +{ +    u32 val = cpu->R[13]; +    if (cpu->CurInstr & (1<<7)) +        val -= ((cpu->CurInstr & 0x7F) << 2); +    else +        val += ((cpu->CurInstr & 0x7F) << 2); +    cpu->R[13] = val; +    return C_S(1); +} + +  }  |