[Pcre-svn] [1751] code/trunk/sljit: JIT compiler update.

Page principale
Supprimer ce message
Auteur: Subversion repository
Date:  
À: pcre-svn
Sujet: [Pcre-svn] [1751] code/trunk/sljit: JIT compiler update.
Revision: 1751
          http://vcs.pcre.org/viewvc?view=rev&revision=1751
Author:   zherczeg
Date:     2019-03-05 09:09:46 +0000 (Tue, 05 Mar 2019)
Log Message:
-----------
JIT compiler update.


Modified Paths:
--------------
    code/trunk/sljit/sljitLir.c
    code/trunk/sljit/sljitNativeMIPS_32.c
    code/trunk/sljit/sljitNativeMIPS_64.c
    code/trunk/sljit/sljitNativeMIPS_common.c


Modified: code/trunk/sljit/sljitLir.c
===================================================================
--- code/trunk/sljit/sljitLir.c    2019-03-01 16:24:05 UTC (rev 1750)
+++ code/trunk/sljit/sljitLir.c    2019-03-05 09:09:46 UTC (rev 1751)
@@ -201,15 +201,16 @@
 #    define IS_CALL        0x010
 #    define IS_BIT26_COND    0x020
 #    define IS_BIT16_COND    0x040
+#    define IS_BIT23_COND    0x080


-#    define IS_COND        (IS_BIT26_COND | IS_BIT16_COND)
+#    define IS_COND        (IS_BIT26_COND | IS_BIT16_COND | IS_BIT23_COND)


-#    define PATCH_B        0x080
-#    define PATCH_J        0x100
+#    define PATCH_B        0x100
+#    define PATCH_J        0x200


 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
-#    define PATCH_ABS32    0x200
-#    define PATCH_ABS48    0x400
+#    define PATCH_ABS32    0x400
+#    define PATCH_ABS48    0x800
 #endif


     /* instruction types */


Modified: code/trunk/sljit/sljitNativeMIPS_32.c
===================================================================
--- code/trunk/sljit/sljitNativeMIPS_32.c    2019-03-01 16:24:05 UTC (rev 1750)
+++ code/trunk/sljit/sljitNativeMIPS_32.c    2019-03-05 09:09:46 UTC (rev 1751)
@@ -368,16 +368,21 @@
         SLJIT_ASSERT(!(flags & SRC2_IMM));


         if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
             return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
-#else
+#else /* !SLJIT_MIPS_R1 && !SLJIT_MIPS_R6 */
             FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
             return push_inst(compiler, MFLO | D(dst), DR(dst));
-#endif
+#endif /* SLJIT_MIPS_R1 || SLJIT_MIPS_R6 */
         }
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+        FAIL_IF(push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)));
+        FAIL_IF(push_inst(compiler, MUH | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+#else /* !SLJIT_MIPS_R6 */
         FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
         FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
         FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
+#endif /* SLJIT_MIPS_R6 */
         FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
         return push_inst(compiler, SUBU | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);



Modified: code/trunk/sljit/sljitNativeMIPS_64.c
===================================================================
--- code/trunk/sljit/sljitNativeMIPS_64.c    2019-03-01 16:24:05 UTC (rev 1750)
+++ code/trunk/sljit/sljitNativeMIPS_64.c    2019-03-05 09:09:46 UTC (rev 1751)
@@ -459,19 +459,26 @@
         SLJIT_ASSERT(!(flags & SRC2_IMM));


         if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+            return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
+#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
             if (op & SLJIT_I32_OP)
                 return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
             FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
             return push_inst(compiler, MFLO | D(dst), DR(dst));
-#else
+#else /* !SLJIT_MIPS_R6 && !SLJIT_MIPS_R1 */
             FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
             return push_inst(compiler, MFLO | D(dst), DR(dst));
-#endif
+#endif /* SLJIT_MIPS_R6 */
         }
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+        FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));
+        FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+#else /* !SLJIT_MIPS_R6 */
         FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
         FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
         FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
+#endif /* SLJIT_MIPS_R6 */
         FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
         return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);



