"Fossies" - the Fresh Open Source Software Archive

Member "pcre-8.44/sljit/sljitNativeSPARC_common.c" (17 Jul 2019, 49021 Bytes) of package /linux/misc/pcre-8.44.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_common.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 8.43_vs_8.44.

    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 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
   28 {
   29     return "SPARC" SLJIT_CPUINFO;
   30 }
   31 
   32 /* Length of an instruction word
   33    Both for sparc-32 and sparc-64 */
   34 typedef sljit_u32 sljit_ins;
   35 
   36 #if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)
   37 
   38 static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
   39 {
   40 #if defined(__SUNPRO_C) && __SUNPRO_C < 0x590
   41     __asm (
   42         /* if (from == to) return */
   43         "cmp %i0, %i1\n"
   44         "be .leave\n"
   45         "nop\n"
   46 
   47         /* loop until from >= to */
   48         ".mainloop:\n"
   49         "flush %i0\n"
   50         "add %i0, 8, %i0\n"
   51         "cmp %i0, %i1\n"
   52         "bcs .mainloop\n"
   53         "nop\n"
   54 
   55         /* The comparison was done above. */
   56         "bne .leave\n"
   57         /* nop is not necessary here, since the
   58            sub operation has no side effect. */
   59         "sub %i0, 4, %i0\n"
   60         "flush %i0\n"
   61         ".leave:"
   62     );
   63 #else
   64     if (SLJIT_UNLIKELY(from == to))
   65         return;
   66 
   67     do {
   68         __asm__ volatile (
   69             "flush %0\n"
   70             : : "r"(from)
   71         );
   72         /* Operates at least on doubleword. */
   73         from += 2;
   74     } while (from < to);
   75 
   76     if (from == to) {
   77         /* Flush the last word. */
   78         from --;
   79         __asm__ volatile (
   80             "flush %0\n"
   81             : : "r"(from)
   82         );
   83     }
   84 #endif
   85 }
   86 
   87 #endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */
   88 
   89 /* TMP_REG2 is not used by getput_arg */
   90 #define TMP_REG1    (SLJIT_NUMBER_OF_REGISTERS + 2)
   91 #define TMP_REG2    (SLJIT_NUMBER_OF_REGISTERS + 3)
   92 #define TMP_REG3    (SLJIT_NUMBER_OF_REGISTERS + 4)
   93 /* This register is modified by calls, which affects the instruction
   94    in the delay slot if it is used as a source register. */
   95 #define TMP_LINK    (SLJIT_NUMBER_OF_REGISTERS + 5)
   96 
   97 #define TMP_FREG1   (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
   98 #define TMP_FREG2   (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
   99 
  100 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
  101     0, 8, 9, 10, 11, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 12, 13, 15
  102 };
  103 
  104 static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
  105     0, 0, 2, 4, 6, 8, 10, 12, 14
  106 };
  107 
  108 /* --------------------------------------------------------------------- */
  109 /*  Instrucion forms                                                     */
  110 /* --------------------------------------------------------------------- */
  111 
  112 #define D(d)        (reg_map[d] << 25)
  113 #define FD(d)       (freg_map[d] << 25)
  114 #define FDN(d)      ((freg_map[d] | 0x1) << 25)
  115 #define DA(d)       ((d) << 25)
  116 #define S1(s1)      (reg_map[s1] << 14)
  117 #define FS1(s1)     (freg_map[s1] << 14)
  118 #define S1A(s1)     ((s1) << 14)
  119 #define S2(s2)      (reg_map[s2])
  120 #define FS2(s2)     (freg_map[s2])
  121 #define FS2N(s2)    (freg_map[s2] | 0x1)
  122 #define S2A(s2)     (s2)
  123 #define IMM_ARG     0x2000
  124 #define DOP(op)     ((op) << 5)
  125 #define IMM(imm)    (((imm) & 0x1fff) | IMM_ARG)
  126 
  127 #define DR(dr)      (reg_map[dr])
  128 #define OPC1(opcode)    ((opcode) << 30)
  129 #define OPC2(opcode)    ((opcode) << 22)
  130 #define OPC3(opcode)    ((opcode) << 19)
  131 #define SET_FLAGS   OPC3(0x10)
  132 
  133 #define ADD     (OPC1(0x2) | OPC3(0x00))
  134 #define ADDC        (OPC1(0x2) | OPC3(0x08))
  135 #define AND     (OPC1(0x2) | OPC3(0x01))
  136 #define ANDN        (OPC1(0x2) | OPC3(0x05))
  137 #define CALL        (OPC1(0x1))
  138 #define FABSS       (OPC1(0x2) | OPC3(0x34) | DOP(0x09))
  139 #define FADDD       (OPC1(0x2) | OPC3(0x34) | DOP(0x42))
  140 #define FADDS       (OPC1(0x2) | OPC3(0x34) | DOP(0x41))
  141 #define FCMPD       (OPC1(0x2) | OPC3(0x35) | DOP(0x52))
  142 #define FCMPS       (OPC1(0x2) | OPC3(0x35) | DOP(0x51))
  143 #define FDIVD       (OPC1(0x2) | OPC3(0x34) | DOP(0x4e))
  144 #define FDIVS       (OPC1(0x2) | OPC3(0x34) | DOP(0x4d))
  145 #define FDTOI       (OPC1(0x2) | OPC3(0x34) | DOP(0xd2))
  146 #define FDTOS       (OPC1(0x2) | OPC3(0x34) | DOP(0xc6))
  147 #define FITOD       (OPC1(0x2) | OPC3(0x34) | DOP(0xc8))
  148 #define FITOS       (OPC1(0x2) | OPC3(0x34) | DOP(0xc4))
  149 #define FMOVS       (OPC1(0x2) | OPC3(0x34) | DOP(0x01))
  150 #define FMULD       (OPC1(0x2) | OPC3(0x34) | DOP(0x4a))
  151 #define FMULS       (OPC1(0x2) | OPC3(0x34) | DOP(0x49))
  152 #define FNEGS       (OPC1(0x2) | OPC3(0x34) | DOP(0x05))
  153 #define FSTOD       (OPC1(0x2) | OPC3(0x34) | DOP(0xc9))
  154 #define FSTOI       (OPC1(0x2) | OPC3(0x34) | DOP(0xd1))
  155 #define FSUBD       (OPC1(0x2) | OPC3(0x34) | DOP(0x46))
  156 #define FSUBS       (OPC1(0x2) | OPC3(0x34) | DOP(0x45))
  157 #define JMPL        (OPC1(0x2) | OPC3(0x38))
  158 #define LDD     (OPC1(0x3) | OPC3(0x03))
  159 #define LDUW        (OPC1(0x3) | OPC3(0x00))
  160 #define NOP     (OPC1(0x0) | OPC2(0x04))
  161 #define OR      (OPC1(0x2) | OPC3(0x02))
  162 #define ORN     (OPC1(0x2) | OPC3(0x06))
  163 #define RDY     (OPC1(0x2) | OPC3(0x28) | S1A(0))
  164 #define RESTORE     (OPC1(0x2) | OPC3(0x3d))
  165 #define SAVE        (OPC1(0x2) | OPC3(0x3c))
  166 #define SETHI       (OPC1(0x0) | OPC2(0x04))
  167 #define SLL     (OPC1(0x2) | OPC3(0x25))
  168 #define SLLX        (OPC1(0x2) | OPC3(0x25) | (1 << 12))
  169 #define SRA     (OPC1(0x2) | OPC3(0x27))
  170 #define SRAX        (OPC1(0x2) | OPC3(0x27) | (1 << 12))
  171 #define SRL     (OPC1(0x2) | OPC3(0x26))
  172 #define SRLX        (OPC1(0x2) | OPC3(0x26) | (1 << 12))
  173 #define STDF        (OPC1(0x3) | OPC3(0x27))
  174 #define STF     (OPC1(0x3) | OPC3(0x24))
  175 #define STW     (OPC1(0x3) | OPC3(0x04))
  176 #define SUB     (OPC1(0x2) | OPC3(0x04))
  177 #define SUBC        (OPC1(0x2) | OPC3(0x0c))
  178 #define TA      (OPC1(0x2) | OPC3(0x3a) | (8 << 25))
  179 #define WRY     (OPC1(0x2) | OPC3(0x30) | DA(0))
  180 #define XOR     (OPC1(0x2) | OPC3(0x03))
  181 #define XNOR        (OPC1(0x2) | OPC3(0x07))
  182 
  183 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  184 #define MAX_DISP    (0x1fffff)
  185 #define MIN_DISP    (-0x200000)
  186 #define DISP_MASK   (0x3fffff)
  187 
  188 #define BICC        (OPC1(0x0) | OPC2(0x2))
  189 #define FBFCC       (OPC1(0x0) | OPC2(0x6))
  190 #define SLL_W       SLL
  191 #define SDIV        (OPC1(0x2) | OPC3(0x0f))
  192 #define SMUL        (OPC1(0x2) | OPC3(0x0b))
  193 #define UDIV        (OPC1(0x2) | OPC3(0x0e))
  194 #define UMUL        (OPC1(0x2) | OPC3(0x0a))
  195 #else
  196 #define SLL_W       SLLX
  197 #endif
  198 
  199 #define SIMM_MAX    (0x0fff)
  200 #define SIMM_MIN    (-0x1000)
  201 
  202 /* dest_reg is the absolute name of the register
  203    Useful for reordering instructions in the delay slot. */
  204 static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
  205 {
  206     sljit_ins *ptr;
  207     SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS
  208         || (delay_slot & DST_INS_MASK) == MOVABLE_INS
  209         || (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f));
  210     ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
  211     FAIL_IF(!ptr);
  212     *ptr = ins;
  213     compiler->size++;
  214     compiler->delay_slot = delay_slot;
  215     return SLJIT_SUCCESS;
  216 }
  217 
  218 static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
  219 {
  220     sljit_sw diff;
  221     sljit_uw target_addr;
  222     sljit_ins *inst;
  223     sljit_ins saved_inst;
  224 
  225     if (jump->flags & SLJIT_REWRITABLE_JUMP)
  226         return code_ptr;
  227 
  228     if (jump->flags & JUMP_ADDR)
  229         target_addr = jump->u.target;
  230     else {
  231         SLJIT_ASSERT(jump->flags & JUMP_LABEL);
  232         target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
  233     }
  234     inst = (sljit_ins*)jump->addr;
  235 
  236 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  237     if (jump->flags & IS_CALL) {
  238         /* Call is always patchable on sparc 32. */
  239         jump->flags |= PATCH_CALL;
  240         if (jump->flags & IS_MOVABLE) {
  241             inst[0] = inst[-1];
  242             inst[-1] = CALL;
  243             jump->addr -= sizeof(sljit_ins);
  244             return inst;
  245         }
  246         inst[0] = CALL;
  247         inst[1] = NOP;
  248         return inst + 1;
  249     }
  250 #else
  251     /* Both calls and BPr instructions shall not pass this point. */
  252 #error "Implementation required"
  253 #endif
  254 
  255     if (jump->flags & IS_COND)
  256         inst--;
  257 
  258     diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1) - executable_offset) >> 2;
  259 
  260     if (jump->flags & IS_MOVABLE) {
  261         if (diff <= MAX_DISP && diff >= MIN_DISP) {
  262             jump->flags |= PATCH_B;
  263             inst--;
  264             if (jump->flags & IS_COND) {
  265                 saved_inst = inst[0];
  266                 inst[0] = inst[1] ^ (1 << 28);
  267                 inst[1] = saved_inst;
  268             } else {
  269                 inst[1] = inst[0];
  270                 inst[0] = BICC | DA(0x8);
  271             }
  272             jump->addr = (sljit_uw)inst;
  273             return inst + 1;
  274         }
  275     }
  276 
  277     diff += sizeof(sljit_ins);
  278 
  279     if (diff <= MAX_DISP && diff >= MIN_DISP) {
  280         jump->flags |= PATCH_B;
  281         if (jump->flags & IS_COND)
  282             inst[0] ^= (1 << 28);
  283         else
  284             inst[0] = BICC | DA(0x8);
  285         inst[1] = NOP;
  286         jump->addr = (sljit_uw)inst;
  287         return inst + 1;
  288     }
  289 
  290     return code_ptr;
  291 }
  292 
  293 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
  294 {
  295     struct sljit_memory_fragment *buf;
  296     sljit_ins *code;
  297     sljit_ins *code_ptr;
  298     sljit_ins *buf_ptr;
  299     sljit_ins *buf_end;
  300     sljit_uw word_count;
  301     sljit_uw next_addr;
  302     sljit_sw executable_offset;
  303     sljit_uw addr;
  304 
  305     struct sljit_label *label;
  306     struct sljit_jump *jump;
  307     struct sljit_const *const_;
  308     struct sljit_put_label *put_label;
  309 
  310     CHECK_ERROR_PTR();
  311     CHECK_PTR(check_sljit_generate_code(compiler));
  312     reverse_buf(compiler);
  313 
  314     code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
  315     PTR_FAIL_WITH_EXEC_IF(code);
  316     buf = compiler->buf;
  317 
  318     code_ptr = code;
  319     word_count = 0;
  320     next_addr = 0;
  321     executable_offset = SLJIT_EXEC_OFFSET(code);
  322 
  323     label = compiler->labels;
  324     jump = compiler->jumps;
  325     const_ = compiler->consts;
  326     put_label = compiler->put_labels;
  327 
  328     do {
  329         buf_ptr = (sljit_ins*)buf->memory;
  330         buf_end = buf_ptr + (buf->used_size >> 2);
  331         do {
  332             *code_ptr = *buf_ptr++;
  333             if (next_addr == word_count) {
  334                 SLJIT_ASSERT(!label || label->size >= word_count);
  335                 SLJIT_ASSERT(!jump || jump->addr >= word_count);
  336                 SLJIT_ASSERT(!const_ || const_->addr >= word_count);
  337                 SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
  338 
  339                 /* These structures are ordered by their address. */
  340                 if (label && label->size == word_count) {
  341                     /* Just recording the address. */
  342                     label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
  343                     label->size = code_ptr - code;
  344                     label = label->next;
  345                 }
  346                 if (jump && jump->addr == word_count) {
  347 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  348                     jump->addr = (sljit_uw)(code_ptr - 3);
  349 #else
  350                     jump->addr = (sljit_uw)(code_ptr - 6);
  351 #endif
  352                     code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
  353                     jump = jump->next;
  354                 }
  355                 if (const_ && const_->addr == word_count) {
  356                     /* Just recording the address. */
  357                     const_->addr = (sljit_uw)code_ptr;
  358                     const_ = const_->next;
  359                 }
  360                 if (put_label && put_label->addr == word_count) {
  361                     SLJIT_ASSERT(put_label->label);
  362                     put_label->addr = (sljit_uw)code_ptr;
  363                     put_label = put_label->next;
  364                 }
  365                 next_addr = compute_next_addr(label, jump, const_, put_label);
  366             }
  367             code_ptr ++;
  368             word_count ++;
  369         } while (buf_ptr < buf_end);
  370 
  371         buf = buf->next;
  372     } while (buf);
  373 
  374     if (label && label->size == word_count) {
  375         label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
  376         label->size = code_ptr - code;
  377         label = label->next;
  378     }
  379 
  380     SLJIT_ASSERT(!label);
  381     SLJIT_ASSERT(!jump);
  382     SLJIT_ASSERT(!const_);
  383     SLJIT_ASSERT(!put_label);
  384     SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size);
  385 
  386     jump = compiler->jumps;
  387     while (jump) {
  388         do {
  389             addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
  390             buf_ptr = (sljit_ins *)jump->addr;
  391 
  392             if (jump->flags & PATCH_CALL) {
  393                 addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
  394                 SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
  395                 buf_ptr[0] = CALL | (addr & 0x3fffffff);
  396                 break;
  397             }
  398             if (jump->flags & PATCH_B) {
  399                 addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
  400                 SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
  401                 buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
  402                 break;
  403             }
  404 
  405             /* Set the fields of immediate loads. */
  406 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  407             SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000));
  408             buf_ptr[0] |= (addr >> 10) & 0x3fffff;
  409             buf_ptr[1] |= addr & 0x3ff;
  410 #else
  411 #error "Implementation required"
  412 #endif
  413         } while (0);
  414         jump = jump->next;
  415     }
  416 
  417     put_label = compiler->put_labels;
  418     while (put_label) {
  419         addr = put_label->label->addr;
  420         buf_ptr = (sljit_ins *)put_label->addr;
  421 
  422 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  423         SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000));
  424         buf_ptr[0] |= (addr >> 10) & 0x3fffff;
  425         buf_ptr[1] |= addr & 0x3ff;
  426 #else
  427 #error "Implementation required"
  428 #endif
  429         put_label = put_label->next;
  430     }
  431 
  432     compiler->error = SLJIT_ERR_COMPILED;
  433     compiler->executable_offset = executable_offset;
  434     compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
  435 
  436     code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
  437     code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
  438 
  439     SLJIT_CACHE_FLUSH(code, code_ptr);
  440     return code;
  441 }
  442 
  443 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
  444 {
  445     switch (feature_type) {
  446     case SLJIT_HAS_FPU:
  447 #ifdef SLJIT_IS_FPU_AVAILABLE
  448         return SLJIT_IS_FPU_AVAILABLE;
  449 #else
  450         /* Available by default. */
  451         return 1;
  452 #endif
  453 
  454 #if (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64)
  455     case SLJIT_HAS_CMOV:
  456         return 1;
  457 #endif
  458 
  459     default:
  460         return 0;
  461     }
  462 }
  463 
  464 /* --------------------------------------------------------------------- */
  465 /*  Entry, exit                                                          */
  466 /* --------------------------------------------------------------------- */
  467 
  468 /* Creates an index in data_transfer_insts array. */
  469 #define LOAD_DATA   0x01
  470 #define WORD_DATA   0x00
  471 #define BYTE_DATA   0x02
  472 #define HALF_DATA   0x04
  473 #define INT_DATA    0x06
  474 #define SIGNED_DATA 0x08
  475 /* Separates integer and floating point registers */
  476 #define GPR_REG     0x0f
  477 #define DOUBLE_DATA 0x10
  478 #define SINGLE_DATA 0x12
  479 
  480 #define MEM_MASK    0x1f
  481 
  482 #define ARG_TEST    0x00020
  483 #define ALT_KEEP_CACHE  0x00040
  484 #define CUMULATIVE_OP   0x00080
  485 #define IMM_OP      0x00100
  486 #define SRC2_IMM    0x00200
  487 
  488 #define REG_DEST    0x00400
  489 #define REG2_SOURCE 0x00800
  490 #define SLOW_SRC1   0x01000
  491 #define SLOW_SRC2   0x02000
  492 #define SLOW_DEST   0x04000
  493 
  494 /* SET_FLAGS (0x10 << 19) also belong here! */
  495 
  496 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  497 #include "sljitNativeSPARC_32.c"
  498 #else
  499 #include "sljitNativeSPARC_64.c"
  500 #endif
  501 
  502 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
  503     sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
  504     sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
  505 {
  506     CHECK_ERROR();
  507     CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
  508     set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
  509 
  510     local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
  511     compiler->local_size = local_size;
  512 
  513     if (local_size <= SIMM_MAX) {
  514         FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | IMM(-local_size), UNMOVABLE_INS));
  515     }
  516     else {
  517         FAIL_IF(load_immediate(compiler, TMP_REG1, -local_size));
  518         FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | S2(TMP_REG1), UNMOVABLE_INS));
  519     }
  520 
  521     /* Arguments are in their appropriate registers. */
  522 
  523     return SLJIT_SUCCESS;
  524 }
  525 
  526 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
  527     sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
  528     sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
  529 {
  530     CHECK_ERROR();
  531     CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
  532     set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
  533 
  534     compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
  535     return SLJIT_SUCCESS;
  536 }
  537 
  538 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
  539 {
  540     CHECK_ERROR();
  541     CHECK(check_sljit_emit_return(compiler, op, src, srcw));
  542 
  543     if (op != SLJIT_MOV || !FAST_IS_REG(src)) {
  544         FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
  545         src = SLJIT_R0;
  546     }
  547 
  548     FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS));
  549     return push_inst(compiler, RESTORE | D(SLJIT_R0) | S1(src) | S2(0), UNMOVABLE_INS);
  550 }
  551 
  552 /* --------------------------------------------------------------------- */
  553 /*  Operators                                                            */
  554 /* --------------------------------------------------------------------- */
  555 
  556 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  557 #define ARCH_32_64(a, b)    a
  558 #else
  559 #define ARCH_32_64(a, b)    b
  560 #endif
  561 
  562 static const sljit_ins data_transfer_insts[16 + 4] = {
  563 /* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
  564 /* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
  565 /* u b s */ OPC1(3) | OPC3(0x05) /* stb */,
  566 /* u b l */ OPC1(3) | OPC3(0x01) /* ldub */,
  567 /* u h s */ OPC1(3) | OPC3(0x06) /* sth */,
  568 /* u h l */ OPC1(3) | OPC3(0x02) /* lduh */,
  569 /* u i s */ OPC1(3) | OPC3(0x04) /* stw */,
  570 /* u i l */ OPC1(3) | OPC3(0x00) /* lduw */,
  571 
  572 /* s w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
  573 /* s w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
  574 /* s b s */ OPC1(3) | OPC3(0x05) /* stb */,
  575 /* s b l */ OPC1(3) | OPC3(0x09) /* ldsb */,
  576 /* s h s */ OPC1(3) | OPC3(0x06) /* sth */,
  577 /* s h l */ OPC1(3) | OPC3(0x0a) /* ldsh */,
  578 /* s i s */ OPC1(3) | OPC3(0x04) /* stw */,
  579 /* s i l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x08) /* ldsw */),
  580 
  581 /* d   s */ OPC1(3) | OPC3(0x27),
  582 /* d   l */ OPC1(3) | OPC3(0x23),
  583 /* s   s */ OPC1(3) | OPC3(0x24),
  584 /* s   l */ OPC1(3) | OPC3(0x20),
  585 };
  586 
  587 #undef ARCH_32_64
  588 
  589 /* Can perform an operation using at most 1 instruction. */
  590 static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
  591 {
  592     SLJIT_ASSERT(arg & SLJIT_MEM);
  593 
  594     if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN)
  595             || ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) {
  596         /* Works for both absoulte and relative addresses (immediate case). */
  597         if (SLJIT_UNLIKELY(flags & ARG_TEST))
  598             return 1;
  599         FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK]
  600             | ((flags & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))
  601             | S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)),
  602             ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS));
  603         return -1;
  604     }
  605     return 0;
  606 }
  607 
  608 /* See getput_arg below.
  609    Note: can_cache is called only for binary operators. Those
  610    operators always uses word arguments without write back. */
  611 static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
  612 {
  613     SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
  614 
  615     /* Simple operation except for updates. */
  616     if (arg & OFFS_REG_MASK) {
  617         argw &= 0x3;
  618         SLJIT_ASSERT(argw);
  619         next_argw &= 0x3;
  620         if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == next_argw)
  621             return 1;
  622         return 0;
  623     }
  624 
  625     if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN))
  626         return 1;
  627     return 0;
  628 }
  629 
  630 /* Emit the necessary instructions. See can_cache above. */
  631 static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
  632 {
  633     sljit_s32 base, arg2, delay_slot;
  634     sljit_ins dest;
  635 
  636     SLJIT_ASSERT(arg & SLJIT_MEM);
  637     if (!(next_arg & SLJIT_MEM)) {
  638         next_arg = 0;
  639         next_argw = 0;
  640     }
  641 
  642     base = arg & REG_MASK;
  643     if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
  644         argw &= 0x3;
  645 
  646         /* Using the cache. */
  647         if (((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) && (argw == compiler->cache_argw))
  648             arg2 = TMP_REG3;
  649         else {
  650             if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) {
  651                 compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
  652                 compiler->cache_argw = argw;
  653                 arg2 = TMP_REG3;
  654             }
  655             else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base && reg != OFFS_REG(arg))
  656                 arg2 = reg;
  657             else /* It must be a mov operation, so tmp1 must be free to use. */
  658                 arg2 = TMP_REG1;
  659             FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | argw, DR(arg2)));
  660         }
  661     }
  662     else {
  663         /* Using the cache. */
  664         if ((compiler->cache_arg == SLJIT_MEM) && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
  665             if (argw != compiler->cache_argw) {
  666                 FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | S1(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
  667                 compiler->cache_argw = argw;
  668             }
  669             arg2 = TMP_REG3;
  670         } else {
  671             if ((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN) {
  672                 compiler->cache_arg = SLJIT_MEM;
  673                 compiler->cache_argw = argw;
  674                 arg2 = TMP_REG3;
  675             }
  676             else if ((flags & LOAD_DATA) && ((flags & MEM_MASK) <= GPR_REG) && reg != base)
  677                 arg2 = reg;
  678             else /* It must be a mov operation, so tmp1 must be free to use. */
  679                 arg2 = TMP_REG1;
  680             FAIL_IF(load_immediate(compiler, arg2, argw));
  681         }
  682     }
  683 
  684     dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg));
  685     delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS;
  686     if (!base)
  687         return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot);
  688     return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
  689 }
  690 
  691 static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
  692 {
  693     if (getput_arg_fast(compiler, flags, reg, arg, argw))
  694         return compiler->error;
  695     compiler->cache_arg = 0;
  696     compiler->cache_argw = 0;
  697     return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
  698 }
  699 
  700 static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
  701 {
  702     if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
  703         return compiler->error;
  704     return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
  705 }
  706 
  707 static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
  708     sljit_s32 dst, sljit_sw dstw,
  709     sljit_s32 src1, sljit_sw src1w,
  710     sljit_s32 src2, sljit_sw src2w)
  711 {
  712     /* arg1 goes to TMP_REG1 or src reg
  713        arg2 goes to TMP_REG2, imm or src reg
  714        TMP_REG3 can be used for caching
  715        result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
  716     sljit_s32 dst_r = TMP_REG2;
  717     sljit_s32 src1_r;
  718     sljit_sw src2_r = 0;
  719     sljit_s32 sugg_src2_r = TMP_REG2;
  720 
  721     if (!(flags & ALT_KEEP_CACHE)) {
  722         compiler->cache_arg = 0;
  723         compiler->cache_argw = 0;
  724     }
  725 
  726     if (dst != SLJIT_UNUSED) {
  727         if (FAST_IS_REG(dst)) {
  728             dst_r = dst;
  729             flags |= REG_DEST;
  730             if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
  731                 sugg_src2_r = dst_r;
  732         }
  733         else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
  734             flags |= SLOW_DEST;
  735     }
  736 
  737     if (flags & IMM_OP) {
  738         if ((src2 & SLJIT_IMM) && src2w) {
  739             if (src2w <= SIMM_MAX && src2w >= SIMM_MIN) {
  740                 flags |= SRC2_IMM;
  741                 src2_r = src2w;
  742             }
  743         }
  744         if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
  745             if (src1w <= SIMM_MAX && src1w >= SIMM_MIN) {
  746                 flags |= SRC2_IMM;
  747                 src2_r = src1w;
  748 
  749                 /* And swap arguments. */
  750                 src1 = src2;
  751                 src1w = src2w;
  752                 src2 = SLJIT_IMM;
  753                 /* src2w = src2_r unneeded. */
  754             }
  755         }
  756     }
  757 
  758     /* Source 1. */
  759     if (FAST_IS_REG(src1))
  760         src1_r = src1;
  761     else if (src1 & SLJIT_IMM) {
  762         if (src1w) {
  763             FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
  764             src1_r = TMP_REG1;
  765         }
  766         else
  767             src1_r = 0;
  768     }
  769     else {
  770         if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))
  771             FAIL_IF(compiler->error);
  772         else
  773             flags |= SLOW_SRC1;
  774         src1_r = TMP_REG1;
  775     }
  776 
  777     /* Source 2. */
  778     if (FAST_IS_REG(src2)) {
  779         src2_r = src2;
  780         flags |= REG2_SOURCE;
  781         if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
  782             dst_r = src2_r;
  783     }
  784     else if (src2 & SLJIT_IMM) {
  785         if (!(flags & SRC2_IMM)) {
  786             if (src2w) {
  787                 FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
  788                 src2_r = sugg_src2_r;
  789             }
  790             else {
  791                 src2_r = 0;
  792                 if ((op >= SLJIT_MOV && op <= SLJIT_MOV_P) && (dst & SLJIT_MEM))
  793                     dst_r = 0;
  794             }
  795         }
  796     }
  797     else {
  798         if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w))
  799             FAIL_IF(compiler->error);
  800         else
  801             flags |= SLOW_SRC2;
  802         src2_r = sugg_src2_r;
  803     }
  804 
  805     if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
  806         SLJIT_ASSERT(src2_r == TMP_REG2);
  807         if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
  808             FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
  809             FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
  810         }
  811         else {
  812             FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
  813             FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
  814         }
  815     }
  816     else if (flags & SLOW_SRC1)
  817         FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
  818     else if (flags & SLOW_SRC2)
  819         FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
  820 
  821     FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
  822 
  823     if (dst & SLJIT_MEM) {
  824         if (!(flags & SLOW_DEST)) {
  825             getput_arg_fast(compiler, flags, dst_r, dst, dstw);
  826             return compiler->error;
  827         }
  828         return getput_arg(compiler, flags, dst_r, dst, dstw, 0, 0);
  829     }
  830 
  831     return SLJIT_SUCCESS;
  832 }
  833 
  834 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
  835 {
  836     CHECK_ERROR();
  837     CHECK(check_sljit_emit_op0(compiler, op));
  838 
  839     op = GET_OPCODE(op);
  840     switch (op) {
  841     case SLJIT_BREAKPOINT:
  842         return push_inst(compiler, TA, UNMOVABLE_INS);
  843     case SLJIT_NOP:
  844         return push_inst(compiler, NOP, UNMOVABLE_INS);
  845     case SLJIT_LMUL_UW:
  846     case SLJIT_LMUL_SW:
  847 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  848         FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
  849         return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1));
  850 #else
  851 #error "Implementation required"
  852 #endif
  853     case SLJIT_DIVMOD_UW:
  854     case SLJIT_DIVMOD_SW:
  855     case SLJIT_DIV_UW:
  856     case SLJIT_DIV_SW:
  857         SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
  858 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  859         if ((op | 0x2) == SLJIT_DIV_UW)
  860             FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));
  861         else {
  862             FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1)));
  863             FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));
  864         }
  865         if (op <= SLJIT_DIVMOD_SW)
  866             FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
  867         FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
  868         if (op >= SLJIT_DIV_UW)
  869             return SLJIT_SUCCESS;
  870         FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1)));
  871         return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1));
  872 #else
  873 #error "Implementation required"
  874 #endif
  875     }
  876 
  877     return SLJIT_SUCCESS;
  878 }
  879 
  880 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
  881     sljit_s32 dst, sljit_sw dstw,
  882     sljit_s32 src, sljit_sw srcw)
  883 {
  884     sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
  885 
  886     CHECK_ERROR();
  887     CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
  888     ADJUST_LOCAL_OFFSET(dst, dstw);
  889     ADJUST_LOCAL_OFFSET(src, srcw);
  890 
  891     if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
  892         return SLJIT_SUCCESS;
  893 
  894     op = GET_OPCODE(op);
  895     switch (op) {
  896     case SLJIT_MOV:
  897     case SLJIT_MOV_P:
  898         return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  899 
  900     case SLJIT_MOV_U32:
  901         return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  902 
  903     case SLJIT_MOV_S32:
  904         return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
  905 
  906     case SLJIT_MOV_U8:
  907         return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
  908 
  909     case SLJIT_MOV_S8:
  910         return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
  911 
  912     case SLJIT_MOV_U16:
  913         return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
  914 
  915     case SLJIT_MOV_S16:
  916         return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
  917 
  918     case SLJIT_NOT:
  919     case SLJIT_CLZ:
  920         return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
  921 
  922     case SLJIT_NEG:
  923         return emit_op(compiler, SLJIT_SUB, flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
  924     }
  925 
  926     return SLJIT_SUCCESS;
  927 }
  928 
  929 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
  930     sljit_s32 dst, sljit_sw dstw,
  931     sljit_s32 src1, sljit_sw src1w,
  932     sljit_s32 src2, sljit_sw src2w)
  933 {
  934     sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
  935 
  936     CHECK_ERROR();
  937     CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
  938     ADJUST_LOCAL_OFFSET(dst, dstw);
  939     ADJUST_LOCAL_OFFSET(src1, src1w);
  940     ADJUST_LOCAL_OFFSET(src2, src2w);
  941 
  942     if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
  943         return SLJIT_SUCCESS;
  944 
  945     op = GET_OPCODE(op);
  946     switch (op) {
  947     case SLJIT_ADD:
  948     case SLJIT_ADDC:
  949     case SLJIT_MUL:
  950     case SLJIT_AND:
  951     case SLJIT_OR:
  952     case SLJIT_XOR:
  953         return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
  954 
  955     case SLJIT_SUB:
  956     case SLJIT_SUBC:
  957         return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
  958 
  959     case SLJIT_SHL:
  960     case SLJIT_LSHR:
  961     case SLJIT_ASHR:
  962 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
  963         if (src2 & SLJIT_IMM)
  964             src2w &= 0x1f;
  965 #else
  966         SLJIT_UNREACHABLE();
  967 #endif
  968         return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
  969     }
  970 
  971     return SLJIT_SUCCESS;
  972 }
  973 
  974 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
  975 {
  976     CHECK_REG_INDEX(check_sljit_get_register_index(reg));
  977     return reg_map[reg];
  978 }
  979 
  980 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
  981 {
  982     CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
  983     return freg_map[reg];
  984 }
  985 
  986 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
  987     void *instruction, sljit_s32 size)
  988 {
  989     CHECK_ERROR();
  990     CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
  991 
  992     return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
  993 }
  994 
  995 /* --------------------------------------------------------------------- */
  996 /*  Floating point operators                                             */
  997 /* --------------------------------------------------------------------- */
  998 
  999 #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7))
 1000 #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
 1001 #define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw))
 1002 
 1003 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
 1004     sljit_s32 dst, sljit_sw dstw,
 1005     sljit_s32 src, sljit_sw srcw)
 1006 {
 1007     if (src & SLJIT_MEM) {
 1008         FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
 1009         src = TMP_FREG1;
 1010     }
 1011 
 1012     FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | FD(TMP_FREG1) | FS2(src), MOVABLE_INS));
 1013 
 1014     if (FAST_IS_REG(dst)) {
 1015         FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
 1016         return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET);
 1017     }
 1018 
 1019     /* Store the integer value from a VFP register. */
 1020     return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
 1021 }
 1022 
 1023 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
 1024     sljit_s32 dst, sljit_sw dstw,
 1025     sljit_s32 src, sljit_sw srcw)
 1026 {
 1027     sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 1028 
 1029     if (src & SLJIT_IMM) {
 1030 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 1031         if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
 1032             srcw = (sljit_s32)srcw;
 1033 #endif
 1034         FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
 1035         src = TMP_REG1;
 1036         srcw = 0;
 1037     }
 1038 
 1039     if (FAST_IS_REG(src)) {
 1040         FAIL_IF(emit_op_mem2(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
 1041         src = SLJIT_MEM1(SLJIT_SP);
 1042         srcw = FLOAT_TMP_MEM_OFFSET;
 1043     }
 1044 
 1045     FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
 1046     FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | FD(dst_r) | FS2(TMP_FREG1), MOVABLE_INS));
 1047 
 1048     if (dst & SLJIT_MEM)
 1049         return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
 1050     return SLJIT_SUCCESS;
 1051 }
 1052 
 1053 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
 1054     sljit_s32 src1, sljit_sw src1w,
 1055     sljit_s32 src2, sljit_sw src2w)
 1056 {
 1057     if (src1 & SLJIT_MEM) {
 1058         FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
 1059         src1 = TMP_FREG1;
 1060     }
 1061 
 1062     if (src2 & SLJIT_MEM) {
 1063         FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
 1064         src2 = TMP_FREG2;
 1065     }
 1066 
 1067     return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | FS1(src1) | FS2(src2), FCC_IS_SET | MOVABLE_INS);
 1068 }
 1069 
 1070 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
 1071     sljit_s32 dst, sljit_sw dstw,
 1072     sljit_s32 src, sljit_sw srcw)
 1073 {
 1074     sljit_s32 dst_r;
 1075 
 1076     CHECK_ERROR();
 1077     compiler->cache_arg = 0;
 1078     compiler->cache_argw = 0;
 1079 
 1080     SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
 1081     SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
 1082 
 1083     if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
 1084         op ^= SLJIT_F32_OP;
 1085 
 1086     dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
 1087 
 1088     if (src & SLJIT_MEM) {
 1089         FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
 1090         src = dst_r;
 1091     }
 1092 
 1093     switch (GET_OPCODE(op)) {
 1094     case SLJIT_MOV_F64:
 1095         if (src != dst_r) {
 1096             if (dst_r != TMP_FREG1) {
 1097                 FAIL_IF(push_inst(compiler, FMOVS | FD(dst_r) | FS2(src), MOVABLE_INS));
 1098                 if (!(op & SLJIT_F32_OP))
 1099                     FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
 1100             }
 1101             else
 1102                 dst_r = src;
 1103         }
 1104         break;
 1105     case SLJIT_NEG_F64:
 1106         FAIL_IF(push_inst(compiler, FNEGS | FD(dst_r) | FS2(src), MOVABLE_INS));
 1107         if (dst_r != src && !(op & SLJIT_F32_OP))
 1108             FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
 1109         break;
 1110     case SLJIT_ABS_F64:
 1111         FAIL_IF(push_inst(compiler, FABSS | FD(dst_r) | FS2(src), MOVABLE_INS));
 1112         if (dst_r != src && !(op & SLJIT_F32_OP))
 1113             FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
 1114         break;
 1115     case SLJIT_CONV_F64_FROM_F32:
 1116         FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | FD(dst_r) | FS2(src), MOVABLE_INS));
 1117         op ^= SLJIT_F32_OP;
 1118         break;
 1119     }
 1120 
 1121     if (dst & SLJIT_MEM)
 1122         FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0));
 1123     return SLJIT_SUCCESS;
 1124 }
 1125 
 1126 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
 1127     sljit_s32 dst, sljit_sw dstw,
 1128     sljit_s32 src1, sljit_sw src1w,
 1129     sljit_s32 src2, sljit_sw src2w)
 1130 {
 1131     sljit_s32 dst_r, flags = 0;
 1132 
 1133     CHECK_ERROR();
 1134     CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
 1135     ADJUST_LOCAL_OFFSET(dst, dstw);
 1136     ADJUST_LOCAL_OFFSET(src1, src1w);
 1137     ADJUST_LOCAL_OFFSET(src2, src2w);
 1138 
 1139     compiler->cache_arg = 0;
 1140     compiler->cache_argw = 0;
 1141 
 1142     dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
 1143 
 1144     if (src1 & SLJIT_MEM) {
 1145         if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
 1146             FAIL_IF(compiler->error);
 1147             src1 = TMP_FREG1;
 1148         } else
 1149             flags |= SLOW_SRC1;
 1150     }
 1151 
 1152     if (src2 & SLJIT_MEM) {
 1153         if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
 1154             FAIL_IF(compiler->error);
 1155             src2 = TMP_FREG2;
 1156         } else
 1157             flags |= SLOW_SRC2;
 1158     }
 1159 
 1160     if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
 1161         if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
 1162             FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
 1163             FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
 1164         }
 1165         else {
 1166             FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
 1167             FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
 1168         }
 1169     }
 1170     else if (flags & SLOW_SRC1)
 1171         FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
 1172     else if (flags & SLOW_SRC2)
 1173         FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
 1174 
 1175     if (flags & SLOW_SRC1)
 1176         src1 = TMP_FREG1;
 1177     if (flags & SLOW_SRC2)
 1178         src2 = TMP_FREG2;
 1179 
 1180     switch (GET_OPCODE(op)) {
 1181     case SLJIT_ADD_F64:
 1182         FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
 1183         break;
 1184 
 1185     case SLJIT_SUB_F64:
 1186         FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
 1187         break;
 1188 
 1189     case SLJIT_MUL_F64:
 1190         FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
 1191         break;
 1192 
 1193     case SLJIT_DIV_F64:
 1194         FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
 1195         break;
 1196     }
 1197 
 1198     if (dst_r == TMP_FREG2)
 1199         FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
 1200 
 1201     return SLJIT_SUCCESS;
 1202 }
 1203 
 1204 #undef FLOAT_DATA
 1205 #undef SELECT_FOP
 1206 
 1207 /* --------------------------------------------------------------------- */
 1208 /*  Other instructions                                                   */
 1209 /* --------------------------------------------------------------------- */
 1210 
 1211 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 1212 {
 1213     CHECK_ERROR();
 1214     CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
 1215     ADJUST_LOCAL_OFFSET(dst, dstw);
 1216 
 1217     if (FAST_IS_REG(dst))
 1218         return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst));
 1219 
 1220     /* Memory. */
 1221     return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw);
 1222 }
 1223 
 1224 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
 1225 {
 1226     CHECK_ERROR();
 1227     CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
 1228     ADJUST_LOCAL_OFFSET(src, srcw);
 1229 
 1230     if (FAST_IS_REG(src))
 1231         FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
 1232     else
 1233         FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
 1234 
 1235     FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
 1236     return push_inst(compiler, NOP, UNMOVABLE_INS);
 1237 }
 1238 
 1239 /* --------------------------------------------------------------------- */
 1240 /*  Conditional instructions                                             */
 1241 /* --------------------------------------------------------------------- */
 1242 
 1243 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
 1244 {
 1245     struct sljit_label *label;
 1246 
 1247     CHECK_ERROR_PTR();
 1248     CHECK_PTR(check_sljit_emit_label(compiler));
 1249 
 1250     if (compiler->last_label && compiler->last_label->size == compiler->size)
 1251         return compiler->last_label;
 1252 
 1253     label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
 1254     PTR_FAIL_IF(!label);
 1255     set_label(label, compiler);
 1256     compiler->delay_slot = UNMOVABLE_INS;
 1257     return label;
 1258 }
 1259 
 1260 static sljit_ins get_cc(sljit_s32 type)
 1261 {
 1262     switch (type) {
 1263     case SLJIT_EQUAL:
 1264     case SLJIT_MUL_NOT_OVERFLOW:
 1265     case SLJIT_NOT_EQUAL_F64: /* Unordered. */
 1266         return DA(0x1);
 1267 
 1268     case SLJIT_NOT_EQUAL:
 1269     case SLJIT_MUL_OVERFLOW:
 1270     case SLJIT_EQUAL_F64:
 1271         return DA(0x9);
 1272 
 1273     case SLJIT_LESS:
 1274     case SLJIT_GREATER_F64: /* Unordered. */
 1275         return DA(0x5);
 1276 
 1277     case SLJIT_GREATER_EQUAL:
 1278     case SLJIT_LESS_EQUAL_F64:
 1279         return DA(0xd);
 1280 
 1281     case SLJIT_GREATER:
 1282     case SLJIT_GREATER_EQUAL_F64: /* Unordered. */
 1283         return DA(0xc);
 1284 
 1285     case SLJIT_LESS_EQUAL:
 1286     case SLJIT_LESS_F64:
 1287         return DA(0x4);
 1288 
 1289     case SLJIT_SIG_LESS:
 1290         return DA(0x3);
 1291 
 1292     case SLJIT_SIG_GREATER_EQUAL:
 1293         return DA(0xb);
 1294 
 1295     case SLJIT_SIG_GREATER:
 1296         return DA(0xa);
 1297 
 1298     case SLJIT_SIG_LESS_EQUAL:
 1299         return DA(0x2);
 1300 
 1301     case SLJIT_OVERFLOW:
 1302     case SLJIT_UNORDERED_F64:
 1303         return DA(0x7);
 1304 
 1305     case SLJIT_NOT_OVERFLOW:
 1306     case SLJIT_ORDERED_F64:
 1307         return DA(0xf);
 1308 
 1309     default:
 1310         SLJIT_UNREACHABLE();
 1311         return DA(0x8);
 1312     }
 1313 }
 1314 
 1315 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
 1316 {
 1317     struct sljit_jump *jump;
 1318 
 1319     CHECK_ERROR_PTR();
 1320     CHECK_PTR(check_sljit_emit_jump(compiler, type));
 1321 
 1322     jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 1323     PTR_FAIL_IF(!jump);
 1324     set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
 1325     type &= 0xff;
 1326 
 1327     if (type < SLJIT_EQUAL_F64) {
 1328         jump->flags |= IS_COND;
 1329         if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET))
 1330             jump->flags |= IS_MOVABLE;
 1331 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 1332         PTR_FAIL_IF(push_inst(compiler, BICC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
 1333 #else
 1334 #error "Implementation required"
 1335 #endif
 1336     }
 1337     else if (type < SLJIT_JUMP) {
 1338         jump->flags |= IS_COND;
 1339         if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & FCC_IS_SET))
 1340             jump->flags |= IS_MOVABLE;
 1341 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 1342         PTR_FAIL_IF(push_inst(compiler, FBFCC | get_cc(type ^ 1) | 5, UNMOVABLE_INS));
 1343 #else
 1344 #error "Implementation required"
 1345 #endif
 1346     }
 1347     else {
 1348         if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
 1349             jump->flags |= IS_MOVABLE;
 1350         if (type >= SLJIT_FAST_CALL)
 1351             jump->flags |= IS_CALL;
 1352     }
 1353 
 1354     PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0));
 1355     PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG1) | IMM(0), UNMOVABLE_INS));
 1356     jump->addr = compiler->size;
 1357     PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
 1358 
 1359     return jump;
 1360 }
 1361 
 1362 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
 1363     sljit_s32 arg_types)
 1364 {
 1365     CHECK_ERROR_PTR();
 1366     CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
 1367 
 1368     PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
 1369 
 1370 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
 1371         || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 1372     compiler->skip_checks = 1;
 1373 #endif
 1374 
 1375     return sljit_emit_jump(compiler, type);
 1376 }
 1377 
 1378 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
 1379 {
 1380     struct sljit_jump *jump = NULL;
 1381     sljit_s32 src_r;
 1382 
 1383     CHECK_ERROR();
 1384     CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
 1385     ADJUST_LOCAL_OFFSET(src, srcw);
 1386 
 1387     if (FAST_IS_REG(src))
 1388         src_r = src;
 1389     else if (src & SLJIT_IMM) {
 1390         jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
 1391         FAIL_IF(!jump);
 1392         set_jump(jump, compiler, JUMP_ADDR);
 1393         jump->u.target = srcw;
 1394 
 1395         if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
 1396             jump->flags |= IS_MOVABLE;
 1397         if (type >= SLJIT_FAST_CALL)
 1398             jump->flags |= IS_CALL;
 1399 
 1400         FAIL_IF(emit_const(compiler, TMP_REG1, 0));
 1401         src_r = TMP_REG1;
 1402     }
 1403     else {
 1404         FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
 1405         src_r = TMP_REG1;
 1406     }
 1407 
 1408     FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS));
 1409     if (jump)
 1410         jump->addr = compiler->size;
 1411     return push_inst(compiler, NOP, UNMOVABLE_INS);
 1412 }
 1413 
 1414 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
 1415     sljit_s32 arg_types,
 1416     sljit_s32 src, sljit_sw srcw)
 1417 {
 1418     CHECK_ERROR();
 1419     CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
 1420 
 1421     if (src & SLJIT_MEM) {
 1422         ADJUST_LOCAL_OFFSET(src, srcw);
 1423         FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
 1424         src = TMP_REG1;
 1425     }
 1426 
 1427     FAIL_IF(call_with_args(compiler, arg_types, &src));
 1428 
 1429 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
 1430         || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
 1431     compiler->skip_checks = 1;
 1432 #endif
 1433 
 1434     return sljit_emit_ijump(compiler, type, src, srcw);
 1435 }
 1436 
 1437 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
 1438     sljit_s32 dst, sljit_sw dstw,
 1439     sljit_s32 type)
 1440 {
 1441     sljit_s32 reg, flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
 1442 
 1443     CHECK_ERROR();
 1444     CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
 1445     ADJUST_LOCAL_OFFSET(dst, dstw);
 1446 
 1447 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 1448     op = GET_OPCODE(op);
 1449     reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;
 1450 
 1451     compiler->cache_arg = 0;
 1452     compiler->cache_argw = 0;
 1453 
 1454     if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
 1455         FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, dst, dstw, dst, dstw));
 1456 
 1457     type &= 0xff;
 1458     if (type < SLJIT_EQUAL_F64)
 1459         FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS));
 1460     else
 1461         FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS));
 1462 
 1463     FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(1), UNMOVABLE_INS));
 1464     FAIL_IF(push_inst(compiler, OR | D(reg) | S1(0) | IMM(0), UNMOVABLE_INS));
 1465 
 1466     if (op >= SLJIT_ADD) {
 1467         flags |= CUMULATIVE_OP | IMM_OP | ALT_KEEP_CACHE;
 1468         if (dst & SLJIT_MEM)
 1469             return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
 1470         return emit_op(compiler, op, flags, dst, 0, dst, 0, TMP_REG2, 0);
 1471     }
 1472 
 1473     if (!(dst & SLJIT_MEM))
 1474         return SLJIT_SUCCESS;
 1475 
 1476     return emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw);
 1477 #else
 1478 #error "Implementation required"
 1479 #endif
 1480 }
 1481 
 1482 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
 1483     sljit_s32 dst_reg,
 1484     sljit_s32 src, sljit_sw srcw)
 1485 {
 1486     CHECK_ERROR();
 1487     CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
 1488 
 1489 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 1490     return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);;
 1491 #else
 1492 #error "Implementation required"
 1493 #endif
 1494 }
 1495 
 1496 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
 1497 {
 1498     struct sljit_const *const_;
 1499     sljit_s32 dst_r;
 1500 
 1501     CHECK_ERROR_PTR();
 1502     CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
 1503     ADJUST_LOCAL_OFFSET(dst, dstw);
 1504 
 1505     const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
 1506     PTR_FAIL_IF(!const_);
 1507     set_const(const_, compiler);
 1508 
 1509     dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
 1510     PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
 1511 
 1512     if (dst & SLJIT_MEM)
 1513         PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
 1514     return const_;
 1515 }
 1516 
 1517 SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 1518 {
 1519     struct sljit_put_label *put_label;
 1520     sljit_s32 dst_r;
 1521 
 1522     CHECK_ERROR_PTR();
 1523     CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
 1524     ADJUST_LOCAL_OFFSET(dst, dstw);
 1525 
 1526     put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
 1527     PTR_FAIL_IF(!put_label);
 1528     set_put_label(put_label, compiler, 0);
 1529 
 1530     dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
 1531     PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
 1532 
 1533     if (dst & SLJIT_MEM)
 1534         PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
 1535     return put_label;
 1536 }