~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/Core/Src/PowerPC/JitILCommon/JitILBase_Integer.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
#ifdef _MSC_VER
 
6
#pragma warning(disable:4146)  // unary minus operator applied to unsigned type, result still unsigned
 
7
#endif
 
8
 
 
9
#include "JitILBase.h"
 
10
 
 
11
static void ComputeRC(IREmitter::IRBuilder& ibuild, IREmitter::InstLoc val)
 
12
{
 
13
        IREmitter::InstLoc res =
 
14
                ibuild.EmitICmpCRSigned(val, ibuild.EmitIntConst(0));
 
15
        ibuild.EmitStoreCR(res, 0);
 
16
}
 
17
 
 
18
void JitILBase::reg_imm(UGeckoInstruction inst)
 
19
{
 
20
        INSTRUCTION_START
 
21
        JITDISABLE(bJITIntegerOff)
 
22
        int d = inst.RD, a = inst.RA, s = inst.RS;
 
23
        IREmitter::InstLoc val, test, c;
 
24
        switch (inst.OPCD)
 
25
        {
 
26
        case 14: //addi
 
27
                val = ibuild.EmitIntConst(inst.SIMM_16);
 
28
                if (a)
 
29
                        val = ibuild.EmitAdd(ibuild.EmitLoadGReg(a), val);
 
30
                ibuild.EmitStoreGReg(val, d);
 
31
                break;
 
32
        case 15: //addis
 
33
                val = ibuild.EmitIntConst(inst.SIMM_16 << 16);
 
34
                if (a)
 
35
                        val = ibuild.EmitAdd(ibuild.EmitLoadGReg(a), val);
 
36
                ibuild.EmitStoreGReg(val, d);
 
37
                break;
 
38
        case 24: //ori
 
39
                val = ibuild.EmitIntConst(inst.UIMM);
 
40
                val = ibuild.EmitOr(ibuild.EmitLoadGReg(s), val);
 
41
                ibuild.EmitStoreGReg(val, a);
 
42
                break;
 
43
        case 25: //oris
 
44
                val = ibuild.EmitIntConst(inst.UIMM << 16);
 
45
                val = ibuild.EmitOr(ibuild.EmitLoadGReg(s), val);
 
46
                ibuild.EmitStoreGReg(val, a);
 
47
                break;
 
48
        case 28: //andi
 
49
                val = ibuild.EmitIntConst(inst.UIMM);
 
50
                val = ibuild.EmitAnd(ibuild.EmitLoadGReg(s), val);
 
51
                ibuild.EmitStoreGReg(val, a);
 
52
                ComputeRC(ibuild, val);
 
53
                break;
 
54
        case 29: //andis
 
55
                val = ibuild.EmitIntConst(inst.UIMM << 16);
 
56
                val = ibuild.EmitAnd(ibuild.EmitLoadGReg(s), val);
 
57
                ibuild.EmitStoreGReg(val, a);
 
58
                ComputeRC(ibuild, val);
 
59
                break;
 
60
        case 26: //xori
 
61
                val = ibuild.EmitIntConst(inst.UIMM);
 
62
                val = ibuild.EmitXor(ibuild.EmitLoadGReg(s), val);
 
63
                ibuild.EmitStoreGReg(val, a);
 
64
                break;
 
65
        case 27: //xoris
 
66
                val = ibuild.EmitIntConst(inst.UIMM << 16);
 
67
                val = ibuild.EmitXor(ibuild.EmitLoadGReg(s), val);
 
68
                ibuild.EmitStoreGReg(val, a);
 
69
                break;
 
70
        case 12: //addic
 
71
        case 13: //addic_rc
 
72
                c = ibuild.EmitIntConst(inst.SIMM_16);
 
73
                val = ibuild.EmitAdd(ibuild.EmitLoadGReg(a), c);
 
74
                ibuild.EmitStoreGReg(val, d);
 
75
                test = ibuild.EmitICmpUgt(c, val);
 
76
                ibuild.EmitStoreCarry(test);
 
77
                if (inst.OPCD == 13)
 
78
                        ComputeRC(ibuild, val);
 
79
                break;
 
80
        default:
 
81
                Default(inst);
 
82
                break;
 
83
        }
 
84
}
 
85
 
 
86
void JitILBase::cmpXX(UGeckoInstruction inst)
 