Modified: code/trunk/sljit/sljitNativeMIPS_common.c
===================================================================
--- code/trunk/sljit/sljitNativeMIPS_common.c    2019-03-01 16:24:05 UTC (rev 1750)
+++ code/trunk/sljit/sljitNativeMIPS_common.c    2019-03-05 09:09:46 UTC (rev 1751)
@@ -27,17 +27,31 @@
 /* Latest MIPS architecture. */
 /* Automatically detect SLJIT_MIPS_R1 */


+#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)
+#define SLJIT_MIPS_R6 1
+#endif
+
 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
 {
-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+    return "MIPS32-R6" SLJIT_CPUINFO;
+#else /* !SLJIT_CONFIG_MIPS_32 */
+    return "MIPS64-R6" SLJIT_CPUINFO;
+#endif /* SLJIT_CONFIG_MIPS_32 */
+
+#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
     return "MIPS32-R1" SLJIT_CPUINFO;
-#else
+#else /* !SLJIT_CONFIG_MIPS_32 */
     return "MIPS64-R1" SLJIT_CPUINFO;
-#endif
+#endif /* SLJIT_CONFIG_MIPS_32 */
+
 #else /* SLJIT_MIPS_R1 */
     return "MIPS III" SLJIT_CPUINFO;
-#endif
+#endif /* SLJIT_MIPS_R6 */
 }


/* Length of an instruction word
@@ -62,6 +76,7 @@

 #define TMP_FREG1    (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
 #define TMP_FREG2    (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
+#define TMP_FREG3    (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)


 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
     0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31
@@ -69,14 +84,14 @@


#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)

-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
-    0, 0, 14, 2, 4, 6, 8, 12, 10
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
+    0, 0, 14, 2, 4, 6, 8, 12, 10, 16
 };


#else

-static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
-    0, 0, 13, 14, 15, 16, 17, 12, 18
+static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
+    0, 0, 13, 14, 15, 16, 17, 12, 18, 10
 };


 #endif
@@ -102,6 +117,11 @@
 #define FR(dr)        (freg_map[dr])
 #define HI(opcode)    ((opcode) << 26)
 #define LO(opcode)    (opcode)
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+/* CMP.cond.fmt */
+/* S = (20 << 21) D = (21 << 21) */
+#define CMP_FMT_S    (20 << 21)
+#endif /* SLJIT_MIPS_R6 */
 /* S = (16 << 21) D = (17 << 21) */
 #define FMT_S        (16 << 21)
 #define FMT_D        (17 << 21)
@@ -114,8 +134,13 @@
 #define ANDI        (HI(12))
 #define B        (HI(4))
 #define BAL        (HI(1) | (17 << 16))
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#define BC1EQZ        (HI(17) | (9 << 21) | FT(TMP_FREG3))
+#define BC1NEZ        (HI(17) | (13 << 21) | FT(TMP_FREG3))
+#else /* !SLJIT_MIPS_R6 */
 #define BC1F        (HI(17) | (8 << 21))
 #define BC1T        (HI(17) | (8 << 21) | (1 << 16))
+#endif /* SLJIT_MIPS_R6 */
 #define BEQ        (HI(4))
 #define BGEZ        (HI(1) | (1 << 16))
 #define BGTZ        (HI(7))
@@ -124,20 +149,42 @@
 #define BNE        (HI(5))
 #define BREAK        (HI(0) | LO(13))
 #define CFC1        (HI(17) | (2 << 21))
-#define C_UN_S        (HI(17) | FMT_S | LO(49))
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#define C_UEQ_S        (HI(17) | CMP_FMT_S | LO(3))
+#define C_ULE_S        (HI(17) | CMP_FMT_S | LO(7))
+#define C_ULT_S        (HI(17) | CMP_FMT_S | LO(5))
+#define C_UN_S        (HI(17) | CMP_FMT_S | LO(1))
+#define C_FD        (FD(TMP_FREG3))
+#else /* !SLJIT_MIPS_R6 */
 #define C_UEQ_S        (HI(17) | FMT_S | LO(51))
 #define C_ULE_S        (HI(17) | FMT_S | LO(55))
 #define C_ULT_S        (HI(17) | FMT_S | LO(53))
