Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_common.c
22240 views
1
/*
2
* Stack-less Just-In-Time compiler
3
*
4
* Copyright Zoltan Herczeg ([email protected]). All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without modification, are
7
* permitted provided that the following conditions are met:
8
*
9
* 1. Redistributions of source code must retain the above copyright notice, this list of
10
* conditions and the following disclaimer.
11
*
12
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
13
* of conditions and the following disclaimer in the documentation and/or other materials
14
* provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
*/
26
27
/* Latest MIPS architecture. */
28
29
#ifdef HAVE_PRCTL
30
#include <sys/prctl.h>
31
#endif
32
33
#if !defined(__mips_hard_float) || defined(__mips_single_float)
34
/* Disable automatic detection, covers both -msoft-float and -mno-float */
35
#define SLJIT_IS_FPU_AVAILABLE 0
36
#endif
37
38
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
39
{
40
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
41
42
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
43
return "MIPS32-R6" SLJIT_CPUINFO;
44
#else /* !SLJIT_CONFIG_MIPS_32 */
45
return "MIPS64-R6" SLJIT_CPUINFO;
46
#endif /* SLJIT_CONFIG_MIPS_32 */
47
48
#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 5)
49
50
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
51
return "MIPS32-R5" SLJIT_CPUINFO;
52
#else /* !SLJIT_CONFIG_MIPS_32 */
53
return "MIPS64-R5" SLJIT_CPUINFO;
54
#endif /* SLJIT_CONFIG_MIPS_32 */
55
56
#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
57
58
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
59
return "MIPS32-R2" SLJIT_CPUINFO;
60
#else /* !SLJIT_CONFIG_MIPS_32 */
61
return "MIPS64-R2" SLJIT_CPUINFO;
62
#endif /* SLJIT_CONFIG_MIPS_32 */
63
64
#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
65
66
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
67
return "MIPS32-R1" SLJIT_CPUINFO;
68
#else /* !SLJIT_CONFIG_MIPS_32 */
69
return "MIPS64-R1" SLJIT_CPUINFO;
70
#endif /* SLJIT_CONFIG_MIPS_32 */
71
72
#else /* SLJIT_MIPS_REV < 1 */
73
return "MIPS III" SLJIT_CPUINFO;
74
#endif /* SLJIT_MIPS_REV >= 6 */
75
}
76
77
/* Length of an instruction word
78
Both for mips-32 and mips-64 */
79
typedef sljit_u32 sljit_ins;
80
81
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
82
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
83
#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
84
85
/* For position independent code, t9 must contain the function address. */
86
#define PIC_ADDR_REG TMP_REG1
87
88
/* Floating point status register. */
89
#define FCSR_REG 31
90
/* Return address register. */
91
#define RETURN_ADDR_REG 31
92
93
/* Flags are kept in volatile registers. */
94
#define EQUAL_FLAG 3
95
#define OTHER_FLAG 1
96
97
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
98
0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 25, 4, 31, 3, 1
99
};
100
101
#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
102
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
103
#define TMP_FREG3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)
104
105
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
106
107
static const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3) << 1) + 1] = {
108
0,
109
0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20,
110
12, 10, 16,
111
1, 15, 3, 5, 7, 9, 19, 31, 29, 27, 25, 23, 21,
112
13, 11, 17
113
};
114
115
#else /* !SLJIT_CONFIG_MIPS_32 */
116
117
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
118
0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 30, 29, 28, 27, 26, 25, 24, 12, 11, 10
119
};
120
121
#endif /* SLJIT_CONFIG_MIPS_32 */
122
123
/* --------------------------------------------------------------------- */
124
/* Instruction forms */
125
/* --------------------------------------------------------------------- */
126
127
#define S(s) ((sljit_ins)reg_map[s] << 21)
128
#define T(t) ((sljit_ins)reg_map[t] << 16)
129
#define D(d) ((sljit_ins)reg_map[d] << 11)
130
#define FT(t) ((sljit_ins)freg_map[t] << 16)
131
#define FS(s) ((sljit_ins)freg_map[s] << 11)
132
#define FD(d) ((sljit_ins)freg_map[d] << 6)
133
/* Absolute registers. */
134
#define SA(s) ((sljit_ins)(s) << 21)
135
#define TA(t) ((sljit_ins)(t) << 16)
136
#define DA(d) ((sljit_ins)(d) << 11)
137
#define IMM(imm) ((sljit_ins)(imm) & 0xffff)
138
#define SH_IMM(imm) ((sljit_ins)(imm) << 6)
139
140
#define DR(dr) (reg_map[dr])
141
#define FR(dr) (freg_map[dr])
142
#define HI(opcode) ((sljit_ins)(opcode) << 26)
143
#define LO(opcode) ((sljit_ins)(opcode))
144
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
145
/* CMP.cond.fmt */
146
/* S = (20 << 21) D = (21 << 21) */
147
#define CMP_FMT_S (20 << 21)
148
#endif /* SLJIT_MIPS_REV >= 6 */
149
/* S = (16 << 21) D = (17 << 21) */
150
#define FMT_S (16 << 21)
151
#define FMT_D (17 << 21)
152
153
#define ABS_S (HI(17) | FMT_S | LO(5))
154
#define ADD_S (HI(17) | FMT_S | LO(0))
155
#define ADDIU (HI(9))
156
#define ADDU (HI(0) | LO(33))
157
#define AND (HI(0) | LO(36))
158
#define ANDI (HI(12))
159
#define B (HI(4))
160
#define BAL (HI(1) | (17 << 16))
161
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
162
#define BC1EQZ (HI(17) | (9 << 21) | FT(TMP_FREG3))
163
#define BC1NEZ (HI(17) | (13 << 21) | FT(TMP_FREG3))
164
#else /* SLJIT_MIPS_REV < 6 */
165
#define BC1F (HI(17) | (8 << 21))
166
#define BC1T (HI(17) | (8 << 21) | (1 << 16))
167
#endif /* SLJIT_MIPS_REV >= 6 */
168
#define BEQ (HI(4))
169
#define BGEZ (HI(1) | (1 << 16))
170
#define BGTZ (HI(7))
171
#define BLEZ (HI(6))
172
#define BLTZ (HI(1) | (0 << 16))
173
#define BNE (HI(5))
174
#define BREAK (HI(0) | LO(13))
175
#define CFC1 (HI(17) | (2 << 21))
176
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
177
#define C_EQ_S (HI(17) | CMP_FMT_S | LO(2))
178
#define C_OLE_S (HI(17) | CMP_FMT_S | LO(6))
179
#define C_OLT_S (HI(17) | CMP_FMT_S | LO(4))
180
#define C_UEQ_S (HI(17) | CMP_FMT_S | LO(3))
181
#define C_ULE_S (HI(17) | CMP_FMT_S | LO(7))
182
#define C_ULT_S (HI(17) | CMP_FMT_S | LO(5))
183
#define C_UN_S (HI(17) | CMP_FMT_S | LO(1))
184
#define C_FD (FD(TMP_FREG3))
185
#else /* SLJIT_MIPS_REV < 6 */
186
#define C_EQ_S (HI(17) | FMT_S | LO(50))
187
#define C_OLE_S (HI(17) | FMT_S | LO(54))
188
#define C_OLT_S (HI(17) | FMT_S | LO(52))
189
#define C_UEQ_S (HI(17) | FMT_S | LO(51))
190
#define C_ULE_S (HI(17) | FMT_S | LO(55))
191
#define C_ULT_S (HI(17) | FMT_S | LO(53))
192
#define C_UN_S (HI(17) | FMT_S | LO(49))
193
#define C_FD (0)
194
#endif /* SLJIT_MIPS_REV >= 6 */
195
#define CVT_S_S (HI(17) | FMT_S | LO(32))
196
#define DADDIU (HI(25))
197
#define DADDU (HI(0) | LO(45))
198
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
199
#define DDIV (HI(0) | (2 << 6) | LO(30))
200
#define DDIVU (HI(0) | (2 << 6) | LO(31))
201
#define DMOD (HI(0) | (3 << 6) | LO(30))
202
#define DMODU (HI(0) | (3 << 6) | LO(31))
203
#define DIV (HI(0) | (2 << 6) | LO(26))
204
#define DIVU (HI(0) | (2 << 6) | LO(27))
205
#define DMUH (HI(0) | (3 << 6) | LO(28))
206
#define DMUHU (HI(0) | (3 << 6) | LO(29))
207
#define DMUL (HI(0) | (2 << 6) | LO(28))
208
#define DMULU (HI(0) | (2 << 6) | LO(29))
209
#else /* SLJIT_MIPS_REV < 6 */
210
#define DDIV (HI(0) | LO(30))
211
#define DDIVU (HI(0) | LO(31))
212
#define DIV (HI(0) | LO(26))
213
#define DIVU (HI(0) | LO(27))
214
#define DMULT (HI(0) | LO(28))
215
#define DMULTU (HI(0) | LO(29))
216
#endif /* SLJIT_MIPS_REV >= 6 */
217
#define DIV_S (HI(17) | FMT_S | LO(3))
218
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
219
#define DINSU (HI(31) | LO(6))
220
#endif /* SLJIT_MIPS_REV >= 2 */
221
#define DMFC1 (HI(17) | (1 << 21))
222
#define DMTC1 (HI(17) | (5 << 21))
223
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
224
#define DROTR (HI(0) | (1 << 21) | LO(58))
225
#define DROTR32 (HI(0) | (1 << 21) | LO(62))
226
#define DROTRV (HI(0) | (1 << 6) | LO(22))
227
#define DSBH (HI(31) | (2 << 6) | LO(36))
228
#define DSHD (HI(31) | (5 << 6) | LO(36))
229
#endif /* SLJIT_MIPS_REV >= 2 */
230
#define DSLL (HI(0) | LO(56))
231
#define DSLL32 (HI(0) | LO(60))
232
#define DSLLV (HI(0) | LO(20))
233
#define DSRA (HI(0) | LO(59))
234
#define DSRA32 (HI(0) | LO(63))
235
#define DSRAV (HI(0) | LO(23))
236
#define DSRL (HI(0) | LO(58))
237
#define DSRL32 (HI(0) | LO(62))
238
#define DSRLV (HI(0) | LO(22))
239
#define DSUBU (HI(0) | LO(47))
240
#define J (HI(2))
241
#define JAL (HI(3))
242
#define JALR (HI(0) | LO(9))
243
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
244
#define JR (HI(0) | LO(9))
245
#else /* SLJIT_MIPS_REV < 6 */
246
#define JR (HI(0) | LO(8))
247
#endif /* SLJIT_MIPS_REV >= 6 */
248
#define LD (HI(55))
249
#define LDL (HI(26))
250
#define LDR (HI(27))
251
#define LDC1 (HI(53))
252
#define LL (HI(48))
253
#define LLD (HI(52))
254
#define LUI (HI(15))
255
#define LW (HI(35))
256
#define LWL (HI(34))
257
#define LWR (HI(38))
258
#define LWC1 (HI(49))
259
#define MFC1 (HI(17))
260
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
261
#define MFHC1 (HI(17) | (3 << 21))
262
#endif /* SLJIT_MIPS_REV >= 2 */
263
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
264
#define MOD (HI(0) | (3 << 6) | LO(26))
265
#define MODU (HI(0) | (3 << 6) | LO(27))
266
#else /* SLJIT_MIPS_REV < 6 */
267
#define MFHI (HI(0) | LO(16))
268
#define MFLO (HI(0) | LO(18))
269
#endif /* SLJIT_MIPS_REV >= 6 */
270
#define MTC1 (HI(17) | (4 << 21))
271
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
272
#define MTHC1 (HI(17) | (7 << 21))
273
#endif /* SLJIT_MIPS_REV >= 2 */
274
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
275
#define MUH (HI(0) | (3 << 6) | LO(24))
276
#define MUHU (HI(0) | (3 << 6) | LO(25))
277
#define MUL (HI(0) | (2 << 6) | LO(24))
278
#define MULU (HI(0) | (2 << 6) | LO(25))
279
#else /* SLJIT_MIPS_REV < 6 */
280
#define MULT (HI(0) | LO(24))
281
#define MULTU (HI(0) | LO(25))
282
#endif /* SLJIT_MIPS_REV >= 6 */
283
#define MUL_S (HI(17) | FMT_S | LO(2))
284
#define NEG_S (HI(17) | FMT_S | LO(7))
285
#define NOP (HI(0) | LO(0))
286
#define NOR (HI(0) | LO(39))
287
#define OR (HI(0) | LO(37))
288
#define ORI (HI(13))
289
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
290
#define ROTR (HI(0) | (1 << 21) | LO(2))
291
#define ROTRV (HI(0) | (1 << 6) | LO(6))
292
#endif /* SLJIT_MIPS_REV >= 2 */
293
#define SC (HI(56))
294
#define SCD (HI(60))
295
#define SD (HI(63))
296
#define SDL (HI(44))
297
#define SDR (HI(45))
298
#define SDC1 (HI(61))
299
#define SLT (HI(0) | LO(42))
300
#define SLTI (HI(10))
301
#define SLTIU (HI(11))
302
#define SLTU (HI(0) | LO(43))
303
#define SLL (HI(0) | LO(0))
304
#define SLLV (HI(0) | LO(4))
305
#define SRL (HI(0) | LO(2))
306
#define SRLV (HI(0) | LO(6))
307
#define SRA (HI(0) | LO(3))
308
#define SRAV (HI(0) | LO(7))
309
#define SUB_S (HI(17) | FMT_S | LO(1))
310
#define SUBU (HI(0) | LO(35))
311
#define SW (HI(43))
312
#define SWL (HI(42))
313
#define SWR (HI(46))
314
#define SWC1 (HI(57))
315
#define SYNC (HI(0) | LO(15))
316
#define TRUNC_W_S (HI(17) | FMT_S | LO(13))
317
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
318
#define WSBH (HI(31) | (2 << 6) | LO(32))
319
#endif /* SLJIT_MIPS_REV >= 2 */
320
#define XOR (HI(0) | LO(38))
321
#define XORI (HI(14))
322
323
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
324
#define CLZ (HI(28) | LO(32))
325
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
326
#define DCLZ (LO(18))
327
#else /* SLJIT_MIPS_REV < 6 */
328
#define DCLZ (HI(28) | LO(36))
329
#define MOVF (HI(0) | (0 << 16) | LO(1))
330
#define MOVF_S (HI(17) | FMT_S | (0 << 16) | LO(17))
331
#define MOVN (HI(0) | LO(11))
332
#define MOVN_S (HI(17) | FMT_S | LO(19))
333
#define MOVT (HI(0) | (1 << 16) | LO(1))
334
#define MOVT_S (HI(17) | FMT_S | (1 << 16) | LO(17))
335
#define MOVZ (HI(0) | LO(10))
336
#define MOVZ_S (HI(17) | FMT_S | LO(18))
337
#define MUL (HI(28) | LO(2))
338
#endif /* SLJIT_MIPS_REV >= 6 */
339
#define PREF (HI(51))
340
#define PREFX (HI(19) | LO(15))
341
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
342
#define SEB (HI(31) | (16 << 6) | LO(32))
343
#define SEH (HI(31) | (24 << 6) | LO(32))
344
#endif /* SLJIT_MIPS_REV >= 2 */
345
#endif /* SLJIT_MIPS_REV >= 1 */
346
347
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
348
#define ADDU_W ADDU
349
#define ADDIU_W ADDIU
350
#define SLL_W SLL
351
#define SRA_W SRA
352
#define SUBU_W SUBU
353
#define STORE_W SW
354
#define LOAD_W LW
355
#else
356
#define ADDU_W DADDU
357
#define ADDIU_W DADDIU
358
#define SLL_W DSLL
359
#define SRA_W DSRA
360
#define SUBU_W DSUBU
361
#define STORE_W SD
362
#define LOAD_W LD
363
#endif
364
365
#define MOV_fmt(f) (HI(17) | f | LO(6))
366
367
#define SIMM_MAX (0x7fff)
368
#define SIMM_MIN (-0x8000)
369
#define UIMM_MAX (0xffff)
370
371
#define CPU_FEATURE_DETECTED (1 << 0)
372
#define CPU_FEATURE_FPU (1 << 1)
373
#define CPU_FEATURE_FP64 (1 << 2)
374
#define CPU_FEATURE_FR (1 << 3)
375
376
static sljit_u32 cpu_feature_list = 0;
377
378
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
379
&& (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
380
381
static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32)
382
{
383
if (compiler->scratches == -1)
384
return 0;
385
386
if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0))
387
fr -= SLJIT_F64_SECOND(0);
388
389
return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches))
390
|| (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0)
391
|| (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));
392
}
393
394
static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type)
395
{
396
SLJIT_UNUSED_ARG(compiler);
397
SLJIT_UNUSED_ARG(vr);
398
SLJIT_UNUSED_ARG(type);
399
400
/* SIMD is not supported. */
401
return 0;
402
}
403
404
#endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_ARGUMENT_CHECKS */
405
406
static void get_cpu_features(void)
407
{
408
#if !defined(SLJIT_IS_FPU_AVAILABLE) && defined(__GNUC__)
409
sljit_u32 fir = 0;
410
#endif /* !SLJIT_IS_FPU_AVAILABLE && __GNUC__ */
411
sljit_u32 feature_list = CPU_FEATURE_DETECTED;
412
413
#if defined(SLJIT_IS_FPU_AVAILABLE)
414
#if SLJIT_IS_FPU_AVAILABLE
415
feature_list |= CPU_FEATURE_FPU;
416
#if SLJIT_IS_FPU_AVAILABLE == 64
417
feature_list |= CPU_FEATURE_FP64;
418
#endif /* SLJIT_IS_FPU_AVAILABLE == 64 */
419
#endif /* SLJIT_IS_FPU_AVAILABLE */
420
#elif defined(__GNUC__)
421
__asm__ ("cfc1 %0, $0" : "=r"(fir));
422
if ((fir & (0x3 << 16)) == (0x3 << 16))
423
feature_list |= CPU_FEATURE_FPU;
424
425
#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64) \
426
&& (!defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV < 2)
427
if ((feature_list & CPU_FEATURE_FPU))
428
feature_list |= CPU_FEATURE_FP64;
429
#else /* SLJIT_CONFIG_MIPS32 || SLJIT_MIPS_REV >= 2 */
430
if ((fir & (1 << 22)))
431
feature_list |= CPU_FEATURE_FP64;
432
#endif /* SLJIT_CONFIG_MIPS_64 && SLJIT_MIPS_REV < 2 */
433
#endif /* SLJIT_IS_FPU_AVAILABLE */
434
435
if ((feature_list & CPU_FEATURE_FPU) && (feature_list & CPU_FEATURE_FP64)) {
436
#if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32
437
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 6
438
feature_list |= CPU_FEATURE_FR;
439
#elif defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 0
440
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 5
441
feature_list |= CPU_FEATURE_FR;
442
#endif /* SLJIT_MIPS_REV >= 5 */
443
#else
444
sljit_s32 flag = -1;
445
#ifndef FR_GET_FP_MODE
446
sljit_f64 zero = 0.0;
447
#else /* PR_GET_FP_MODE */
448
flag = prctl(PR_GET_FP_MODE);
449
450
if (flag > 0)
451
feature_list |= CPU_FEATURE_FR;
452
#endif /* FP_GET_PR_MODE */
453
#if ((defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 2) \
454
|| (!defined(PR_GET_FP_MODE) && (!defined(SLJIT_DETECT_FR) || SLJIT_DETECT_FR >= 1))) \
455
&& (defined(__GNUC__) && (defined(__mips) && __mips >= 2))
456
if (flag < 0) {
457
__asm__ (".set oddspreg\n"
458
"lwc1 $f17, %0\n"
459
"ldc1 $f16, %1\n"
460
"swc1 $f17, %0\n"
461
: "+m" (flag) : "m" (zero) : "$f16", "$f17");
462
if (flag)
463
feature_list |= CPU_FEATURE_FR;
464
}
465
#endif /* (!PR_GET_FP_MODE || (PR_GET_FP_MODE && SLJIT_DETECT_FR == 2)) && __GNUC__ */
466
#endif /* SLJIT_MIPS_REV >= 6 */
467
#else /* !SLJIT_CONFIG_MIPS_32 */
468
/* StatusFR=1 is the only mode supported by the code in MIPS64 */
469
feature_list |= CPU_FEATURE_FR;
470
#endif /* SLJIT_CONFIG_MIPS_32 */
471
}
472
473
cpu_feature_list = feature_list;
474
}
475
476
/* dest_reg is the absolute name of the register
477
Useful for reordering instructions in the delay slot. */
478
static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
479
{
480
sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
481
SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
482
|| (sljit_ins)delay_slot == ((ins >> 11) & 0x1f)
483
|| (sljit_ins)delay_slot == ((ins >> 16) & 0x1f));
484
FAIL_IF(!ptr);
485
*ptr = ins;
486
compiler->size++;
487
compiler->delay_slot = delay_slot;
488
return SLJIT_SUCCESS;
489
}
490
491
static SLJIT_INLINE sljit_ins invert_branch(sljit_uw flags)
492
{
493
if (flags & IS_BIT26_COND)
494
return (1 << 26);
495
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
496
if (flags & IS_BIT23_COND)
497
return (1 << 23);
498
#endif /* SLJIT_MIPS_REV >= 6 */
499
return (1 << 16);
500
}
501
502
static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
503
{
504
sljit_sw diff;
505
sljit_uw target_addr;
506
sljit_ins *inst;
507
sljit_ins saved_inst;
508
509
inst = (sljit_ins *)jump->addr;
510
511
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
512
if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
513
goto exit;
514
#else
515
if (jump->flags & SLJIT_REWRITABLE_JUMP)
516
goto exit;
517
#endif
518
519
if (jump->flags & JUMP_ADDR)
520
target_addr = jump->u.target;
521
else {
522
SLJIT_ASSERT(jump->u.label != NULL);
523
target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
524
}
525
526
if (jump->flags & IS_COND)
527
inst--;
528
529
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
530
if (jump->flags & IS_CALL)
531
goto preserve_addr;
532
#endif
533
534
/* B instructions. */
535
if (jump->flags & IS_MOVABLE) {
536
diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;
537
if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
538
jump->flags |= PATCH_B;
539
540
if (!(jump->flags & IS_COND)) {
541
inst[0] = inst[-1];
542
inst[-1] = (jump->flags & IS_JAL) ? BAL : B;
543
jump->addr -= sizeof(sljit_ins);
544
return inst;
545
}
546
saved_inst = inst[0];
547
inst[0] = inst[-1];
548
inst[-1] = saved_inst ^ invert_branch(jump->flags);
549
jump->addr -= 2 * sizeof(sljit_ins);
550
return inst;
551
}
552
} else {
553
diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;
554
if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
555
jump->flags |= PATCH_B;
556
557
if (!(jump->flags & IS_COND)) {
558
inst[0] = (jump->flags & IS_JAL) ? BAL : B;
559
/* Keep inst[1] */
560
return inst + 1;
561
}
562
inst[0] ^= invert_branch(jump->flags);
563
inst[1] = NOP;
564
jump->addr -= sizeof(sljit_ins);
565
return inst + 1;
566
}
567
}
568
569
if (jump->flags & IS_COND) {
570
if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
571
jump->flags |= PATCH_J;
572
saved_inst = inst[0];
573
inst[0] = inst[-1];
574
inst[-1] = (saved_inst & 0xffff0000) | 3;
575
inst[1] = J;
576
inst[2] = NOP;
577
return inst + 2;
578
}
579
else if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
580
jump->flags |= PATCH_J;
581
inst[0] = (inst[0] & 0xffff0000) | 3;
582
inst[1] = NOP;
583
inst[2] = J;
584
inst[3] = NOP;
585
jump->addr += sizeof(sljit_ins);
586
return inst + 3;
587
}
588
}
589
else {
590
/* J instuctions. */
591
if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == (jump->addr & ~(sljit_uw)0xfffffff)) {
592
jump->flags |= PATCH_J;
593
inst[0] = inst[-1];
594
inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
595
jump->addr -= sizeof(sljit_ins);
596
return inst;
597
}
598
599
if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
600
jump->flags |= PATCH_J;
601
inst[0] = (jump->flags & IS_JAL) ? JAL : J;
602
/* Keep inst[1] */
603
return inst + 1;
604
}
605
}
606
607
if (jump->flags & IS_COND)
608
inst++;
609
610
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
611
preserve_addr:
612
if (target_addr <= 0x7fffffff) {
613
jump->flags |= PATCH_ABS32;
614
if (jump->flags & IS_COND)
615
inst[-1] -= 4;
616
617
inst[2] = inst[0];
618
inst[3] = inst[1];
619
return inst + 3;
620
}
621
if (target_addr <= 0x7fffffffffffl) {
622
jump->flags |= PATCH_ABS48;
623
if (jump->flags & IS_COND)
624
inst[-1] -= 2;
625
626
inst[4] = inst[0];
627
inst[5] = inst[1];
628
return inst + 5;
629
}
630
#endif
631
632
exit:
633
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
634
inst[2] = inst[0];
635
inst[3] = inst[1];
636
return inst + 3;
637
#else
638
inst[6] = inst[0];
639
inst[7] = inst[1];
640
return inst + 7;
641
#endif
642
}
643
644
#ifdef __GNUC__
645
static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)
646
{
647
SLJIT_CACHE_FLUSH(code, code_ptr);
648
}
649
#endif
650
651
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
652
653
static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
654
{
655
sljit_uw addr;
656
SLJIT_UNUSED_ARG(executable_offset);
657
658
if (jump->flags & JUMP_ADDR)
659
addr = jump->u.target;
660
else
661
addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
662
663
if (addr < 0x80000000l) {
664
jump->flags |= PATCH_ABS32;
665
return 1;
666
}
667
668
if (addr < 0x800000000000l) {
669
jump->flags |= PATCH_ABS48;
670
return 3;
671
}
672
673
return 5;
674
}
675
676
#endif /* SLJIT_CONFIG_MIPS_64 */
677
678
static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump)
679
{
680
sljit_uw flags = jump->flags;
681
sljit_ins *ins = (sljit_ins*)jump->addr;
682
sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
683
sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : PIC_ADDR_REG;
684
685
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
686
ins[0] = LUI | T(reg) | IMM(addr >> 16);
687
#else /* !SLJIT_CONFIG_MIPS_32 */
688
if (flags & PATCH_ABS32) {
689
SLJIT_ASSERT(addr < 0x80000000l);
690
ins[0] = LUI | T(reg) | IMM(addr >> 16);
691
}
692
else if (flags & PATCH_ABS48) {
693
SLJIT_ASSERT(addr < 0x800000000000l);
694
ins[0] = LUI | T(reg) | IMM(addr >> 32);
695
ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
696
ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
697
ins += 2;
698
}
699
else {
700
ins[0] = LUI | T(reg) | IMM(addr >> 48);
701
ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
702
ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
703
ins[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
704
ins[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
705
ins += 4;
706
}
707
#endif /* SLJIT_CONFIG_MIPS_32 */
708
709
ins[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
710
}
711
712
static SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)
713
{
714
SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
715
return (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));
716
}
717
718
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
719
{
720
struct sljit_memory_fragment *buf;
721
sljit_ins *code;
722
sljit_ins *code_ptr;
723
sljit_ins *buf_ptr;
724
sljit_ins *buf_end;
725
sljit_uw word_count;
726
SLJIT_NEXT_DEFINE_TYPES;
727
sljit_sw executable_offset;
728
sljit_uw addr;
729
struct sljit_label *label;
730
struct sljit_jump *jump;
731
struct sljit_const *const_;
732
733
CHECK_ERROR_PTR();
734
CHECK_PTR(check_sljit_generate_code(compiler, options));
735
reverse_buf(compiler);
736
737
code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
738
PTR_FAIL_WITH_EXEC_IF(code);
739
buf = compiler->buf;
740
741
code_ptr = code;
742
word_count = 0;
743
label = compiler->labels;
744
jump = compiler->jumps;
745
const_ = compiler->consts;
746
SLJIT_NEXT_INIT_TYPES();
747
SLJIT_GET_NEXT_MIN();
748
749
do {
750
buf_ptr = (sljit_ins*)buf->memory;
751
buf_end = buf_ptr + (buf->used_size >> 2);
752
do {
753
*code_ptr = *buf_ptr++;
754
if (next_min_addr == word_count) {
755
SLJIT_ASSERT(!label || label->size >= word_count);
756
SLJIT_ASSERT(!jump || jump->addr >= word_count);
757
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
758
759
/* These structures are ordered by their address. */
760
if (next_min_addr == next_label_size) {
761
if (label->u.index >= SLJIT_LABEL_ALIGNED) {
762
code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
763
*code_ptr = buf_ptr[-1];
764
}
765
766
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
767
label->size = (sljit_uw)(code_ptr - code);
768
label = label->next;
769
next_label_size = SLJIT_GET_NEXT_SIZE(label);
770
}
771
772
if (next_min_addr == next_jump_addr) {
773
if (!(jump->flags & JUMP_MOV_ADDR)) {
774
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
775
word_count += 2;
776
#else /* !SLJIT_CONFIG_MIPS_32 */
777
word_count += 6;
778
#endif /* SLJIT_CONFIG_MIPS_32 */
779
jump->addr = (sljit_uw)(code_ptr - 1);
780
code_ptr = detect_jump_type(jump, code, executable_offset);
781
} else {
782
jump->addr = (sljit_uw)code_ptr;
783
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
784
code_ptr += 1;
785
word_count += 1;
786
#else /* !SLJIT_CONFIG_MIPS_32 */
787
code_ptr += mov_addr_get_length(jump, code, executable_offset);
788
word_count += 5;
789
#endif /* SLJIT_CONFIG_MIPS_32 */
790
}
791
792
jump = jump->next;
793
next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
794
} else if (next_min_addr == next_const_addr) {
795
const_->addr = (sljit_uw)code_ptr;
796
const_ = const_->next;
797
next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
798
}
799
800
SLJIT_GET_NEXT_MIN();
801
}
802
code_ptr++;
803
word_count++;
804
} while (buf_ptr < buf_end);
805
806
buf = buf->next;
807
} while (buf);
808
809
if (label && label->size == word_count) {
810
if (label->u.index >= SLJIT_LABEL_ALIGNED)
811
code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
812
813
label->u.addr = (sljit_uw)code_ptr;
814
label->size = (sljit_uw)(code_ptr - code);
815
label = label->next;
816
}
817
818
SLJIT_ASSERT(!label);
819
SLJIT_ASSERT(!jump);
820
SLJIT_ASSERT(!const_);
821
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
822
823
jump = compiler->jumps;
824
while (jump) {
825
do {
826
addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
827
buf_ptr = (sljit_ins *)jump->addr;
828
829
if (jump->flags & PATCH_B) {
830
addr = (sljit_uw)((sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) - sizeof(sljit_ins)) >> 2);
831
SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
832
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((sljit_ins)addr & 0xffff);
833
break;
834
}
835
if (jump->flags & PATCH_J) {
836
SLJIT_ASSERT((addr & ~(sljit_uw)0xfffffff)
837
== (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff));
838
buf_ptr[0] |= (sljit_ins)(addr >> 2) & 0x03ffffff;
839
break;
840
}
841
842
load_addr_to_reg(jump);
843
} while (0);
844
845
jump = jump->next;
846
}
847
848
compiler->error = SLJIT_ERR_COMPILED;
849
compiler->executable_offset = executable_offset;
850
compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
851
852
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
853
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
854
855
#ifndef __GNUC__
856
SLJIT_CACHE_FLUSH(code, code_ptr);
857
#else
858
/* GCC workaround for invalid code generation with -O2. */
859
sljit_cache_flush(code, code_ptr);
860
#endif
861
SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
862
return code;
863
}
864
865
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
866
{
867
switch (feature_type) {
868
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
869
&& (!defined(SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE)
870
case SLJIT_HAS_F64_AS_F32_PAIR:
871
if (!cpu_feature_list)
872
get_cpu_features();
873
874
return (cpu_feature_list & CPU_FEATURE_FR) != 0;
875
#endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_IS_FPU_AVAILABLE */
876
case SLJIT_HAS_FPU:
877
if (!cpu_feature_list)
878
get_cpu_features();
879
880
return (cpu_feature_list & CPU_FEATURE_FPU) != 0;
881
case SLJIT_HAS_ZERO_REGISTER:
882
case SLJIT_HAS_COPY_F32:
883
case SLJIT_HAS_COPY_F64:
884
return 1;
885
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
886
case SLJIT_HAS_CLZ:
887
case SLJIT_HAS_CMOV:
888
case SLJIT_HAS_PREFETCH:
889
case SLJIT_HAS_ATOMIC:
890
case SLJIT_HAS_MEMORY_BARRIER:
891
return 1;
892
893
case SLJIT_HAS_CTZ:
894
return 2;
895
#endif /* SLJIT_MIPS_REV >= 1 */
896
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
897
case SLJIT_HAS_REV:
898
case SLJIT_HAS_ROT:
899
return 1;
900
#endif /* SLJIT_MIPS_REV >= 2 */
901
default:
902
return 0;
903
}
904
}
905
906
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
907
{
908
SLJIT_UNUSED_ARG(type);
909
return 0;
910
}
911
912
/* --------------------------------------------------------------------- */
913
/* Entry, exit */
914
/* --------------------------------------------------------------------- */
915
916
/* Creates an index in data_transfer_insts array. */
917
#define LOAD_DATA 0x01
918
#define WORD_DATA 0x00
919
#define BYTE_DATA 0x02
920
#define HALF_DATA 0x04
921
#define INT_DATA 0x06
922
#define SIGNED_DATA 0x08
923
/* Separates integer and floating point registers */
924
#define GPR_REG 0x0f
925
#define DOUBLE_DATA 0x10
926
#define SINGLE_DATA 0x12
927
928
#define MEM_MASK 0x1f
929
930
#define ARG_TEST 0x00020
931
#define ALT_KEEP_CACHE 0x00040
932
#define CUMULATIVE_OP 0x00080
933
#define LOGICAL_OP 0x00100
934
#define IMM_OP 0x00200
935
#define MOVE_OP 0x00400
936
#define SRC2_IMM 0x00800
937
938
#define UNUSED_DEST 0x01000
939
#define REG_DEST 0x02000
940
#define REG1_SOURCE 0x04000
941
#define REG2_SOURCE 0x08000
942
#define SLOW_SRC1 0x10000
943
#define SLOW_SRC2 0x20000
944
#define SLOW_DEST 0x40000
945
946
static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
947
static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr);
948
949
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
950
#define SELECT_OP(d, w) (w)
951
#else
952
#define SELECT_OP(d, w) (!(op & SLJIT_32) ? (d) : (w))
953
#endif
954
955
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
956
#include "sljitNativeMIPS_32.c"
957
#else
958
#include "sljitNativeMIPS_64.c"
959
#endif
960
961
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
962
sljit_s32 options, sljit_s32 arg_types,
963
sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)
964
{
965
sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches);
966
sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds);
967
sljit_ins base;
968
sljit_s32 i, tmp, offset;
969
sljit_s32 arg_count, word_arg_count, float_arg_count;
970
sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
971
972
CHECK_ERROR();
973
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size));
974
set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);
975
976
scratches = ENTER_GET_REGS(scratches);
977
saveds = ENTER_GET_REGS(saveds);
978
979
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
980
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
981
if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
982
if ((local_size & SSIZE_OF(sw)) != 0)
983
local_size += SSIZE_OF(sw);
984
local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
985
}
986
987
local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
988
#else
989
local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
990
local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
991
#endif
992
compiler->local_size = local_size;
993
994
offset = 0;
995
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
996
if (!(options & SLJIT_ENTER_REG_ARG)) {
997
tmp = arg_types >> SLJIT_ARG_SHIFT;
998
arg_count = 0;
999
1000
while (tmp) {
1001
offset = arg_count;
1002
if ((tmp & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64) {
1003
if ((arg_count & 0x1) != 0)
1004
arg_count++;
1005
arg_count++;
1006
}
1007
1008
arg_count++;
1009
tmp >>= SLJIT_ARG_SHIFT;
1010
}
1011
1012
compiler->args_size = (sljit_uw)arg_count << 2;
1013
offset = (offset >= 4) ? (offset << 2) : 0;
1014
}
1015
#endif /* SLJIT_CONFIG_MIPS_32 */
1016
1017
if (local_size + offset <= -SIMM_MIN) {
1018
/* Frequent case. */
1019
FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
1020
base = S(SLJIT_SP);
1021
offset = local_size - SSIZE_OF(sw);
1022
} else {
1023
FAIL_IF(load_immediate(compiler, OTHER_FLAG, local_size));
1024
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
1025
FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | TA(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
1026
base = S(TMP_REG1);
1027
offset = -SSIZE_OF(sw);
1028
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1029
local_size = 0;
1030
#endif
1031
}
1032
1033
FAIL_IF(push_inst(compiler, STORE_W | base | TA(RETURN_ADDR_REG) | IMM(offset), UNMOVABLE_INS));
1034
1035
tmp = SLJIT_S0 - saveds;
1036
for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
1037
offset -= SSIZE_OF(sw);
1038
FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
1039
}
1040
1041
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1042
offset -= SSIZE_OF(sw);
1043
FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
1044
}
1045
1046
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1047
/* This alignment is valid because offset is not used after storing FPU regs. */
1048
if ((offset & SSIZE_OF(sw)) != 0)
1049
offset -= SSIZE_OF(sw);
1050
#endif
1051
1052
tmp = SLJIT_FS0 - fsaveds;
1053
for (i = SLJIT_FS0; i > tmp; i--) {
1054
offset -= SSIZE_OF(f64);
1055
FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
1056
}
1057
1058
for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
1059
offset -= SSIZE_OF(f64);
1060
FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
1061
}
1062
1063
if (options & SLJIT_ENTER_REG_ARG)
1064
return SLJIT_SUCCESS;
1065
1066
arg_types >>= SLJIT_ARG_SHIFT;
1067
arg_count = 0;
1068
word_arg_count = 0;
1069
float_arg_count = 0;
1070
1071
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1072
/* The first maximum two floating point arguments are passed in floating point
1073
registers if no integer argument precedes them. The first 16 byte data is
1074
passed in four integer registers, the rest is placed onto the stack.
1075
The floating point registers are also part of the first 16 byte data, so
1076
their corresponding integer registers are not used when they are present. */
1077
1078
while (arg_types) {
1079
switch (arg_types & SLJIT_ARG_MASK) {
1080
case SLJIT_ARG_TYPE_F64:
1081
float_arg_count++;
1082
if ((arg_count & 0x1) != 0)
1083
arg_count++;
1084
1085
if (word_arg_count == 0 && float_arg_count <= 2) {
1086
if (float_arg_count == 1)
1087
FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1088
} else if (arg_count < 4) {
1089
FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
1090
switch (cpu_feature_list & CPU_FEATURE_FR) {
1091
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
1092
case CPU_FEATURE_FR:
1093
FAIL_IF(push_inst(compiler, MTHC1 | TA(5 + arg_count) | FS(float_arg_count), MOVABLE_INS));
1094
break;
1095
#endif /* SLJIT_MIPS_REV >= 2 */
1096
default:
1097
FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS));
1098
break;
1099
}
1100
} else
1101
FAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
1102
arg_count++;
1103
break;
1104
case SLJIT_ARG_TYPE_F32:
1105
float_arg_count++;
1106
1107
if (word_arg_count == 0 && float_arg_count <= 2) {
1108
if (float_arg_count == 1)
1109
FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1110
} else if (arg_count < 4)
1111
FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
1112
else
1113
FAIL_IF(push_inst(compiler, LWC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
1114
break;
1115
default:
1116
word_arg_count++;
1117
1118
if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
1119
tmp = SLJIT_S0 - saved_arg_count;
1120
saved_arg_count++;
1121
} else if (word_arg_count != arg_count + 1 || arg_count == 0)
1122
tmp = word_arg_count;
1123
else
1124
break;
1125
1126
if (arg_count < 4)
1127
FAIL_IF(push_inst(compiler, ADDU_W | SA(4 + arg_count) | TA(0) | D(tmp), DR(tmp)));
1128
else
1129
FAIL_IF(push_inst(compiler, LW | base | T(tmp) | IMM(local_size + (arg_count << 2)), DR(tmp)));
1130
break;
1131
}
1132
arg_count++;
1133
arg_types >>= SLJIT_ARG_SHIFT;
1134
}
1135
1136
SLJIT_ASSERT(compiler->args_size == (sljit_uw)arg_count << 2);
1137
#else /* !SLJIT_CONFIG_MIPS_32 */
1138
while (arg_types) {
1139
arg_count++;
1140
switch (arg_types & SLJIT_ARG_MASK) {
1141
case SLJIT_ARG_TYPE_F64:
1142
float_arg_count++;
1143
if (arg_count != float_arg_count)
1144
FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
1145
else if (arg_count == 1)
1146
FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1147
break;
1148
case SLJIT_ARG_TYPE_F32:
1149
float_arg_count++;
1150
if (arg_count != float_arg_count)
1151
FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
1152
else if (arg_count == 1)
1153
FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1154
break;
1155
default:
1156
word_arg_count++;
1157
1158
if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
1159
tmp = SLJIT_S0 - saved_arg_count;
1160
saved_arg_count++;
1161
} else if (word_arg_count != arg_count || word_arg_count <= 1)
1162
tmp = word_arg_count;
1163
else
1164
break;
1165
1166
FAIL_IF(push_inst(compiler, ADDU_W | SA(3 + arg_count) | TA(0) | D(tmp), DR(tmp)));
1167
break;
1168
}
1169
arg_types >>= SLJIT_ARG_SHIFT;
1170
}
1171
#endif /* SLJIT_CONFIG_MIPS_32 */
1172
1173
return SLJIT_SUCCESS;
1174
}
1175
1176
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
1177
sljit_s32 options, sljit_s32 arg_types,
1178
sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)
1179
{
1180
sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches);
1181
sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds);
1182
1183
CHECK_ERROR();
1184
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));
1185
set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);
1186
1187
scratches = ENTER_GET_REGS(scratches);
1188
saveds = ENTER_GET_REGS(saveds);
1189
1190
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);
1191
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1192
if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
1193
if ((local_size & SSIZE_OF(sw)) != 0)
1194
local_size += SSIZE_OF(sw);
1195
local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1196
}
1197
1198
compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
1199
#else
1200
local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1201
compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
1202
#endif
1203
return SLJIT_SUCCESS;
1204
}
1205
1206
static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr)
1207
{
1208
sljit_s32 local_size, i, tmp, offset;
1209
sljit_s32 load_return_addr = (frame_size == 0);
1210
sljit_s32 scratches = compiler->scratches;
1211
sljit_s32 saveds = compiler->saveds;
1212
sljit_s32 fsaveds = compiler->fsaveds;
1213
sljit_s32 fscratches = compiler->fscratches;
1214
sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
1215
1216
SLJIT_ASSERT(frame_size == 1 || (frame_size & 0xf) == 0);
1217
frame_size &= ~0xf;
1218
1219
local_size = compiler->local_size;
1220
1221
tmp = GET_SAVED_REGISTERS_SIZE(scratches, saveds - kept_saveds_count, 1);
1222
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1223
if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
1224
if ((tmp & SSIZE_OF(sw)) != 0)
1225
tmp += SSIZE_OF(sw);
1226
tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1227
}
1228
#else
1229
tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1230
#endif
1231
1232
if (local_size <= SIMM_MAX) {
1233
if (local_size < frame_size) {
1234
FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size), DR(SLJIT_SP)));
1235
local_size = frame_size;
1236
}
1237
} else {
1238
if (tmp < frame_size)
1239
tmp = frame_size;
1240
1241
FAIL_IF(load_immediate(compiler, DR(TMP_REG2), local_size - tmp));
1242
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG2) | D(SLJIT_SP), DR(SLJIT_SP)));
1243
local_size = tmp;
1244
}
1245
1246
SLJIT_ASSERT(local_size >= frame_size);
1247
1248
offset = local_size - SSIZE_OF(sw);
1249
if (load_return_addr)
1250
FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | TA(RETURN_ADDR_REG) | IMM(offset), RETURN_ADDR_REG));
1251
1252
tmp = SLJIT_S0 - saveds;
1253
for (i = SLJIT_S0 - kept_saveds_count; i > tmp; i--) {
1254
offset -= SSIZE_OF(sw);
1255
FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1256
}
1257
1258
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1259
offset -= SSIZE_OF(sw);
1260
FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1261
}
1262
1263
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1264
/* This alignment is valid because offset is not used after storing FPU regs. */
1265
if ((offset & SSIZE_OF(sw)) != 0)
1266
offset -= SSIZE_OF(sw);
1267
#endif
1268
1269
tmp = SLJIT_FS0 - fsaveds;
1270
for (i = SLJIT_FS0; i > tmp; i--) {
1271
offset -= SSIZE_OF(f64);
1272
FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1273
}
1274
1275
for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
1276
offset -= SSIZE_OF(f64);
1277
FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1278
}
1279
1280
if (local_size > frame_size)
1281
*ins_ptr = ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size);
1282
else
1283
*ins_ptr = NOP;
1284
1285
return SLJIT_SUCCESS;
1286
}
1287
1288
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
1289
{
1290
sljit_ins ins;
1291
1292
CHECK_ERROR();
1293
CHECK(check_sljit_emit_return_void(compiler));
1294
1295
emit_stack_frame_release(compiler, 0, &ins);
1296
1297
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
1298
return push_inst(compiler, ins, UNMOVABLE_INS);
1299
}
1300
1301
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
1302
sljit_s32 src, sljit_sw srcw)
1303
{
1304
sljit_ins ins;
1305
1306
CHECK_ERROR();
1307
CHECK(check_sljit_emit_return_to(compiler, src, srcw));
1308
1309
if (src & SLJIT_MEM) {
1310
ADJUST_LOCAL_OFFSET(src, srcw);
1311
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
1312
src = PIC_ADDR_REG;
1313
srcw = 0;
1314
} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
1315
FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
1316
src = PIC_ADDR_REG;
1317
srcw = 0;
1318
}
1319
1320
FAIL_IF(emit_stack_frame_release(compiler, 1, &ins));
1321
1322
if (src != SLJIT_IMM) {
1323
FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
1324
return push_inst(compiler, ins, UNMOVABLE_INS);
1325
}
1326
1327
if (ins != NOP)
1328
FAIL_IF(push_inst(compiler, ins, MOVABLE_INS));
1329
1330
SLJIT_SKIP_CHECKS(compiler);
1331
return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
1332
}
1333
1334
/* --------------------------------------------------------------------- */
1335
/* Operators */
1336
/* --------------------------------------------------------------------- */
1337
1338
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1339
#define ARCH_32_64(a, b) a
1340
#else
1341
#define ARCH_32_64(a, b) b
1342
#endif
1343
1344
static const sljit_ins data_transfer_insts[16 + 4] = {
1345
/* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1346
/* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1347
/* u b s */ HI(40) /* sb */,
1348
/* u b l */ HI(36) /* lbu */,
1349
/* u h s */ HI(41) /* sh */,
1350
/* u h l */ HI(37) /* lhu */,
1351
/* u i s */ HI(43) /* sw */,
1352
/* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),
1353
1354
/* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1355
/* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1356
/* s b s */ HI(40) /* sb */,
1357
/* s b l */ HI(32) /* lb */,
1358
/* s h s */ HI(41) /* sh */,
1359
/* s h l */ HI(33) /* lh */,
1360
/* s i s */ HI(43) /* sw */,
1361
/* s i l */ HI(35) /* lw */,
1362
1363
/* d s */ HI(61) /* sdc1 */,
1364
/* d l */ HI(53) /* ldc1 */,
1365
/* s s */ HI(57) /* swc1 */,
1366
/* s l */ HI(49) /* lwc1 */,
1367
};
1368
1369
#undef ARCH_32_64
1370
1371
/* reg_ar is an absoulute register! */
1372
1373
/* Can perform an operation using at most 1 instruction. */
1374
static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1375
{
1376
SLJIT_ASSERT(arg & SLJIT_MEM);
1377
1378
if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
1379
/* Works for both absoulte and relative addresses. */
1380
if (SLJIT_UNLIKELY(flags & ARG_TEST))
1381
return 1;
1382
FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK)
1383
| TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS));
1384
return -1;
1385
}
1386
return 0;
1387
}
1388
1389
#define TO_ARGW_HI(argw) (((argw) & ~0xffff) + (((argw) & 0x8000) ? 0x10000 : 0))
1390
1391
/* See getput_arg below.
1392
Note: can_cache is called only for binary operators. */
1393
static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
1394
{
1395
SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
1396
1397
/* Simple operation except for updates. */
1398
if (arg & OFFS_REG_MASK) {
1399
argw &= 0x3;
1400
next_argw &= 0x3;
1401
if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
1402
return 1;
1403
return 0;
1404
}
1405
1406
if (arg == next_arg) {
1407
if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)
1408
|| TO_ARGW_HI(argw) == TO_ARGW_HI(next_argw))
1409
return 1;
1410
return 0;
1411
}
1412
1413
return 0;
1414
}
1415
1416
/* Emit the necessary instructions. See can_cache above. */
1417
static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
1418
{
1419
sljit_s32 tmp_ar, base, delay_slot;
1420
sljit_sw offset, argw_hi;
1421
1422
SLJIT_ASSERT(arg & SLJIT_MEM);
1423
if (!(next_arg & SLJIT_MEM)) {
1424
next_arg = 0;
1425
next_argw = 0;
1426
}
1427
1428
/* Since tmp can be the same as base or offset registers,
1429
* these might be unavailable after modifying tmp. */
1430
if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1431
tmp_ar = reg_ar;
1432
delay_slot = reg_ar;
1433
}
1434
else {
1435
tmp_ar = DR(TMP_REG1);
1436
delay_slot = MOVABLE_INS;
1437
}
1438
base = arg & REG_MASK;
1439
1440
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1441
argw &= 0x3;
1442
1443
/* Using the cache. */
1444
if (argw == compiler->cache_argw) {
1445
if (arg == compiler->cache_arg)
1446
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1447
1448
if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
1449
if (arg == next_arg && argw == (next_argw & 0x3)) {
1450
compiler->cache_arg = arg;
1451
compiler->cache_argw = argw;
1452
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1453
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1454
}
1455
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
1456
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1457
}
1458
}
1459
1460
if (SLJIT_UNLIKELY(argw)) {
1461
compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
1462
compiler->cache_argw = argw;
1463
FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
1464
}
1465
1466
if (arg == next_arg && argw == (next_argw & 0x3)) {
1467
compiler->cache_arg = arg;
1468
compiler->cache_argw = argw;
1469
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1470
tmp_ar = DR(TMP_REG3);
1471
}
1472
else
1473
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));
1474
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1475
}
1476
1477
if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
1478
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(argw - compiler->cache_argw), delay_slot);
1479
1480
if (compiler->cache_arg == SLJIT_MEM && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
1481
offset = argw - compiler->cache_argw;
1482
} else {
1483
compiler->cache_arg = SLJIT_MEM;
1484
1485
argw_hi = TO_ARGW_HI(argw);
1486
1487
if (next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN && argw_hi != TO_ARGW_HI(next_argw)) {
1488
FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
1489
compiler->cache_argw = argw;
1490
offset = 0;
1491
} else {
1492
FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw_hi));
1493
compiler->cache_argw = argw_hi;
1494
offset = argw & 0xffff;
1495
argw = argw_hi;
1496
}
1497
}
1498
1499
if (!base)
1500
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
1501
1502
if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
1503
compiler->cache_arg = arg;
1504
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));
1505
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
1506
}
1507
1508
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));
1509
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(offset), delay_slot);
1510
}
1511
1512
static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1513
{
1514
sljit_s32 tmp_ar, base, delay_slot;
1515
1516
if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
1517
return compiler->error;
1518
1519
if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1520
tmp_ar = reg_ar;
1521
delay_slot = reg_ar;
1522
}
1523
else {
1524
tmp_ar = DR(TMP_REG1);
1525
delay_slot = MOVABLE_INS;
1526
}
1527
base = arg & REG_MASK;
1528
1529
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1530
argw &= 0x3;
1531
1532
if (SLJIT_UNLIKELY(argw)) {
1533
FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));
1534
FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
1535
}
1536
else
1537
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));
1538
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1539
}
1540
1541
FAIL_IF(load_immediate(compiler, tmp_ar, TO_ARGW_HI(argw)));
1542
1543
if (base != 0)
1544
FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
1545
1546
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(argw), delay_slot);
1547
}
1548
1549
static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
1550
{
1551
if (getput_arg_fast(compiler, flags, reg_ar, arg1, arg1w))
1552
return compiler->error;
1553
return getput_arg(compiler, flags, reg_ar, arg1, arg1w, arg2, arg2w);
1554
}
1555
1556
#define EMIT_LOGICAL(op_imm, op_reg) \
1557
if (flags & SRC2_IMM) { \
1558
if (op & SLJIT_SET_Z) \
1559
FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
1560
if (!(flags & UNUSED_DEST)) \
1561
FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
1562
} \
1563
else { \
1564
if (op & SLJIT_SET_Z) \
1565
FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
1566
if (!(flags & UNUSED_DEST)) \
1567
FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | D(dst), DR(dst))); \
1568
}
1569
1570
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1571
1572
#define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
1573
op_imm = (imm); \
1574
op_v = (v);
1575
1576
#else /* !SLJIT_CONFIG_MIPS_32 */
1577
1578
1579
#define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
1580
op_dimm = (dimm); \
1581
op_dimm32 = (dimm32); \
1582
op_imm = (imm); \
1583
op_dv = (dv); \
1584
op_v = (v);
1585
1586
#endif /* SLJIT_CONFIG_MIPS_32 */
1587
1588
#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV < 1)
1589
1590
static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1591
{
1592
sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ);
1593
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1594
sljit_ins word_size = (op & SLJIT_32) ? 32 : 64;
1595
#else /* !SLJIT_CONFIG_MIPS_64 */
1596
sljit_ins word_size = 32;
1597
#endif /* SLJIT_CONFIG_MIPS_64 */
1598
1599
/* The TMP_REG2 is the next value. */
1600
if (src != TMP_REG2)
1601
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
1602
1603
FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(is_clz ? 13 : 14), UNMOVABLE_INS));
1604
/* The OTHER_FLAG is the counter. Delay slot. */
1605
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(word_size), OTHER_FLAG));
1606
1607
if (!is_clz) {
1608
FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG2) | T(TMP_REG1) | IMM(1), DR(TMP_REG1)));
1609
FAIL_IF(push_inst(compiler, BNE | S(TMP_REG1) | TA(0) | IMM(11), UNMOVABLE_INS));
1610
} else
1611
FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG2) | TA(0) | IMM(11), UNMOVABLE_INS));
1612
1613
/* Delay slot. */
1614
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(0), OTHER_FLAG));
1615
1616
/* The TMP_REG1 is the next shift. */
1617
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(word_size), DR(TMP_REG1)));
1618
1619
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(TMP_REG2) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1620
FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
1621
1622
FAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG1) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));
1623
FAIL_IF(push_inst(compiler, BNE | S(TMP_REG2) | TA(0) | IMM(-4), UNMOVABLE_INS));
1624
/* Delay slot. */
1625
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
1626
1627
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(TMP_REG1) | T(TMP_REG2) | IMM(-1), DR(TMP_REG2)));
1628
FAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG2) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));
1629
1630
FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(-7), UNMOVABLE_INS));
1631
/* Delay slot. */
1632
FAIL_IF(push_inst(compiler, OR | SA(OTHER_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG));
1633
1634
return push_inst(compiler, SELECT_OP(DADDU, ADDU) | SA(OTHER_FLAG) | TA(0) | D(dst), DR(dst));
1635
}
1636
1637
#endif /* SLJIT_MIPS_REV < 1 */
1638
1639
static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1640
{
1641
#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64
1642
int is_32 = (op & SLJIT_32);
1643
#endif /* SLJIT_CONFIG_MIPS_64 */
1644
1645
op = GET_OPCODE(op);
1646
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
1647
#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64
1648
if (!is_32 && (op == SLJIT_REV)) {
1649
FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst)));
1650
return push_inst(compiler, DSHD | T(dst) | D(dst), DR(dst));
1651
}
1652
if (op != SLJIT_REV && src != TMP_REG2) {
1653
FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG1), DR(TMP_REG1)));
1654
src = TMP_REG1;
1655
}
1656
#endif /* SLJIT_CONFIG_MIPS_64 */
1657
FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst)));
1658
FAIL_IF(push_inst(compiler, ROTR | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
1659
#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64
1660
if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3)
1661
FAIL_IF(push_inst(compiler, DINSU | T(dst) | SA(0) | (31 << 11), DR(dst)));
1662
#endif /* SLJIT_CONFIG_MIPS_64 */
1663
#else /* SLJIT_MIPS_REV < 2 */
1664
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1665
if (!is_32) {
1666
FAIL_IF(push_inst(compiler, DSRL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));
1667
FAIL_IF(push_inst(compiler, ORI | SA(0) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG));
1668
FAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(dst) | SH_IMM(0), DR(dst)));
1669
FAIL_IF(push_inst(compiler, DSLL32 | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(0), OTHER_FLAG));
1670
FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1671
1672
FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1)));
1673
FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG));
1674
FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1675
FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1676
FAIL_IF(push_inst(compiler, DSLL | TA(OTHER_FLAG) | DA(EQUAL_FLAG) | SH_IMM(8), EQUAL_FLAG));
1677
FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
1678
FAIL_IF(push_inst(compiler, XOR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
1679
FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1680
1681
FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));
1682
FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1683
FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1684
FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(8), DR(dst)));
1685
return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1686
}
1687
1688
if (op != SLJIT_REV && src != TMP_REG2) {
1689
FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(0), DR(TMP_REG2)));
1690
src = TMP_REG2;
1691
}
1692
#endif /* SLJIT_CONFIG_MIPS_64 */
1693
1694
FAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1)));
1695
FAIL_IF(push_inst(compiler, LUI | TA(OTHER_FLAG) | 0xff, OTHER_FLAG));
1696
FAIL_IF(push_inst(compiler, SLL | T(src) | D(dst) | SH_IMM(16), DR(dst)));
1697
FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xff, OTHER_FLAG));
1698
FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1699
1700
FAIL_IF(push_inst(compiler, SRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));
1701
FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1702
FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1703
FAIL_IF(push_inst(compiler, SLL | T(dst) | D(dst) | SH_IMM(8), DR(dst)));
1704
FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1705
1706
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1707
if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3) {
1708
FAIL_IF(push_inst(compiler, DSLL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)));
1709
FAIL_IF(push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)));
1710
}
1711
#endif /* SLJIT_CONFIG_MIPS_64 */
1712
#endif /* SLJIT_MIPR_REV >= 2 */
1713
return SLJIT_SUCCESS;
1714
}
1715
1716
static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1717
{
1718
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
1719
#if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32
1720
FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst)));
1721
#else /* !SLJIT_CONFIG_MIPS_32 */
1722
FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst)));
1723
#endif /* SLJIT_CONFIG_MIPS_32 */
1724
if (GET_OPCODE(op) == SLJIT_REV_U16)
1725
return push_inst(compiler, ANDI | S(dst) | T(dst) | 0xffff, DR(dst));
1726
else
1727
return push_inst(compiler, SEH | T(dst) | D(dst), DR(dst));
1728
#else /* SLJIT_MIPS_REV < 2 */
1729
FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(src) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));
1730
FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(src) | D(dst) | SH_IMM(24), DR(dst)));
1731
FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG1) | T(TMP_REG1) | 0xff, DR(TMP_REG1)));
1732
FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SELECT_OP(DSRL32, SRL) : SELECT_OP(DSRA32, SRA)) | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
1733
return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1734
#endif /* SLJIT_MIPS_REV >= 2 */
1735
}
1736
1737
static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
1738
sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
1739
{
1740
sljit_s32 is_overflow, is_carry, carry_src_ar, is_handled, reg;
1741
sljit_ins op_imm, op_v;
1742
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1743
sljit_ins ins, op_dimm, op_dimm32, op_dv;
1744
#endif
1745
1746
switch (GET_OPCODE(op)) {
1747
case SLJIT_MOV:
1748
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1749
if (dst != src2)
1750
return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));
1751
return SLJIT_SUCCESS;
1752
1753
case SLJIT_MOV_U8:
1754
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1755
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
1756
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
1757
SLJIT_ASSERT(dst == src2);
1758
return SLJIT_SUCCESS;
1759
1760
case SLJIT_MOV_S8:
1761
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1762
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1763
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1764
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1765
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
1766
#else /* SLJIT_MIPS_REV < 2 */
1767
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
1768
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
1769
#endif /* SLJIT_MIPS_REV >= 2 */
1770
#else /* !SLJIT_CONFIG_MIPS_32 */
1771
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1772
if (op & SLJIT_32)
1773
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
1774
#endif /* SLJIT_MIPS_REV >= 2 */
1775
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
1776
return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
1777
#endif /* SLJIT_CONFIG_MIPS_32 */
1778
}
1779
SLJIT_ASSERT(dst == src2);
1780
return SLJIT_SUCCESS;
1781
1782
case SLJIT_MOV_U16:
1783
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1784
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
1785
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
1786
SLJIT_ASSERT(dst == src2);
1787
return SLJIT_SUCCESS;
1788
1789
case SLJIT_MOV_S16:
1790
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1791
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1792
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1793
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1794
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
1795
#else /* SLJIT_MIPS_REV < 2 */
1796
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
1797
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
1798
#endif /* SLJIT_MIPS_REV >= 2 */
1799
#else /* !SLJIT_CONFIG_MIPS_32 */
1800
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1801
if (op & SLJIT_32)
1802
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
1803
#endif /* SLJIT_MIPS_REV >= 2 */
1804
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
1805
return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
1806
#endif /* SLJIT_CONFIG_MIPS_32 */
1807
}
1808
SLJIT_ASSERT(dst == src2);
1809
return SLJIT_SUCCESS;
1810
1811
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1812
case SLJIT_MOV_U32:
1813
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
1814
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1815
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1816
if (dst == src2)
1817
return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11), DR(dst));
1818
#endif /* SLJIT_MIPS_REV >= 2 */
1819
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
1820
return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
1821
}
1822
SLJIT_ASSERT(dst == src2);
1823
return SLJIT_SUCCESS;
1824
1825
case SLJIT_MOV_S32:
1826
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
1827
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1828
return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
1829
}
1830
SLJIT_ASSERT(dst == src2);
1831
return SLJIT_SUCCESS;
1832
#endif /* SLJIT_CONFIG_MIPS_64 */
1833
1834
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1835
case SLJIT_CLZ:
1836
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1837
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1838
return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | D(dst), DR(dst));
1839
#else /* SLJIT_MIPS_REV < 6 */
1840
return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst));
1841
#endif /* SLJIT_MIPS_REV >= 6 */
1842
case SLJIT_CTZ:
1843
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1844
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
1845
FAIL_IF(push_inst(compiler, AND | S(src2) | T(TMP_REG1) | D(dst), DR(dst)));
1846
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1847
FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | D(dst), DR(dst)));
1848
#else /* SLJIT_MIPS_REV < 6 */
1849
FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | T(dst) | D(dst), DR(dst)));
1850
#endif /* SLJIT_MIPS_REV >= 6 */
1851
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(TMP_REG1) | IMM(SELECT_OP(-64, -32)), DR(TMP_REG1)));
1852
FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(SELECT_OP(26, 27)), DR(TMP_REG1)));
1853
return push_inst(compiler, XOR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1854
#else /* SLJIT_MIPS_REV < 1 */
1855
case SLJIT_CLZ:
1856
case SLJIT_CTZ:
1857
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1858
return emit_clz_ctz(compiler, op, dst, src2);
1859
#endif /* SLJIT_MIPS_REV >= 1 */
1860
1861
case SLJIT_REV:
1862
case SLJIT_REV_U32:
1863
case SLJIT_REV_S32:
1864
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && src2 != TMP_REG1 && dst != TMP_REG1);
1865
return emit_rev(compiler, op, dst, src2);
1866
1867
case SLJIT_REV_U16:
1868
case SLJIT_REV_S16:
1869
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1870
return emit_rev16(compiler, op, dst, src2);
1871
1872
case SLJIT_ADD:
1873
/* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */
1874
is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
1875
carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY;
1876
1877
if (flags & SRC2_IMM) {
1878
if (is_overflow) {
1879
if (src2 >= 0)
1880
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1881
else
1882
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1883
}
1884
else if (op & SLJIT_SET_Z)
1885
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
1886
1887
/* Only the zero flag is needed. */
1888
if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1889
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
1890
}
1891
else {
1892
if (is_overflow)
1893
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1894
else if (op & SLJIT_SET_Z)
1895
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1896
1897
if (is_overflow || carry_src_ar != 0) {
1898
if (src1 != dst)
1899
carry_src_ar = DR(src1);
1900
else if (src2 != dst)
1901
carry_src_ar = DR(src2);
1902
else {
1903
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG));
1904
carry_src_ar = OTHER_FLAG;
1905
}
1906
}
1907
1908
/* Only the zero flag is needed. */
1909
if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1910
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
1911
}
1912
1913
/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1914
if (is_overflow || carry_src_ar != 0) {
1915
if (flags & SRC2_IMM)
1916
FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1917
else
1918
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(OTHER_FLAG), OTHER_FLAG));
1919
}
1920
1921
if (!is_overflow)
1922
return SLJIT_SUCCESS;
1923
1924
FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1925
if (op & SLJIT_SET_Z)
1926
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1927
FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
1928
return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1929
1930
case SLJIT_ADDC:
1931
carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY;
1932
1933
if (flags & SRC2_IMM) {
1934
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
1935
} else {
1936
if (carry_src_ar != 0) {
1937
if (src1 != dst)
1938
carry_src_ar = DR(src1);
1939
else if (src2 != dst)
1940
carry_src_ar = DR(src2);
1941
else {
1942
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1943
carry_src_ar = EQUAL_FLAG;
1944
}
1945
}
1946
1947
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
1948
}
1949
1950
/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1951
if (carry_src_ar != 0) {
1952
if (flags & SRC2_IMM)
1953
FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
1954
else
1955
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(EQUAL_FLAG), EQUAL_FLAG));
1956
}
1957
1958
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1959
1960
if (carry_src_ar == 0)
1961
return SLJIT_SUCCESS;
1962
1963
/* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */
1964
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
1965
/* Set carry flag. */
1966
return push_inst(compiler, OR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1967
1968
case SLJIT_SUB:
1969
if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
1970
FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
1971
src2 = TMP_REG2;
1972
flags &= ~SRC2_IMM;
1973
}
1974
1975
is_handled = 0;
1976
1977
if (flags & SRC2_IMM) {
1978
if (GET_FLAG_TYPE(op) == SLJIT_LESS) {
1979
FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1980
is_handled = 1;
1981
}
1982
else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {
1983
FAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1984
is_handled = 1;
1985
}
1986
}
1987
1988
if (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
1989
is_handled = 1;
1990
1991
if (flags & SRC2_IMM) {
1992
reg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
1993
FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(reg) | IMM(src2), DR(reg)));
1994
src2 = reg;
1995
flags &= ~SRC2_IMM;
1996
}
1997
1998
switch (GET_FLAG_TYPE(op)) {
1999
case SLJIT_LESS:
2000
FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
2001
break;
2002
case SLJIT_GREATER:
2003
FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
2004
break;
2005
case SLJIT_SIG_LESS:
2006
FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
2007
break;
2008
case SLJIT_SIG_GREATER:
2009
FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
2010
break;
2011
}
2012
}
2013
2014
if (is_handled) {
2015
if (flags & SRC2_IMM) {
2016
if (op & SLJIT_SET_Z)
2017
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
2018
if (!(flags & UNUSED_DEST))
2019
return push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst));
2020
}
2021
else {
2022
if (op & SLJIT_SET_Z)
2023
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2024
if (!(flags & UNUSED_DEST))
2025
return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst));
2026
}
2027
return SLJIT_SUCCESS;
2028
}
2029
2030
is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
2031
is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;
2032
2033
if (flags & SRC2_IMM) {
2034
if (is_overflow) {
2035
if (src2 >= 0)
2036
FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2037
else
2038
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2039
}
2040
else if (op & SLJIT_SET_Z)
2041
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
2042
2043
if (is_overflow || is_carry)
2044
FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
2045
2046
/* Only the zero flag is needed. */
2047
if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
2048
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
2049
}
2050
else {
2051
if (is_overflow)
2052
FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2053
else if (op & SLJIT_SET_Z)
2054
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2055
2056
if (is_overflow || is_carry)
2057
FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
2058
2059
/* Only the zero flag is needed. */
2060
if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
2061
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
2062
}
2063
2064
if (!is_overflow)
2065
return SLJIT_SUCCESS;
2066
2067
FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
2068
if (op & SLJIT_SET_Z)
2069
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
2070
FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
2071
return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
2072
2073
case SLJIT_SUBC:
2074
if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
2075
FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
2076
src2 = TMP_REG2;
2077
flags &= ~SRC2_IMM;
2078
}
2079
2080
is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;
2081
2082
if (flags & SRC2_IMM) {
2083
if (is_carry)
2084
FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
2085
2086
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
2087
}
2088
else {
2089
if (is_carry)
2090
FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2091
2092
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
2093
}
2094
2095
if (is_carry)
2096
FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
2097
2098
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
2099
2100
if (!is_carry)
2101
return SLJIT_SUCCESS;
2102
2103
return push_inst(compiler, OR | SA(EQUAL_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG);
2104
2105
case SLJIT_MUL:
2106
SLJIT_ASSERT(!(flags & SRC2_IMM));
2107
2108
if (GET_FLAG_TYPE(op) != SLJIT_OVERFLOW) {
2109
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2110
return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
2111
#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2112
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2113
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
2114
#else /* !SLJIT_CONFIG_MIPS_32 */
2115
if (op & SLJIT_32)
2116
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
2117
FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
2118
return push_inst(compiler, MFLO | D(dst), DR(dst));
2119
#endif /* SLJIT_CONFIG_MIPS_32 */
2120
#else /* SLJIT_MIPS_REV < 1 */
2121
FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
2122
return push_inst(compiler, MFLO | D(dst), DR(dst));
2123
#endif /* SLJIT_MIPS_REV >= 6 */
2124
}
2125
2126
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2127
FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));
2128
FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2129
#else /* SLJIT_MIPS_REV < 6 */
2130
FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
2131
FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
2132
FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
2133
#endif /* SLJIT_MIPS_REV >= 6 */
2134
FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
2135
return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
2136
2137
case SLJIT_AND:
2138
EMIT_LOGICAL(ANDI, AND);
2139
return SLJIT_SUCCESS;
2140
2141
case SLJIT_OR:
2142
EMIT_LOGICAL(ORI, OR);
2143
return SLJIT_SUCCESS;
2144
2145
case SLJIT_XOR:
2146
if (!(flags & LOGICAL_OP)) {
2147
SLJIT_ASSERT((flags & SRC2_IMM) && src2 == -1);
2148
if (op & SLJIT_SET_Z)
2149
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2150
if (!(flags & UNUSED_DEST))
2151
FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | D(dst), DR(dst)));
2152
return SLJIT_SUCCESS;
2153
}
2154
EMIT_LOGICAL(XORI, XOR);
2155
return SLJIT_SUCCESS;
2156
2157
case SLJIT_SHL:
2158
case SLJIT_MSHL:
2159
EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV);
2160
break;
2161
2162
case SLJIT_LSHR:
2163
case SLJIT_MLSHR:
2164
EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV);
2165
break;
2166
2167
case SLJIT_ASHR:
2168
case SLJIT_MASHR:
2169
EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV);
2170
break;
2171
2172
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
2173
case SLJIT_ROTL:
2174
if ((flags & SRC2_IMM) || src2 == 0) {
2175
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2176
src2 = -src2 & 0x1f;
2177
#else /* !SLJIT_CONFIG_MIPS_32 */
2178
src2 = -src2 & ((op & SLJIT_32) ? 0x1f : 0x3f);
2179
#endif /* SLJIT_CONFIG_MIPS_32 */
2180
} else {
2181
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2)));
2182
src2 = TMP_REG2;
2183
}
2184
SLJIT_FALLTHROUGH
2185
2186
case SLJIT_ROTR:
2187
EMIT_SHIFT(DROTR, DROTR32, ROTR, DROTRV, ROTRV);
2188
break;
2189
#else /* SLJIT_MIPS_REV < 1 */
2190
case SLJIT_ROTL:
2191
case SLJIT_ROTR:
2192
if (flags & SRC2_IMM) {
2193
SLJIT_ASSERT(src2 != 0);
2194
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2195
if (!(op & SLJIT_32)) {
2196
if (GET_OPCODE(op) == SLJIT_ROTL)
2197
op_imm = ((src2 < 32) ? DSLL : DSLL32);
2198
else
2199
op_imm = ((src2 < 32) ? DSRL : DSRL32);
2200
2201
FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | (((sljit_ins)src2 & 0x1f) << 6), OTHER_FLAG));
2202
2203
src2 = 64 - src2;
2204
if (GET_OPCODE(op) == SLJIT_ROTL)
2205
op_imm = ((src2 < 32) ? DSRL : DSRL32);
2206
else
2207
op_imm = ((src2 < 32) ? DSLL : DSLL32);
2208
2209
FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
2210
return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2211
}
2212
#endif /* SLJIT_CONFIG_MIPS_64 */
2213
2214
op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLL : SRL;
2215
FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | ((sljit_ins)src2 << 6), OTHER_FLAG));
2216
2217
src2 = 32 - src2;
2218
op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL;
2219
FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
2220
return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2221
}
2222
2223
if (src2 == 0) {
2224
if (dst != src1)
2225
return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | D(dst), DR(dst));
2226
return SLJIT_SUCCESS;
2227
}
2228
2229
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2230
2231
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2232
if (!(op & SLJIT_32)) {
2233
op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSLLV : DSRLV;
2234
FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
2235
op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSRLV : DSLLV;
2236
FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
2237
return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2238
}
2239
#endif /* SLJIT_CONFIG_MIPS_64 */
2240
2241
op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLV : SRLV;
2242
FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
2243
op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLV : SLLV;
2244
FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
2245
return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2246
#endif /* SLJIT_MIPS_REV >= 2 */
2247
2248
default:
2249
SLJIT_UNREACHABLE();
2250
return SLJIT_SUCCESS;
2251
}
2252
2253
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2254
if ((flags & SRC2_IMM) || src2 == 0) {
2255
if (op & SLJIT_SET_Z)
2256
FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
2257
2258
if (flags & UNUSED_DEST)
2259
return SLJIT_SUCCESS;
2260
return push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
2261
}
2262
2263
if (op & SLJIT_SET_Z)
2264
FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2265
2266
if (flags & UNUSED_DEST)
2267
return SLJIT_SUCCESS;
2268
return push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst));
2269
#else /* !SLJIT_CONFIG_MIPS_32 */
2270
if ((flags & SRC2_IMM) || src2 == 0) {
2271
if (src2 >= 32) {
2272
SLJIT_ASSERT(!(op & SLJIT_32));
2273
ins = op_dimm32;
2274
src2 -= 32;
2275
}
2276
else
2277
ins = (op & SLJIT_32) ? op_imm : op_dimm;
2278
2279
if (op & SLJIT_SET_Z)
2280
FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
2281
2282
if (flags & UNUSED_DEST)
2283
return SLJIT_SUCCESS;
2284
return push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
2285
}
2286
2287
ins = (op & SLJIT_32) ? op_v : op_dv;
2288
if (op & SLJIT_SET_Z)
2289
FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2290
2291
if (flags & UNUSED_DEST)
2292
return SLJIT_SUCCESS;
2293
return push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst));
2294
#endif /* SLJIT_CONFIG_MIPS_32 */
2295
}
2296
2297
#define CHECK_IMM(flags, srcw) \
2298
((!((flags) & LOGICAL_OP) && ((srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)) \
2299
|| (((flags) & LOGICAL_OP) && !((srcw) & ~UIMM_MAX)))
2300
2301
static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
2302
sljit_s32 dst, sljit_sw dstw,
2303
sljit_s32 src1, sljit_sw src1w,
2304
sljit_s32 src2, sljit_sw src2w)
2305
{
2306
/* arg1 goes to TMP_REG1 or src reg
2307
arg2 goes to TMP_REG2, imm or src reg
2308
TMP_REG3 can be used for caching
2309
result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
2310
sljit_s32 dst_r = TMP_REG2;
2311
sljit_s32 src1_r;
2312
sljit_sw src2_r = 0;
2313
sljit_s32 src2_tmp_reg = (GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;
2314
2315
if (!(flags & ALT_KEEP_CACHE)) {
2316
compiler->cache_arg = 0;
2317
compiler->cache_argw = 0;
2318
}
2319
2320
if (dst == 0) {
2321
SLJIT_ASSERT(HAS_FLAGS(op));
2322
flags |= UNUSED_DEST;
2323
dst = TMP_REG2;
2324
}
2325
else if (FAST_IS_REG(dst)) {
2326
dst_r = dst;
2327
flags |= REG_DEST;
2328
if (flags & MOVE_OP)
2329
src2_tmp_reg = dst_r;
2330
}
2331
else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
2332
flags |= SLOW_DEST;
2333
2334
if (flags & IMM_OP) {
2335
if (src2 == SLJIT_IMM && src2w != 0 && CHECK_IMM(flags, src2w)) {
2336
flags |= SRC2_IMM;
2337
src2_r = src2w;
2338
} else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && CHECK_IMM(flags, src1w)) {
2339
flags |= SRC2_IMM;
2340
src2_r = src1w;
2341
2342
/* And swap arguments. */
2343
src1 = src2;
2344
src1w = src2w;
2345
src2 = SLJIT_IMM;
2346
/* src2w = src2_r unneeded. */
2347
}
2348
}
2349
2350
/* Source 1. */
2351
if (FAST_IS_REG(src1)) {
2352
src1_r = src1;
2353
flags |= REG1_SOURCE;
2354
}
2355
else if (src1 == SLJIT_IMM) {
2356
if (src1w) {
2357
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
2358
src1_r = TMP_REG1;
2359
}
2360
else
2361
src1_r = 0;
2362
}
2363
else {
2364
if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))
2365
FAIL_IF(compiler->error);
2366
else
2367
flags |= SLOW_SRC1;
2368
src1_r = TMP_REG1;
2369
}
2370
2371
/* Source 2. */
2372
if (FAST_IS_REG(src2)) {
2373
src2_r = src2;
2374
flags |= REG2_SOURCE;
2375
if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)
2376
dst_r = (sljit_s32)src2_r;
2377
}
2378
else if (src2 == SLJIT_IMM) {
2379
if (!(flags & SRC2_IMM)) {
2380
if (src2w) {
2381
FAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w));
2382
src2_r = src2_tmp_reg;
2383
}
2384
else {
2385
src2_r = 0;
2386
if (flags & MOVE_OP) {
2387
if (dst & SLJIT_MEM)
2388
dst_r = 0;
2389
else
2390
op = SLJIT_MOV;
2391
}
2392
}
2393
}
2394
}
2395
else {
2396
if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w))
2397
FAIL_IF(compiler->error);
2398
else
2399
flags |= SLOW_SRC2;
2400
src2_r = src2_tmp_reg;
2401
}
2402
2403
if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
2404
SLJIT_ASSERT(src2_r == TMP_REG2);
2405
if ((flags & SLOW_DEST) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
2406
FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
2407
FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
2408
}
2409
else {
2410
FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));
2411
FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));
2412
}
2413
}
2414
else if (flags & SLOW_SRC1)
2415
FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
2416
else if (flags & SLOW_SRC2)
2417
FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w, dst, dstw));
2418
2419
FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
2420
2421
if (dst & SLJIT_MEM) {
2422
if (!(flags & SLOW_DEST)) {
2423
getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);
2424
return compiler->error;
2425
}
2426
return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);
2427
}
2428
2429
return SLJIT_SUCCESS;
2430
}
2431
2432
#undef CHECK_IMM
2433
2434
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
2435
{
2436
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2437
sljit_s32 int_op = op & SLJIT_32;
2438
#endif
2439
2440
CHECK_ERROR();
2441
CHECK(check_sljit_emit_op0(compiler, op));
2442
2443
op = GET_OPCODE(op);
2444
switch (op) {
2445
case SLJIT_BREAKPOINT:
2446
return push_inst(compiler, BREAK, UNMOVABLE_INS);
2447
case SLJIT_NOP:
2448
return push_inst(compiler, NOP, UNMOVABLE_INS);
2449
case SLJIT_LMUL_UW:
2450
case SLJIT_LMUL_SW:
2451
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2452
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2453
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2454
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2455
#else /* !SLJIT_CONFIG_MIPS_64 */
2456
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2457
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2458
#endif /* SLJIT_CONFIG_MIPS_64 */
2459
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
2460
return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
2461
#else /* SLJIT_MIPS_REV < 6 */
2462
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2463
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2464
#else /* !SLJIT_CONFIG_MIPS_64 */
2465
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2466
#endif /* SLJIT_CONFIG_MIPS_64 */
2467
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
2468
return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
2469
#endif /* SLJIT_MIPS_REV >= 6 */
2470
case SLJIT_DIVMOD_UW:
2471
case SLJIT_DIVMOD_SW:
2472
case SLJIT_DIV_UW:
2473
case SLJIT_DIV_SW:
2474
SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
2475
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2476
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2477
if (int_op) {
2478
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2479
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2480
}
2481
else {
2482
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2483
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2484
}
2485
#else /* !SLJIT_CONFIG_MIPS_64 */
2486
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2487
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2488
#endif /* SLJIT_CONFIG_MIPS_64 */
2489
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
2490
return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
2491
#else /* SLJIT_MIPS_REV < 6 */
2492
#if !(defined SLJIT_MIPS_REV)
2493
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2494
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2495
#endif /* !SLJIT_MIPS_REV */
2496
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2497
if (int_op)
2498
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2499
else
2500
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2501
#else /* !SLJIT_CONFIG_MIPS_64 */
2502
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2503
#endif /* SLJIT_CONFIG_MIPS_64 */
2504
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
2505
return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
2506
#endif /* SLJIT_MIPS_REV >= 6 */
2507
case SLJIT_MEMORY_BARRIER:
2508
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2509
return push_inst(compiler, SYNC, UNMOVABLE_INS);
2510
#else /* SLJIT_MIPS_REV < 1 */
2511
return SLJIT_ERR_UNSUPPORTED;
2512
#endif /* SLJIT_MIPS_REV >= 1 */
2513
case SLJIT_ENDBR:
2514
case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
2515
return SLJIT_SUCCESS;
2516
}
2517
2518
return SLJIT_SUCCESS;
2519
}
2520
2521
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2522
static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
2523
sljit_s32 src, sljit_sw srcw)
2524
{
2525
if (!(src & OFFS_REG_MASK)) {
2526
if (srcw <= SIMM_MAX && srcw >= SIMM_MIN)
2527
return push_inst(compiler, PREF | S(src & REG_MASK) | IMM(srcw), MOVABLE_INS);
2528
2529
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
2530
return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
2531
}
2532
2533
srcw &= 0x3;
2534
2535
if (SLJIT_UNLIKELY(srcw != 0)) {
2536
FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(src)) | D(TMP_REG1) | SH_IMM(srcw), DR(TMP_REG1)));
2537
return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
2538
}
2539
2540
return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);
2541
}
2542
#endif /* SLJIT_MIPS_REV >= 1 */
2543
2544
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
2545
sljit_s32 dst, sljit_sw dstw,
2546
sljit_s32 src, sljit_sw srcw)
2547
{
2548
sljit_s32 flags = 0;
2549
2550
CHECK_ERROR();
2551
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
2552
ADJUST_LOCAL_OFFSET(dst, dstw);
2553
ADJUST_LOCAL_OFFSET(src, srcw);
2554
2555
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2556
if (op & SLJIT_32)
2557
flags = INT_DATA | SIGNED_DATA;
2558
#endif
2559
2560
switch (GET_OPCODE(op)) {
2561
case SLJIT_MOV:
2562
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2563
case SLJIT_MOV_U32:
2564
case SLJIT_MOV_S32:
2565
case SLJIT_MOV32:
2566
#endif
2567
case SLJIT_MOV_P:
2568
return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
2569
2570
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2571
case SLJIT_MOV_U32:
2572
return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw);
2573
2574
case SLJIT_MOV_S32:
2575
case SLJIT_MOV32:
2576
return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw);
2577
#endif
2578
2579
case SLJIT_MOV_U8:
2580
return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw);
2581
2582
case SLJIT_MOV_S8:
2583
return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw);
2584
2585
case SLJIT_MOV_U16:
2586
return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw);
2587
2588
case SLJIT_MOV_S16:
2589
return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw);
2590
2591
case SLJIT_CLZ:
2592
case SLJIT_CTZ:
2593
case SLJIT_REV:
2594
return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
2595
2596
case SLJIT_REV_U16:
2597
case SLJIT_REV_S16:
2598
return emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
2599
2600
case SLJIT_REV_U32:
2601
case SLJIT_REV_S32:
2602
return emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
2603
}
2604
2605
SLJIT_UNREACHABLE();
2606
return SLJIT_SUCCESS;
2607
}
2608
2609
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
2610
sljit_s32 dst, sljit_sw dstw,
2611
sljit_s32 src1, sljit_sw src1w,
2612
sljit_s32 src2, sljit_sw src2w)
2613
{
2614
sljit_s32 flags = 0;
2615
2616
CHECK_ERROR();
2617
CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
2618
ADJUST_LOCAL_OFFSET(dst, dstw);
2619
ADJUST_LOCAL_OFFSET(src1, src1w);
2620
ADJUST_LOCAL_OFFSET(src2, src2w);
2621
2622
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2623
if (op & SLJIT_32) {
2624
flags |= INT_DATA | SIGNED_DATA;
2625
if (src1 == SLJIT_IMM)
2626
src1w = (sljit_s32)src1w;
2627
if (src2 == SLJIT_IMM)
2628
src2w = (sljit_s32)src2w;
2629
}
2630
#endif
2631
2632
switch (GET_OPCODE(op)) {
2633
case SLJIT_ADD:
2634
case SLJIT_ADDC:
2635
compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
2636
return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2637
2638
case SLJIT_SUB:
2639
case SLJIT_SUBC:
2640
compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
2641
return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2642
2643
case SLJIT_MUL:
2644
compiler->status_flags_state = 0;
2645
return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
2646
2647
case SLJIT_XOR:
2648
if ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) {
2649
return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2650
}
2651
SLJIT_FALLTHROUGH
2652
case SLJIT_AND:
2653
case SLJIT_OR:
2654
return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2655
2656
case SLJIT_SHL:
2657
case SLJIT_MSHL:
2658
case SLJIT_LSHR:
2659
case SLJIT_MLSHR:
2660
case SLJIT_ASHR:
2661
case SLJIT_MASHR:
2662
case SLJIT_ROTL:
2663
case SLJIT_ROTR:
2664
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2665
if (src2 == SLJIT_IMM)
2666
src2w &= 0x1f;
2667
#else
2668
if (src2 == SLJIT_IMM) {
2669
if (op & SLJIT_32)
2670
src2w &= 0x1f;
2671
else
2672
src2w &= 0x3f;
2673
}
2674
#endif
2675
return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2676
}
2677
2678
SLJIT_UNREACHABLE();
2679
return SLJIT_SUCCESS;
2680
}
2681
2682
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
2683
sljit_s32 src1, sljit_sw src1w,
2684
sljit_s32 src2, sljit_sw src2w)
2685
{
2686
CHECK_ERROR();
2687
CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
2688
2689
SLJIT_SKIP_CHECKS(compiler);
2690
return sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w);
2691
}
2692
2693
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2694
#define SELECT_OP3(op, src2w, D, D32, W) (((op & SLJIT_32) ? (W) : ((src2w) < 32) ? (D) : (D32)) | (((sljit_ins)src2w & 0x1f) << 6))
2695
#else /* !SLJIT_CONFIG_MIPS_64 */
2696
#define SELECT_OP3(op, src2w, D, D32, W) ((W) | ((sljit_ins)(src2w) << 6))
2697
#endif /* SLJIT_CONFIG_MIPS_64 */
2698
2699
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
2700
sljit_s32 dst_reg,
2701
sljit_s32 src1, sljit_sw src1w,
2702
sljit_s32 src2, sljit_sw src2w)
2703
{
2704
CHECK_ERROR();
2705
CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
2706
2707
switch (GET_OPCODE(op)) {
2708
case SLJIT_MULADD:
2709
SLJIT_SKIP_CHECKS(compiler);
2710
FAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));
2711
return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst_reg) | T(TMP_REG2) | D(dst_reg), DR(dst_reg));
2712
}
2713
2714
return SLJIT_SUCCESS;
2715
}
2716
2717
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
2718
sljit_s32 dst_reg,
2719
sljit_s32 src1_reg,
2720
sljit_s32 src2_reg,
2721
sljit_s32 src3, sljit_sw src3w)
2722
{
2723
sljit_s32 is_left;
2724
sljit_ins ins1, ins2, ins3;
2725
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2726
sljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
2727
sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;
2728
#else /* !SLJIT_CONFIG_MIPS_64 */
2729
sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;
2730
sljit_sw bit_length = 32;
2731
#endif /* SLJIT_CONFIG_MIPS_64 */
2732
2733
CHECK_ERROR();
2734
CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));
2735
2736
is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);
2737
2738
if (src1_reg == src2_reg) {
2739
SLJIT_SKIP_CHECKS(compiler);
2740
return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w);
2741
}
2742
2743
ADJUST_LOCAL_OFFSET(src3, src3w);
2744
2745
if (src3 == SLJIT_IMM) {
2746
src3w &= bit_length - 1;
2747
2748
if (src3w == 0)
2749
return SLJIT_SUCCESS;
2750
2751
if (is_left) {
2752
ins1 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL);
2753
src3w = bit_length - src3w;
2754
ins2 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL);
2755
} else {
2756
ins1 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL);
2757
src3w = bit_length - src3w;
2758
ins2 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL);
2759
}
2760
2761
FAIL_IF(push_inst(compiler, ins1 | T(src1_reg) | D(dst_reg), DR(dst_reg)));
2762
FAIL_IF(push_inst(compiler, ins2 | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1)));
2763
return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg));
2764
}
2765
2766
if (src3 & SLJIT_MEM) {
2767
FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src3, src3w));
2768
src3 = TMP_REG2;
2769
} else if (dst_reg == src3) {
2770
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src3) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
2771
src3 = TMP_REG2;
2772
}
2773
2774
if (is_left) {
2775
ins1 = SELECT_OP(DSRL, SRL);
2776
ins2 = SELECT_OP(DSLLV, SLLV);
2777
ins3 = SELECT_OP(DSRLV, SRLV);
2778
} else {
2779
ins1 = SELECT_OP(DSLL, SLL);
2780
ins2 = SELECT_OP(DSRLV, SRLV);
2781
ins3 = SELECT_OP(DSLLV, SLLV);
2782
}
2783
2784
FAIL_IF(push_inst(compiler, ins2 | S(src3) | T(src1_reg) | D(dst_reg), DR(dst_reg)));
2785
2786
if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {
2787
FAIL_IF(push_inst(compiler, ins1 | T(src2_reg) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1)));
2788
FAIL_IF(push_inst(compiler, XORI | S(src3) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2)));
2789
src2_reg = TMP_REG1;
2790
} else
2791
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src3) | D(TMP_REG2), DR(TMP_REG2)));
2792
2793
FAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1)));
2794
return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg));
2795
}
2796
2797
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
2798
sljit_s32 dst, sljit_sw dstw,
2799
sljit_s32 src1, sljit_sw src1w,
2800
sljit_s32 src2, sljit_sw src2w,
2801
sljit_sw shift_arg)
2802
{
2803
sljit_s32 dst_r, tmp_r;
2804
2805
CHECK_ERROR();
2806
CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
2807
ADJUST_LOCAL_OFFSET(dst, dstw);
2808
ADJUST_LOCAL_OFFSET(src1, src1w);
2809
ADJUST_LOCAL_OFFSET(src2, src2w);
2810
2811
shift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);
2812
2813
if (src2 == SLJIT_IMM) {
2814
src2w = src2w << shift_arg;
2815
shift_arg = 0;
2816
}
2817
2818
if (shift_arg == 0) {
2819
SLJIT_SKIP_CHECKS(compiler);
2820
return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
2821
}
2822
2823
if (src2 & SLJIT_MEM) {
2824
FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
2825
src2 = TMP_REG2;
2826
}
2827
2828
if (src1 == SLJIT_IMM) {
2829
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
2830
src1 = TMP_REG1;
2831
} else if (src1 & SLJIT_MEM) {
2832
FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
2833
src1 = TMP_REG1;
2834
}
2835
2836
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
2837
tmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
2838
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2839
FAIL_IF(push_inst(compiler, (shift_arg >= 32 ? DSLL32 : DSLL) | T(src2) | D(tmp_r) | SH_IMM(shift_arg & 0x1f), DR(tmp_r)));
2840
#else /* !SLJIT_CONFIG_MIPS_64 */
2841
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(tmp_r) | SH_IMM(shift_arg), DR(tmp_r)));
2842
#endif /* SLJIT_CONFIG_MIPS_64 */
2843
FAIL_IF(push_inst(compiler, ADDU_W | S(src1) | T(tmp_r) | D(dst_r), DR(dst_r)));
2844
2845
if (dst & SLJIT_MEM)
2846
return emit_op_mem2(compiler, WORD_DATA, DR(dst_r), dst, dstw, 0, 0);
2847
return SLJIT_SUCCESS;
2848
}
2849
2850
#undef SELECT_OP3
2851
2852
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
2853
sljit_s32 src, sljit_sw srcw)
2854
{
2855
CHECK_ERROR();
2856
CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
2857
ADJUST_LOCAL_OFFSET(src, srcw);
2858
2859
switch (op) {
2860
case SLJIT_FAST_RETURN:
2861
if (FAST_IS_REG(src)) {
2862
if (DR(src) != RETURN_ADDR_REG)
2863
FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
2864
} else
2865
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
2866
2867
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
2868
return push_inst(compiler, NOP, UNMOVABLE_INS);
2869
case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
2870
return SLJIT_SUCCESS;
2871
case SLJIT_PREFETCH_L1:
2872
case SLJIT_PREFETCH_L2:
2873
case SLJIT_PREFETCH_L3:
2874
case SLJIT_PREFETCH_ONCE:
2875
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2876
return emit_prefetch(compiler, src, srcw);
2877
#else /* SLJIT_MIPS_REV < 1 */
2878
return SLJIT_SUCCESS;
2879
#endif /* SLJIT_MIPS_REV >= 1 */
2880
}
2881
2882
return SLJIT_SUCCESS;
2883
}
2884
2885
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,
2886
sljit_s32 dst, sljit_sw dstw)
2887
{
2888
sljit_s32 dst_ar = RETURN_ADDR_REG;
2889
2890
CHECK_ERROR();
2891
CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));
2892
ADJUST_LOCAL_OFFSET(dst, dstw);
2893
2894
switch (op) {
2895
case SLJIT_FAST_ENTER:
2896
if (FAST_IS_REG(dst)) {
2897
if (DR(dst) == RETURN_ADDR_REG)
2898
return SLJIT_SUCCESS;
2899
return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);
2900
}
2901
break;
2902
case SLJIT_GET_RETURN_ADDRESS:
2903
dst_ar = DR(FAST_IS_REG(dst) ? dst : TMP_REG2);
2904
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_ar, SLJIT_MEM1(SLJIT_SP), compiler->local_size - SSIZE_OF(sw)));
2905
break;
2906
}
2907
2908
if (dst & SLJIT_MEM) {
2909
FAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw));
2910
2911
if (op == SLJIT_FAST_ENTER)
2912
compiler->delay_slot = UNMOVABLE_INS;
2913
}
2914
2915
return SLJIT_SUCCESS;
2916
}
2917
2918
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)
2919
{
2920
CHECK_REG_INDEX(check_sljit_get_register_index(type, reg));
2921
2922
if (type == SLJIT_GP_REGISTER)
2923
return reg_map[reg];
2924
2925
if (type != SLJIT_FLOAT_REGISTER)
2926
return -1;
2927
2928
return FR(reg);
2929
}
2930
2931
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
2932
void *instruction, sljit_u32 size)
2933
{
2934
SLJIT_UNUSED_ARG(size);
2935
2936
CHECK_ERROR();
2937
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
2938
2939
return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
2940
}
2941
2942
/* --------------------------------------------------------------------- */
2943
/* Floating point operators */
2944
/* --------------------------------------------------------------------- */
2945
2946
#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))
2947
#define FMT(op) (FMT_S | (~(sljit_ins)op & SLJIT_32) << (21 - (5 + 3)))
2948
2949
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
2950
sljit_s32 dst, sljit_sw dstw,
2951
sljit_s32 src, sljit_sw srcw)
2952
{
2953
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2954
sljit_u32 flags = 0;
2955
#else
2956
sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21;
2957
#endif
2958
2959
if (src & SLJIT_MEM) {
2960
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
2961
src = TMP_FREG1;
2962
}
2963
2964
FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));
2965
2966
if (FAST_IS_REG(dst)) {
2967
FAIL_IF(push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS));
2968
#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)
2969
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2970
#endif /* MIPS III */
2971
return SLJIT_SUCCESS;
2972
}
2973
2974
return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0);
2975
}
2976
2977
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
2978
sljit_s32 dst, sljit_sw dstw,
2979
sljit_s32 src, sljit_sw srcw)
2980
{
2981
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2982
sljit_u32 flags = 0;
2983
#else
2984
sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21;
2985
#endif
2986
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
2987
2988
if (src & SLJIT_MEM)
2989
FAIL_IF(emit_op_mem2(compiler, (flags ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
2990
else {
2991
if (src == SLJIT_IMM) {
2992
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2993
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
2994
srcw = (sljit_s32)srcw;
2995
#endif
2996
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
2997
src = TMP_REG1;
2998
}
2999
3000
FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
3001
#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)
3002
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3003
#endif /* MIPS III */
3004
}
3005
3006
FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
3007
3008
if (dst & SLJIT_MEM)
3009
return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
3010
return SLJIT_SUCCESS;
3011
}
3012
3013
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,
3014
sljit_s32 dst, sljit_sw dstw,
3015
sljit_s32 src, sljit_sw srcw)
3016
{
3017
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3018
sljit_u32 flags = 0;
3019
#else
3020
sljit_u32 flags = 1 << 21;
3021
#endif
3022
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
3023
3024
if (src & SLJIT_MEM) {
3025
FAIL_IF(emit_op_mem2(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW ? WORD_DATA : INT_DATA) | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw));
3026
src = TMP_REG1;
3027
} else if (src == SLJIT_IMM) {
3028
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3029
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32)
3030
srcw = (sljit_u32)srcw;
3031
#endif
3032
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
3033
src = TMP_REG1;
3034
}
3035
3036
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3037
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) {
3038
if (src != TMP_REG1) {
3039
FAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));
3040
FAIL_IF(push_inst(compiler, DSRL32 | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));
3041
}
3042
3043
FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));
3044
#if !defined(SLJIT_MIPS_REV)
3045
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3046
#endif /* MIPS III */
3047
3048
FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
3049
3050
if (dst & SLJIT_MEM)
3051
return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
3052
return SLJIT_SUCCESS;
3053
}
3054
#else /* !SLJIT_CONFIG_MIPS_64 */
3055
if (!(op & SLJIT_32)) {
3056
FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2)));
3057
FAIL_IF(push_inst(compiler, SRL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2)));
3058
3059
FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG2) | FS(TMP_FREG1), MOVABLE_INS));
3060
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
3061
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3062
#endif /* MIPS III */
3063
3064
FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | 1 | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
3065
3066
#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1)
3067
FAIL_IF(push_inst(compiler, BGEZ | S(src) | 5, UNMOVABLE_INS));
3068
#else /* SLJIT_MIPS_REV >= 1 */
3069
FAIL_IF(push_inst(compiler, BGEZ | S(src) | 4, UNMOVABLE_INS));
3070
#endif /* SLJIT_MIPS_REV < 1 */
3071
3072
FAIL_IF(push_inst(compiler, LUI | T(TMP_REG2) | IMM(0x41e0), UNMOVABLE_INS));
3073
FAIL_IF(push_inst(compiler, MTC1 | TA(0) | FS(TMP_FREG2), UNMOVABLE_INS));
3074
switch (cpu_feature_list & CPU_FEATURE_FR) {
3075
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
3076
case CPU_FEATURE_FR:
3077
FAIL_IF(push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(TMP_FREG2), UNMOVABLE_INS));
3078
break;
3079
#endif /* SLJIT_MIPS_REV >= 2 */
3080
default:
3081
FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(TMP_FREG2) | (1 << 11), UNMOVABLE_INS));
3082
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
3083
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3084
#endif /* MIPS III */
3085
break;
3086
}
3087
FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(TMP_FREG2) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS));
3088
3089
if (dst & SLJIT_MEM)
3090
return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
3091
return SLJIT_SUCCESS;
3092
}
3093
#endif /* SLJIT_CONFIG_MIPS_64 */
3094
3095
#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1)
3096
FAIL_IF(push_inst(compiler, BLTZ | S(src) | 5, UNMOVABLE_INS));
3097
#else /* SLJIT_MIPS_REV >= 1 */
3098
FAIL_IF(push_inst(compiler, BLTZ | S(src) | 4, UNMOVABLE_INS));
3099
#endif /* SLJIT_MIPS_REV < 1 */
3100
FAIL_IF(push_inst(compiler, ANDI | S(src) | T(TMP_REG2) | IMM(1), DR(TMP_REG2)));
3101
3102
FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
3103
#if !defined(SLJIT_MIPS_REV)
3104
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3105
#endif /* !SLJIT_MIPS_REV */
3106
3107
FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
3108
3109
#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1)
3110
FAIL_IF(push_inst(compiler, BEQ | 6, UNMOVABLE_INS));
3111
#else /* SLJIT_MIPS_REV >= 1 */
3112
FAIL_IF(push_inst(compiler, BEQ | 5, UNMOVABLE_INS));
3113
#endif /* SLJIT_MIPS_REV < 1 */
3114
3115
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3116
FAIL_IF(push_inst(compiler, DSRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
3117
#else /* !SLJIT_CONFIG_MIPS_64 */
3118
FAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
3119
#endif /* SLJIT_CONFIG_MIPS_64 */
3120
3121
FAIL_IF(push_inst(compiler, OR | S(TMP_REG1) | T(TMP_REG2) | D(TMP_REG1), DR(TMP_REG1)));
3122
3123
FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));
3124
#if !defined(SLJIT_MIPS_REV)
3125
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3126
#endif /* !SLJIT_MIPS_REV */
3127
3128
FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
3129
FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(dst_r) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS));
3130
3131
if (dst & SLJIT_MEM)
3132
return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
3133
return SLJIT_SUCCESS;
3134
}
3135
3136
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
3137
sljit_s32 src1, sljit_sw src1w,
3138
sljit_s32 src2, sljit_sw src2w)
3139
{
3140
sljit_ins inst;
3141
3142
if (src1 & SLJIT_MEM) {
3143
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
3144
src1 = TMP_FREG1;
3145
}
3146
3147
if (src2 & SLJIT_MEM) {
3148
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, 0, 0));
3149
src2 = TMP_FREG2;
3150
}
3151
3152
switch (GET_FLAG_TYPE(op)) {
3153
case SLJIT_F_EQUAL:
3154
case SLJIT_ORDERED_EQUAL:
3155
inst = C_EQ_S;
3156
break;
3157
case SLJIT_F_NOT_EQUAL:
3158
case SLJIT_UNORDERED_OR_EQUAL:
3159
inst = C_UEQ_S;
3160
break;
3161
case SLJIT_F_LESS:
3162
case SLJIT_ORDERED_LESS:
3163
inst = C_OLT_S;
3164
break;
3165
case SLJIT_F_GREATER_EQUAL:
3166
case SLJIT_UNORDERED_OR_LESS:
3167
inst = C_ULT_S;
3168
break;
3169
case SLJIT_F_GREATER:
3170
case SLJIT_ORDERED_GREATER:
3171
inst = C_ULE_S;
3172
break;
3173
case SLJIT_F_LESS_EQUAL:
3174
case SLJIT_UNORDERED_OR_GREATER:
3175
inst = C_OLE_S;
3176
break;
3177
default:
3178
SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED);
3179
inst = C_UN_S;
3180
break;
3181
}
3182
return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS);
3183
}
3184
3185
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
3186
sljit_s32 dst, sljit_sw dstw,
3187
sljit_s32 src, sljit_sw srcw)
3188
{
3189
sljit_s32 dst_r;
3190
3191
CHECK_ERROR();
3192
compiler->cache_arg = 0;
3193
compiler->cache_argw = 0;
3194
3195
SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
3196
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
3197
3198
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
3199
op ^= SLJIT_32;
3200
3201
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
3202
3203
if (src & SLJIT_MEM) {
3204
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(dst_r), src, srcw, dst, dstw));
3205
src = dst_r;
3206
}
3207
3208
switch (GET_OPCODE(op)) {
3209
case SLJIT_MOV_F64:
3210
if (src != dst_r) {
3211
if (!(dst & SLJIT_MEM))
3212
FAIL_IF(push_inst(compiler, MOV_fmt(FMT(op)) | FS(src) | FD(dst_r), MOVABLE_INS));
3213
else
3214
dst_r = src;
3215
}
3216
break;
3217
case SLJIT_NEG_F64:
3218
FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
3219
break;
3220
case SLJIT_ABS_F64:
3221
FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
3222
break;
3223
case SLJIT_CONV_F64_FROM_F32:
3224
/* The SLJIT_32 bit is inverted because sljit_f32 needs to be loaded from the memory. */
3225
FAIL_IF(push_inst(compiler, CVT_S_S | (sljit_ins)((op & SLJIT_32) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));
3226
op ^= SLJIT_32;
3227
break;
3228
}
3229
3230
if (dst & SLJIT_MEM)
3231
return emit_op_mem2(compiler, FLOAT_DATA(op), FR(dst_r), dst, dstw, 0, 0);
3232
return SLJIT_SUCCESS;
3233
}
3234
3235
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
3236
sljit_s32 dst, sljit_sw dstw,
3237
sljit_s32 src1, sljit_sw src1w,
3238
sljit_s32 src2, sljit_sw src2w)
3239
{
3240
sljit_s32 dst_r, flags = 0;
3241
3242
CHECK_ERROR();
3243
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
3244
ADJUST_LOCAL_OFFSET(dst, dstw);
3245
ADJUST_LOCAL_OFFSET(src1, src1w);
3246
ADJUST_LOCAL_OFFSET(src2, src2w);
3247
3248
compiler->cache_arg = 0;
3249
compiler->cache_argw = 0;
3250
3251
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
3252
3253
if (src1 & SLJIT_MEM) {
3254
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)) {
3255
FAIL_IF(compiler->error);
3256
src1 = TMP_FREG1;
3257
} else
3258
flags |= SLOW_SRC1;
3259
}
3260
3261
if (src2 & SLJIT_MEM) {
3262
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w)) {
3263
FAIL_IF(compiler->error);
3264
src2 = TMP_FREG2;
3265
} else
3266
flags |= SLOW_SRC2;
3267
}
3268
3269
if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
3270
if ((dst & SLJIT_MEM) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
3271
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, src1, src1w));
3272
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
3273
} else {
3274
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
3275
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
3276
}
3277
}
3278
else if (flags & SLOW_SRC1)
3279
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
3280
else if (flags & SLOW_SRC2)
3281
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
3282
3283
if (flags & SLOW_SRC1)
3284
src1 = TMP_FREG1;
3285
if (flags & SLOW_SRC2)
3286
src2 = TMP_FREG2;
3287
3288
switch (GET_OPCODE(op)) {
3289
case SLJIT_ADD_F64:
3290
FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3291
break;
3292
case SLJIT_SUB_F64:
3293
FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3294
break;
3295
case SLJIT_MUL_F64:
3296
FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3297
break;
3298
case SLJIT_DIV_F64:
3299
FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3300
break;
3301
case SLJIT_COPYSIGN_F64:
3302
return emit_copysign(compiler, op, src1, src2, dst_r);
3303
}
3304
3305
if (dst_r == TMP_FREG2)
3306
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));
3307
3308
return SLJIT_SUCCESS;
3309
}
3310
3311
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,
3312
sljit_s32 freg, sljit_f32 value)
3313
{
3314
union {
3315
sljit_s32 imm;
3316
sljit_f32 value;
3317
} u;
3318
3319
CHECK_ERROR();
3320
CHECK(check_sljit_emit_fset32(compiler, freg, value));
3321
3322
u.value = value;
3323
3324
if (u.imm == 0)
3325
return push_inst(compiler, MTC1 | TA(0) | FS(freg), MOVABLE_INS);
3326
3327
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm));
3328
return push_inst(compiler, MTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS);
3329
}
3330
3331
/* --------------------------------------------------------------------- */
3332
/* Conditional instructions */
3333
/* --------------------------------------------------------------------- */
3334
3335
SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
3336
{
3337
struct sljit_label *label;
3338
3339
CHECK_ERROR_PTR();
3340
CHECK_PTR(check_sljit_emit_label(compiler));
3341
3342
if (compiler->last_label && compiler->last_label->size == compiler->size)
3343
return compiler->last_label;
3344
3345
label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
3346
PTR_FAIL_IF(!label);
3347
set_label(label, compiler);
3348
compiler->delay_slot = UNMOVABLE_INS;
3349
return label;
3350
}
3351
3352
SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
3353
sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
3354
{
3355
sljit_uw mask, i;
3356
struct sljit_label *label;
3357
struct sljit_label *next_label;
3358
struct sljit_extended_label *ext_label;
3359
3360
CHECK_ERROR_PTR();
3361
CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
3362
3363
sljit_reset_read_only_buffers(buffers);
3364
3365
if (alignment <= SLJIT_LABEL_ALIGN_4) {
3366
SLJIT_SKIP_CHECKS(compiler);
3367
label = sljit_emit_label(compiler);
3368
PTR_FAIL_IF(!label);
3369
} else {
3370
/* The used space is filled with NOPs. */
3371
mask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);
3372
3373
for (i = (mask >> 2); i != 0; i--)
3374
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3375
3376
ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
3377
PTR_FAIL_IF(!ext_label);
3378
set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
3379
label = &ext_label->label;
3380
}
3381
3382
if (buffers == NULL)
3383
return label;
3384
3385
next_label = label;
3386
3387
while (1) {
3388
buffers->u.label = next_label;
3389
3390
for (i = (buffers->size + 3) >> 2; i > 0; i--)
3391
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3392
3393
buffers = buffers->next;
3394
3395
if (buffers == NULL)
3396
break;
3397
3398
SLJIT_SKIP_CHECKS(compiler);
3399
next_label = sljit_emit_label(compiler);
3400
PTR_FAIL_IF(!next_label);
3401
}
3402
3403
return label;
3404
}
3405
3406
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3407
#define BRANCH_LENGTH 4
3408
#else
3409
#define BRANCH_LENGTH 8
3410
#endif
3411
3412
#define BR_Z(src) \
3413
inst = BEQ | SA(src) | TA(0) | BRANCH_LENGTH; \
3414
flags = IS_BIT26_COND; \
3415
delay_check = src;
3416
3417
#define BR_NZ(src) \
3418
inst = BNE | SA(src) | TA(0) | BRANCH_LENGTH; \
3419
flags = IS_BIT26_COND; \
3420
delay_check = src;
3421
3422
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3423
3424
#define BR_T() \
3425
inst = BC1NEZ; \
3426
flags = IS_BIT23_COND; \
3427
delay_check = FCSR_FCC;
3428
#define BR_F() \
3429
inst = BC1EQZ; \
3430
flags = IS_BIT23_COND; \
3431
delay_check = FCSR_FCC;
3432
3433
#else /* SLJIT_MIPS_REV < 6 */
3434
3435
#define BR_T() \
3436
inst = BC1T | BRANCH_LENGTH; \
3437
flags = IS_BIT16_COND; \
3438
delay_check = FCSR_FCC;
3439
#define BR_F() \
3440
inst = BC1F | BRANCH_LENGTH; \
3441
flags = IS_BIT16_COND; \
3442
delay_check = FCSR_FCC;
3443
3444
#endif /* SLJIT_MIPS_REV >= 6 */
3445
3446
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
3447
{
3448
struct sljit_jump *jump;
3449
sljit_ins inst;
3450
sljit_u32 flags = 0;
3451
sljit_s32 delay_check = UNMOVABLE_INS;
3452
3453
CHECK_ERROR_PTR();
3454
CHECK_PTR(check_sljit_emit_jump(compiler, type));
3455
3456
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
3457
PTR_FAIL_IF(!jump);
3458
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
3459
type &= 0xff;
3460
3461
switch (type) {
3462
case SLJIT_EQUAL:
3463
BR_NZ(EQUAL_FLAG);
3464
break;
3465
case SLJIT_NOT_EQUAL:
3466
BR_Z(EQUAL_FLAG);
3467
break;
3468
case SLJIT_LESS:
3469
case SLJIT_GREATER:
3470
case SLJIT_SIG_LESS:
3471
case SLJIT_SIG_GREATER:
3472
case SLJIT_OVERFLOW:
3473
case SLJIT_CARRY:
3474
case SLJIT_ATOMIC_STORED:
3475
BR_Z(OTHER_FLAG);
3476
break;
3477
case SLJIT_GREATER_EQUAL:
3478
case SLJIT_LESS_EQUAL:
3479
case SLJIT_SIG_GREATER_EQUAL:
3480
case SLJIT_SIG_LESS_EQUAL:
3481
case SLJIT_NOT_OVERFLOW:
3482
case SLJIT_NOT_CARRY:
3483
case SLJIT_ATOMIC_NOT_STORED:
3484
BR_NZ(OTHER_FLAG);
3485
break;
3486
case SLJIT_F_NOT_EQUAL:
3487
case SLJIT_F_GREATER_EQUAL:
3488
case SLJIT_F_GREATER:
3489
case SLJIT_UNORDERED_OR_NOT_EQUAL:
3490
case SLJIT_ORDERED_NOT_EQUAL:
3491
case SLJIT_UNORDERED_OR_GREATER_EQUAL:
3492
case SLJIT_ORDERED_GREATER_EQUAL:
3493
case SLJIT_ORDERED_GREATER:
3494
case SLJIT_UNORDERED_OR_GREATER:
3495
case SLJIT_ORDERED:
3496
BR_T();
3497
break;
3498
case SLJIT_F_EQUAL:
3499
case SLJIT_F_LESS:
3500
case SLJIT_F_LESS_EQUAL:
3501
case SLJIT_ORDERED_EQUAL:
3502
case SLJIT_UNORDERED_OR_EQUAL:
3503
case SLJIT_ORDERED_LESS:
3504
case SLJIT_UNORDERED_OR_LESS:
3505
case SLJIT_UNORDERED_OR_LESS_EQUAL:
3506
case SLJIT_ORDERED_LESS_EQUAL:
3507
case SLJIT_UNORDERED:
3508
BR_F();
3509
break;
3510
default:
3511
/* Not conditional branch. */
3512
inst = 0;
3513
break;
3514
}
3515
3516
jump->flags |= flags;
3517
if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))
3518
jump->flags |= IS_MOVABLE;
3519
3520
if (inst)
3521
PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
3522
3523
if (type <= SLJIT_JUMP)
3524
PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
3525
else {
3526
jump->flags |= IS_JAL;
3527
PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
3528
}
3529
3530
jump->addr = compiler->size;
3531
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3532
3533
/* Maximum number of instructions required for generating a constant. */
3534
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3535
compiler->size += 2;
3536
#else
3537
compiler->size += 6;
3538
#endif
3539
return jump;
3540
}
3541
3542
#define RESOLVE_IMM1() \
3543
if (src1 == SLJIT_IMM) { \
3544
if (src1w) { \
3545
PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
3546
src1 = TMP_REG1; \
3547
} \
3548
else \
3549
src1 = 0; \
3550
}
3551
3552
#define RESOLVE_IMM2() \
3553
if (src2 == SLJIT_IMM) { \
3554
if (src2w) { \
3555
PTR_FAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w)); \
3556
src2 = src2_tmp_reg; \
3557
} \
3558
else \
3559
src2 = 0; \
3560
}
3561
3562
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
3563
sljit_s32 src1, sljit_sw src1w,
3564
sljit_s32 src2, sljit_sw src2w)
3565
{
3566
struct sljit_jump *jump;
3567
sljit_s32 flags;
3568
sljit_ins inst;
3569
sljit_s32 src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;
3570
3571
CHECK_ERROR_PTR();
3572
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
3573
ADJUST_LOCAL_OFFSET(src1, src1w);
3574
ADJUST_LOCAL_OFFSET(src2, src2w);
3575
3576
compiler->cache_arg = 0;
3577
compiler->cache_argw = 0;
3578
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3579
flags = WORD_DATA | LOAD_DATA;
3580
#else /* !SLJIT_CONFIG_MIPS_32 */
3581
flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
3582
#endif /* SLJIT_CONFIG_MIPS_32 */
3583
3584
if (src1 & SLJIT_MEM) {
3585
PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));
3586
src1 = TMP_REG1;
3587
}
3588
3589
if (src2 & SLJIT_MEM) {
3590
PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(src2_tmp_reg), src2, src2w, 0, 0));
3591
src2 = src2_tmp_reg;
3592
}
3593
3594
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
3595
PTR_FAIL_IF(!jump);
3596
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
3597
type &= 0xff;
3598
3599
if (type <= SLJIT_NOT_EQUAL) {
3600
RESOLVE_IMM1();
3601
RESOLVE_IMM2();
3602
jump->flags |= IS_BIT26_COND;
3603
if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))
3604
jump->flags |= IS_MOVABLE;
3605
PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | BRANCH_LENGTH, UNMOVABLE_INS));
3606
} else if (type >= SLJIT_SIG_LESS && ((src1 == SLJIT_IMM && src1w == 0) || (src2 == SLJIT_IMM && src2w == 0))) {
3607
inst = NOP;
3608
if (src1 == SLJIT_IMM && src1w == 0) {
3609
RESOLVE_IMM2();
3610
switch (type) {
3611
case SLJIT_SIG_LESS:
3612
inst = BLEZ;
3613
jump->flags |= IS_BIT26_COND;
3614
break;
3615
case SLJIT_SIG_GREATER_EQUAL:
3616
inst = BGTZ;
3617
jump->flags |= IS_BIT26_COND;
3618
break;
3619
case SLJIT_SIG_GREATER:
3620
inst = BGEZ;
3621
jump->flags |= IS_BIT16_COND;
3622
break;
3623
case SLJIT_SIG_LESS_EQUAL:
3624
inst = BLTZ;
3625
jump->flags |= IS_BIT16_COND;
3626
break;
3627
}
3628
src1 = src2;
3629
}
3630
else {
3631
RESOLVE_IMM1();
3632
switch (type) {
3633
case SLJIT_SIG_LESS:
3634
inst = BGEZ;
3635
jump->flags |= IS_BIT16_COND;
3636
break;
3637
case SLJIT_SIG_GREATER_EQUAL:
3638
inst = BLTZ;
3639
jump->flags |= IS_BIT16_COND;
3640
break;
3641
case SLJIT_SIG_GREATER:
3642
inst = BLEZ;
3643
jump->flags |= IS_BIT26_COND;
3644
break;
3645
case SLJIT_SIG_LESS_EQUAL:
3646
inst = BGTZ;
3647
jump->flags |= IS_BIT26_COND;
3648
break;
3649
}
3650
}
3651
PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | BRANCH_LENGTH, UNMOVABLE_INS));
3652
}
3653
else {
3654
if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) {
3655
RESOLVE_IMM1();
3656
if (src2 == SLJIT_IMM && src2w <= SIMM_MAX && src2w >= SIMM_MIN)
3657
PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));
3658
else {
3659
RESOLVE_IMM2();
3660
PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
3661
}
3662
type = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
3663
}
3664
else {
3665
RESOLVE_IMM2();
3666
if (src1 == SLJIT_IMM && src1w <= SIMM_MAX && src1w >= SIMM_MIN)
3667
PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));
3668
else {
3669
RESOLVE_IMM1();
3670
PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
3671
}
3672
type = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
3673
}
3674
3675
jump->flags |= IS_BIT26_COND;
3676
PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | BRANCH_LENGTH, UNMOVABLE_INS));
3677
}
3678
3679
PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
3680
jump->addr = compiler->size;
3681
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3682
3683
/* Maximum number of instructions required for generating a constant. */
3684
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3685
compiler->size += 2;
3686
#else
3687
compiler->size += 6;
3688
#endif
3689
return jump;
3690
}
3691
3692
#undef RESOLVE_IMM1
3693
#undef RESOLVE_IMM2
3694
3695
#undef BRANCH_LENGTH
3696
#undef BR_Z
3697
#undef BR_NZ
3698
#undef BR_T
3699
#undef BR_F
3700
3701
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
3702
{
3703
struct sljit_jump *jump = NULL;
3704
3705
CHECK_ERROR();
3706
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
3707
3708
if (src == SLJIT_IMM) {
3709
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
3710
FAIL_IF(!jump);
3711
set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
3712
jump->u.target = (sljit_uw)srcw;
3713
3714
if (compiler->delay_slot != UNMOVABLE_INS)
3715
jump->flags |= IS_MOVABLE;
3716
3717
src = PIC_ADDR_REG;
3718
} else if (src & SLJIT_MEM) {
3719
ADJUST_LOCAL_OFFSET(src, srcw);
3720
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
3721
src = PIC_ADDR_REG;
3722
}
3723
3724
if (type <= SLJIT_JUMP)
3725
FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
3726
else
3727
FAIL_IF(push_inst(compiler, JALR | S(src) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
3728
3729
if (jump != NULL) {
3730
jump->addr = compiler->size;
3731
3732
/* Maximum number of instructions required for generating a constant. */
3733
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3734
compiler->size += 2;
3735
#else
3736
compiler->size += 6;
3737
#endif
3738
}
3739
3740
return push_inst(compiler, NOP, UNMOVABLE_INS);
3741
}
3742
3743
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
3744
sljit_s32 dst, sljit_sw dstw,
3745
sljit_s32 type)
3746
{
3747
sljit_s32 src_ar, dst_ar, invert;
3748
sljit_s32 saved_op = op;
3749
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3750
sljit_s32 mem_type = WORD_DATA;
3751
#else
3752
sljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
3753
#endif
3754
3755
CHECK_ERROR();
3756
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
3757
ADJUST_LOCAL_OFFSET(dst, dstw);
3758
3759
op = GET_OPCODE(op);
3760
dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);
3761
3762
compiler->cache_arg = 0;
3763
compiler->cache_argw = 0;
3764
3765
if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
3766
FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), dst, dstw, dst, dstw));
3767
3768
if (type < SLJIT_F_EQUAL) {
3769
src_ar = OTHER_FLAG;
3770
invert = type & 0x1;
3771
3772
switch (type) {
3773
case SLJIT_EQUAL:
3774
case SLJIT_NOT_EQUAL:
3775
FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
3776
src_ar = dst_ar;
3777
break;
3778
case SLJIT_OVERFLOW:
3779
case SLJIT_NOT_OVERFLOW:
3780
if (compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) {
3781
src_ar = OTHER_FLAG;
3782
break;
3783
}
3784
FAIL_IF(push_inst(compiler, SLTIU | SA(OTHER_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
3785
src_ar = dst_ar;
3786
invert ^= 0x1;
3787
break;
3788
}
3789
} else {
3790
invert = 0;
3791
3792
switch (type) {
3793
case SLJIT_F_NOT_EQUAL:
3794
case SLJIT_F_GREATER_EQUAL:
3795
case SLJIT_F_GREATER:
3796
case SLJIT_UNORDERED_OR_NOT_EQUAL:
3797
case SLJIT_ORDERED_NOT_EQUAL:
3798
case SLJIT_UNORDERED_OR_GREATER_EQUAL:
3799
case SLJIT_ORDERED_GREATER_EQUAL:
3800
case SLJIT_ORDERED_GREATER:
3801
case SLJIT_UNORDERED_OR_GREATER:
3802
case SLJIT_ORDERED:
3803
invert = 1;
3804
break;
3805
}
3806
3807
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3808
FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));
3809
#else /* SLJIT_MIPS_REV < 6 */
3810
FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
3811
#endif /* SLJIT_MIPS_REV >= 6 */
3812
FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
3813
FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
3814
src_ar = dst_ar;
3815
}
3816
3817
if (invert) {
3818
FAIL_IF(push_inst(compiler, XORI | SA(src_ar) | TA(dst_ar) | IMM(1), dst_ar));
3819
src_ar = dst_ar;
3820
}
3821
3822
if (op < SLJIT_ADD) {
3823
if (dst & SLJIT_MEM)
3824
return emit_op_mem(compiler, mem_type, src_ar, dst, dstw);
3825
3826
if (src_ar != dst_ar)
3827
return push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | DA(dst_ar), dst_ar);
3828
return SLJIT_SUCCESS;
3829
}
3830
3831
/* OTHER_FLAG cannot be specified as src2 argument at the moment. */
3832
if (DR(TMP_REG2) != src_ar)
3833
FAIL_IF(push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
3834
3835
mem_type |= CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE;
3836
3837
if (dst & SLJIT_MEM)
3838
return emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
3839
return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, TMP_REG2, 0);
3840
}
3841
3842
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3843
3844
static sljit_ins get_select_cc(sljit_s32 type, sljit_s32 is_float)
3845
{
3846
switch (type) {
3847
case SLJIT_EQUAL:
3848
return (is_float ? MOVZ_S : MOVZ) | TA(EQUAL_FLAG);
3849
case SLJIT_NOT_EQUAL:
3850
return (is_float ? MOVN_S : MOVN) | TA(EQUAL_FLAG);
3851
case SLJIT_LESS:
3852
case SLJIT_GREATER:
3853
case SLJIT_SIG_LESS:
3854
case SLJIT_SIG_GREATER:
3855
case SLJIT_OVERFLOW:
3856
case SLJIT_CARRY:
3857
return (is_float ? MOVN_S : MOVN) | TA(OTHER_FLAG);
3858
case SLJIT_GREATER_EQUAL:
3859
case SLJIT_LESS_EQUAL:
3860
case SLJIT_SIG_GREATER_EQUAL:
3861
case SLJIT_SIG_LESS_EQUAL:
3862
case SLJIT_NOT_OVERFLOW:
3863
case SLJIT_NOT_CARRY:
3864
return (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG);
3865
case SLJIT_F_EQUAL:
3866
case SLJIT_F_LESS:
3867
case SLJIT_F_LESS_EQUAL:
3868
case SLJIT_ORDERED_EQUAL:
3869
case SLJIT_UNORDERED_OR_EQUAL:
3870
case SLJIT_ORDERED_LESS:
3871
case SLJIT_UNORDERED_OR_LESS:
3872
case SLJIT_UNORDERED_OR_LESS_EQUAL:
3873
case SLJIT_ORDERED_LESS_EQUAL:
3874
case SLJIT_UNORDERED:
3875
return is_float ? MOVT_S : MOVT;
3876
case SLJIT_F_NOT_EQUAL:
3877
case SLJIT_F_GREATER_EQUAL:
3878
case SLJIT_F_GREATER:
3879
case SLJIT_UNORDERED_OR_NOT_EQUAL:
3880
case SLJIT_ORDERED_NOT_EQUAL:
3881
case SLJIT_UNORDERED_OR_GREATER_EQUAL:
3882
case SLJIT_ORDERED_GREATER_EQUAL:
3883
case SLJIT_ORDERED_GREATER:
3884
case SLJIT_UNORDERED_OR_GREATER:
3885
case SLJIT_ORDERED:
3886
return is_float ? MOVF_S : MOVF;
3887
default:
3888
SLJIT_UNREACHABLE();
3889
return (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG);
3890
}
3891
}
3892
3893
#endif /* SLJIT_MIPS_REV >= 1 */
3894
3895
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,
3896
sljit_s32 dst_reg,
3897
sljit_s32 src1, sljit_sw src1w,
3898
sljit_s32 src2_reg)
3899
{
3900
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3901
sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
3902
sljit_ins mov_ins = (type & SLJIT_32) ? ADDU : DADDU;
3903
#else /* !SLJIT_CONFIG_MIPS_64 */
3904
sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;
3905
sljit_ins mov_ins = ADDU;
3906
#endif /* SLJIT_CONFIG_MIPS_64 */
3907
3908
#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3909
struct sljit_label *label;
3910
struct sljit_jump *jump;
3911
#endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */
3912
3913
CHECK_ERROR();
3914
CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));
3915
ADJUST_LOCAL_OFFSET(src1, src1w);
3916
3917
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3918
if (src1 == SLJIT_IMM && (type & SLJIT_32))
3919
src1w = (sljit_s32)src1w;
3920
#endif
3921
3922
type &= ~SLJIT_32;
3923
3924
if (type & SLJIT_COMPARE_SELECT) {
3925
type ^= SLJIT_COMPARE_SELECT;
3926
3927
if (src1 & SLJIT_MEM) {
3928
FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));
3929
src1 = TMP_REG1;
3930
} else if (src1 == SLJIT_IMM) {
3931
if (src1w == 0) {
3932
src1 = 0;
3933
} else {
3934
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
3935
src1 = TMP_REG1;
3936
}
3937
}
3938
3939
src1w = 0;
3940
FAIL_IF(emit_op(compiler, SLJIT_SUB | SLJIT_SET(type & ~0x1), IMM_OP, 0, 0, src1, 0, src2_reg, 0));
3941
}
3942
3943
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3944
if (src1 & SLJIT_MEM) {
3945
FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));
3946
src1 = TMP_REG1;
3947
} else if (src1 == SLJIT_IMM) {
3948
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
3949
src1 = TMP_REG1;
3950
}
3951
3952
if (dst_reg != src2_reg) {
3953
if (dst_reg == src1) {
3954
src1 = src2_reg;
3955
type ^= 0x1;
3956
} else
3957
FAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg)));
3958
}
3959
3960
return push_inst(compiler, get_select_cc(type, 0) | S(src1) | D(dst_reg), DR(dst_reg));
3961
3962
#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
3963
if (dst_reg != src2_reg) {
3964
if (dst_reg == src1) {
3965
src1 = src2_reg;
3966
src1w = 0;
3967
type ^= 0x1;
3968
} else {
3969
if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
3970
FAIL_IF(push_inst(compiler, ADDU_W | S(dst_reg) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
3971
3972
if ((src1 & REG_MASK) == dst_reg)
3973
src1 = (src1 & ~REG_MASK) | TMP_REG1;
3974
3975
if (OFFS_REG(src1) == dst_reg)
3976
src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);
3977
}
3978
3979
FAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg)));
3980
}
3981
}
3982
3983
SLJIT_SKIP_CHECKS(compiler);
3984
jump = sljit_emit_jump(compiler, type ^ 0x1);
3985
FAIL_IF(!jump);
3986
3987
if (src1 & SLJIT_MEM) {
3988
FAIL_IF(emit_op_mem(compiler, inp_flags, DR(dst_reg), src1, src1w));
3989
} else if (src1 == SLJIT_IMM) {
3990
FAIL_IF(load_immediate(compiler, DR(dst_reg), src1w));
3991
} else
3992
FAIL_IF(push_inst(compiler, mov_ins | S(src1) | TA(0) | D(dst_reg), DR(dst_reg)));
3993
3994
SLJIT_SKIP_CHECKS(compiler);
3995
label = sljit_emit_label(compiler);
3996
FAIL_IF(!label);
3997
3998
sljit_set_label(jump, label);
3999
return SLJIT_SUCCESS;
4000
#endif /* SLJIT_MIPS_REV >= 1 */
4001
}
4002
4003
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,
4004
sljit_s32 dst_freg,
4005
sljit_s32 src1, sljit_sw src1w,
4006
sljit_s32 src2_freg)
4007
{
4008
#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
4009
struct sljit_label *label;
4010
struct sljit_jump *jump;
4011
#endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */
4012
4013
CHECK_ERROR();
4014
CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));
4015
4016
ADJUST_LOCAL_OFFSET(src1, src1w);
4017
4018
if (dst_freg != src2_freg) {
4019
if (dst_freg == src1) {
4020
src1 = src2_freg;
4021
src1w = 0;
4022
type ^= 0x1;
4023
} else
4024
FAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src2_freg) | FD(dst_freg), MOVABLE_INS));
4025
}
4026
4027
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
4028
if (src1 & SLJIT_MEM) {
4029
FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(TMP_FREG2), src1, src1w));
4030
src1 = TMP_FREG2;
4031
}
4032
4033
return push_inst(compiler, get_select_cc(type & ~SLJIT_32, 1) | FMT(type) | FS(src1) | FD(dst_freg), MOVABLE_INS);
4034
4035
#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
4036
SLJIT_SKIP_CHECKS(compiler);
4037
jump = sljit_emit_jump(compiler, type ^ 0x1);
4038
FAIL_IF(!jump);
4039
4040
if (src1 & SLJIT_MEM)
4041
FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(dst_freg), src1, src1w));
4042
else
4043
FAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src1) | FD(dst_freg), MOVABLE_INS));
4044
4045
SLJIT_SKIP_CHECKS(compiler);
4046
label = sljit_emit_label(compiler);
4047
FAIL_IF(!label);
4048
4049
sljit_set_label(jump, label);
4050
return SLJIT_SUCCESS;
4051
#endif /* SLJIT_MIPS_REV >= 1 */
4052
}
4053
4054
#undef FLOAT_DATA
4055
#undef FMT
4056
4057
static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s16 max_offset)
4058
{
4059
sljit_s32 arg = *mem;
4060
sljit_sw argw = *memw;
4061
4062
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
4063
argw &= 0x3;
4064
4065
if (SLJIT_UNLIKELY(argw)) {
4066
FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1)));
4067
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1)));
4068
} else
4069
FAIL_IF(push_inst(compiler, ADDU_W | S(arg & REG_MASK) | T(OFFS_REG(arg)) | D(TMP_REG1), DR(TMP_REG1)));
4070
4071
*mem = TMP_REG1;
4072
*memw = 0;
4073
4074
return SLJIT_SUCCESS;
4075
}
4076
4077
if (argw <= max_offset && argw >= SIMM_MIN) {
4078
*mem = arg & REG_MASK;
4079
return SLJIT_SUCCESS;
4080
}
4081
4082
*mem = TMP_REG1;
4083
4084
if ((sljit_s16)argw > max_offset) {
4085
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), argw));
4086
*memw = 0;
4087
} else {
4088
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), TO_ARGW_HI(argw)));
4089
*memw = (sljit_s16)argw;
4090
}
4091
4092
if ((arg & REG_MASK) == 0)
4093
return SLJIT_SUCCESS;
4094
4095
return push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1));
4096
}
4097
4098
#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
4099
#define IMM_LEFT(memw) IMM((memw) + SSIZE_OF(sw) - 1)
4100
#define IMM_RIGHT(memw) IMM(memw)
4101
#define IMM_32_LEFT(memw) IMM((memw) + SSIZE_OF(s32) - 1)
4102
#define IMM_32_RIGHT(memw) IMM(memw)
4103
#define IMM_F64_FIRST_LEFT(memw) IMM((memw) + SSIZE_OF(s32) - 1)
4104
#define IMM_F64_FIRST_RIGHT(memw) IMM(memw)
4105
#define IMM_F64_SECOND_LEFT(memw) IMM((memw) + SSIZE_OF(f64) - 1)
4106
#define IMM_F64_SECOND_RIGHT(memw) IMM((memw) + SSIZE_OF(s32))
4107
#define IMM_16_FIRST(memw) IMM((memw) + 1)
4108
#define IMM_16_SECOND(memw) IMM(memw)
4109
#else /* !SLJIT_LITTLE_ENDIAN */
4110
#define IMM_LEFT(memw) IMM(memw)
4111
#define IMM_RIGHT(memw) IMM((memw) + SSIZE_OF(sw) - 1)
4112
#define IMM_32_LEFT(memw) IMM(memw)
4113
#define IMM_32_RIGHT(memw) IMM((memw) + SSIZE_OF(s32) - 1)
4114
#define IMM_F64_FIRST_LEFT(memw) IMM((memw) + SSIZE_OF(s32))
4115
#define IMM_F64_FIRST_RIGHT(memw) IMM((memw) + SSIZE_OF(f64) - 1)
4116
#define IMM_F64_SECOND_LEFT(memw) IMM(memw)
4117
#define IMM_F64_SECOND_RIGHT(memw) IMM((memw) + SSIZE_OF(s32) - 1)
4118
#define IMM_16_FIRST(memw) IMM(memw)
4119
#define IMM_16_SECOND(memw) IMM((memw) + 1)
4120
#endif /* SLJIT_LITTLE_ENDIAN */
4121
4122
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4123
#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16))
4124
#else /* !SLJIT_CONFIG_MIPS_32 */
4125
#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))
4126
#endif /* SLJIT_CONFIG_MIPS_32 */
4127
4128
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
4129
sljit_s32 reg,
4130
sljit_s32 mem, sljit_sw memw)
4131
{
4132
sljit_s32 op = type & 0xff;
4133
sljit_s32 flags = 0;
4134
sljit_ins ins;
4135
#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
4136
sljit_ins ins_right;
4137
#endif /* !(SLJIT_MIPS_REV >= 6) */
4138
4139
CHECK_ERROR();
4140
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
4141
4142
if (reg & REG_PAIR_MASK) {
4143
ADJUST_LOCAL_OFFSET(mem, memw);
4144
4145
#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
4146
if (MEM_CHECK_UNALIGNED(type)) {
4147
FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (2 * SSIZE_OF(sw) - 1)));
4148
4149
if (!(type & SLJIT_MEM_STORE) && (mem == REG_PAIR_FIRST(reg) || mem == REG_PAIR_SECOND(reg))) {
4150
FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
4151
mem = TMP_REG1;
4152
}
4153
4154
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4155
ins = ((type & SLJIT_MEM_STORE) ? SWL : LWL) | S(mem);
4156
ins_right = ((type & SLJIT_MEM_STORE) ? SWR : LWR) | S(mem);
4157
#else /* !SLJIT_CONFIG_MIPS_32 */
4158
ins = ((type & SLJIT_MEM_STORE) ? SDL : LDL) | S(mem);
4159
ins_right = ((type & SLJIT_MEM_STORE) ? SDR : LDR) | S(mem);
4160
#endif /* SLJIT_CONFIG_MIPS_32 */
4161
4162
FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM_LEFT(memw), DR(REG_PAIR_FIRST(reg))));
4163
FAIL_IF(push_inst(compiler, ins_right | T(REG_PAIR_FIRST(reg)) | IMM_RIGHT(memw), DR(REG_PAIR_FIRST(reg))));
4164
FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM_LEFT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));
4165
return push_inst(compiler, ins_right | T(REG_PAIR_SECOND(reg)) | IMM_RIGHT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)));
4166
}
4167
#endif /* !(SLJIT_MIPS_REV >= 6) */
4168
4169
FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - SSIZE_OF(sw)));
4170
4171
ins = ((type & SLJIT_MEM_STORE) ? STORE_W : LOAD_W) | S(mem);
4172
4173
if (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {
4174
FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));
4175
return push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg)));
4176
}
4177
4178
FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg))));
4179
return push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)));
4180
}
4181
4182
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
4183
return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
4184
#else /* !(SLJIT_MIPS_REV >= 6) */
4185
ADJUST_LOCAL_OFFSET(mem, memw);
4186
4187
switch (op) {
4188
case SLJIT_MOV_U8:
4189
case SLJIT_MOV_S8:
4190
flags = BYTE_DATA;
4191
if (!(type & SLJIT_MEM_STORE))
4192
flags |= LOAD_DATA;
4193
4194
if (op == SLJIT_MOV_S8)
4195
flags |= SIGNED_DATA;
4196
4197
return emit_op_mem(compiler, flags, DR(reg), mem, memw);
4198
4199
case SLJIT_MOV_U16:
4200
case SLJIT_MOV_S16:
4201
FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 1));
4202
SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
4203
4204
if (type & SLJIT_MEM_STORE) {
4205
FAIL_IF(push_inst(compiler, SRA_W | T(reg) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));
4206
FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), MOVABLE_INS));
4207
return push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), MOVABLE_INS);
4208
}
4209
4210
flags = BYTE_DATA | LOAD_DATA;
4211
4212
if (op == SLJIT_MOV_S16)
4213
flags |= SIGNED_DATA;
4214
4215
FAIL_IF(push_inst(compiler, data_transfer_insts[flags] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), DR(TMP_REG2)));
4216
FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA | LOAD_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), DR(reg)));
4217
FAIL_IF(push_inst(compiler, SLL_W | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));
4218
return push_inst(compiler, OR | S(reg) | T(TMP_REG2) | D(reg), DR(reg));
4219
4220
case SLJIT_MOV:
4221
case SLJIT_MOV_P:
4222
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4223
if (type & SLJIT_MEM_ALIGNED_32) {
4224
flags = WORD_DATA;
4225
if (!(type & SLJIT_MEM_STORE))
4226
flags |= LOAD_DATA;
4227
4228
return emit_op_mem(compiler, flags, DR(reg), mem, memw);
4229
}
4230
#else /* !SLJIT_CONFIG_MIPS_32 */
4231
FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 7));
4232
SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
4233
4234
if (type & SLJIT_MEM_STORE) {
4235
FAIL_IF(push_inst(compiler, SDL | S(mem) | T(reg) | IMM_LEFT(memw), MOVABLE_INS));
4236
return push_inst(compiler, SDR | S(mem) | T(reg) | IMM_RIGHT(memw), MOVABLE_INS);
4237
}
4238
4239
if (mem == reg) {
4240
FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
4241
mem = TMP_REG1;
4242
}
4243
4244
FAIL_IF(push_inst(compiler, LDL | S(mem) | T(reg) | IMM_LEFT(memw), DR(reg)));
4245
return push_inst(compiler, LDR | S(mem) | T(reg) | IMM_RIGHT(memw), DR(reg));
4246
#endif /* SLJIT_CONFIG_MIPS_32 */
4247
}
4248
4249
FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 3));
4250
SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
4251
4252
if (type & SLJIT_MEM_STORE) {
4253
FAIL_IF(push_inst(compiler, SWL | S(mem) | T(reg) | IMM_32_LEFT(memw), MOVABLE_INS));
4254
return push_inst(compiler, SWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), MOVABLE_INS);
4255
}
4256
4257
if (mem == reg) {
4258
FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
4259
mem = TMP_REG1;
4260
}
4261
4262
FAIL_IF(push_inst(compiler, LWL | S(mem) | T(reg) | IMM_32_LEFT(memw), DR(reg)));
4263
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4264
return push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg));
4265
#else /* !SLJIT_CONFIG_MIPS_32 */
4266
FAIL_IF(push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg)));
4267
4268
if (op != SLJIT_MOV_U32)
4269
return SLJIT_SUCCESS;
4270
4271
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
4272
return push_inst(compiler, DINSU | T(reg) | SA(0) | (31 << 11), DR(reg));
4273
#else /* SLJIT_MIPS_REV < 2 */
4274
FAIL_IF(push_inst(compiler, DSLL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg)));
4275
return push_inst(compiler, DSRL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg));
4276
#endif /* SLJIT_MIPS_REV >= 2 */
4277
#endif /* SLJIT_CONFIG_MIPS_32 */
4278
#endif /* SLJIT_MIPS_REV >= 6 */
4279
}
4280
4281
#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
4282
4283
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
4284
sljit_s32 freg,
4285
sljit_s32 mem, sljit_sw memw)
4286
{
4287
CHECK_ERROR();
4288
CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
4289
4290
FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (type & SLJIT_32) ? 3 : 7));
4291
SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
4292
4293
if (type & SLJIT_MEM_STORE) {
4294
if (type & SLJIT_32) {
4295
FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
4296
#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)
4297
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4298
#endif /* MIPS III */
4299
FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), MOVABLE_INS));
4300
return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), MOVABLE_INS);
4301
}
4302
4303
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4304
FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
4305
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
4306
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4307
#endif /* MIPS III */
4308
FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), MOVABLE_INS));
4309
FAIL_IF(push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), MOVABLE_INS));
4310
switch (cpu_feature_list & CPU_FEATURE_FR) {
4311
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
4312
case CPU_FEATURE_FR:
4313
FAIL_IF(push_inst(compiler, MFHC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
4314
break;
4315
#endif /* SLJIT_MIPS_REV >= 2 */
4316
default:
4317
FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg) | (1 << 11), DR(TMP_REG2)));
4318
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
4319
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4320
#endif
4321
break;
4322
}
4323
4324
FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), MOVABLE_INS));
4325
return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), MOVABLE_INS);
4326
#else /* !SLJIT_CONFIG_MIPS_32 */
4327
FAIL_IF(push_inst(compiler, DMFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
4328
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
4329
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4330
#endif /* MIPS III */
4331
FAIL_IF(push_inst(compiler, SDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), MOVABLE_INS));
4332
return push_inst(compiler, SDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), MOVABLE_INS);
4333
#endif /* SLJIT_CONFIG_MIPS_32 */
4334
}
4335
4336
if (type & SLJIT_32) {
4337
FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), DR(TMP_REG2)));
4338
FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), DR(TMP_REG2)));
4339
4340
FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));
4341
#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)
4342
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4343
#endif /* MIPS III */
4344
return SLJIT_SUCCESS;
4345
}
4346
4347
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4348
FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), DR(TMP_REG2)));
4349
FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), DR(TMP_REG2)));
4350
FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));
4351
4352
FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), DR(TMP_REG2)));
4353
FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), DR(TMP_REG2)));
4354
switch (cpu_feature_list & CPU_FEATURE_FR) {
4355
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
4356
case CPU_FEATURE_FR:
4357
return push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS);
4358
#endif /* SLJIT_MIPS_REV >= 2 */
4359
default:
4360
FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg) | (1 << 11), MOVABLE_INS));
4361
break;
4362
}
4363
#else /* !SLJIT_CONFIG_MIPS_32 */
4364
FAIL_IF(push_inst(compiler, LDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), DR(TMP_REG2)));
4365
FAIL_IF(push_inst(compiler, LDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), DR(TMP_REG2)));
4366
4367
FAIL_IF(push_inst(compiler, DMTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));
4368
#endif /* SLJIT_CONFIG_MIPS_32 */
4369
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
4370
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4371
#endif /* MIPS III */
4372
return SLJIT_SUCCESS;
4373
}
4374
4375
#endif /* !SLJIT_MIPS_REV || SLJIT_MIPS_REV < 6 */
4376
4377
#undef IMM_16_SECOND
4378
#undef IMM_16_FIRST
4379
#undef IMM_F64_SECOND_RIGHT
4380
#undef IMM_F64_SECOND_LEFT
4381
#undef IMM_F64_FIRST_RIGHT
4382
#undef IMM_F64_FIRST_LEFT
4383
#undef IMM_32_RIGHT
4384
#undef IMM_32_LEFT
4385
#undef IMM_RIGHT
4386
#undef IMM_LEFT
4387
#undef MEM_CHECK_UNALIGNED
4388
4389
#undef TO_ARGW_HI
4390
4391
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,
4392
sljit_s32 dst_reg,
4393
sljit_s32 mem_reg)
4394
{
4395
sljit_ins ins;
4396
4397
CHECK_ERROR();
4398
CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));
4399
4400
if (op & SLJIT_ATOMIC_USE_CAS)
4401
return SLJIT_ERR_UNSUPPORTED;
4402
4403
switch (GET_OPCODE(op)) {
4404
case SLJIT_MOV:
4405
case SLJIT_MOV_P:
4406
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
4407
ins = LLD;
4408
break;
4409
#endif /* SLJIT_CONFIG_MIPS_64 */
4410
case SLJIT_MOV_S32:
4411
case SLJIT_MOV32:
4412
ins = LL;
4413
break;
4414
4415
default:
4416
return SLJIT_ERR_UNSUPPORTED;
4417
}
4418
4419
if (op & SLJIT_ATOMIC_TEST)
4420
return SLJIT_SUCCESS;
4421
4422
return push_inst(compiler, ins | T(dst_reg) | S(mem_reg), DR(dst_reg));
4423
}
4424
4425
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,
4426
sljit_s32 src_reg,
4427
sljit_s32 mem_reg,
4428
sljit_s32 temp_reg)
4429
{
4430
sljit_ins ins;
4431
4432
/* temp_reg == mem_reg is undefined so use another temp register */
4433
SLJIT_UNUSED_ARG(temp_reg);
4434
4435
CHECK_ERROR();
4436
CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));
4437
4438
if (op & SLJIT_ATOMIC_USE_CAS)
4439
return SLJIT_ERR_UNSUPPORTED;
4440
4441
switch (GET_OPCODE(op)) {
4442
case SLJIT_MOV:
4443
case SLJIT_MOV_P:
4444
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
4445
ins = SCD;
4446
break;
4447
#endif /* SLJIT_CONFIG_MIPS_64 */
4448
case SLJIT_MOV_S32:
4449
case SLJIT_MOV32:
4450
op |= SLJIT_32;
4451
ins = SC;
4452
break;
4453
4454
default:
4455
return SLJIT_ERR_UNSUPPORTED;
4456
}
4457
4458
if (op & SLJIT_ATOMIC_TEST)
4459
return SLJIT_SUCCESS;
4460
4461
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src_reg) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG));
4462
return push_inst(compiler, ins | TA(OTHER_FLAG) | S(mem_reg), OTHER_FLAG);
4463
}
4464
4465
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
4466
sljit_s32 dst, sljit_sw dstw,
4467
sljit_sw init_value)
4468
{
4469
struct sljit_const *const_;
4470
sljit_s32 dst_r;
4471
sljit_s32 mem_flags = WORD_DATA;
4472
4473
CHECK_ERROR_PTR();
4474
CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
4475
ADJUST_LOCAL_OFFSET(dst, dstw);
4476
4477
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
4478
PTR_FAIL_IF(!const_);
4479
set_const(const_, compiler);
4480
4481
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
4482
4483
switch (GET_OPCODE(op)) {
4484
case SLJIT_MOV_U8:
4485
if (init_value & 0x100)
4486
init_value |= 0xff00;
4487
else
4488
init_value &= 0xff;
4489
4490
PTR_FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(dst_r) | IMM(init_value), DR(dst_r)));
4491
mem_flags = BYTE_DATA;
4492
break;
4493
4494
#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64)
4495
case SLJIT_MOV32:
4496
mem_flags = INT_DATA;
4497
SLJIT_FALLTHROUGH
4498
case SLJIT_MOV_S32:
4499
PTR_FAIL_IF(push_inst(compiler, LUI | T(dst_r) | IMM(init_value >> 16), DR(dst_r)));
4500
PTR_FAIL_IF(push_inst(compiler, ORI | S(dst_r) | T(dst_r) | IMM(init_value), DR(dst_r)));
4501
break;
4502
#endif /* SLJIT_CONFIG_MIPS_64 */
4503
4504
default:
4505
PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
4506
break;
4507
}
4508
4509
if (dst & SLJIT_MEM)
4510
PTR_FAIL_IF(emit_op_mem(compiler, mem_flags, DR(TMP_REG2), dst, dstw));
4511
4512
return const_;
4513
}
4514
4515
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
4516
sljit_s32 dst, sljit_sw dstw)
4517
{
4518
struct sljit_jump *jump;
4519
sljit_s32 dst_r, target_r;
4520
SLJIT_UNUSED_ARG(op);
4521
4522
CHECK_ERROR_PTR();
4523
CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
4524
ADJUST_LOCAL_OFFSET(dst, dstw);
4525
4526
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
4527
4528
if (op != SLJIT_ADD_ABS_ADDR)
4529
target_r = dst_r;
4530
else {
4531
target_r = TMP_REG1;
4532
4533
if (dst & SLJIT_MEM)
4534
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), dst, dstw));
4535
}
4536
4537
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
4538
PTR_FAIL_IF(!jump);
4539
set_mov_addr(jump, compiler, 0);
4540
4541
PTR_FAIL_IF(push_inst(compiler, (sljit_ins)target_r, UNMOVABLE_INS));
4542
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4543
compiler->size += 1;
4544
#else
4545
compiler->size += 5;
4546
#endif
4547
4548
if (op == SLJIT_ADD_ABS_ADDR)
4549
PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(dst_r) | T(TMP_REG1) | D(dst_r), DR(dst_r)));
4550
4551
if (dst & SLJIT_MEM)
4552
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
4553
4554
return jump;
4555
}
4556
4557
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
4558
{
4559
sljit_ins *inst;
4560
4561
switch (GET_OPCODE(op)) {
4562
case SLJIT_MOV_U8:
4563
inst = (sljit_ins *)addr;
4564
SLJIT_ASSERT((inst[0] & 0xfc000000) == ADDIU);
4565
4566
if (new_constant & 0x100)
4567
new_constant |= 0xff00;
4568
else
4569
new_constant &= 0xff;
4570
4571
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
4572
inst[0] = (inst[0] & 0xffff0000) | IMM(new_constant);
4573
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
4574
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
4575
SLJIT_CACHE_FLUSH(inst, inst + 1);
4576
return;
4577
4578
#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64)
4579
case SLJIT_MOV32:
4580
case SLJIT_MOV_S32:
4581
inst = (sljit_ins *)addr;
4582
SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
4583
4584
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
4585
inst[0] = (inst[0] & 0xffff0000) | IMM(new_constant >> 16);
4586
inst[1] = (inst[1] & 0xffff0000) | IMM(new_constant);
4587
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
4588
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
4589
SLJIT_CACHE_FLUSH(inst, inst + 2);
4590
return;
4591
#endif /* SLJIT_CONFIG_MIPS_64 */
4592
4593
default:
4594
sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
4595
return;
4596
}
4597
}
4598
4599