87
{
 
88
        INSTRUCTION_START
 
89
        JITDISABLE(bJITIntegerOff)
 
90
        IREmitter::InstLoc lhs, rhs, res;
 
91
        lhs = ibuild.EmitLoadGReg(inst.RA);
 
92
 
 
93
        if (inst.OPCD == 31)
 
94
        {
 
95
                rhs = ibuild.EmitLoadGReg(inst.RB);
 
96
                if (inst.SUBOP10 == 32)
 
97
                {
 
98
                        res = ibuild.EmitICmpCRUnsigned(lhs, rhs);
 
99
                }
 
100
                else
 
101
                {
 
102
                        res = ibuild.EmitICmpCRSigned(lhs, rhs);
 
103
                }
 
104
        }
 
105
        else if (inst.OPCD == 10)
 
106
        {
 
107
                rhs = ibuild.EmitIntConst(inst.UIMM);
 
108
                res = ibuild.EmitICmpCRUnsigned(lhs, rhs);
 
109
        }
 
110
        else // inst.OPCD == 11
 
111
        {
 
112
                rhs = ibuild.EmitIntConst(inst.SIMM_16);
 
113
                res = ibuild.EmitICmpCRSigned(lhs, rhs);
 
114
        }
 
115
 
 
116
        js.downcountAmount++; //TODO: should this be somewhere else?
 
117
        
 
118
        ibuild.EmitStoreCR(res, inst.CRFD);
 
119
}
 
120
 
 
121
void JitILBase::boolX(UGeckoInstruction inst)
 
122
{
 
123
        INSTRUCTION_START
 
124
        JITDISABLE(bJITIntegerOff)
 
125
 
 
126
        IREmitter::InstLoc a = NULL;
 
127
        IREmitter::InstLoc s = ibuild.EmitLoadGReg(inst.RS);
 
128
        IREmitter::InstLoc b = ibuild.EmitLoadGReg(inst.RB);
 
129
 
 
130
        // FIXME: Some instructions does not work well in NSMBW, MP2, etc.
 
131
        //        Refer JitIL_Tables.cpp.
 
132
        if (inst.SUBOP10 == 28) /* andx */
 
133
        {
 
134
                a = ibuild.EmitAnd(s, b);
 
135
        }
 
136
        else if (inst.SUBOP10 == 476) /* nandx */
 
137
        {
 
138
                a = ibuild.EmitNot(ibuild.EmitAnd(s, b));
 
139
        }
 
140
        else if (inst.SUBOP10 == 60) /* andcx */
 
141
        {
 
142
                a = ibuild.EmitAnd(s, ibuild.EmitNot(b));
 
143
        }
 
144
        else if (inst.SUBOP10 == 444) /* orx */
 
145
        {
 
146
                a = ibuild.EmitOr(s, b);
 
147
        }
 
148
        else if (inst.SUBOP10 == 124) /* norx */
 
149
        {
 
150
                a = ibuild.EmitNot(ibuild.EmitOr(s, b));
 
151
        }
 
152
        else if (inst.SUBOP10 == 412) /* orcx */
 
153
        {
 
154
                a = ibuild.EmitOr(s, ibuild.EmitNot(b));
 
155
        }
 
156
        else if (inst.SUBOP10 == 316) /* xorx */
 
157
        {
 
158
                a = ibuild.EmitXor(s, b);
 
159
        }
 
160
        else if (inst.SUBOP10 == 284) /* eqvx */
 
161
        {
 
162
                a = ibuild.EmitNot(ibuild.EmitXor(s, b));
 
163
        }
 
164
        else
 
165
        {
 
166
                PanicAlert("WTF!");
 
167
        }
 
168
 
 
169
        ibuild.EmitStoreGReg(a, inst.RA);
 
170
        if (inst.Rc)
 
171
                ComputeRC(ibuild, a);
 
172
}
 
173
 
 
174
void JitILBase::extsbx(UGeckoInstruction inst)
 
175
{
 
176
        INSTRUCTION_START
 
177
        JITDISABLE(bJITIntegerOff)
 
178
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS);
 
179
        val = ibuild.EmitSExt8(val);
 
180
        ibuild.EmitStoreGReg(val, inst.RA);
 
181
        if (inst.Rc)
 
182
                ComputeRC(ibuild, val);
 
183
}
 
184
 
 
185
void JitILBase::extshx(UGeckoInstruction inst)
 
186
{
 
187
        INSTRUCTION_START
 
188
        JITDISABLE(bJITIntegerOff)
 
189
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS);
 