+#define C_UN_S        (HI(17) | FMT_S | LO(49))
+#define C_FD        (0)
+#endif /* SLJIT_MIPS_R6 */
 #define CVT_S_S        (HI(17) | FMT_S | LO(32))
 #define DADDIU        (HI(25))
 #define DADDU        (HI(0) | LO(45))
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#define DDIV        (HI(0) | (2 << 6) | LO(30))
+#define DDIVU        (HI(0) | (2 << 6) | LO(31))
+#define DMOD        (HI(0) | (3 << 6) | LO(30))
+#define DMODU        (HI(0) | (3 << 6) | LO(31))
+#define DIV        (HI(0) | (2 << 6) | LO(26))
+#define DIVU        (HI(0) | (2 << 6) | LO(27))
+#define DMUH        (HI(0) | (3 << 6) | LO(28))
+#define DMUHU        (HI(0) | (3 << 6) | LO(29))
+#define DMUL        (HI(0) | (2 << 6) | LO(28))
+#define DMULU        (HI(0) | (2 << 6) | LO(29))
+#else /* !SLJIT_MIPS_R6 */
 #define DDIV        (HI(0) | LO(30))
 #define DDIVU        (HI(0) | LO(31))
 #define DIV        (HI(0) | LO(26))
 #define DIVU        (HI(0) | LO(27))
-#define DIV_S        (HI(17) | FMT_S | LO(3))
 #define DMULT        (HI(0) | LO(28))
 #define DMULTU        (HI(0) | LO(29))
+#endif /* SLJIT_MIPS_R6 */
+#define DIV_S        (HI(17) | FMT_S | LO(3))
 #define DSLL        (HI(0) | LO(56))
 #define DSLL32        (HI(0) | LO(60))
 #define DSLLV        (HI(0) | LO(20))
@@ -151,18 +198,34 @@
 #define J        (HI(2))
 #define JAL        (HI(3))
 #define JALR        (HI(0) | LO(9))
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#define JR        (HI(0) | LO(9))
+#else /* !SLJIT_MIPS_R6 */
 #define JR        (HI(0) | LO(8))
+#endif /* SLJIT_MIPS_R6 */
 #define LD        (HI(55))
 #define LUI        (HI(15))
 #define LW        (HI(35))
 #define MFC1        (HI(17))
+#if !(defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
 #define MFHI        (HI(0) | LO(16))
 #define MFLO        (HI(0) | LO(18))
+#else /* SLJIT_MIPS_R6 */
+#define MOD        (HI(0) | (3 << 6) | LO(26))
+#define MODU        (HI(0) | (3 << 6) | LO(27))
+#endif /* !SLJIT_MIPS_R6 */
 #define MOV_S        (HI(17) | FMT_S | LO(6))
 #define MTC1        (HI(17) | (4 << 21))
-#define MUL_S        (HI(17) | FMT_S | LO(2))
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#define MUH        (HI(0) | (3 << 6) | LO(24))
+#define MUHU        (HI(0) | (3 << 6) | LO(25))
+#define MUL        (HI(0) | (2 << 6) | LO(24))
+#define MULU        (HI(0) | (2 << 6) | LO(25))
+#else /* !SLJIT_MIPS_R6 */
 #define MULT        (HI(0) | LO(24))
 #define MULTU        (HI(0) | LO(25))
+#endif /* SLJIT_MIPS_R6 */
+#define MUL_S        (HI(17) | FMT_S | LO(2))
 #define NEG_S        (HI(17) | FMT_S | LO(7))
 #define NOP        (HI(0) | LO(0))
 #define NOR        (HI(0) | LO(39))
@@ -188,8 +251,11 @@
 #define XOR        (HI(0) | LO(38))
 #define XORI        (HI(14))


-#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
+#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
 #define CLZ        (HI(28) | LO(32))
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#define DCLZ        (LO(18))
+#else /* !SLJIT_MIPS_R6 */
 #define DCLZ        (HI(28) | LO(36))
 #define MOVF        (HI(0) | (0 << 16) | LO(1))
 #define MOVN        (HI(0) | LO(11))
