~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/Core/Src/PowerPC/JitILCommon/JitILBase_SystemRegisters.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Dolphin Emulator Project
 
2
// Licensed under GPLv2
 
3
// Refer to the license.txt file included.
 
4
 
 
5
#include "Common.h"
 
6
#include "JitILBase.h"
 
7
 
 
8
#include "../../HW/SystemTimers.h"
 
9
 
 
10
 
 
11
void JitILBase::mtspr(UGeckoInstruction inst)
 
12
{
 
13
        INSTRUCTION_START
 
14
                JITDISABLE(bJITSystemRegistersOff)
 
15
                u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
 
16
        switch(iIndex) {
 
17
                case SPR_TL:
 
18
                case SPR_TU:
 
19
                        Default(inst);
 
20
                        return;
 
21
                case SPR_LR:
 
22
                        ibuild.EmitStoreLink(ibuild.EmitLoadGReg(inst.RD));
 
23
                        return;
 
24
                case SPR_CTR:
 
25
                        ibuild.EmitStoreCTR(ibuild.EmitLoadGReg(inst.RD));
 
26
                        return;
 
27
                case SPR_GQR0:
 
28
                case SPR_GQR0 + 1:
 
29
                case SPR_GQR0 + 2:
 
30
                case SPR_GQR0 + 3:
 
31
                case SPR_GQR0 + 4:
 
32
                case SPR_GQR0 + 5:
 
33
                case SPR_GQR0 + 6:
 
34
                case SPR_GQR0 + 7:
 
35
                        ibuild.EmitStoreGQR(ibuild.EmitLoadGReg(inst.RD), iIndex - SPR_GQR0);
 
36
                        return;
 
37
                case SPR_SRR0:
 
38
                case SPR_SRR1:
 
39
                        ibuild.EmitStoreSRR(ibuild.EmitLoadGReg(inst.RD), iIndex - SPR_SRR0);
 
40
                        return;
 
41
                default:
 
42
                        Default(inst);
 
43
                        return;
 
44
        }
 
45
}
 
46
 
 
47
void JitILBase::mfspr(UGeckoInstruction inst)
 
48
{
 
49
        INSTRUCTION_START
 
50
                JITDISABLE(bJITSystemRegistersOff)
 
51
                u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
 
52
        switch (iIndex)
 
53
        {
 
54
        case SPR_TL:
 
55
        case SPR_TU:
 
56
                Default(inst);
 
57
                return;
 
58
        case SPR_LR:
 
59
                ibuild.EmitStoreGReg(ibuild.EmitLoadLink(), inst.RD);
 
60
                return;
 
61
        case SPR_CTR:
 
62
                ibuild.EmitStoreGReg(ibuild.EmitLoadCTR(), inst.RD);
 
63
                return;
 
64
        case SPR_GQR0:
 
65
        case SPR_GQR0 + 1:
 
66
        case SPR_GQR0 + 2:
 
67
        case SPR_GQR0 + 3:
 
68
        case SPR_GQR0 + 4:
 
69
        case SPR_GQR0 + 5:
 
70
        case SPR_GQR0 + 6:
 
71
        case SPR_GQR0 + 7:
 
72
                ibuild.EmitStoreGReg(ibuild.EmitLoadGQR(iIndex - SPR_GQR0), inst.RD);
 
73
                return;
 
74
        default:
 
75
                Default(inst);
 
76
                return;
 
77
        }
 
78
}
 
79
 
 
80
 
 
81
// =======================================================================================
 
82
// Don't interpret this, if we do we get thrown out
 
83
// --------------
 
84
void JitILBase::mtmsr(UGeckoInstruction inst)
 
85
{
 
86
        ibuild.EmitStoreMSR(ibuild.EmitLoadGReg(inst.RS), ibuild.EmitIntConst(js.compilerPC));
 
87
        ibuild.EmitBranchUncond(ibuild.EmitIntConst(js.compilerPC + 4));
 
88
}
 
89
// ==============
 
90
 
 
91
 
 
92
void JitILBase::mfmsr(UGeckoInstruction inst)
 
93
{
 
94
        INSTRUCTION_START
 
95
                JITDISABLE(bJITSystemRegistersOff)
 
96
                ibuild.EmitStoreGReg(ibuild.EmitLoadMSR(), inst.RD);
 
97
}
 
98
 
 
99
void JitILBase::mftb(UGeckoInstruction inst)
 
100
{
 
101
        INSTRUCTION_START;
 
102
        JITDISABLE(bJITSystemRegistersOff)
 
103
                mfspr(inst);
 
104
}
 
105
 
 
106
void JitILBase::mfcr(UGeckoInstruction inst)
 
107
{
 
108
        INSTRUCTION_START;
 
109
        JITDISABLE(bJITSystemRegistersOff)
 
110
 
 
111
        IREmitter::InstLoc d = ibuild.EmitIntConst(0);
 
112
        for (int i = 0; i < 8; ++i)
 
113
        {
 
114
                d = ibuild.EmitShl(d, ibuild.EmitIntConst(4));
 
115
                d = ibuild.EmitOr(d, ibuild.EmitLoadCR(i));
 
116
        }
 
117
        ibuild.EmitStoreGReg(d, inst.RD);
 
118
}
 