190
        val = ibuild.EmitSExt16(val);
 
191
        ibuild.EmitStoreGReg(val, inst.RA);
 
192
        if (inst.Rc)
 
193
                ComputeRC(ibuild, val);
 
194
}
 
195
 
 
196
void JitILBase::subfic(UGeckoInstruction inst)
 
197
{
 
198
        INSTRUCTION_START
 
199
        JITDISABLE(bJITIntegerOff)
 
200
        IREmitter::InstLoc nota, lhs, val, test;
 
201
        nota = ibuild.EmitXor(ibuild.EmitLoadGReg(inst.RA),
 
202
                              ibuild.EmitIntConst(-1));
 
203
 
 
204
        if (inst.SIMM_16 == -1)
 
205
        {
 
206
                val = nota;
 
207
                test = ibuild.EmitIntConst(1);
 
208
        }
 
209
        else
 
210
        {
 
211
                lhs = ibuild.EmitIntConst(inst.SIMM_16 + 1);
 
212
                val = ibuild.EmitAdd(nota, lhs);
 
213
                test = ibuild.EmitICmpUgt(lhs, val);
 
214
        }
 
215
 
 
216
        ibuild.EmitStoreGReg(val, inst.RD);
 
217
        ibuild.EmitStoreCarry(test);
 
218
}
 
219
 
 
220
void JitILBase::subfcx(UGeckoInstruction inst) 
 
221
{
 
222
        INSTRUCTION_START
 
223
        JITDISABLE(bJITIntegerOff)
 
224
        if (inst.OE) PanicAlert("OE: subfcx");
 
225
        IREmitter::InstLoc val, test, lhs, rhs;
 
226
        lhs = ibuild.EmitLoadGReg(inst.RB);
 
227
        rhs = ibuild.EmitLoadGReg(inst.RA);
 
228
        val = ibuild.EmitSub(lhs, rhs);
 
229
        ibuild.EmitStoreGReg(val, inst.RD);
 
230
        test = ibuild.EmitICmpEq(rhs, ibuild.EmitIntConst(0));
 
231
        test = ibuild.EmitOr(test, ibuild.EmitICmpUgt(lhs, val));
 
232
        ibuild.EmitStoreCarry(test);
 
233
        if (inst.Rc)
 
234
                ComputeRC(ibuild, val);
 
235
}
 
236
 
 
237
void JitILBase::subfex(UGeckoInstruction inst) 
 
238
{
 
239
        INSTRUCTION_START
 
240
        JITDISABLE(bJITIntegerOff)
 
241
        if (inst.OE) PanicAlert("OE: subfex");
 
242
        IREmitter::InstLoc val, test, lhs, rhs, carry;
 
243
        rhs = ibuild.EmitLoadGReg(inst.RA);
 
244
        carry = ibuild.EmitLoadCarry();
 
245
        rhs = ibuild.EmitXor(rhs, ibuild.EmitIntConst(-1));
 
246
        rhs = ibuild.EmitAdd(rhs, carry);
 
247
        test = ibuild.EmitICmpEq(rhs, ibuild.EmitIntConst(0));
 
248
        test = ibuild.EmitAnd(test, carry);
 
249
        lhs = ibuild.EmitLoadGReg(inst.RB);
 
250
        val = ibuild.EmitAdd(lhs, rhs);
 
251
        ibuild.EmitStoreGReg(val, inst.RD);
 
252
        test = ibuild.EmitOr(test, ibuild.EmitICmpUgt(lhs, val));
 
253
        ibuild.EmitStoreCarry(test);
 
254
        if (inst.Rc)
 
255
                ComputeRC(ibuild, val);
 
256
}
 
257
 
 
258
void JitILBase::subfx(UGeckoInstruction inst)
 
259
{
 
260
        INSTRUCTION_START
 
261
        JITDISABLE(bJITIntegerOff)
 
262
        if (inst.OE) PanicAlert("OE: subfx");
 
263
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RB);
 
264
        val = ibuild.EmitSub(val, ibuild.EmitLoadGReg(inst.RA));
 
265
        ibuild.EmitStoreGReg(val, inst.RD);
 
266
        if (inst.Rc)
 
267
                ComputeRC(ibuild, val);
 
268
}
 
269
 
 
270
void JitILBase::mulli(UGeckoInstruction inst)
 
