@@ -109,6 +109,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
109
109
#define ORR 0xe1800000
110
110
#define PUSH 0xe92d0000
111
111
#define POP 0xe8bd0000
112
+ #define RBIT 0xe6ff0f30
112
113
#define RSB 0xe0600000
113
114
#define RSC 0xe0e00000
114
115
#define SBC 0xe0c00000
@@ -959,12 +960,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
959
960
#endif
960
961
961
962
case SLJIT_HAS_CLZ :
963
+ case SLJIT_HAS_ROT :
962
964
case SLJIT_HAS_CMOV :
963
965
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7 )
966
+ case SLJIT_HAS_CTZ :
964
967
case SLJIT_HAS_PREFETCH :
965
968
#endif
966
969
return 1 ;
967
970
971
+ #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5 )
972
+ case SLJIT_HAS_CTZ :
973
+ return 2 ;
974
+ #endif
975
+
968
976
default :
969
977
return 0 ;
970
978
}
@@ -1478,11 +1486,24 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
1478
1486
return push_inst (compiler , MVN | (flags & SET_FLAGS ) | RD (dst ) | RM (src2 ));
1479
1487
1480
1488
case SLJIT_CLZ :
1481
- SLJIT_ASSERT (!(flags & INV_IMM ));
1482
- SLJIT_ASSERT (!(src2 & SRC2_IMM ));
1489
+ SLJIT_ASSERT (!(flags & INV_IMM ) && !(src2 & SRC2_IMM ));
1483
1490
FAIL_IF (push_inst (compiler , CLZ | RD (dst ) | RM (src2 )));
1484
1491
return SLJIT_SUCCESS ;
1485
1492
1493
+ case SLJIT_CTZ :
1494
+ SLJIT_ASSERT (!(flags & INV_IMM ) && !(src2 & SRC2_IMM ));
1495
+ SLJIT_ASSERT (src1 == TMP_REG1 && !(flags & ARGS_SWAPPED ));
1496
+ #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5 )
1497
+ FAIL_IF (push_inst (compiler , RSB | SRC2_IMM | RD (TMP_REG1 ) | RN (src2 ) | 0 ));
1498
+ FAIL_IF (push_inst (compiler , AND | RD (TMP_REG2 ) | RN (src2 ) | RM (TMP_REG1 )));
1499
+ FAIL_IF (push_inst (compiler , CLZ | RD (dst ) | RM (TMP_REG2 )));
1500
+ FAIL_IF (push_inst (compiler , CMP | SET_FLAGS | SRC2_IMM | RN (dst ) | 32 ));
1501
+ return push_inst (compiler , (EOR ^ 0xf0000000 ) | SRC2_IMM | RD (dst ) | RN (dst ) | 0x1f );
1502
+ #else /* !SLJIT_CONFIG_ARM_V5 */
1503
+ FAIL_IF (push_inst (compiler , RBIT | RD (dst ) | RM (src2 )));
1504
+ return push_inst (compiler , CLZ | RD (dst ) | RM (dst ));
1505
+ #endif /* SLJIT_CONFIG_ARM_V5 */
1506
+
1486
1507
case SLJIT_ADD :
1487
1508
SLJIT_ASSERT (!(flags & INV_IMM ));
1488
1509
@@ -1553,6 +1574,19 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
1553
1574
is_masked = GET_OPCODE (op ) == SLJIT_MASHR ;
1554
1575
break ;
1555
1576
1577
+ case SLJIT_ROTL :
1578
+ if (compiler -> shift_imm == 0x20 ) {
1579
+ FAIL_IF (push_inst (compiler , RSB | SRC2_IMM | RD (TMP_REG2 ) | RN (src2 ) | 0 ));
1580
+ src2 = TMP_REG2 ;
1581
+ } else
1582
+ compiler -> shift_imm = (sljit_uw )(- (sljit_sw )compiler -> shift_imm ) & 0x1f ;
1583
+ /* fallthrough */
1584
+
1585
+ case SLJIT_ROTR :
1586
+ shift_type = 3 ;
1587
+ is_masked = 0 ;
1588
+ break ;
1589
+
1556
1590
default :
1557
1591
SLJIT_UNREACHABLE ();
1558
1592
return SLJIT_SUCCESS ;
@@ -2125,6 +2159,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
2125
2159
return emit_op (compiler , op , ALLOW_ANY_IMM , dst , dstw , TMP_REG1 , 0 , src , srcw );
2126
2160
2127
2161
case SLJIT_CLZ :
2162
+ case SLJIT_CTZ :
2128
2163
return emit_op (compiler , op , 0 , dst , dstw , TMP_REG1 , 0 , src , srcw );
2129
2164
}
2130
2165
@@ -2165,6 +2200,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
2165
2200
case SLJIT_MLSHR :
2166
2201
case SLJIT_ASHR :
2167
2202
case SLJIT_MASHR :
2203
+ case SLJIT_ROTL :
2204
+ case SLJIT_ROTR :
2168
2205
if (src2 & SLJIT_IMM ) {
2169
2206
compiler -> shift_imm = src2w & 0x1f ;
2170
2207
return emit_op (compiler , op , 0 , dst , dstw , TMP_REG1 , 0 , src1 , src1w );
@@ -2188,6 +2225,63 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil
2188
2225
return sljit_emit_op2 (compiler , op , TMP_REG2 , 0 , src1 , src1w , src2 , src2w );
2189
2226
}
2190
2227
2228
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into (struct sljit_compiler * compiler , sljit_s32 op ,
2229
+ sljit_s32 src_dst ,
2230
+ sljit_s32 src1 , sljit_sw src1w ,
2231
+ sljit_s32 src2 , sljit_sw src2w )
2232
+ {
2233
+ sljit_s32 is_left ;
2234
+
2235
+ CHECK_ERROR ();
2236
+ CHECK (check_sljit_emit_shift_into (compiler , op , src_dst , src1 , src1w , src2 , src2w ));
2237
+
2238
+ op = GET_OPCODE (op );
2239
+ is_left = (op == SLJIT_SHL || op == SLJIT_MSHL );
2240
+
2241
+ if (src_dst == src1 ) {
2242
+ SLJIT_SKIP_CHECKS (compiler );
2243
+ return sljit_emit_op2 (compiler , is_left ? SLJIT_ROTL : SLJIT_ROTR , src_dst , 0 , src_dst , 0 , src2 , src2w );
2244
+ }
2245
+
2246
+ ADJUST_LOCAL_OFFSET (src1 , src1w );
2247
+ ADJUST_LOCAL_OFFSET (src2 , src2w );
2248
+
2249
+ /* Shift type of ROR is 3. */
2250
+ if (src2 & SLJIT_IMM ) {
2251
+ src2w &= 0x1f ;
2252
+
2253
+ if (src2w == 0 )
2254
+ return SLJIT_SUCCESS ;
2255
+ } else if (src2 & SLJIT_MEM ) {
2256
+ FAIL_IF (emit_op_mem (compiler , WORD_SIZE | LOAD_DATA , TMP_REG2 , src2 , src2w , TMP_REG2 ));
2257
+ src2 = TMP_REG2 ;
2258
+ }
2259
+
2260
+ if (src1 & SLJIT_MEM ) {
2261
+ FAIL_IF (emit_op_mem (compiler , WORD_SIZE | LOAD_DATA , TMP_REG1 , src1 , src1w , TMP_REG1 ));
2262
+ src1 = TMP_REG1 ;
2263
+ } else if (src1 & SLJIT_IMM ) {
2264
+ FAIL_IF (load_immediate (compiler , TMP_REG1 , (sljit_uw )src1w ));
2265
+ src1 = TMP_REG1 ;
2266
+ }
2267
+
2268
+ if (src2 & SLJIT_IMM ) {
2269
+ FAIL_IF (push_inst (compiler , MOV | RD (src_dst ) | RM (src_dst ) | ((sljit_uw )(is_left ? 0 : 1 ) << 5 ) | ((sljit_uw )src2w << 7 )));
2270
+ src2w = (src2w ^ 0x1f ) + 1 ;
2271
+ return push_inst (compiler , ORR | RD (src_dst ) | RN (src_dst ) | RM (src1 ) | ((sljit_uw )(is_left ? 1 : 0 ) << 5 ) | ((sljit_uw )src2w << 7 ));
2272
+ }
2273
+
2274
+ if (op == SLJIT_MSHL || op == SLJIT_MLSHR ) {
2275
+ FAIL_IF (push_inst (compiler , AND | SRC2_IMM | RD (TMP_REG2 ) | RN (src2 ) | 0x1f ));
2276
+ src2 = TMP_REG2 ;
2277
+ }
2278
+
2279
+ FAIL_IF (push_inst (compiler , MOV | RD (src_dst ) | RM8 (src2 ) | ((sljit_uw )(is_left ? 0 : 1 ) << 5 ) | 0x10 | RM (src_dst )));
2280
+ FAIL_IF (push_inst (compiler , MOV | RD (TMP_REG1 ) | RM (src1 ) | ((sljit_uw )(is_left ? 1 : 0 ) << 5 ) | (1 << 7 )));
2281
+ FAIL_IF (push_inst (compiler , EOR | SRC2_IMM | RD (TMP_REG2 ) | RN (src2 ) | 0x1f ));
2282
+ return push_inst (compiler , ORR | RD (src_dst ) | RN (src_dst ) | RM (TMP_REG1 ) | ((sljit_uw )(is_left ? 1 : 0 ) << 5 ) | 0x10 | RM8 (TMP_REG2 ));
2283
+ }
2284
+
2191
2285
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src (struct sljit_compiler * compiler , sljit_s32 op ,
2192
2286
sljit_s32 src , sljit_sw srcw )
2193
2287
{
0 commit comments