119
 
 
120
void JitILBase::mtcrf(UGeckoInstruction inst)
 
121
{
 
122
        INSTRUCTION_START;
 
123
        JITDISABLE(bJITSystemRegistersOff)
 
124
 
 
125
        IREmitter::InstLoc s = ibuild.EmitLoadGReg(inst.RS);
 
126
        for (int i = 0; i < 8; ++i)
 
127
        {
 
128
                if (inst.CRM & (0x80 >> i))
 
129
                {
 
130
                        IREmitter::InstLoc value;
 
131
                        value = ibuild.EmitShrl(s, ibuild.EmitIntConst(28 - i * 4));
 
132
                        value = ibuild.EmitAnd(value, ibuild.EmitIntConst(0xF));
 
133
                        ibuild.EmitStoreCR(value, i);
 
134
                }
 
135
        }
 
136
}
 
137
 
 
138
void JitILBase::mcrf(UGeckoInstruction inst)
 
139
{
 
140
        INSTRUCTION_START
 
141
        JITDISABLE(bJITSystemRegistersOff)
 
142
 
 
143
        if (inst.CRFS != inst.CRFD)
 
144
        {
 
145
                ibuild.EmitStoreCR(ibuild.EmitLoadCR(inst.CRFS), inst.CRFD);
 
146
        }
 
147
}
 
148
 
 
149
void JitILBase::crXX(UGeckoInstruction inst)
 
150
{
 
151
        // Ported from Jit_SystemRegister.cpp
 
152
 
 
153
        // Get bit CRBA in EAX aligned with bit CRBD
 
154
        const int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3);
 
155
        IREmitter::InstLoc eax = ibuild.EmitLoadCR(inst.CRBA >> 2);
 
156
        if (shiftA < 0)
 
157
                eax = ibuild.EmitShl(eax, ibuild.EmitIntConst(-shiftA));
 
158
        else if (shiftA > 0)
 
159
                eax = ibuild.EmitShrl(eax, ibuild.EmitIntConst(shiftA));
 
160
 
 
161
        // Get bit CRBB in ECX aligned with bit CRBD
 
162
        const int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3);
 
163
        IREmitter::InstLoc ecx = ibuild.EmitLoadCR(inst.CRBB >> 2);
 
164
        if (shiftB < 0)
 
165
                ecx = ibuild.EmitShl(ecx, ibuild.EmitIntConst(-shiftB));
 
166
        else if (shiftB > 0)
 
167
                ecx = ibuild.EmitShrl(ecx, ibuild.EmitIntConst(shiftB));
 
168
 
 
169
        // Compute combined bit
 
170
        const unsigned subop = inst.SUBOP10;
 
171
        switch (subop) {
 
172
                case 257:
 
173
                        // crand
 
174
                        eax = ibuild.EmitAnd(eax, ecx); 
 
175
                        break;
 
176
                case 129:
 
177
                        // crandc
 
178
                        ecx = ibuild.EmitNot(ecx);
 
179
                        eax = ibuild.EmitAnd(eax, ecx); 
 
180
                        break;
 
181
                case 289:
 
182
                        // creqv
 
183
                        eax = ibuild.EmitXor(eax, ecx);
 
184
                        eax = ibuild.EmitNot(eax);
 
185
                        break;
 
186
                case 225:
 
187
                        // crnand
 
188
                        eax = ibuild.EmitAnd(eax, ecx);
 
189
                        eax = ibuild.EmitNot(eax);
 
190
                        break;
 
191
                case 33:
 
192
                        // crnor
 
193
                        eax = ibuild.EmitOr(eax, ecx);
 
194
                        eax = ibuild.EmitNot(eax);
 
195
                        break;
 
196
                case 449:
 
197
                        // cror
 
198
                        eax = ibuild.EmitOr(eax, ecx);
 
199
                        break;
 
200
                case 417:
 
201
                        // crorc
 
202
                        ecx = ibuild.EmitNot(ecx);
 
203
                        eax = ibuild.EmitOr(eax, ecx);
 
204
                        break;
 
205
                case 193:
 
206
                        // crxor
 
207
                        eax = ibuild.EmitXor(eax, ecx);
 
208
                        break;
 
209
                default:
 
210
                        PanicAlert("crXX: invalid instruction");
 
211
                        break;
 
212
        }
 
213
 
 
214
        // Store result bit in CRBD
 
215
        eax = ibuild.EmitAnd(eax, ibuild.EmitIntConst(0x8 >> (inst.CRBD & 3)));
 
216
        IREmitter::InstLoc bd = ibuild.EmitLoadCR(inst.CRBD >> 2);
 
217
        bd = ibuild.EmitAnd(bd, ibuild.EmitIntConst(~(0x8 >> (inst.CRBD & 3))));
 
218
        bd = ibuild.EmitOr(bd, eax);
 
219
        ibuild.EmitStoreCR(bd, inst.CRBD >> 2);
 
220
}