271
{
 
272
        INSTRUCTION_START
 
273
        JITDISABLE(bJITIntegerOff)
 
274
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RA);
 
275
        val = ibuild.EmitMul(val, ibuild.EmitIntConst(inst.SIMM_16));
 
276
        ibuild.EmitStoreGReg(val, inst.RD);
 
277
}
 
278
 
 
279
void JitILBase::mullwx(UGeckoInstruction inst)
 
280
{
 
281
        INSTRUCTION_START
 
282
        JITDISABLE(bJITIntegerOff)
 
283
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RB);
 
284
        val = ibuild.EmitMul(ibuild.EmitLoadGReg(inst.RA), val);
 
285
        ibuild.EmitStoreGReg(val, inst.RD);
 
286
        if (inst.Rc)
 
287
                ComputeRC(ibuild, val);
 
288
}
 
289
 
 
290
void JitILBase::mulhwux(UGeckoInstruction inst)
 
291
{
 
292
        INSTRUCTION_START
 
293
        JITDISABLE(bJITIntegerOff)
 
294
 
 
295
        IREmitter::InstLoc a = ibuild.EmitLoadGReg(inst.RA);
 
296
        IREmitter::InstLoc b = ibuild.EmitLoadGReg(inst.RB);
 
297
        IREmitter::InstLoc d = ibuild.EmitMulHighUnsigned(a, b);
 
298
        ibuild.EmitStoreGReg(d, inst.RD);
 
299
        if (inst.Rc)
 
300
                ComputeRC(ibuild, d);
 
301
}
 
302
 
 
303
// skipped some of the special handling in here - if we get crashes, let the interpreter handle this op
 
304
void JitILBase::divwux(UGeckoInstruction inst)
 
305
{
 
306
        Default(inst); return;
 
307
#if 0
 
308
        int a = inst.RA, b = inst.RB, d = inst.RD;
 
309
        gpr.FlushLockX(EDX);
 
310
        gpr.Lock(a, b, d);
 
311
 
 
312
        if (d != a && d != b)
 
313
        {
 
314
                gpr.LoadToX64(d, false, true);
 
315
        }
 
316
        else
 
317
        {
 
318
                gpr.LoadToX64(d, true, true);
 
319
        }
 
320
 
 
321
        MOV(32, R(EAX), gpr.R(a));
 
322
        XOR(32, R(EDX), R(EDX));
 
323
        gpr.KillImmediate(b);
 
324
        DIV(32, gpr.R(b));
 
325
        MOV(32, gpr.R(d), R(EAX));
 
326
        gpr.UnlockAll();
 
327
        gpr.UnlockAllX();
 
328
        if (inst.Rc) {
 
329
                CALL((u8*)asm_routines.computeRc);
 
330
        }
 
331
#endif
 
332
}
 
333
 
 
334
void JitILBase::addx(UGeckoInstruction inst)
 
335
{
 
336
        INSTRUCTION_START
 
337
        JITDISABLE(bJITIntegerOff)
 
338
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RB);
 
339
        val = ibuild.EmitAdd(ibuild.EmitLoadGReg(inst.RA), val);
 
340
        ibuild.EmitStoreGReg(val, inst.RD);
 
341
        if (inst.Rc)
 
342
                ComputeRC(ibuild, val);
 
343
}
 
344
 
 
345
void JitILBase::addzex(UGeckoInstruction inst)
 
346
{
 
347
        INSTRUCTION_START
 
348
        JITDISABLE(bJITIntegerOff)
 
349
        IREmitter::InstLoc lhs = ibuild.EmitLoadGReg(inst.RA),
 
350
                           val, newcarry;
 
351
        val = ibuild.EmitAdd(lhs, ibuild.EmitLoadCarry());
 
352
        ibuild.EmitStoreGReg(val, inst.RD);
 
353
        newcarry = ibuild.EmitICmpUlt(val, lhs);
 
354
        ibuild.EmitStoreCarry(newcarry);
 
355
        if (inst.Rc)
 
356
                ComputeRC(ibuild, val);
 
357
}
 
358
 
 
359
void JitILBase::addex(UGeckoInstruction inst)
 