@@ -196,6 +262,7 @@
 #define MOVT        (HI(0) | (1 << 16) | LO(1))
 #define MOVZ        (HI(0) | LO(10))
 #define MUL        (HI(28) | LO(2))
+#endif /* SLJIT_MIPS_R6 */
 #define PREF        (HI(51))
 #define PREFX        (HI(19) | LO(15))
 #define SEB        (HI(31) | (16 << 6) | LO(32))
@@ -234,7 +301,13 @@


 static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags)
 {
-    return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16);
+    if (flags & IS_BIT26_COND)
+        return (1 << 26);
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+    if (flags & IS_BIT23_COND)
+        return (1 << 23);
+#endif /* SLJIT_MIPS_R6 */
+    return (1 << 16);
 }


 static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
@@ -1075,34 +1148,62 @@
         return push_inst(compiler, NOP, UNMOVABLE_INS);
     case SLJIT_LMUL_UW:
     case SLJIT_LMUL_SW:
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+        FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
+        FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
+#else /* !SLJIT_CONFIG_MIPS_64 */
+        FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
+        FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
+#endif /* SLJIT_CONFIG_MIPS_64 */
+        FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
+        return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
+#else /* !SLJIT_MIPS_R6 */
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
         FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
-#else
+#else /* !SLJIT_CONFIG_MIPS_64 */
         FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
-#endif
+#endif /* SLJIT_CONFIG_MIPS_64 */
         FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
         return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
+#endif /* SLJIT_MIPS_R6 */
     case SLJIT_DIVMOD_UW:
     case SLJIT_DIVMOD_SW:
     case SLJIT_DIV_UW:
     case SLJIT_DIV_SW:
         SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+        if (int_op) {
+            FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
+            FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
+        }
+        else {
+            FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
+            FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
+        }
+#else /* !SLJIT_CONFIG_MIPS_64 */
+        FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
+        FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
+#endif /* SLJIT_CONFIG_MIPS_64 */
+        FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
+        return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
+#else /* !SLJIT_MIPS_R6 */
 #if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
         FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
         FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
-#endif
-
+#endif /* !SLJIT_MIPS_R1 */
 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
         if (int_op)
             FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
         else
             FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
-#else
+#else /* !SLJIT_CONFIG_MIPS_64 */
         FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
-#endif
-
+#endif /* SLJIT_CONFIG_MIPS_64 */
         FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
         return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
+#endif /* SLJIT_MIPS_R6 */
     }


     return SLJIT_SUCCESS;
@@ -1408,8 +1509,7 @@
         inst = C_UN_S;
         break;
     }
-
-    return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS);
+    return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS);
 }


 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
@@ -1608,16 +1708,30 @@
     flags = IS_BIT26_COND; \
     delay_check = src;


+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+
 #define BR_T() \
+    inst = BC1NEZ; \
+    flags = IS_BIT23_COND; \
+    delay_check = FCSR_FCC;
+#define BR_F() \
+    inst = BC1EQZ; \
+    flags = IS_BIT23_COND; \
+    delay_check = FCSR_FCC;
+
+#else /* !SLJIT_MIPS_R6 */
+
+#define BR_T() \
     inst = BC1T | JUMP_LENGTH; \
     flags = IS_BIT16_COND; \
     delay_check = FCSR_FCC;
-
 #define BR_F() \
     inst = BC1F | JUMP_LENGTH; \
     flags = IS_BIT16_COND; \
     delay_check = FCSR_FCC;


+#endif /* SLJIT_MIPS_R6 */
+
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
 {
     struct sljit_jump *jump;
@@ -1927,7 +2041,11 @@
     case SLJIT_GREATER_EQUAL_F64:
     case SLJIT_UNORDERED_F64:
     case SLJIT_ORDERED_F64:
+#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
+        FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));
+#else /* !SLJIT_MIPS_R6 */
         FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
+#endif /* SLJIT_MIPS_R6 */
         FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
         FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
         src_ar = dst_ar;