~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to Core/MIPS/MIPSCodeUtils.cpp

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2012- PPSSPP Project.
 
2
 
 
3
// This program is free software: you can redistribute it and/or modify
 
4
// it under the terms of the GNU General Public License as published by
 
5
// the Free Software Foundation, version 2.0 or later versions.
 
6
 
 
7
// This program is distributed in the hope that it will be useful,
 
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
// GNU General Public License 2.0 for more details.
 
11
 
 
12
// A copy of the GPL 2.0 should have been included with the program.
 
13
// If not, see http://www.gnu.org/licenses/
 
14
 
 
15
// Official git repository and contact information can be found at
 
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
 
17
 
 
18
#include "Core/MIPS/MIPS.h"
 
19
#include "Core/MIPS/MIPSTables.h"
 
20
#include "Core/MIPS/MIPSCodeUtils.h"
 
21
#include "Core/Host.h"
 
22
#include "Core/MemMap.h"
 
23
 
 
24
namespace MIPSCodeUtils
 
25
{
 
26
 
 
27
#define OP_SYSCALL   0x0000000c
 
28
#define OP_SYSCALL_MASK 0xFC00003F
 
29
#define _RS   ((op>>21) & 0x1F)
 
30
#define _RT   ((op>>16) & 0x1F)
 
31
 
 
32
        u32 GetJumpTarget(u32 addr)
 
33
        {
 
34
                MIPSOpcode op = Memory::Read_Instruction(addr, true);
 
35
                if (op != 0)
 
36
                {
 
37
                        MIPSInfo info = MIPSGetInfo(op);
 
38
                        if ((info & IS_JUMP) && (info & IN_IMM26))
 
39
                        {
 
40
                                u32 target = (addr & 0xF0000000) | ((op&0x03FFFFFF) << 2);
 
41
                                return target;
 
42
                        }
 
43
                        else
 
44
                                return INVALIDTARGET;
 
45
                }
 
46
                else
 
47
                        return INVALIDTARGET;
 
48
        }
 
49
 
 
50
        u32 GetBranchTarget(u32 addr)
 
51
        {
 
52
                MIPSOpcode op = Memory::Read_Instruction(addr, true);
 
53
                if (op != 0)
 
54
                {
 
55
                        MIPSInfo info = MIPSGetInfo(op);
 
56
                        if (info & IS_CONDBRANCH)
 
57
                        {
 
58
                                return addr + 4 + ((signed short)(op&0xFFFF)<<2);
 
59
                        }
 
60
                        else
 
61
                                return INVALIDTARGET;
 
62
                }
 
63
                else
 
64
                        return INVALIDTARGET;
 
65
        }
 
66
 
 
67
        u32 GetBranchTargetNoRA(u32 addr)
 
68
        {
 
69
                MIPSOpcode op = Memory::Read_Instruction(addr, true);
 
70
                return GetBranchTargetNoRA(addr, op);
 
71
        }
 
72
 
 
73
        u32 GetBranchTargetNoRA(u32 addr, MIPSOpcode op)
 
74
        {
 
75
                if (op != 0)
 
76
                {
 
77
                        MIPSInfo info = MIPSGetInfo(op);
 
78
                        if ((info & IS_CONDBRANCH) && !(info & OUT_RA))
 
79
                        {
 
80
                                return addr + 4 + ((signed short)(op&0xFFFF)<<2);
 
81
                        }
 
82
                        else
 
83
                                return INVALIDTARGET;
 
84
                }
 
85
                else
 
86
                        return INVALIDTARGET;
 
87
        }
 
88
 
 
89
        u32 GetSureBranchTarget(u32 addr)
 
90
        {
 
91
                MIPSOpcode op = Memory::Read_Instruction(addr, true);
 
92
                if (op != 0)
 
93
                {
 
94
                        MIPSInfo info = MIPSGetInfo(op);
 
95
                        if ((info & IS_CONDBRANCH) && !(info & (IN_FPUFLAG | IS_VFPU)))
 
96
                        {
 
97
                                bool sure;
 
98
                                bool takeBranch;
 
99
                                switch (info & CONDTYPE_MASK)
 
100
                                {
 
101
                                case CONDTYPE_EQ:
 
102
                                        sure = _RS == _RT;
 
103
                                        takeBranch = true;
 
104
                                        break;
 
105
 
 
106
                                case CONDTYPE_NE:
 
107
                                        sure = _RS == _RT;
 
108
                                        takeBranch = false;
 
109
                                        break;
 
110
 
 
111
                                case CONDTYPE_LEZ:
 
112
                                case CONDTYPE_GEZ:
 
113
                                        sure = _RS == 0;
 
114
                                        takeBranch = true;
 
115
                                        break;
 
116
 
 
117
                                case CONDTYPE_LTZ:
 
118
                                case CONDTYPE_GTZ:
 
119
                                        sure = _RS == 0;
 
120
                                        takeBranch = false;
 
121
                                        break;
 
122
 
 
123
                                default:
 
124
                                        sure = false;
 
125
                                }
 
126
 
 
127
                                if (sure && takeBranch)
 
128
                                        return addr + 4 + ((signed short)(op&0xFFFF)<<2);
 
129
                                else if (sure && !takeBranch)
 
130
                                        return addr + 8;
 
131
                                else
 
132
                                        return INVALIDTARGET;
 
133
                        }
 
134
                        else
 
135
                                return INVALIDTARGET;
 
136
                }
 
137
                else
 
138
                        return INVALIDTARGET;
 
139
        }
 
140
 
 
141
        bool IsVFPUBranch(MIPSOpcode op) {
 
142
                return (MIPSGetInfo(op) & (IS_VFPU | IS_CONDBRANCH)) == (IS_VFPU | IS_CONDBRANCH);
 
143
        }
 
144
 
 
145
        bool IsBranch(MIPSOpcode op) {
 
146
                return (MIPSGetInfo(op) & IS_CONDBRANCH) == IS_CONDBRANCH;
 
147
        }
 
148
 
 
149
 
 
150
}