360
{
 
361
        INSTRUCTION_START
 
362
        JITDISABLE(bJITIntegerOff)
 
363
 
 
364
        IREmitter::InstLoc a = ibuild.EmitLoadGReg(inst.RA);
 
365
        IREmitter::InstLoc b = ibuild.EmitLoadGReg(inst.RB);
 
366
 
 
367
        IREmitter::InstLoc ab = ibuild.EmitAdd(a, b);
 
368
        IREmitter::InstLoc new_carry = ibuild.EmitICmpUlt(ab, a);
 
369
 
 
370
        IREmitter::InstLoc previous_carry = ibuild.EmitLoadCarry();
 
371
        IREmitter::InstLoc abc = ibuild.EmitAdd(ab, previous_carry);
 
372
        new_carry = ibuild.EmitOr(new_carry, ibuild.EmitICmpUlt(abc, ab));
 
373
 
 
374
        ibuild.EmitStoreGReg(abc, inst.RD);
 
375
        ibuild.EmitStoreCarry(new_carry);
 
376
 
 
377
        if (inst.OE) PanicAlert("OE: addex");
 
378
        if (inst.Rc)
 
379
                ComputeRC(ibuild, abc);
 
380
}
 
381
 
 
382
void JitILBase::rlwinmx(UGeckoInstruction inst)
 
383
{
 
384
        INSTRUCTION_START
 
385
        JITDISABLE(bJITIntegerOff)
 
386
        unsigned mask = Helper_Mask(inst.MB, inst.ME);
 
387
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS);
 
388
        val = ibuild.EmitRol(val, ibuild.EmitIntConst(inst.SH));
 
389
        val = ibuild.EmitAnd(val, ibuild.EmitIntConst(mask));
 
390
        ibuild.EmitStoreGReg(val, inst.RA);
 
391
        if (inst.Rc)
 
392
                ComputeRC(ibuild, val);
 
393
}
 
394
 
 
395
 
 
396
void JitILBase::rlwimix(UGeckoInstruction inst)
 
397
{
 
398
        INSTRUCTION_START
 
399
        JITDISABLE(bJITIntegerOff)
 
400
        unsigned mask = Helper_Mask(inst.MB, inst.ME);
 
401
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS);
 
402
        val = ibuild.EmitRol(val, ibuild.EmitIntConst(inst.SH));
 
403
        val = ibuild.EmitAnd(val, ibuild.EmitIntConst(mask));
 
404
        IREmitter::InstLoc ival = ibuild.EmitLoadGReg(inst.RA);
 
405
        ival = ibuild.EmitAnd(ival, ibuild.EmitIntConst(~mask));
 
406
        val = ibuild.EmitOr(ival, val);
 
407
        ibuild.EmitStoreGReg(val, inst.RA);
 
408
        if (inst.Rc)
 
409
                ComputeRC(ibuild, val);
 
410
}
 
411
 
 
412
void JitILBase::rlwnmx(UGeckoInstruction inst)
 
413
{
 
414
        INSTRUCTION_START
 
415
        JITDISABLE(bJITIntegerOff)
 
416
        unsigned int mask = Helper_Mask(inst.MB, inst.ME);
 
417
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS);
 
418
        val = ibuild.EmitRol(val, ibuild.EmitLoadGReg(inst.RB));
 
419
        val = ibuild.EmitAnd(val, ibuild.EmitIntConst(mask));
 
420
        ibuild.EmitStoreGReg(val, inst.RA);
 
421
        if (inst.Rc)
 
422
                ComputeRC(ibuild, val);
 
423
}
 
424
 
 
425
void JitILBase::negx(UGeckoInstruction inst)
 
426
{
 
427
        INSTRUCTION_START
 
428
        JITDISABLE(bJITIntegerOff)
 
429
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RA);
 
430
        val = ibuild.EmitSub(ibuild.EmitIntConst(0), val);
 
431
        ibuild.EmitStoreGReg(val, inst.RD);
 
432
        if (inst.Rc)
 
433
                ComputeRC(ibuild, val);
 
434
}
 
435
 
 
436
void JitILBase::srwx(UGeckoInstruction inst)
 
437
{
 
438
        INSTRUCTION_START
 
439
        JITDISABLE(bJITIntegerOff)
 
440
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS),
 
441
                           samt = ibuild.EmitLoadGReg(inst.RB),
 
442
                           corr;
 
443
        // FIXME: We can do better with a cmov
 
444
        // FIXME: We can do better on 64-bit
 
445
        val = ibuild.EmitShrl(val, samt);
 
446
        corr = ibuild.EmitShl(samt, ibuild.EmitIntConst(26));
 
