"Fossies" - the Fresh Open Source Software Archive

Member "pcre-8.43/sljit/sljitNativeSPARC_32.c" (30 Nov 2017, 11005 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 "sljitNativeSPARC_32.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 static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw imm)
   28 {
   29     if (imm <= SIMM_MAX && imm >= SIMM_MIN)
   30         return push_inst(compiler, OR | D(dst) | S1(0) | IMM(imm), DR(dst));
   31 
   32     FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((imm >> 10) & 0x3fffff), DR(dst)));
   33     return (imm & 0x3ff) ? push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (imm & 0x3ff), DR(dst)) : SLJIT_SUCCESS;
   34 }
   35 
   36 #define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2))
   37 
   38 static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
   39     sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
   40 {
   41     SLJIT_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same);
   42 
   43     switch (op) {
   44     case SLJIT_MOV:
   45     case SLJIT_MOV_U32:
   46     case SLJIT_MOV_S32:
   47     case SLJIT_MOV_P:
   48         SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
   49         if (dst != src2)
   50             return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst));
   51         return SLJIT_SUCCESS;
   52 
   53     case SLJIT_MOV_U8:
   54     case SLJIT_MOV_S8:
   55         SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
   56         if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
   57             if (op == SLJIT_MOV_U8)
   58                 return push_inst(compiler, AND | D(dst) | S1(src2) | IMM(0xff), DR(dst));
   59             FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst)));
   60             return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst));
   61         }
   62         else if (dst != src2)
   63             SLJIT_UNREACHABLE();
   64         return SLJIT_SUCCESS;
   65 
   66     case SLJIT_MOV_U16:
   67     case SLJIT_MOV_S16:
   68         SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
   69         if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
   70             FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst)));
   71             return push_inst(compiler, (op == SLJIT_MOV_S16 ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst));
   72         }
   73         else if (dst != src2)
   74             SLJIT_UNREACHABLE();
   75         return SLJIT_SUCCESS;
   76 
   77     case SLJIT_NOT:
   78         SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
   79         return push_inst(compiler, XNOR | (flags & SET_FLAGS) | D(dst) | S1(0) | S2(src2), DR(dst) | (flags & SET_FLAGS));
   80 
   81     case SLJIT_CLZ:
   82         SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
   83         FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(src2) | S2(0), SET_FLAGS));
   84         FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2(src2), DR(TMP_REG1)));
   85         FAIL_IF(push_inst(compiler, BICC | DA(0x1) | (7 & DISP_MASK), UNMOVABLE_INS));
   86         FAIL_IF(push_inst(compiler, OR | D(dst) | S1(0) | IMM(32), UNMOVABLE_INS));
   87         FAIL_IF(push_inst(compiler, OR | D(dst) | S1(0) | IMM(-1), DR(dst)));
   88 
   89         /* Loop. */
   90         FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(0), SET_FLAGS));
   91         FAIL_IF(push_inst(compiler, SLL | D(TMP_REG1) | S1(TMP_REG1) | IMM(1), DR(TMP_REG1)));
   92         FAIL_IF(push_inst(compiler, BICC | DA(0xe) | (-2 & DISP_MASK), UNMOVABLE_INS));
   93         return push_inst(compiler, ADD | D(dst) | S1(dst) | IMM(1), UNMOVABLE_INS);
   94 
   95     case SLJIT_ADD:
   96         return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
   97 
   98     case SLJIT_ADDC:
   99         return push_inst(compiler, ADDC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
  100 
  101     case SLJIT_SUB:
  102         return push_inst(compiler, SUB | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
  103 
  104     case SLJIT_SUBC:
  105         return push_inst(compiler, SUBC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
  106 
  107     case SLJIT_MUL:
  108         FAIL_IF(push_inst(compiler, SMUL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));
  109         if (!(flags & SET_FLAGS))
  110             return SLJIT_SUCCESS;
  111         FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(dst) | IMM(31), DR(TMP_REG1)));
  112         FAIL_IF(push_inst(compiler, RDY | D(TMP_LINK), DR(TMP_LINK)));
  113         return push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(TMP_LINK), MOVABLE_INS | SET_FLAGS);
  114 
  115     case SLJIT_AND:
  116         return push_inst(compiler, AND | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
  117 
  118     case SLJIT_OR:
  119         return push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
  120 
  121     case SLJIT_XOR:
  122         return push_inst(compiler, XOR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
  123 
  124     case SLJIT_SHL:
  125         FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));
  126         return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);
  127 
  128     case SLJIT_LSHR:
  129         FAIL_IF(push_inst(compiler, SRL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));
  130         return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);
  131 
  132     case SLJIT_ASHR:
  133         FAIL_IF(push_inst(compiler, SRA | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));
  134         return !(flags & SET_FLAGS) ? SLJIT_SUCCESS : push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(dst) | S2(0), SET_FLAGS);
  135     }
  136 
  137     SLJIT_UNREACHABLE();
  138     return SLJIT_SUCCESS;
  139 }
  140 
  141 static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
  142 {
  143     sljit_s32 reg_index = 8;
  144     sljit_s32 word_reg_index = 8;
  145     sljit_s32 float_arg_index = 1;
  146     sljit_s32 double_arg_count = 0;
  147     sljit_s32 float_offset = (16 + 6) * sizeof(sljit_sw);
  148     sljit_s32 types = 0;
  149     sljit_s32 reg = 0;
  150     sljit_s32 move_to_tmp2 = 0;
  151 
  152     if (src)
  153         reg = reg_map[*src & REG_MASK];
  154 
  155     arg_types >>= SLJIT_DEF_SHIFT;
  156 
  157     while (arg_types) {
  158         types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
  159 
  160         switch (arg_types & SLJIT_DEF_MASK) {
  161         case SLJIT_ARG_TYPE_F32:
  162             float_arg_index++;
  163             if (reg_index == reg)
  164                 move_to_tmp2 = 1;
  165             reg_index++;
  166             break;
  167         case SLJIT_ARG_TYPE_F64:
  168             float_arg_index++;
  169             double_arg_count++;
  170             if (reg_index == reg || reg_index + 1 == reg)
  171                 move_to_tmp2 = 1;
  172             reg_index += 2;
  173             break;
  174         default:
  175             if (reg_index != word_reg_index && reg_index < 14 && reg_index == reg)
  176                 move_to_tmp2 = 1;
  177             reg_index++;
  178             word_reg_index++;
  179             break;
  180         }
  181 
  182         if (move_to_tmp2) {
  183             move_to_tmp2 = 0;
  184             if (reg < 14)
  185                 FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2A(reg), DR(TMP_REG1)));
  186             *src = TMP_REG1;
  187         }
  188 
  189         arg_types >>= SLJIT_DEF_SHIFT;
  190     }
  191 
  192     arg_types = types;
  193 
  194     while (arg_types) {
  195         switch (arg_types & SLJIT_DEF_MASK) {
  196         case SLJIT_ARG_TYPE_F32:
  197             float_arg_index--;
  198             FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
  199             float_offset -= sizeof(sljit_f64);
  200             break;
  201         case SLJIT_ARG_TYPE_F64:
  202             float_arg_index--;
  203             if (float_arg_index == 4 && double_arg_count == 4) {
  204                 FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | S1(SLJIT_SP) | IMM((16 + 7) * sizeof(sljit_sw)), MOVABLE_INS));
  205                 FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | (1 << 25) | S1(SLJIT_SP) | IMM((16 + 8) * sizeof(sljit_sw)), MOVABLE_INS));
  206             }
  207             else
  208                 FAIL_IF(push_inst(compiler, STDF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
  209             float_offset -= sizeof(sljit_f64);
  210             break;
  211         default:
  212             break;
  213         }
  214 
  215         arg_types >>= SLJIT_DEF_SHIFT;
  216     }
  217 
  218     float_offset = (16 + 6) * sizeof(sljit_sw);
  219 
  220     while (types) {
  221         switch (types & SLJIT_DEF_MASK) {
  222         case SLJIT_ARG_TYPE_F32:
  223             reg_index--;
  224             if (reg_index < 14)
  225                 FAIL_IF(push_inst(compiler, LDUW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
  226             float_offset -= sizeof(sljit_f64);
  227             break;
  228         case SLJIT_ARG_TYPE_F64:
  229             reg_index -= 2;
  230             if (reg_index < 14) {
  231                 if ((reg_index & 0x1) != 0) {
  232                     FAIL_IF(push_inst(compiler, LDUW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
  233                     if (reg_index < 13)
  234                         FAIL_IF(push_inst(compiler, LDUW | DA(reg_index + 1) | S1(SLJIT_SP) | IMM(float_offset + sizeof(sljit_sw)), reg_index + 1));
  235                 }
  236                 else 
  237                     FAIL_IF(push_inst(compiler, LDD | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
  238             }
  239             float_offset -= sizeof(sljit_f64);
  240             break;
  241         default:
  242             reg_index--;
  243             word_reg_index--;
  244 
  245             if (reg_index != word_reg_index) {
  246                 if (reg_index < 14)
  247                     FAIL_IF(push_inst(compiler, OR | DA(reg_index) | S1(0) | S2A(word_reg_index), reg_index));
  248                 else
  249                     FAIL_IF(push_inst(compiler, STW | DA(word_reg_index) | S1(SLJIT_SP) | IMM(92), word_reg_index));
  250             }
  251             break;
  252         }
  253 
  254         types >>= SLJIT_DEF_SHIFT;
  255     }
  256 
  257     return SLJIT_SUCCESS;
  258 }
  259 
  260 static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
  261 {
  262     FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst)));
  263     return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst));
  264 }
  265 
  266 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
  267 {
  268     sljit_ins *inst = (sljit_ins *)addr;
  269 
  270     inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);
  271     inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);
  272     inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
  273     SLJIT_CACHE_FLUSH(inst, inst + 2);
  274 }
  275 
  276 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
  277 {
  278     sljit_ins *inst = (sljit_ins *)addr;
  279 
  280     inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
  281     inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
  282     inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
  283     SLJIT_CACHE_FLUSH(inst, inst + 2);
  284 }