"Fossies" - the Fresh Open Source Software Archive

Member "pcre-8.43/sljit/sljitNativePPC_32.c" (26 Apr 2017, 10279 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_32.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 8.40_vs_8.41.

    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 32-bit arch dependent functions. */
   28 
   29 static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
   30 {
   31     if (imm <= SIMM_MAX && imm >= SIMM_MIN)
   32         return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
   33 
   34     if (!(imm & ~0xffff))
   35         return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));
   36 
   37     FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
   38     return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
   39 }
   40 
   41 #define INS_CLEAR_LEFT(dst, src, from) \
   42     (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1))
   43 
   44 static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
   45     sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
   46 {
   47     switch (op) {
   48     case SLJIT_MOV:
   49     case SLJIT_MOV_U32:
   50     case SLJIT_MOV_S32:
   51     case SLJIT_MOV_P:
   52         SLJIT_ASSERT(src1 == TMP_REG1);
   53         if (dst != src2)
   54             return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
   55         return SLJIT_SUCCESS;
   56 
   57     case SLJIT_MOV_U8:
   58     case SLJIT_MOV_S8:
   59         SLJIT_ASSERT(src1 == TMP_REG1);
   60         if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
   61             if (op == SLJIT_MOV_S8)
   62                 return push_inst(compiler, EXTSB | S(src2) | A(dst));
   63             return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
   64         }
   65         else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
   66             return push_inst(compiler, EXTSB | S(src2) | A(dst));
   67         else {
   68             SLJIT_ASSERT(dst == src2);
   69         }
   70         return SLJIT_SUCCESS;
   71 
   72     case SLJIT_MOV_U16:
   73     case SLJIT_MOV_S16:
   74         SLJIT_ASSERT(src1 == TMP_REG1);
   75         if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
   76             if (op == SLJIT_MOV_S16)
   77                 return push_inst(compiler, EXTSH | S(src2) | A(dst));
   78             return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
   79         }
   80         else {
   81             SLJIT_ASSERT(dst == src2);
   82         }
   83         return SLJIT_SUCCESS;
   84 
   85     case SLJIT_NOT:
   86         SLJIT_ASSERT(src1 == TMP_REG1);
   87         return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
   88 
   89     case SLJIT_NEG:
   90         SLJIT_ASSERT(src1 == TMP_REG1);
   91         /* Setting XER SO is not enough, CR SO is also needed. */
   92         return push_inst(compiler, NEG | OE((flags & ALT_FORM1) ? ALT_SET_FLAGS : 0) | RC(flags) | D(dst) | A(src2));
   93 
   94     case SLJIT_CLZ:
   95         SLJIT_ASSERT(src1 == TMP_REG1);
   96         return push_inst(compiler, CNTLZW | S(src2) | A(dst));
   97 
   98     case SLJIT_ADD:
   99         if (flags & ALT_FORM1) {
  100             /* Setting XER SO is not enough, CR SO is also needed. */
  101             return push_inst(compiler, ADD | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
  102         }
  103 
  104         if (flags & ALT_FORM2) {
  105             /* Flags does not set: BIN_IMM_EXTS unnecessary. */
  106             SLJIT_ASSERT(src2 == TMP_REG2);
  107 
  108             if (flags & ALT_FORM3)
  109                 return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
  110 
  111             if (flags & ALT_FORM4) {
  112                 FAIL_IF(push_inst(compiler, ADDIS | D(dst) | A(src1) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1))));
  113                 src1 = dst;
  114             }
  115 
  116             return push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff));
  117         }
  118         if (flags & ALT_FORM3) {
  119             SLJIT_ASSERT(src2 == TMP_REG2);
  120             return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
  121         }
  122         if (!(flags & ALT_SET_FLAGS))
  123             return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
  124         if (flags & ALT_FORM4)
  125             return push_inst(compiler, ADDC | RC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
  126         return push_inst(compiler, ADD | RC(flags) | D(dst) | A(src1) | B(src2));
  127 
  128     case SLJIT_ADDC:
  129         return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
  130 
  131     case SLJIT_SUB:
  132         if (flags & ALT_FORM1) {
  133             if (flags & ALT_FORM2) {
  134                 FAIL_IF(push_inst(compiler, CMPLI | CRD(0) | A(src1) | compiler->imm));
  135                 if (!(flags & ALT_FORM3))
  136                     return SLJIT_SUCCESS;
  137                 return push_inst(compiler, ADDI | D(dst) | A(src1) | (-compiler->imm & 0xffff));
  138             }
  139             FAIL_IF(push_inst(compiler, CMPL | CRD(0) | A(src1) | B(src2)));
  140             if (!(flags & ALT_FORM3))
  141                 return SLJIT_SUCCESS;
  142             return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
  143         }
  144 
  145         if (flags & ALT_FORM2) {
  146             /* Setting XER SO is not enough, CR SO is also needed. */
  147             return push_inst(compiler, SUBF | OE(ALT_SET_FLAGS) | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
  148         }
  149 
  150         if (flags & ALT_FORM3) {
  151             /* Flags does not set: BIN_IMM_EXTS unnecessary. */
  152             SLJIT_ASSERT(src2 == TMP_REG2);
  153             return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
  154         }
  155 
  156         if (flags & ALT_FORM4) {
  157             if (flags & ALT_FORM5) {
  158                 SLJIT_ASSERT(src2 == TMP_REG2);
  159                 return push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm);
  160             }
  161             return push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2));
  162         }
  163 
  164         if (!(flags & ALT_SET_FLAGS))
  165             return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
  166         if (flags & ALT_FORM5)
  167             return push_inst(compiler, SUBFC | RC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
  168         return push_inst(compiler, SUBF | RC(flags) | D(dst) | A(src2) | B(src1));
  169 
  170     case SLJIT_SUBC:
  171         return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
  172 
  173     case SLJIT_MUL:
  174         if (flags & ALT_FORM1) {
  175             SLJIT_ASSERT(src2 == TMP_REG2);
  176             return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
  177         }
  178         return push_inst(compiler, MULLW | OE(flags) | RC(flags) | D(dst) | A(src2) | B(src1));
  179 
  180     case SLJIT_AND:
  181         if (flags & ALT_FORM1) {
  182             SLJIT_ASSERT(src2 == TMP_REG2);
  183             return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
  184         }
  185         if (flags & ALT_FORM2) {
  186             SLJIT_ASSERT(src2 == TMP_REG2);
  187             return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
  188         }
  189         return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
  190 
  191     case SLJIT_OR:
  192         if (flags & ALT_FORM1) {
  193             SLJIT_ASSERT(src2 == TMP_REG2);
  194             return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
  195         }
  196         if (flags & ALT_FORM2) {
  197             SLJIT_ASSERT(src2 == TMP_REG2);
  198             return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
  199         }
  200         if (flags & ALT_FORM3) {
  201             SLJIT_ASSERT(src2 == TMP_REG2);
  202             FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));
  203             return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
  204         }
  205         return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
  206 
  207     case SLJIT_XOR:
  208         if (flags & ALT_FORM1) {
  209             SLJIT_ASSERT(src2 == TMP_REG2);
  210             return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
  211         }
  212         if (flags & ALT_FORM2) {
  213             SLJIT_ASSERT(src2 == TMP_REG2);
  214             return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
  215         }
  216         if (flags & ALT_FORM3) {
  217             SLJIT_ASSERT(src2 == TMP_REG2);
  218             FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));
  219             return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
  220         }
  221         return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
  222 
  223     case SLJIT_SHL:
  224         if (flags & ALT_FORM1) {
  225             SLJIT_ASSERT(src2 == TMP_REG2);
  226             compiler->imm &= 0x1f;
  227             return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
  228         }
  229         return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));
  230 
  231     case SLJIT_LSHR:
  232         if (flags & ALT_FORM1) {
  233             SLJIT_ASSERT(src2 == TMP_REG2);
  234             compiler->imm &= 0x1f;
  235             return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
  236         }
  237         return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
  238 
  239     case SLJIT_ASHR:
  240         if (flags & ALT_FORM1) {
  241             SLJIT_ASSERT(src2 == TMP_REG2);
  242             compiler->imm &= 0x1f;
  243             return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
  244         }
  245         return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
  246     }
  247 
  248     SLJIT_UNREACHABLE();
  249     return SLJIT_SUCCESS;
  250 }
  251 
  252 static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
  253 {
  254     FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));
  255     return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
  256 }
  257 
  258 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
  259 {
  260     sljit_ins *inst = (sljit_ins *)addr;
  261 
  262     inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
  263     inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
  264     inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
  265     SLJIT_CACHE_FLUSH(inst, inst + 2);
  266 }
  267 
  268 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
  269 {
  270     sljit_ins *inst = (sljit_ins *)addr;
  271 
  272     inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
  273     inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
  274     inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
  275     SLJIT_CACHE_FLUSH(inst, inst + 2);
  276 }