447
        corr = ibuild.EmitSarl(corr, ibuild.EmitIntConst(31));
 
448
        corr = ibuild.EmitXor(corr, ibuild.EmitIntConst(-1));
 
449
        val = ibuild.EmitAnd(corr, val);
 
450
        ibuild.EmitStoreGReg(val, inst.RA);
 
451
        if (inst.Rc)
 
452
                ComputeRC(ibuild, val);
 
453
}
 
454
 
 
455
void JitILBase::slwx(UGeckoInstruction inst)
 
456
{
 
457
        INSTRUCTION_START
 
458
        JITDISABLE(bJITIntegerOff)
 
459
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS),
 
460
                           samt = ibuild.EmitLoadGReg(inst.RB),
 
461
                           corr;
 
462
        // FIXME: We can do better with a cmov
 
463
        // FIXME: We can do better on 64-bit
 
464
        val = ibuild.EmitShl(val, samt);
 
465
        corr = ibuild.EmitShl(samt, ibuild.EmitIntConst(26));
 
466
        corr = ibuild.EmitSarl(corr, ibuild.EmitIntConst(31));
 
467
        corr = ibuild.EmitXor(corr, ibuild.EmitIntConst(-1));
 
468
        val = ibuild.EmitAnd(corr, val);
 
469
        ibuild.EmitStoreGReg(val, inst.RA);
 
470
        if (inst.Rc)
 
471
                ComputeRC(ibuild, val);
 
472
}
 
473
 
 
474
void JitILBase::srawx(UGeckoInstruction inst)
 
475
{
 
476
        INSTRUCTION_START
 
477
        JITDISABLE(bJITIntegerOff)
 
478
        // FIXME: We can do a lot better on 64-bit
 
479
        IREmitter::InstLoc val, samt, mask, mask2, test;
 
480
        val = ibuild.EmitLoadGReg(inst.RS);
 
481
        samt = ibuild.EmitLoadGReg(inst.RB);
 
482
        mask = ibuild.EmitIntConst(-1);
 
483
        val = ibuild.EmitSarl(val, samt);
 
484
        mask = ibuild.EmitShl(mask, samt);
 
485
        samt = ibuild.EmitShl(samt, ibuild.EmitIntConst(26));
 
486
        samt = ibuild.EmitSarl(samt, ibuild.EmitIntConst(31));
 
487
        samt = ibuild.EmitAnd(samt, ibuild.EmitIntConst(31));
 
488
        val = ibuild.EmitSarl(val, samt);
 
489
        ibuild.EmitStoreGReg(val, inst.RA);
 
490
        mask = ibuild.EmitShl(mask, samt);
 
491
        mask2 = ibuild.EmitAnd(mask, ibuild.EmitIntConst(0x7FFFFFFF));
 
492
        test = ibuild.EmitOr(val, mask2);
 
493
        test = ibuild.EmitICmpUgt(test, mask);
 
494
        ibuild.EmitStoreCarry(test);
 
495
        
 
496
        if (inst.Rc)
 
497
                ComputeRC(ibuild, val);
 
498
}
 
499
 
 
500
void JitILBase::srawix(UGeckoInstruction inst)
 
501
{
 
502
        INSTRUCTION_START
 
503
        JITDISABLE(bJITIntegerOff)
 
504
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS), test;
 
505
        val = ibuild.EmitSarl(val, ibuild.EmitIntConst(inst.SH));
 
506
        ibuild.EmitStoreGReg(val, inst.RA);
 
507
        unsigned int mask = -1u << inst.SH;
 
508
        test = ibuild.EmitOr(val, ibuild.EmitIntConst(mask & 0x7FFFFFFF));
 
509
        test = ibuild.EmitICmpUgt(test, ibuild.EmitIntConst(mask));
 
510
        
 
511
        ibuild.EmitStoreCarry(test);
 
512
        if (inst.Rc)
 
513
                ComputeRC(ibuild, val);
 
514
}
 
515
 
 
516
// count leading zeroes
 
517
void JitILBase::cntlzwx(UGeckoInstruction inst)
 
518
{
 
519
        INSTRUCTION_START
 
520
        JITDISABLE(bJITIntegerOff)
 
521
        IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS);
 
522
        val = ibuild.EmitCntlzw(val);
 
523
        ibuild.EmitStoreGReg(val, inst.RA);
 
524
        if (inst.Rc)
 
525
                ComputeRC(ibuild, val);
 
526
}