"Fossies" - the Fresh Open Source Software Archive

Member "pcre-8.43/sljit/sljitNativePPC_64.c" (30 Nov 2017, 17528 Bytes) of package /linux/misc/pcre-8.43.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sljitNativePPC_64.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 8.41_vs_8.42.

    1 /*
    2  *    Stack-less Just-In-Time compiler
    3  *
    4  *    Copyright Zoltan Herczeg (hzmester@freemail.hu). 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 /* ppc 64-bit arch dependent functions. */
   28 
   29 #if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
   30 #define ASM_SLJIT_CLZ(src, dst) \
   31     __asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
   32 #elif defined(__xlc__)
   33 #error "Please enable GCC syntax for inline assembly statements"
   34 #else
   35 #error "Must implement count leading zeroes"
   36 #endif
   37 
   38 #define RLDI(dst, src, sh, mb, type) \
   39     (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))
   40 
   41 #define PUSH_RLDICR(reg, shift) \
   42     push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
   43 
   44 static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
   45 {
   46     sljit_uw tmp;
   47     sljit_uw shift;
   48     sljit_uw tmp2;
   49     sljit_uw shift2;
   50 
   51     if (imm <= SIMM_MAX && imm >= SIMM_MIN)
   52         return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
   53 
   54     if (!(imm & ~0xffff))
   55         return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));
   56 
   57     if (imm <= 0x7fffffffl && imm >= -0x80000000l) {
   58         FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
   59         return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
   60     }
   61 
   62     /* Count leading zeroes. */
   63     tmp = (imm >= 0) ? imm : ~imm;
   64     ASM_SLJIT_CLZ(tmp, shift);
   65     SLJIT_ASSERT(shift > 0);
   66     shift--;
   67     tmp = (imm << shift);
   68 
   69     if ((tmp & ~0xffff000000000000ul) == 0) {
   70         FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
   71         shift += 15;
   72         return PUSH_RLDICR(reg, shift);
   73     }
   74 
   75     if ((tmp & ~0xffffffff00000000ul) == 0) {
   76         FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48)));
   77         FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32)));
   78         shift += 31;
   79         return PUSH_RLDICR(reg, shift);
   80     }
   81 
   82     /* Cut out the 16 bit from immediate. */
   83     shift += 15;
   84     tmp2 = imm & ((1ul << (63 - shift)) - 1);
   85 
   86     if (tmp2 <= 0xffff) {
   87         FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
   88         FAIL_IF(PUSH_RLDICR(reg, shift));
   89         return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2);
   90     }
   91 
   92     if (tmp2 <= 0xffffffff) {
   93         FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
   94         FAIL_IF(PUSH_RLDICR(reg, shift));
   95         FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16)));
   96         return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS;
   97     }
   98 
   99     ASM_SLJIT_CLZ(tmp2, shift2);
  100     tmp2 <<= shift2;
  101 
  102     if ((tmp2 & ~0xffff000000000000ul) == 0) {
  103         FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
  104         shift2 += 15;
  105         shift += (63 - shift2);
  106         FAIL_IF(PUSH_RLDICR(reg, shift));
  107         FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48)));
  108         return PUSH_RLDICR(reg, shift2);
  109     }
  110 
  111     /* The general version. */
  112     FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48)));
  113     FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32)));
  114     FAIL_IF(PUSH_RLDICR(reg, 31));
  115     FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16)));
  116     return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm));
  117 }
  118 
  119 /* Simplified mnemonics: clrldi. */
  120 #define INS_CLEAR_LEFT(dst, src, from) \
  121     (RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5))
  122 
  123 /* Sign extension for integer operations. */
  124 #define UN_EXTS() \
  125     if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \
  126         FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
  127         src2 = TMP_REG2; \
  128     }
  129 
  130 #define BIN_EXTS() \
  131     if (flags & ALT_SIGN_EXT) { \
  132         if (flags & REG1_SOURCE) { \
  133             FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
  134             src1 = TMP_REG1; \
  135         } \
  136         if (flags & REG2_SOURCE) { \
  137             FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
  138             src2 = TMP_REG2; \
  139         } \
  140     }
  141 
  142 #define BIN_IMM_EXTS() \
  143     if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \
  144         FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
  145         src1 = TMP_REG1; \
  146     }
  147 
  148 static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
  149     sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
  150 {
  151     switch (op) {
  152     case SLJIT_MOV:
  153     case SLJIT_MOV_P:
  154         SLJIT_ASSERT(src1 == TMP_REG1);
  155         if (dst != src2)
  156             return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
  157         return SLJIT_SUCCESS;
  158 
  159     case SLJIT_MOV_U32:
  160     case SLJIT_MOV_S32:
  161         SLJIT_ASSERT(src1 == TMP_REG1);
  162         if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
  163             if (op == SLJIT_MOV_S32)
  164                 return push_inst(compiler, EXTSW | S(src2) | A(dst));
  165             return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0));
  166         }
  167         else {
  168             SLJIT_ASSERT(dst == src2);
  169         }
  170         return SLJIT_SUCCESS;
  171 
  172     case SLJIT_MOV_U8:
  173     case SLJIT_MOV_S8:
  174         SLJIT_ASSERT(src1 == TMP_REG1);
  175         if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
  176             if (op == SLJIT_MOV_S8)
  177                 return push_inst(compiler, EXTSB | S(src2) | A(dst));
  178             return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
  179         }
  180         else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
  181             return push_inst(compiler, EXTSB | S(src2) | A(dst));
  182         else {
  183             SLJIT_ASSERT(dst == src2);
  184         }
  185         return SLJIT_SUCCESS;
  186 
  187     case SLJIT_MOV_U16:
  188     case SLJIT_MOV_S16:
  189         SLJIT_ASSERT(src1 == TMP_REG1);
  190         if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
  191             if (op == SLJIT_MOV_S16)
  192                 return push_inst(compiler, EXTSH | S(src2) | A(dst));
  193             return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
  194         }
  195         else {
  196             SLJIT_ASSERT(dst == src2);
  197         }
  198         return SLJIT_SUCCESS;
  199 
  200     case SLJIT_NOT:
  201         SLJIT_ASSERT(src1 == TMP_REG1);
  202         UN_EXTS();
  203         return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
  204 
  205     case SLJIT_NEG:
  206         SLJIT_ASSERT(src1 == TMP_REG1);
  207 
  208         if ((flags & (ALT_FORM1 | ALT_SIGN_EXT)) == (ALT_FORM1 | ALT_SIGN_EXT)) {
  209             FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, src2, 32, 31, 1)));
  210             FAIL_IF(push_inst(compiler, NEG | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(TMP_REG2)));
  211             return push_inst(compiler, RLDI(dst, dst, 32, 32, 0));
  212         }
  213 
  214         UN_EXTS();
  215         /* Setting XER SO is not enough, CR SO is also needed. */
  216         return push_inst(compiler, NEG | OE((flags & ALT_FORM1) ? ALT_SET_FLAGS : 0) | RC(flags) | D(dst) | A(src2));
  217 
  218     case SLJIT_CLZ:
  219         SLJIT_ASSERT(src1 == TMP_REG1);
  220         if (flags & ALT_FORM1)
  221             return push_inst(compiler, CNTLZW | S(src2) | A(dst));
  222         return push_inst(compiler, CNTLZD | S(src2) | A(dst));
  223 
  224     case SLJIT_ADD:
  225         if (flags & ALT_FORM1) {
  226             if (flags & ALT_SIGN_EXT) {
  227                 FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, src1, 32, 31, 1)));
  228                 src1 = TMP_REG1;
  229                 FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, src2, 32, 31, 1)));
  230                 src2 = TMP_REG2;
  231             }
  232             /* Setting XER SO is not enough, CR SO is also needed. */
  233             FAIL_IF(push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2)));
  234             if (flags & ALT_SIGN_EXT)
  235                 return push_inst(compiler, RLDI(dst, dst, 32, 32, 0));
  236             return SLJIT_SUCCESS;
  237         }
  238 
  239         if (flags & ALT_FORM2) {
  240             /* Flags does not set: BIN_IMM_EXTS unnecessary. */
  241             SLJIT_ASSERT(src2 == TMP_REG2);
  242 
  243             if (flags & ALT_FORM3)
  244                 return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
  245 
  246             if (flags & ALT_FORM4) {
  247                 FAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))));
  248                 src1 = dst;
  249             }
  250 
  251             return push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff));
  252         }
  253         if (flags & ALT_FORM3) {
  254             SLJIT_ASSERT(src2 == TMP_REG2);
  255             BIN_IMM_EXTS();
  256             return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
  257         }
  258         if (!(flags & ALT_SET_FLAGS))
  259             return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
  260         BIN_EXTS();
  261         if (flags & ALT_FORM4)
  262             return push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
  263         return push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));
  264 
  265     case SLJIT_ADDC:
  266         BIN_EXTS();
  267         return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
  268 
  269     case SLJIT_SUB:
  270         if (flags & ALT_FORM1) {
  271             if (flags & ALT_FORM2) {
  272                 FAIL_IF(push_inst(compiler, CMPLI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
  273                 if (!(flags & ALT_FORM3))
  274                     return SLJIT_SUCCESS;
  275                 return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
  276             }
  277             FAIL_IF(push_inst(compiler, CMPL | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
  278             if (!(flags & ALT_FORM3))
  279                 return SLJIT_SUCCESS;
  280             return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
  281         }
  282 
  283         if (flags & ALT_FORM2) {
  284             if (flags & ALT_SIGN_EXT) {
  285                 FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, src1, 32, 31, 1)));
  286                 src1 = TMP_REG1;
  287                 FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, src2, 32, 31, 1)));
  288                 src2 = TMP_REG2;
  289             }
  290             /* Setting XER SO is not enough, CR SO is also needed. */
  291             FAIL_IF(push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1)));
  292             if (flags & ALT_SIGN_EXT)
  293                 return push_inst(compiler, RLDI(dst, dst, 32, 32, 0));
  294             return SLJIT_SUCCESS;
  295         }
  296 
  297         if (flags & ALT_FORM3) {
  298             /* Flags does not set: BIN_IMM_EXTS unnecessary. */
  299             SLJIT_ASSERT(src2 == TMP_REG2);
  300             return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
  301         }
  302 
  303         if (flags & ALT_FORM4) {
  304             if (flags & ALT_FORM5) {
  305                 SLJIT_ASSERT(src2 == TMP_REG2);
  306                 return push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm);
  307             }
  308             return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2));
  309         }
  310 
  311         if (!(flags & ALT_SET_FLAGS))
  312             return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
  313         BIN_EXTS();
  314         if (flags & ALT_FORM5)
  315             return push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
  316         return push_inst(compiler, SUBF | RC(flags) | D(dst) | A(src2) | B(src1));
  317 
  318     case SLJIT_SUBC:
  319         BIN_EXTS();
  320         return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
  321 
  322     case SLJIT_MUL:
  323         if (flags & ALT_FORM1) {
  324             SLJIT_ASSERT(src2 == TMP_REG2);
  325             return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
  326         }
  327         BIN_EXTS();
  328         if (flags & ALT_FORM2)
  329             return push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
  330         return push_inst(compiler, MULLD | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
  331 
  332     case SLJIT_AND:
  333         if (flags & ALT_FORM1) {
  334             SLJIT_ASSERT(src2 == TMP_REG2);
  335             return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
  336         }
  337         if (flags & ALT_FORM2) {
  338             SLJIT_ASSERT(src2 == TMP_REG2);
  339             return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
  340         }
  341         return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
  342 
  343     case SLJIT_OR:
  344         if (flags & ALT_FORM1) {
  345             SLJIT_ASSERT(src2 == TMP_REG2);
  346             return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
  347         }
  348         if (flags & ALT_FORM2) {
  349             SLJIT_ASSERT(src2 == TMP_REG2);
  350             return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
  351         }
  352         if (flags & ALT_FORM3) {
  353             SLJIT_ASSERT(src2 == TMP_REG2);
  354             FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));
  355             return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
  356         }
  357         return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
  358 
  359     case SLJIT_XOR:
  360         if (flags & ALT_FORM1) {
  361             SLJIT_ASSERT(src2 == TMP_REG2);
  362             return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
  363         }
  364         if (flags & ALT_FORM2) {
  365             SLJIT_ASSERT(src2 == TMP_REG2);
  366             return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
  367         }
  368         if (flags & ALT_FORM3) {
  369             SLJIT_ASSERT(src2 == TMP_REG2);
  370             FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));
  371             return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
  372         }
  373         return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
  374 
  375     case SLJIT_SHL:
  376         if (flags & ALT_FORM1) {
  377             SLJIT_ASSERT(src2 == TMP_REG2);
  378             if (flags & ALT_FORM2) {
  379                 compiler->imm &= 0x1f;
  380                 return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
  381             }
  382             compiler->imm &= 0x3f;
  383             return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags));
  384         }
  385         return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2));
  386 
  387     case SLJIT_LSHR:
  388         if (flags & ALT_FORM1) {
  389             SLJIT_ASSERT(src2 == TMP_REG2);
  390             if (flags & ALT_FORM2) {
  391                 compiler->imm &= 0x1f;
  392                 return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
  393             }
  394             compiler->imm &= 0x3f;
  395             return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags));
  396         }
  397         return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2));
  398 
  399     case SLJIT_ASHR:
  400         if (flags & ALT_FORM1) {
  401             SLJIT_ASSERT(src2 == TMP_REG2);
  402             if (flags & ALT_FORM2) {
  403                 compiler->imm &= 0x1f;
  404                 return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
  405             }
  406             compiler->imm &= 0x3f;
  407             return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4));
  408         }
  409         return push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2));
  410     }
  411 
  412     SLJIT_UNREACHABLE();
  413     return SLJIT_SUCCESS;
  414 }
  415 
  416 static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
  417 {
  418     sljit_s32 arg_count = 0;
  419     sljit_s32 word_arg_count = 0;
  420     sljit_s32 types = 0;
  421     sljit_s32 reg = 0;
  422 
  423     if (src)
  424         reg = *src & REG_MASK;
  425 
  426     arg_types >>= SLJIT_DEF_SHIFT;
  427 
  428     while (arg_types) {
  429         types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
  430 
  431         switch (arg_types & SLJIT_DEF_MASK) {
  432         case SLJIT_ARG_TYPE_F32:
  433         case SLJIT_ARG_TYPE_F64:
  434             arg_count++;
  435             break;
  436         default:
  437             arg_count++;
  438             word_arg_count++;
  439 
  440             if (arg_count != word_arg_count && arg_count == reg) {
  441                 FAIL_IF(push_inst(compiler, OR | S(reg) | A(TMP_CALL_REG) | B(reg)));
  442                 *src = TMP_CALL_REG;
  443             }
  444             break;
  445         }
  446 
  447         arg_types >>= SLJIT_DEF_SHIFT;
  448     }
  449 
  450     while (types) {
  451         switch (types & SLJIT_DEF_MASK) {
  452         case SLJIT_ARG_TYPE_F32:
  453         case SLJIT_ARG_TYPE_F64:
  454             arg_count--;
  455             break;
  456         default:
  457             if (arg_count != word_arg_count)
  458                 FAIL_IF(push_inst(compiler, OR | S(word_arg_count) | A(arg_count) | B(word_arg_count)));
  459 
  460             arg_count--;
  461             word_arg_count--;
  462             break;
  463         }
  464 
  465         types >>= SLJIT_DEF_SHIFT;
  466     }
  467 
  468     return SLJIT_SUCCESS;
  469 }
  470 
  471 static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
  472 {
  473     FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));
  474     FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));
  475     FAIL_IF(PUSH_RLDICR(reg, 31));
  476     FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16)));
  477     return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
  478 }
  479 
  480 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
  481 {
  482     sljit_ins *inst = (sljit_ins*)addr;
  483 
  484     inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
  485     inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
  486     inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
  487     inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff);
  488     inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
  489     SLJIT_CACHE_FLUSH(inst, inst + 5);
  490 }
  491 
  492 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
  493 {
  494     sljit_ins *inst = (sljit_ins*)addr;
  495 
  496     inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
  497     inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
  498     inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
  499     inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
  500     inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
  501     SLJIT_CACHE_FLUSH(inst, inst + 5);
  502 }