1 1.8 alnsn /* $NetBSD: sljitNativePPC_common.c,v 1.8 2019/01/20 23:14:16 alnsn Exp $ */ 2 1.4 alnsn 3 1.1 alnsn /* 4 1.1 alnsn * Stack-less Just-In-Time compiler 5 1.1 alnsn * 6 1.8 alnsn * Copyright Zoltan Herczeg (hzmester (at) freemail.hu). All rights reserved. 7 1.1 alnsn * 8 1.1 alnsn * Redistribution and use in source and binary forms, with or without modification, are 9 1.1 alnsn * permitted provided that the following conditions are met: 10 1.1 alnsn * 11 1.1 alnsn * 1. Redistributions of source code must retain the above copyright notice, this list of 12 1.1 alnsn * conditions and the following disclaimer. 13 1.1 alnsn * 14 1.1 alnsn * 2. Redistributions in binary form must reproduce the above copyright notice, this list 15 1.1 alnsn * of conditions and the following disclaimer in the documentation and/or other materials 16 1.1 alnsn * provided with the distribution. 17 1.1 alnsn * 18 1.1 alnsn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 19 1.1 alnsn * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 alnsn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 1.1 alnsn * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 alnsn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 23 1.1 alnsn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 1.1 alnsn * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 1.1 alnsn * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 26 1.1 alnsn * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 1.1 alnsn */ 28 1.1 alnsn 29 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) 30 1.1 alnsn { 31 1.1 alnsn return "PowerPC" SLJIT_CPUINFO; 32 1.1 alnsn } 33 1.1 alnsn 34 1.1 alnsn /* Length of an instruction word. 35 1.1 alnsn Both for ppc-32 and ppc-64. */ 36 1.5 alnsn typedef sljit_u32 sljit_ins; 37 1.1 alnsn 38 1.3 alnsn #if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \ 39 1.3 alnsn || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 40 1.3 alnsn #define SLJIT_PPC_STACK_FRAME_V2 1 41 1.3 alnsn #endif 42 1.3 alnsn 43 1.1 alnsn #ifdef _AIX 44 1.1 alnsn #include <sys/cache.h> 45 1.1 alnsn #endif 46 1.1 alnsn 47 1.3 alnsn #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) 48 1.3 alnsn #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1 49 1.3 alnsn #endif 50 1.3 alnsn 51 1.7 alnsn #if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) 52 1.7 alnsn 53 1.7 alnsn static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) 54 1.7 alnsn { 55 1.7 alnsn #ifdef _AIX 56 1.7 alnsn _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from)); 57 1.7 alnsn #elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM) 58 1.7 alnsn # if defined(_ARCH_PWR) || defined(_ARCH_PWR2) 59 1.7 alnsn /* Cache flush for POWER architecture. */ 60 1.7 alnsn while (from < to) { 61 1.7 alnsn __asm__ volatile ( 62 1.7 alnsn "clf 0, %0\n" 63 1.7 alnsn "dcs\n" 64 1.7 alnsn : : "r"(from) 65 1.7 alnsn ); 66 1.7 alnsn from++; 67 1.7 alnsn } 68 1.7 alnsn __asm__ volatile ( "ics" ); 69 1.7 alnsn # elif defined(_ARCH_COM) && !defined(_ARCH_PPC) 70 1.7 alnsn # error "Cache flush is not implemented for PowerPC/POWER common mode." 71 1.7 alnsn # else 72 1.7 alnsn /* Cache flush for PowerPC architecture. */ 73 1.7 alnsn while (from < to) { 74 1.7 alnsn __asm__ volatile ( 75 1.7 alnsn "dcbf 0, %0\n" 76 1.7 alnsn "sync\n" 77 1.7 alnsn "icbi 0, %0\n" 78 1.7 alnsn : : "r"(from) 79 1.7 alnsn ); 80 1.7 alnsn from++; 81 1.7 alnsn } 82 1.7 alnsn __asm__ volatile ( "isync" ); 83 1.7 alnsn # endif 84 1.7 alnsn # ifdef __xlc__ 85 1.7 alnsn # warning "This file may fail to compile if -qfuncsect is used" 86 1.7 alnsn # endif 87 1.7 alnsn #elif defined(__xlc__) 88 1.7 alnsn #error "Please enable GCC syntax for inline assembly statements with -qasm=gcc" 89 1.7 alnsn #else 90 1.7 alnsn #error "This platform requires a cache flush implementation." 91 1.7 alnsn #endif /* _AIX */ 92 1.7 alnsn } 93 1.7 alnsn 94 1.7 alnsn #endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */ 95 1.7 alnsn 96 1.6 alnsn #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) 97 1.6 alnsn #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) 98 1.6 alnsn #define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) 99 1.6 alnsn #define TMP_ZERO (SLJIT_NUMBER_OF_REGISTERS + 5) 100 1.1 alnsn 101 1.3 alnsn #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) 102 1.5 alnsn #define TMP_CALL_REG (SLJIT_NUMBER_OF_REGISTERS + 6) 103 1.3 alnsn #else 104 1.3 alnsn #define TMP_CALL_REG TMP_REG2 105 1.3 alnsn #endif 106 1.3 alnsn 107 1.3 alnsn #define TMP_FREG1 (0) 108 1.5 alnsn #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) 109 1.1 alnsn 110 1.5 alnsn static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { 111 1.5 alnsn 0, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 8, 9, 10, 31, 12 112 1.2 alnsn }; 113 1.2 alnsn 114 1.1 alnsn /* --------------------------------------------------------------------- */ 115 1.1 alnsn /* Instrucion forms */ 116 1.1 alnsn /* --------------------------------------------------------------------- */ 117 1.1 alnsn #define D(d) (reg_map[d] << 21) 118 1.1 alnsn #define S(s) (reg_map[s] << 21) 119 1.1 alnsn #define A(a) (reg_map[a] << 16) 120 1.1 alnsn #define B(b) (reg_map[b] << 11) 121 1.1 alnsn #define C(c) (reg_map[c] << 6) 122 1.1 alnsn #define FD(fd) ((fd) << 21) 123 1.5 alnsn #define FS(fs) ((fs) << 21) 124 1.1 alnsn #define FA(fa) ((fa) << 16) 125 1.1 alnsn #define FB(fb) ((fb) << 11) 126 1.1 alnsn #define FC(fc) ((fc) << 6) 127 1.1 alnsn #define IMM(imm) ((imm) & 0xffff) 128 1.1 alnsn #define CRD(d) ((d) << 21) 129 1.1 alnsn 130 1.1 alnsn /* Instruction bit sections. 131 1.1 alnsn OE and Rc flag (see ALT_SET_FLAGS). */ 132 1.1 alnsn #define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS)) 133 1.1 alnsn /* Rc flag (see ALT_SET_FLAGS). */ 134 1.1 alnsn #define RC(flags) ((flags & ALT_SET_FLAGS) >> 10) 135 1.1 alnsn #define HI(opcode) ((opcode) << 26) 136 1.1 alnsn #define LO(opcode) ((opcode) << 1) 137 1.1 alnsn 138 1.1 alnsn #define ADD (HI(31) | LO(266)) 139 1.1 alnsn #define ADDC (HI(31) | LO(10)) 140 1.1 alnsn #define ADDE (HI(31) | LO(138)) 141 1.1 alnsn #define ADDI (HI(14)) 142 1.1 alnsn #define ADDIC (HI(13)) 143 1.1 alnsn #define ADDIS (HI(15)) 144 1.1 alnsn #define ADDME (HI(31) | LO(234)) 145 1.1 alnsn #define AND (HI(31) | LO(28)) 146 1.1 alnsn #define ANDI (HI(28)) 147 1.1 alnsn #define ANDIS (HI(29)) 148 1.1 alnsn #define Bx (HI(18)) 149 1.1 alnsn #define BCx (HI(16)) 150 1.1 alnsn #define BCCTR (HI(19) | LO(528) | (3 << 11)) 151 1.1 alnsn #define BLR (HI(19) | LO(16) | (0x14 << 21)) 152 1.1 alnsn #define CNTLZD (HI(31) | LO(58)) 153 1.1 alnsn #define CNTLZW (HI(31) | LO(26)) 154 1.1 alnsn #define CMP (HI(31) | LO(0)) 155 1.1 alnsn #define CMPI (HI(11)) 156 1.1 alnsn #define CMPL (HI(31) | LO(32)) 157 1.1 alnsn #define CMPLI (HI(10)) 158 1.1 alnsn #define CROR (HI(19) | LO(449)) 159 1.1 alnsn #define DIVD (HI(31) | LO(489)) 160 1.1 alnsn #define DIVDU (HI(31) | LO(457)) 161 1.1 alnsn #define DIVW (HI(31) | LO(491)) 162 1.1 alnsn #define DIVWU (HI(31) | LO(459)) 163 1.1 alnsn #define EXTSB (HI(31) | LO(954)) 164 1.1 alnsn #define EXTSH (HI(31) | LO(922)) 165 1.1 alnsn #define EXTSW (HI(31) | LO(986)) 166 1.1 alnsn #define FABS (HI(63) | LO(264)) 167 1.1 alnsn #define FADD (HI(63) | LO(21)) 168 1.3 alnsn #define FADDS (HI(59) | LO(21)) 169 1.5 alnsn #define FCFID (HI(63) | LO(846)) 170 1.1 alnsn #define FCMPU (HI(63) | LO(0)) 171 1.5 alnsn #define FCTIDZ (HI(63) | LO(815)) 172 1.5 alnsn #define FCTIWZ (HI(63) | LO(15)) 173 1.1 alnsn #define FDIV (HI(63) | LO(18)) 174 1.3 alnsn #define FDIVS (HI(59) | LO(18)) 175 1.1 alnsn #define FMR (HI(63) | LO(72)) 176 1.1 alnsn #define FMUL (HI(63) | LO(25)) 177 1.3 alnsn #define FMULS (HI(59) | LO(25)) 178 1.1 alnsn #define FNEG (HI(63) | LO(40)) 179 1.5 alnsn #define FRSP (HI(63) | LO(12)) 180 1.1 alnsn #define FSUB (HI(63) | LO(20)) 181 1.3 alnsn #define FSUBS (HI(59) | LO(20)) 182 1.1 alnsn #define LD (HI(58) | 0) 183 1.1 alnsn #define LWZ (HI(32)) 184 1.1 alnsn #define MFCR (HI(31) | LO(19)) 185 1.1 alnsn #define MFLR (HI(31) | LO(339) | 0x80000) 186 1.1 alnsn #define MFXER (HI(31) | LO(339) | 0x10000) 187 1.1 alnsn #define MTCTR (HI(31) | LO(467) | 0x90000) 188 1.1 alnsn #define MTLR (HI(31) | LO(467) | 0x80000) 189 1.1 alnsn #define MTXER (HI(31) | LO(467) | 0x10000) 190 1.1 alnsn #define MULHD (HI(31) | LO(73)) 191 1.1 alnsn #define MULHDU (HI(31) | LO(9)) 192 1.1 alnsn #define MULHW (HI(31) | LO(75)) 193 1.1 alnsn #define MULHWU (HI(31) | LO(11)) 194 1.1 alnsn #define MULLD (HI(31) | LO(233)) 195 1.1 alnsn #define MULLI (HI(7)) 196 1.1 alnsn #define MULLW (HI(31) | LO(235)) 197 1.1 alnsn #define NEG (HI(31) | LO(104)) 198 1.1 alnsn #define NOP (HI(24)) 199 1.1 alnsn #define NOR (HI(31) | LO(124)) 200 1.1 alnsn #define OR (HI(31) | LO(444)) 201 1.1 alnsn #define ORI (HI(24)) 202 1.1 alnsn #define ORIS (HI(25)) 203 1.1 alnsn #define RLDICL (HI(30)) 204 1.1 alnsn #define RLWINM (HI(21)) 205 1.1 alnsn #define SLD (HI(31) | LO(27)) 206 1.1 alnsn #define SLW (HI(31) | LO(24)) 207 1.1 alnsn #define SRAD (HI(31) | LO(794)) 208 1.1 alnsn #define SRADI (HI(31) | LO(413 << 1)) 209 1.1 alnsn #define SRAW (HI(31) | LO(792)) 210 1.1 alnsn #define SRAWI (HI(31) | LO(824)) 211 1.1 alnsn #define SRD (HI(31) | LO(539)) 212 1.1 alnsn #define SRW (HI(31) | LO(536)) 213 1.1 alnsn #define STD (HI(62) | 0) 214 1.1 alnsn #define STDU (HI(62) | 1) 215 1.1 alnsn #define STDUX (HI(31) | LO(181)) 216 1.5 alnsn #define STFIWX (HI(31) | LO(983)) 217 1.1 alnsn #define STW (HI(36)) 218 1.1 alnsn #define STWU (HI(37)) 219 1.1 alnsn #define STWUX (HI(31) | LO(183)) 220 1.1 alnsn #define SUBF (HI(31) | LO(40)) 221 1.1 alnsn #define SUBFC (HI(31) | LO(8)) 222 1.1 alnsn #define SUBFE (HI(31) | LO(136)) 223 1.1 alnsn #define SUBFIC (HI(8)) 224 1.1 alnsn #define XOR (HI(31) | LO(316)) 225 1.1 alnsn #define XORI (HI(26)) 226 1.1 alnsn #define XORIS (HI(27)) 227 1.1 alnsn 228 1.1 alnsn #define SIMM_MAX (0x7fff) 229 1.1 alnsn #define SIMM_MIN (-0x8000) 230 1.1 alnsn #define UIMM_MAX (0xffff) 231 1.1 alnsn 232 1.1 alnsn #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) 233 1.3 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func) 234 1.1 alnsn { 235 1.3 alnsn sljit_sw* ptrs; 236 1.1 alnsn if (func_ptr) 237 1.1 alnsn *func_ptr = (void*)context; 238 1.3 alnsn ptrs = (sljit_sw*)func; 239 1.1 alnsn context->addr = addr ? addr : ptrs[0]; 240 1.1 alnsn context->r2 = ptrs[1]; 241 1.1 alnsn context->r11 = ptrs[2]; 242 1.1 alnsn } 243 1.1 alnsn #endif 244 1.1 alnsn 245 1.5 alnsn static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) 246 1.1 alnsn { 247 1.1 alnsn sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); 248 1.1 alnsn FAIL_IF(!ptr); 249 1.1 alnsn *ptr = ins; 250 1.1 alnsn compiler->size++; 251 1.1 alnsn return SLJIT_SUCCESS; 252 1.1 alnsn } 253 1.1 alnsn 254 1.8 alnsn static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) 255 1.1 alnsn { 256 1.3 alnsn sljit_sw diff; 257 1.1 alnsn sljit_uw target_addr; 258 1.3 alnsn sljit_sw extra_jump_flags; 259 1.1 alnsn 260 1.3 alnsn #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 261 1.3 alnsn if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL)) 262 1.3 alnsn return 0; 263 1.3 alnsn #else 264 1.1 alnsn if (jump->flags & SLJIT_REWRITABLE_JUMP) 265 1.1 alnsn return 0; 266 1.3 alnsn #endif 267 1.1 alnsn 268 1.1 alnsn if (jump->flags & JUMP_ADDR) 269 1.1 alnsn target_addr = jump->u.target; 270 1.1 alnsn else { 271 1.1 alnsn SLJIT_ASSERT(jump->flags & JUMP_LABEL); 272 1.8 alnsn target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; 273 1.1 alnsn } 274 1.1 alnsn 275 1.3 alnsn #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 276 1.3 alnsn if (jump->flags & IS_CALL) 277 1.3 alnsn goto keep_address; 278 1.3 alnsn #endif 279 1.3 alnsn 280 1.8 alnsn diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l; 281 1.3 alnsn 282 1.3 alnsn extra_jump_flags = 0; 283 1.3 alnsn if (jump->flags & IS_COND) { 284 1.1 alnsn if (diff <= 0x7fff && diff >= -0x8000) { 285 1.1 alnsn jump->flags |= PATCH_B; 286 1.1 alnsn return 1; 287 1.1 alnsn } 288 1.1 alnsn if (target_addr <= 0xffff) { 289 1.3 alnsn jump->flags |= PATCH_B | PATCH_ABS_B; 290 1.1 alnsn return 1; 291 1.1 alnsn } 292 1.3 alnsn extra_jump_flags = REMOVE_COND; 293 1.3 alnsn 294 1.3 alnsn diff -= sizeof(sljit_ins); 295 1.3 alnsn } 296 1.3 alnsn 297 1.3 alnsn if (diff <= 0x01ffffff && diff >= -0x02000000) { 298 1.3 alnsn jump->flags |= PATCH_B | extra_jump_flags; 299 1.3 alnsn return 1; 300 1.3 alnsn } 301 1.8 alnsn 302 1.3 alnsn if (target_addr <= 0x03ffffff) { 303 1.3 alnsn jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags; 304 1.3 alnsn return 1; 305 1.3 alnsn } 306 1.3 alnsn 307 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 308 1.3 alnsn #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) 309 1.3 alnsn keep_address: 310 1.3 alnsn #endif 311 1.3 alnsn if (target_addr <= 0x7fffffff) { 312 1.3 alnsn jump->flags |= PATCH_ABS32; 313 1.3 alnsn return 1; 314 1.3 alnsn } 315 1.8 alnsn 316 1.3 alnsn if (target_addr <= 0x7fffffffffffl) { 317 1.3 alnsn jump->flags |= PATCH_ABS48; 318 1.3 alnsn return 1; 319 1.1 alnsn } 320 1.3 alnsn #endif 321 1.3 alnsn 322 1.1 alnsn return 0; 323 1.1 alnsn } 324 1.1 alnsn 325 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) 326 1.1 alnsn { 327 1.1 alnsn struct sljit_memory_fragment *buf; 328 1.1 alnsn sljit_ins *code; 329 1.1 alnsn sljit_ins *code_ptr; 330 1.1 alnsn sljit_ins *buf_ptr; 331 1.1 alnsn sljit_ins *buf_end; 332 1.1 alnsn sljit_uw word_count; 333 1.8 alnsn sljit_sw executable_offset; 334 1.1 alnsn sljit_uw addr; 335 1.1 alnsn 336 1.1 alnsn struct sljit_label *label; 337 1.1 alnsn struct sljit_jump *jump; 338 1.1 alnsn struct sljit_const *const_; 339 1.1 alnsn 340 1.1 alnsn CHECK_ERROR_PTR(); 341 1.5 alnsn CHECK_PTR(check_sljit_generate_code(compiler)); 342 1.1 alnsn reverse_buf(compiler); 343 1.1 alnsn 344 1.1 alnsn #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) 345 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 346 1.1 alnsn compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); 347 1.1 alnsn #else 348 1.1 alnsn compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); 349 1.1 alnsn #endif 350 1.1 alnsn #endif 351 1.1 alnsn code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); 352 1.1 alnsn PTR_FAIL_WITH_EXEC_IF(code); 353 1.1 alnsn buf = compiler->buf; 354 1.1 alnsn 355 1.1 alnsn code_ptr = code; 356 1.1 alnsn word_count = 0; 357 1.8 alnsn executable_offset = SLJIT_EXEC_OFFSET(code); 358 1.8 alnsn 359 1.1 alnsn label = compiler->labels; 360 1.1 alnsn jump = compiler->jumps; 361 1.1 alnsn const_ = compiler->consts; 362 1.8 alnsn 363 1.1 alnsn do { 364 1.1 alnsn buf_ptr = (sljit_ins*)buf->memory; 365 1.1 alnsn buf_end = buf_ptr + (buf->used_size >> 2); 366 1.1 alnsn do { 367 1.1 alnsn *code_ptr = *buf_ptr++; 368 1.1 alnsn SLJIT_ASSERT(!label || label->size >= word_count); 369 1.1 alnsn SLJIT_ASSERT(!jump || jump->addr >= word_count); 370 1.1 alnsn SLJIT_ASSERT(!const_ || const_->addr >= word_count); 371 1.1 alnsn /* These structures are ordered by their address. */ 372 1.1 alnsn if (label && label->size == word_count) { 373 1.1 alnsn /* Just recording the address. */ 374 1.8 alnsn label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); 375 1.1 alnsn label->size = code_ptr - code; 376 1.1 alnsn label = label->next; 377 1.1 alnsn } 378 1.1 alnsn if (jump && jump->addr == word_count) { 379 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 380 1.1 alnsn jump->addr = (sljit_uw)(code_ptr - 3); 381 1.1 alnsn #else 382 1.1 alnsn jump->addr = (sljit_uw)(code_ptr - 6); 383 1.1 alnsn #endif 384 1.8 alnsn if (detect_jump_type(jump, code_ptr, code, executable_offset)) { 385 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 386 1.1 alnsn code_ptr[-3] = code_ptr[0]; 387 1.1 alnsn code_ptr -= 3; 388 1.1 alnsn #else 389 1.3 alnsn if (jump->flags & PATCH_ABS32) { 390 1.3 alnsn code_ptr -= 3; 391 1.3 alnsn code_ptr[-1] = code_ptr[2]; 392 1.3 alnsn code_ptr[0] = code_ptr[3]; 393 1.3 alnsn } 394 1.3 alnsn else if (jump->flags & PATCH_ABS48) { 395 1.3 alnsn code_ptr--; 396 1.3 alnsn code_ptr[-1] = code_ptr[0]; 397 1.3 alnsn code_ptr[0] = code_ptr[1]; 398 1.3 alnsn /* rldicr rX,rX,32,31 -> rX,rX,16,47 */ 399 1.3 alnsn SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6); 400 1.3 alnsn code_ptr[-3] ^= 0x8422; 401 1.3 alnsn /* oris -> ori */ 402 1.3 alnsn code_ptr[-2] ^= 0x4000000; 403 1.3 alnsn } 404 1.3 alnsn else { 405 1.3 alnsn code_ptr[-6] = code_ptr[0]; 406 1.3 alnsn code_ptr -= 6; 407 1.3 alnsn } 408 1.1 alnsn #endif 409 1.3 alnsn if (jump->flags & REMOVE_COND) { 410 1.3 alnsn code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001); 411 1.3 alnsn code_ptr++; 412 1.3 alnsn jump->addr += sizeof(sljit_ins); 413 1.3 alnsn code_ptr[0] = Bx; 414 1.3 alnsn jump->flags -= IS_COND; 415 1.3 alnsn } 416 1.1 alnsn } 417 1.1 alnsn jump = jump->next; 418 1.1 alnsn } 419 1.1 alnsn if (const_ && const_->addr == word_count) { 420 1.1 alnsn const_->addr = (sljit_uw)code_ptr; 421 1.1 alnsn const_ = const_->next; 422 1.1 alnsn } 423 1.1 alnsn code_ptr ++; 424 1.1 alnsn word_count ++; 425 1.1 alnsn } while (buf_ptr < buf_end); 426 1.1 alnsn 427 1.1 alnsn buf = buf->next; 428 1.1 alnsn } while (buf); 429 1.1 alnsn 430 1.1 alnsn if (label && label->size == word_count) { 431 1.8 alnsn label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); 432 1.1 alnsn label->size = code_ptr - code; 433 1.1 alnsn label = label->next; 434 1.1 alnsn } 435 1.1 alnsn 436 1.1 alnsn SLJIT_ASSERT(!label); 437 1.1 alnsn SLJIT_ASSERT(!jump); 438 1.1 alnsn SLJIT_ASSERT(!const_); 439 1.1 alnsn #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) 440 1.3 alnsn SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins))); 441 1.1 alnsn #else 442 1.3 alnsn SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); 443 1.1 alnsn #endif 444 1.1 alnsn 445 1.1 alnsn jump = compiler->jumps; 446 1.1 alnsn while (jump) { 447 1.1 alnsn do { 448 1.1 alnsn addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; 449 1.8 alnsn buf_ptr = (sljit_ins *)jump->addr; 450 1.8 alnsn 451 1.1 alnsn if (jump->flags & PATCH_B) { 452 1.3 alnsn if (jump->flags & IS_COND) { 453 1.3 alnsn if (!(jump->flags & PATCH_ABS_B)) { 454 1.8 alnsn addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset); 455 1.3 alnsn SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000); 456 1.3 alnsn *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001); 457 1.1 alnsn } 458 1.1 alnsn else { 459 1.3 alnsn SLJIT_ASSERT(addr <= 0xffff); 460 1.3 alnsn *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001); 461 1.1 alnsn } 462 1.1 alnsn } 463 1.1 alnsn else { 464 1.3 alnsn if (!(jump->flags & PATCH_ABS_B)) { 465 1.8 alnsn addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset); 466 1.3 alnsn SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000); 467 1.3 alnsn *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1); 468 1.1 alnsn } 469 1.1 alnsn else { 470 1.3 alnsn SLJIT_ASSERT(addr <= 0x03ffffff); 471 1.3 alnsn *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1); 472 1.1 alnsn } 473 1.1 alnsn } 474 1.1 alnsn break; 475 1.1 alnsn } 476 1.8 alnsn 477 1.1 alnsn /* Set the fields of immediate loads. */ 478 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 479 1.1 alnsn buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); 480 1.1 alnsn buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); 481 1.1 alnsn #else 482 1.3 alnsn if (jump->flags & PATCH_ABS32) { 483 1.3 alnsn SLJIT_ASSERT(addr <= 0x7fffffff); 484 1.3 alnsn buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); 485 1.3 alnsn buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); 486 1.3 alnsn break; 487 1.3 alnsn } 488 1.3 alnsn if (jump->flags & PATCH_ABS48) { 489 1.3 alnsn SLJIT_ASSERT(addr <= 0x7fffffffffff); 490 1.3 alnsn buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff); 491 1.3 alnsn buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff); 492 1.3 alnsn buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff); 493 1.3 alnsn break; 494 1.3 alnsn } 495 1.1 alnsn buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); 496 1.1 alnsn buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); 497 1.1 alnsn buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); 498 1.1 alnsn buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff); 499 1.1 alnsn #endif 500 1.1 alnsn } while (0); 501 1.1 alnsn jump = jump->next; 502 1.1 alnsn } 503 1.1 alnsn 504 1.3 alnsn compiler->error = SLJIT_ERR_COMPILED; 505 1.8 alnsn compiler->executable_offset = executable_offset; 506 1.3 alnsn compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); 507 1.8 alnsn 508 1.8 alnsn code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); 509 1.1 alnsn 510 1.1 alnsn #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) 511 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 512 1.3 alnsn if (((sljit_sw)code_ptr) & 0x4) 513 1.1 alnsn code_ptr++; 514 1.8 alnsn #endif 515 1.3 alnsn sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); 516 1.8 alnsn #endif 517 1.8 alnsn 518 1.8 alnsn code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); 519 1.8 alnsn 520 1.8 alnsn SLJIT_CACHE_FLUSH(code, code_ptr); 521 1.8 alnsn 522 1.8 alnsn #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) 523 1.1 alnsn return code_ptr; 524 1.1 alnsn #else 525 1.1 alnsn return code; 526 1.1 alnsn #endif 527 1.1 alnsn } 528 1.1 alnsn 529 1.2 alnsn /* --------------------------------------------------------------------- */ 530 1.2 alnsn /* Entry, exit */ 531 1.2 alnsn /* --------------------------------------------------------------------- */ 532 1.2 alnsn 533 1.1 alnsn /* inp_flags: */ 534 1.1 alnsn 535 1.1 alnsn /* Creates an index in data_transfer_insts array. */ 536 1.2 alnsn #define LOAD_DATA 0x01 537 1.2 alnsn #define INDEXED 0x02 538 1.2 alnsn #define WRITE_BACK 0x04 539 1.1 alnsn #define WORD_DATA 0x00 540 1.2 alnsn #define BYTE_DATA 0x08 541 1.2 alnsn #define HALF_DATA 0x10 542 1.2 alnsn #define INT_DATA 0x18 543 1.2 alnsn #define SIGNED_DATA 0x20 544 1.2 alnsn /* Separates integer and floating point registers */ 545 1.2 alnsn #define GPR_REG 0x3f 546 1.2 alnsn #define DOUBLE_DATA 0x40 547 1.1 alnsn 548 1.2 alnsn #define MEM_MASK 0x7f 549 1.1 alnsn 550 1.1 alnsn /* Other inp_flags. */ 551 1.1 alnsn 552 1.1 alnsn #define ARG_TEST 0x000100 553 1.1 alnsn /* Integer opertion and set flags -> requires exts on 64 bit systems. */ 554 1.1 alnsn #define ALT_SIGN_EXT 0x000200 555 1.1 alnsn /* This flag affects the RC() and OERC() macros. */ 556 1.1 alnsn #define ALT_SET_FLAGS 0x000400 557 1.3 alnsn #define ALT_KEEP_CACHE 0x000800 558 1.1 alnsn #define ALT_FORM1 0x010000 559 1.1 alnsn #define ALT_FORM2 0x020000 560 1.1 alnsn #define ALT_FORM3 0x040000 561 1.1 alnsn #define ALT_FORM4 0x080000 562 1.1 alnsn #define ALT_FORM5 0x100000 563 1.1 alnsn #define ALT_FORM6 0x200000 564 1.8 alnsn #define ALT_FORM7 0x400000 565 1.1 alnsn 566 1.1 alnsn /* Source and destination is register. */ 567 1.1 alnsn #define REG_DEST 0x000001 568 1.1 alnsn #define REG1_SOURCE 0x000002 569 1.1 alnsn #define REG2_SOURCE 0x000004 570 1.1 alnsn /* getput_arg_fast returned true. */ 571 1.1 alnsn #define FAST_DEST 0x000008 572 1.1 alnsn /* Multiple instructions are required. */ 573 1.1 alnsn #define SLOW_DEST 0x000010 574 1.1 alnsn /* 575 1.1 alnsn ALT_SIGN_EXT 0x000200 576 1.1 alnsn ALT_SET_FLAGS 0x000400 577 1.1 alnsn ALT_FORM1 0x010000 578 1.1 alnsn ... 579 1.8 alnsn ALT_FORM7 0x400000 */ 580 1.1 alnsn 581 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 582 1.1 alnsn #include "sljitNativePPC_32.c" 583 1.1 alnsn #else 584 1.1 alnsn #include "sljitNativePPC_64.c" 585 1.1 alnsn #endif 586 1.1 alnsn 587 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 588 1.1 alnsn #define STACK_STORE STW 589 1.1 alnsn #define STACK_LOAD LWZ 590 1.1 alnsn #else 591 1.1 alnsn #define STACK_STORE STD 592 1.1 alnsn #define STACK_LOAD LD 593 1.1 alnsn #endif 594 1.1 alnsn 595 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, 596 1.5 alnsn sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 597 1.5 alnsn sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 598 1.1 alnsn { 599 1.5 alnsn sljit_s32 i, tmp, offs; 600 1.5 alnsn 601 1.1 alnsn CHECK_ERROR(); 602 1.5 alnsn CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); 603 1.5 alnsn set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); 604 1.5 alnsn 605 1.5 alnsn FAIL_IF(push_inst(compiler, MFLR | D(0))); 606 1.5 alnsn offs = -(sljit_s32)(sizeof(sljit_sw)); 607 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); 608 1.5 alnsn 609 1.5 alnsn tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; 610 1.5 alnsn for (i = SLJIT_S0; i >= tmp; i--) { 611 1.5 alnsn offs -= (sljit_s32)(sizeof(sljit_sw)); 612 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); 613 1.5 alnsn } 614 1.1 alnsn 615 1.5 alnsn for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { 616 1.5 alnsn offs -= (sljit_s32)(sizeof(sljit_sw)); 617 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); 618 1.5 alnsn } 619 1.5 alnsn 620 1.5 alnsn SLJIT_ASSERT(offs == -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1)); 621 1.1 alnsn 622 1.3 alnsn #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) 623 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw)))); 624 1.3 alnsn #else 625 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw)))); 626 1.3 alnsn #endif 627 1.1 alnsn 628 1.3 alnsn FAIL_IF(push_inst(compiler, ADDI | D(TMP_ZERO) | A(0) | 0)); 629 1.1 alnsn if (args >= 1) 630 1.5 alnsn FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(SLJIT_S0) | B(SLJIT_R0))); 631 1.1 alnsn if (args >= 2) 632 1.5 alnsn FAIL_IF(push_inst(compiler, OR | S(SLJIT_R1) | A(SLJIT_S1) | B(SLJIT_R1))); 633 1.1 alnsn if (args >= 3) 634 1.5 alnsn FAIL_IF(push_inst(compiler, OR | S(SLJIT_R2) | A(SLJIT_S2) | B(SLJIT_R2))); 635 1.1 alnsn 636 1.5 alnsn local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; 637 1.5 alnsn local_size = (local_size + 15) & ~0xf; 638 1.5 alnsn compiler->local_size = local_size; 639 1.1 alnsn 640 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 641 1.5 alnsn if (local_size <= SIMM_MAX) 642 1.5 alnsn FAIL_IF(push_inst(compiler, STWU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size))); 643 1.1 alnsn else { 644 1.5 alnsn FAIL_IF(load_immediate(compiler, 0, -local_size)); 645 1.5 alnsn FAIL_IF(push_inst(compiler, STWUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0))); 646 1.1 alnsn } 647 1.1 alnsn #else 648 1.5 alnsn if (local_size <= SIMM_MAX) 649 1.5 alnsn FAIL_IF(push_inst(compiler, STDU | S(SLJIT_SP) | A(SLJIT_SP) | IMM(-local_size))); 650 1.1 alnsn else { 651 1.5 alnsn FAIL_IF(load_immediate(compiler, 0, -local_size)); 652 1.5 alnsn FAIL_IF(push_inst(compiler, STDUX | S(SLJIT_SP) | A(SLJIT_SP) | B(0))); 653 1.1 alnsn } 654 1.1 alnsn #endif 655 1.1 alnsn 656 1.1 alnsn return SLJIT_SUCCESS; 657 1.1 alnsn } 658 1.1 alnsn 659 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, 660 1.5 alnsn sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, 661 1.5 alnsn sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) 662 1.1 alnsn { 663 1.5 alnsn CHECK_ERROR(); 664 1.5 alnsn CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); 665 1.5 alnsn set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); 666 1.1 alnsn 667 1.5 alnsn local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET; 668 1.5 alnsn compiler->local_size = (local_size + 15) & ~0xf; 669 1.5 alnsn return SLJIT_SUCCESS; 670 1.1 alnsn } 671 1.1 alnsn 672 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) 673 1.1 alnsn { 674 1.5 alnsn sljit_s32 i, tmp, offs; 675 1.5 alnsn 676 1.1 alnsn CHECK_ERROR(); 677 1.5 alnsn CHECK(check_sljit_emit_return(compiler, op, src, srcw)); 678 1.1 alnsn 679 1.1 alnsn FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); 680 1.1 alnsn 681 1.1 alnsn if (compiler->local_size <= SIMM_MAX) 682 1.5 alnsn FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_SP) | A(SLJIT_SP) | IMM(compiler->local_size))); 683 1.1 alnsn else { 684 1.1 alnsn FAIL_IF(load_immediate(compiler, 0, compiler->local_size)); 685 1.5 alnsn FAIL_IF(push_inst(compiler, ADD | D(SLJIT_SP) | A(SLJIT_SP) | B(0))); 686 1.1 alnsn } 687 1.1 alnsn 688 1.3 alnsn #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) 689 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw)))); 690 1.3 alnsn #else 691 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw)))); 692 1.3 alnsn #endif 693 1.5 alnsn 694 1.5 alnsn offs = -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); 695 1.5 alnsn 696 1.5 alnsn tmp = compiler->scratches; 697 1.5 alnsn for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { 698 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); 699 1.5 alnsn offs += (sljit_s32)(sizeof(sljit_sw)); 700 1.5 alnsn } 701 1.5 alnsn 702 1.5 alnsn tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; 703 1.5 alnsn for (i = tmp; i <= SLJIT_S0; i++) { 704 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); 705 1.5 alnsn offs += (sljit_s32)(sizeof(sljit_sw)); 706 1.5 alnsn } 707 1.5 alnsn 708 1.5 alnsn FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); 709 1.5 alnsn SLJIT_ASSERT(offs == -(sljit_sw)(sizeof(sljit_sw))); 710 1.1 alnsn 711 1.1 alnsn FAIL_IF(push_inst(compiler, MTLR | S(0))); 712 1.1 alnsn FAIL_IF(push_inst(compiler, BLR)); 713 1.1 alnsn 714 1.1 alnsn return SLJIT_SUCCESS; 715 1.1 alnsn } 716 1.1 alnsn 717 1.1 alnsn #undef STACK_STORE 718 1.1 alnsn #undef STACK_LOAD 719 1.1 alnsn 720 1.1 alnsn /* --------------------------------------------------------------------- */ 721 1.1 alnsn /* Operators */ 722 1.1 alnsn /* --------------------------------------------------------------------- */ 723 1.1 alnsn 724 1.1 alnsn /* i/x - immediate/indexed form 725 1.1 alnsn n/w - no write-back / write-back (1 bit) 726 1.1 alnsn s/l - store/load (1 bit) 727 1.1 alnsn u/s - signed/unsigned (1 bit) 728 1.1 alnsn w/b/h/i - word/byte/half/int allowed (2 bit) 729 1.1 alnsn It contans 32 items, but not all are different. */ 730 1.1 alnsn 731 1.1 alnsn /* 64 bit only: [reg+imm] must be aligned to 4 bytes. */ 732 1.3 alnsn #define INT_ALIGNED 0x10000 733 1.1 alnsn /* 64-bit only: there is no lwau instruction. */ 734 1.1 alnsn #define UPDATE_REQ 0x20000 735 1.1 alnsn 736 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 737 1.2 alnsn #define ARCH_32_64(a, b) a 738 1.2 alnsn #define INST_CODE_AND_DST(inst, flags, reg) \ 739 1.2 alnsn ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) 740 1.1 alnsn #else 741 1.2 alnsn #define ARCH_32_64(a, b) b 742 1.2 alnsn #define INST_CODE_AND_DST(inst, flags, reg) \ 743 1.3 alnsn (((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) 744 1.1 alnsn #endif 745 1.1 alnsn 746 1.5 alnsn static const sljit_ins data_transfer_insts[64 + 8] = { 747 1.2 alnsn 748 1.2 alnsn /* -------- Unsigned -------- */ 749 1.2 alnsn 750 1.2 alnsn /* Word. */ 751 1.2 alnsn 752 1.3 alnsn /* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */), 753 1.3 alnsn /* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */), 754 1.2 alnsn /* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), 755 1.2 alnsn /* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), 756 1.2 alnsn 757 1.3 alnsn /* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */), 758 1.3 alnsn /* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */), 759 1.2 alnsn /* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), 760 1.2 alnsn /* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), 761 1.2 alnsn 762 1.2 alnsn /* Byte. */ 763 1.2 alnsn 764 1.2 alnsn /* u b n i s */ HI(38) /* stb */, 765 1.2 alnsn /* u b n i l */ HI(34) /* lbz */, 766 1.2 alnsn /* u b n x s */ HI(31) | LO(215) /* stbx */, 767 1.2 alnsn /* u b n x l */ HI(31) | LO(87) /* lbzx */, 768 1.2 alnsn 769 1.2 alnsn /* u b w i s */ HI(39) /* stbu */, 770 1.2 alnsn /* u b w i l */ HI(35) /* lbzu */, 771 1.2 alnsn /* u b w x s */ HI(31) | LO(247) /* stbux */, 772 1.2 alnsn /* u b w x l */ HI(31) | LO(119) /* lbzux */, 773 1.2 alnsn 774 1.2 alnsn /* Half. */ 775 1.2 alnsn 776 1.2 alnsn /* u h n i s */ HI(44) /* sth */, 777 1.2 alnsn /* u h n i l */ HI(40) /* lhz */, 778 1.2 alnsn /* u h n x s */ HI(31) | LO(407) /* sthx */, 779 1.2 alnsn /* u h n x l */ HI(31) | LO(279) /* lhzx */, 780 1.2 alnsn 781 1.2 alnsn /* u h w i s */ HI(45) /* sthu */, 782 1.2 alnsn /* u h w i l */ HI(41) /* lhzu */, 783 1.2 alnsn /* u h w x s */ HI(31) | LO(439) /* sthux */, 784 1.2 alnsn /* u h w x l */ HI(31) | LO(311) /* lhzux */, 785 1.1 alnsn 786 1.2 alnsn /* Int. */ 787 1.2 alnsn 788 1.2 alnsn /* u i n i s */ HI(36) /* stw */, 789 1.2 alnsn /* u i n i l */ HI(32) /* lwz */, 790 1.2 alnsn /* u i n x s */ HI(31) | LO(151) /* stwx */, 791 1.2 alnsn /* u i n x l */ HI(31) | LO(23) /* lwzx */, 792 1.2 alnsn 793 1.2 alnsn /* u i w i s */ HI(37) /* stwu */, 794 1.2 alnsn /* u i w i l */ HI(33) /* lwzu */, 795 1.2 alnsn /* u i w x s */ HI(31) | LO(183) /* stwux */, 796 1.2 alnsn /* u i w x l */ HI(31) | LO(55) /* lwzux */, 797 1.2 alnsn 798 1.2 alnsn /* -------- Signed -------- */ 799 1.2 alnsn 800 1.2 alnsn /* Word. */ 801 1.2 alnsn 802 1.3 alnsn /* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | INT_ALIGNED | 0x0 /* std */), 803 1.3 alnsn /* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x0 /* ld */), 804 1.2 alnsn /* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), 805 1.2 alnsn /* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), 806 1.2 alnsn 807 1.3 alnsn /* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | INT_ALIGNED | 0x1 /* stdu */), 808 1.3 alnsn /* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | 0x1 /* ldu */), 809 1.2 alnsn /* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), 810 1.2 alnsn /* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), 811 1.2 alnsn 812 1.2 alnsn /* Byte. */ 813 1.2 alnsn 814 1.2 alnsn /* s b n i s */ HI(38) /* stb */, 815 1.2 alnsn /* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */, 816 1.2 alnsn /* s b n x s */ HI(31) | LO(215) /* stbx */, 817 1.2 alnsn /* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */, 818 1.2 alnsn 819 1.2 alnsn /* s b w i s */ HI(39) /* stbu */, 820 1.2 alnsn /* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */, 821 1.2 alnsn /* s b w x s */ HI(31) | LO(247) /* stbux */, 822 1.2 alnsn /* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */, 823 1.2 alnsn 824 1.2 alnsn /* Half. */ 825 1.2 alnsn 826 1.2 alnsn /* s h n i s */ HI(44) /* sth */, 827 1.2 alnsn /* s h n i l */ HI(42) /* lha */, 828 1.2 alnsn /* s h n x s */ HI(31) | LO(407) /* sthx */, 829 1.2 alnsn /* s h n x l */ HI(31) | LO(343) /* lhax */, 830 1.2 alnsn 831 1.2 alnsn /* s h w i s */ HI(45) /* sthu */, 832 1.2 alnsn /* s h w i l */ HI(43) /* lhau */, 833 1.2 alnsn /* s h w x s */ HI(31) | LO(439) /* sthux */, 834 1.2 alnsn /* s h w x l */ HI(31) | LO(375) /* lhaux */, 835 1.2 alnsn 836 1.2 alnsn /* Int. */ 837 1.2 alnsn 838 1.2 alnsn /* s i n i s */ HI(36) /* stw */, 839 1.3 alnsn /* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | INT_ALIGNED | 0x2 /* lwa */), 840 1.2 alnsn /* s i n x s */ HI(31) | LO(151) /* stwx */, 841 1.2 alnsn /* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */), 842 1.2 alnsn 843 1.2 alnsn /* s i w i s */ HI(37) /* stwu */, 844 1.3 alnsn /* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | INT_ALIGNED | UPDATE_REQ | 0x2 /* lwa */), 845 1.2 alnsn /* s i w x s */ HI(31) | LO(183) /* stwux */, 846 1.2 alnsn /* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */), 847 1.2 alnsn 848 1.2 alnsn /* -------- Double -------- */ 849 1.2 alnsn 850 1.2 alnsn /* d n i s */ HI(54) /* stfd */, 851 1.2 alnsn /* d n i l */ HI(50) /* lfd */, 852 1.2 alnsn /* d n x s */ HI(31) | LO(727) /* stfdx */, 853 1.2 alnsn /* d n x l */ HI(31) | LO(599) /* lfdx */, 854 1.1 alnsn 855 1.3 alnsn /* s n i s */ HI(52) /* stfs */, 856 1.3 alnsn /* s n i l */ HI(48) /* lfs */, 857 1.3 alnsn /* s n x s */ HI(31) | LO(663) /* stfsx */, 858 1.3 alnsn /* s n x l */ HI(31) | LO(535) /* lfsx */, 859 1.3 alnsn 860 1.1 alnsn }; 861 1.1 alnsn 862 1.2 alnsn #undef ARCH_32_64 863 1.1 alnsn 864 1.1 alnsn /* Simple cases, (no caching is required). */ 865 1.5 alnsn static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) 866 1.1 alnsn { 867 1.1 alnsn sljit_ins inst; 868 1.1 alnsn 869 1.3 alnsn /* Should work when (arg & REG_MASK) == 0. */ 870 1.8 alnsn SLJIT_ASSERT(A(0) == 0); 871 1.1 alnsn SLJIT_ASSERT(arg & SLJIT_MEM); 872 1.1 alnsn 873 1.3 alnsn if (arg & OFFS_REG_MASK) { 874 1.3 alnsn if (argw & 0x3) 875 1.3 alnsn return 0; 876 1.3 alnsn if (inp_flags & ARG_TEST) 877 1.3 alnsn return 1; 878 1.3 alnsn 879 1.3 alnsn inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; 880 1.3 alnsn SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); 881 1.3 alnsn FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(OFFS_REG(arg)))); 882 1.3 alnsn return -1; 883 1.3 alnsn } 884 1.3 alnsn 885 1.3 alnsn if (SLJIT_UNLIKELY(!(arg & REG_MASK))) 886 1.3 alnsn inp_flags &= ~WRITE_BACK; 887 1.3 alnsn 888 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 889 1.3 alnsn inst = data_transfer_insts[inp_flags & MEM_MASK]; 890 1.3 alnsn SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ)); 891 1.3 alnsn 892 1.3 alnsn if (argw > SIMM_MAX || argw < SIMM_MIN || ((inst & INT_ALIGNED) && (argw & 0x3)) || (inst & UPDATE_REQ)) 893 1.3 alnsn return 0; 894 1.3 alnsn if (inp_flags & ARG_TEST) 895 1.3 alnsn return 1; 896 1.1 alnsn #endif 897 1.1 alnsn 898 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 899 1.3 alnsn if (argw > SIMM_MAX || argw < SIMM_MIN) 900 1.3 alnsn return 0; 901 1.3 alnsn if (inp_flags & ARG_TEST) 902 1.3 alnsn return 1; 903 1.1 alnsn 904 1.3 alnsn inst = data_transfer_insts[inp_flags & MEM_MASK]; 905 1.3 alnsn SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); 906 1.3 alnsn #endif 907 1.1 alnsn 908 1.3 alnsn FAIL_IF(push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | IMM(argw))); 909 1.3 alnsn return -1; 910 1.1 alnsn } 911 1.1 alnsn 912 1.1 alnsn /* See getput_arg below. 913 1.1 alnsn Note: can_cache is called only for binary operators. Those operator always 914 1.1 alnsn uses word arguments without write back. */ 915 1.5 alnsn static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) 916 1.1 alnsn { 917 1.3 alnsn sljit_sw high_short, next_high_short; 918 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 919 1.3 alnsn sljit_sw diff; 920 1.3 alnsn #endif 921 1.3 alnsn 922 1.2 alnsn SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); 923 1.1 alnsn 924 1.3 alnsn if (arg & OFFS_REG_MASK) 925 1.3 alnsn return ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && (argw & 0x3) == (next_argw & 0x3)); 926 1.1 alnsn 927 1.3 alnsn if (next_arg & OFFS_REG_MASK) 928 1.3 alnsn return 0; 929 1.1 alnsn 930 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 931 1.3 alnsn high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff; 932 1.3 alnsn next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; 933 1.3 alnsn return high_short == next_high_short; 934 1.3 alnsn #else 935 1.3 alnsn if (argw <= 0x7fffffffl && argw >= -0x80000000l) { 936 1.3 alnsn high_short = (argw + ((argw & 0x8000) << 1)) & ~0xffff; 937 1.3 alnsn next_high_short = (next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; 938 1.3 alnsn if (high_short == next_high_short) 939 1.1 alnsn return 1; 940 1.1 alnsn } 941 1.1 alnsn 942 1.3 alnsn diff = argw - next_argw; 943 1.3 alnsn if (!(arg & REG_MASK)) 944 1.3 alnsn return diff <= SIMM_MAX && diff >= SIMM_MIN; 945 1.3 alnsn 946 1.3 alnsn if (arg == next_arg && diff <= SIMM_MAX && diff >= SIMM_MIN) 947 1.1 alnsn return 1; 948 1.1 alnsn 949 1.1 alnsn return 0; 950 1.3 alnsn #endif 951 1.1 alnsn } 952 1.1 alnsn 953 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 954 1.1 alnsn #define ADJUST_CACHED_IMM(imm) \ 955 1.3 alnsn if ((inst & INT_ALIGNED) && (imm & 0x3)) { \ 956 1.1 alnsn /* Adjust cached value. Fortunately this is really a rare case */ \ 957 1.1 alnsn compiler->cache_argw += imm & 0x3; \ 958 1.1 alnsn FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \ 959 1.1 alnsn imm &= ~0x3; \ 960 1.1 alnsn } 961 1.1 alnsn #endif 962 1.1 alnsn 963 1.1 alnsn /* Emit the necessary instructions. See can_cache above. */ 964 1.5 alnsn static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) 965 1.1 alnsn { 966 1.5 alnsn sljit_s32 tmp_r; 967 1.1 alnsn sljit_ins inst; 968 1.3 alnsn sljit_sw high_short, next_high_short; 969 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 970 1.3 alnsn sljit_sw diff; 971 1.3 alnsn #endif 972 1.1 alnsn 973 1.1 alnsn SLJIT_ASSERT(arg & SLJIT_MEM); 974 1.1 alnsn 975 1.2 alnsn tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1; 976 1.2 alnsn /* Special case for "mov reg, [reg, ... ]". */ 977 1.3 alnsn if ((arg & REG_MASK) == tmp_r) 978 1.2 alnsn tmp_r = TMP_REG1; 979 1.1 alnsn 980 1.3 alnsn if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { 981 1.1 alnsn argw &= 0x3; 982 1.1 alnsn /* Otherwise getput_arg_fast would capture it. */ 983 1.1 alnsn SLJIT_ASSERT(argw); 984 1.2 alnsn 985 1.3 alnsn if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg && argw == compiler->cache_argw) 986 1.2 alnsn tmp_r = TMP_REG3; 987 1.2 alnsn else { 988 1.3 alnsn if ((arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK) && argw == (next_argw & 0x3)) { 989 1.3 alnsn compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK); 990 1.2 alnsn compiler->cache_argw = argw; 991 1.2 alnsn tmp_r = TMP_REG3; 992 1.2 alnsn } 993 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 994 1.3 alnsn FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(arg)) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1))); 995 1.1 alnsn #else 996 1.3 alnsn FAIL_IF(push_inst(compiler, RLDI(tmp_r, OFFS_REG(arg), argw, 63 - argw, 1))); 997 1.1 alnsn #endif 998 1.2 alnsn } 999 1.1 alnsn inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; 1000 1.3 alnsn SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); 1001 1.3 alnsn return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r)); 1002 1.1 alnsn } 1003 1.1 alnsn 1004 1.3 alnsn if (SLJIT_UNLIKELY(!(arg & REG_MASK))) 1005 1.3 alnsn inp_flags &= ~WRITE_BACK; 1006 1.3 alnsn 1007 1.1 alnsn inst = data_transfer_insts[inp_flags & MEM_MASK]; 1008 1.3 alnsn SLJIT_ASSERT((arg & REG_MASK) || !(inst & UPDATE_REQ)); 1009 1.1 alnsn 1010 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1011 1.3 alnsn if (argw <= 0x7fff7fffl && argw >= -0x80000000l 1012 1.3 alnsn && (!(inst & INT_ALIGNED) || !(argw & 0x3)) && !(inst & UPDATE_REQ)) { 1013 1.3 alnsn #endif 1014 1.3 alnsn 1015 1.3 alnsn arg &= REG_MASK; 1016 1.5 alnsn high_short = (sljit_s32)(argw + ((argw & 0x8000) << 1)) & ~0xffff; 1017 1.3 alnsn /* The getput_arg_fast should handle this otherwise. */ 1018 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1019 1.3 alnsn SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l); 1020 1.3 alnsn #else 1021 1.3 alnsn SLJIT_ASSERT(high_short && !(inst & (INT_ALIGNED | UPDATE_REQ))); 1022 1.3 alnsn #endif 1023 1.3 alnsn 1024 1.3 alnsn if (inp_flags & WRITE_BACK) { 1025 1.3 alnsn tmp_r = arg; 1026 1.3 alnsn FAIL_IF(push_inst(compiler, ADDIS | D(arg) | A(arg) | IMM(high_short >> 16))); 1027 1.3 alnsn } 1028 1.5 alnsn else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) { 1029 1.3 alnsn if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) { 1030 1.5 alnsn next_high_short = (sljit_s32)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; 1031 1.3 alnsn if (high_short == next_high_short) { 1032 1.5 alnsn compiler->cache_arg = SLJIT_MEM | arg; 1033 1.5 alnsn compiler->cache_argw = high_short; 1034 1.3 alnsn tmp_r = TMP_REG3; 1035 1.3 alnsn } 1036 1.3 alnsn } 1037 1.3 alnsn FAIL_IF(push_inst(compiler, ADDIS | D(tmp_r) | A(arg & REG_MASK) | IMM(high_short >> 16))); 1038 1.3 alnsn } 1039 1.3 alnsn else 1040 1.3 alnsn tmp_r = TMP_REG3; 1041 1.3 alnsn 1042 1.3 alnsn return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r) | IMM(argw)); 1043 1.3 alnsn 1044 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1045 1.1 alnsn } 1046 1.1 alnsn 1047 1.3 alnsn /* Everything else is PPC-64 only. */ 1048 1.3 alnsn if (SLJIT_UNLIKELY(!(arg & REG_MASK))) { 1049 1.3 alnsn diff = argw - compiler->cache_argw; 1050 1.3 alnsn if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { 1051 1.3 alnsn ADJUST_CACHED_IMM(diff); 1052 1.3 alnsn return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff)); 1053 1.3 alnsn } 1054 1.3 alnsn 1055 1.3 alnsn diff = argw - next_argw; 1056 1.3 alnsn if ((next_arg & SLJIT_MEM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { 1057 1.3 alnsn SLJIT_ASSERT(inp_flags & LOAD_DATA); 1058 1.3 alnsn 1059 1.3 alnsn compiler->cache_arg = SLJIT_IMM; 1060 1.3 alnsn compiler->cache_argw = argw; 1061 1.3 alnsn tmp_r = TMP_REG3; 1062 1.3 alnsn } 1063 1.3 alnsn 1064 1.3 alnsn FAIL_IF(load_immediate(compiler, tmp_r, argw)); 1065 1.3 alnsn return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r)); 1066 1.3 alnsn } 1067 1.3 alnsn 1068 1.3 alnsn diff = argw - compiler->cache_argw; 1069 1.3 alnsn if (compiler->cache_arg == arg && diff <= SIMM_MAX && diff >= SIMM_MIN) { 1070 1.3 alnsn SLJIT_ASSERT(!(inp_flags & WRITE_BACK) && !(inst & UPDATE_REQ)); 1071 1.3 alnsn ADJUST_CACHED_IMM(diff); 1072 1.3 alnsn return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(diff)); 1073 1.3 alnsn } 1074 1.3 alnsn 1075 1.3 alnsn if ((compiler->cache_arg & SLJIT_IMM) && diff <= SIMM_MAX && diff >= SIMM_MIN) { 1076 1.1 alnsn inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; 1077 1.3 alnsn SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); 1078 1.3 alnsn if (compiler->cache_argw != argw) { 1079 1.3 alnsn FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | IMM(diff))); 1080 1.3 alnsn compiler->cache_argw = argw; 1081 1.3 alnsn } 1082 1.3 alnsn return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3)); 1083 1.1 alnsn } 1084 1.1 alnsn 1085 1.1 alnsn if (argw == next_argw && (next_arg & SLJIT_MEM)) { 1086 1.1 alnsn SLJIT_ASSERT(inp_flags & LOAD_DATA); 1087 1.1 alnsn FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); 1088 1.1 alnsn 1089 1.1 alnsn compiler->cache_arg = SLJIT_IMM; 1090 1.1 alnsn compiler->cache_argw = argw; 1091 1.1 alnsn 1092 1.1 alnsn inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; 1093 1.3 alnsn SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); 1094 1.3 alnsn return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(TMP_REG3)); 1095 1.1 alnsn } 1096 1.1 alnsn 1097 1.3 alnsn diff = argw - next_argw; 1098 1.3 alnsn if (arg == next_arg && !(inp_flags & WRITE_BACK) && diff <= SIMM_MAX && diff >= SIMM_MIN) { 1099 1.1 alnsn SLJIT_ASSERT(inp_flags & LOAD_DATA); 1100 1.1 alnsn FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); 1101 1.3 alnsn FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & REG_MASK))); 1102 1.1 alnsn 1103 1.1 alnsn compiler->cache_arg = arg; 1104 1.1 alnsn compiler->cache_argw = argw; 1105 1.1 alnsn 1106 1.2 alnsn return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3)); 1107 1.1 alnsn } 1108 1.1 alnsn 1109 1.3 alnsn if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK) && diff <= SIMM_MAX && diff >= SIMM_MIN) { 1110 1.3 alnsn SLJIT_ASSERT(inp_flags & LOAD_DATA); 1111 1.3 alnsn FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); 1112 1.3 alnsn 1113 1.3 alnsn compiler->cache_arg = SLJIT_IMM; 1114 1.3 alnsn compiler->cache_argw = argw; 1115 1.3 alnsn tmp_r = TMP_REG3; 1116 1.3 alnsn } 1117 1.3 alnsn else 1118 1.3 alnsn FAIL_IF(load_immediate(compiler, tmp_r, argw)); 1119 1.3 alnsn 1120 1.1 alnsn /* Get the indexed version instead of the normal one. */ 1121 1.1 alnsn inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; 1122 1.3 alnsn SLJIT_ASSERT(!(inst & (INT_ALIGNED | UPDATE_REQ))); 1123 1.3 alnsn return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & REG_MASK) | B(tmp_r)); 1124 1.3 alnsn #endif 1125 1.1 alnsn } 1126 1.1 alnsn 1127 1.5 alnsn 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) 1128 1.2 alnsn { 1129 1.2 alnsn if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) 1130 1.2 alnsn return compiler->error; 1131 1.2 alnsn return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); 1132 1.2 alnsn } 1133 1.2 alnsn 1134 1.5 alnsn static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags, 1135 1.5 alnsn sljit_s32 dst, sljit_sw dstw, 1136 1.5 alnsn sljit_s32 src1, sljit_sw src1w, 1137 1.5 alnsn sljit_s32 src2, sljit_sw src2w) 1138 1.1 alnsn { 1139 1.1 alnsn /* arg1 goes to TMP_REG1 or src reg 1140 1.1 alnsn arg2 goes to TMP_REG2, imm or src reg 1141 1.1 alnsn TMP_REG3 can be used for caching 1142 1.1 alnsn result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ 1143 1.5 alnsn sljit_s32 dst_r; 1144 1.5 alnsn sljit_s32 src1_r; 1145 1.5 alnsn sljit_s32 src2_r; 1146 1.5 alnsn sljit_s32 sugg_src2_r = TMP_REG2; 1147 1.8 alnsn sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_FORM7 | ALT_SIGN_EXT | ALT_SET_FLAGS); 1148 1.3 alnsn 1149 1.3 alnsn if (!(input_flags & ALT_KEEP_CACHE)) { 1150 1.3 alnsn compiler->cache_arg = 0; 1151 1.3 alnsn compiler->cache_argw = 0; 1152 1.3 alnsn } 1153 1.1 alnsn 1154 1.1 alnsn /* Destination check. */ 1155 1.3 alnsn if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { 1156 1.5 alnsn if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) 1157 1.3 alnsn return SLJIT_SUCCESS; 1158 1.3 alnsn dst_r = TMP_REG2; 1159 1.3 alnsn } 1160 1.3 alnsn else if (FAST_IS_REG(dst)) { 1161 1.1 alnsn dst_r = dst; 1162 1.1 alnsn flags |= REG_DEST; 1163 1.5 alnsn if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) 1164 1.1 alnsn sugg_src2_r = dst_r; 1165 1.1 alnsn } 1166 1.1 alnsn else { 1167 1.1 alnsn SLJIT_ASSERT(dst & SLJIT_MEM); 1168 1.2 alnsn if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) { 1169 1.1 alnsn flags |= FAST_DEST; 1170 1.1 alnsn dst_r = TMP_REG2; 1171 1.1 alnsn } 1172 1.1 alnsn else { 1173 1.1 alnsn flags |= SLOW_DEST; 1174 1.1 alnsn dst_r = 0; 1175 1.1 alnsn } 1176 1.1 alnsn } 1177 1.1 alnsn 1178 1.1 alnsn /* Source 1. */ 1179 1.3 alnsn if (FAST_IS_REG(src1)) { 1180 1.1 alnsn src1_r = src1; 1181 1.1 alnsn flags |= REG1_SOURCE; 1182 1.1 alnsn } 1183 1.1 alnsn else if (src1 & SLJIT_IMM) { 1184 1.1 alnsn FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); 1185 1.1 alnsn src1_r = TMP_REG1; 1186 1.1 alnsn } 1187 1.2 alnsn else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { 1188 1.1 alnsn FAIL_IF(compiler->error); 1189 1.1 alnsn src1_r = TMP_REG1; 1190 1.1 alnsn } 1191 1.1 alnsn else 1192 1.1 alnsn src1_r = 0; 1193 1.1 alnsn 1194 1.1 alnsn /* Source 2. */ 1195 1.3 alnsn if (FAST_IS_REG(src2)) { 1196 1.1 alnsn src2_r = src2; 1197 1.1 alnsn flags |= REG2_SOURCE; 1198 1.5 alnsn if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) 1199 1.1 alnsn dst_r = src2_r; 1200 1.1 alnsn } 1201 1.1 alnsn else if (src2 & SLJIT_IMM) { 1202 1.1 alnsn FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); 1203 1.1 alnsn src2_r = sugg_src2_r; 1204 1.1 alnsn } 1205 1.2 alnsn else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { 1206 1.1 alnsn FAIL_IF(compiler->error); 1207 1.1 alnsn src2_r = sugg_src2_r; 1208 1.1 alnsn } 1209 1.1 alnsn else 1210 1.1 alnsn src2_r = 0; 1211 1.1 alnsn 1212 1.1 alnsn /* src1_r, src2_r and dst_r can be zero (=unprocessed). 1213 1.1 alnsn All arguments are complex addressing modes, and it is a binary operator. */ 1214 1.1 alnsn if (src1_r == 0 && src2_r == 0 && dst_r == 0) { 1215 1.1 alnsn if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { 1216 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); 1217 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); 1218 1.1 alnsn } 1219 1.1 alnsn else { 1220 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); 1221 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); 1222 1.1 alnsn } 1223 1.1 alnsn src1_r = TMP_REG1; 1224 1.1 alnsn src2_r = TMP_REG2; 1225 1.1 alnsn } 1226 1.1 alnsn else if (src1_r == 0 && src2_r == 0) { 1227 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); 1228 1.1 alnsn src1_r = TMP_REG1; 1229 1.1 alnsn } 1230 1.1 alnsn else if (src1_r == 0 && dst_r == 0) { 1231 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); 1232 1.1 alnsn src1_r = TMP_REG1; 1233 1.1 alnsn } 1234 1.1 alnsn else if (src2_r == 0 && dst_r == 0) { 1235 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); 1236 1.1 alnsn src2_r = sugg_src2_r; 1237 1.1 alnsn } 1238 1.1 alnsn 1239 1.1 alnsn if (dst_r == 0) 1240 1.1 alnsn dst_r = TMP_REG2; 1241 1.1 alnsn 1242 1.1 alnsn if (src1_r == 0) { 1243 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); 1244 1.1 alnsn src1_r = TMP_REG1; 1245 1.1 alnsn } 1246 1.1 alnsn 1247 1.1 alnsn if (src2_r == 0) { 1248 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); 1249 1.1 alnsn src2_r = sugg_src2_r; 1250 1.1 alnsn } 1251 1.1 alnsn 1252 1.1 alnsn FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r)); 1253 1.1 alnsn 1254 1.1 alnsn if (flags & (FAST_DEST | SLOW_DEST)) { 1255 1.1 alnsn if (flags & FAST_DEST) 1256 1.2 alnsn FAIL_IF(getput_arg_fast(compiler, input_flags, dst_r, dst, dstw)); 1257 1.1 alnsn else 1258 1.2 alnsn FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0)); 1259 1.1 alnsn } 1260 1.1 alnsn return SLJIT_SUCCESS; 1261 1.1 alnsn } 1262 1.1 alnsn 1263 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) 1264 1.1 alnsn { 1265 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1266 1.5 alnsn sljit_s32 int_op = op & SLJIT_I32_OP; 1267 1.3 alnsn #endif 1268 1.3 alnsn 1269 1.1 alnsn CHECK_ERROR(); 1270 1.5 alnsn CHECK(check_sljit_emit_op0(compiler, op)); 1271 1.1 alnsn 1272 1.3 alnsn op = GET_OPCODE(op); 1273 1.3 alnsn switch (op) { 1274 1.1 alnsn case SLJIT_BREAKPOINT: 1275 1.1 alnsn case SLJIT_NOP: 1276 1.1 alnsn return push_inst(compiler, NOP); 1277 1.5 alnsn case SLJIT_LMUL_UW: 1278 1.5 alnsn case SLJIT_LMUL_SW: 1279 1.5 alnsn FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); 1280 1.5 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1281 1.5 alnsn FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); 1282 1.5 alnsn return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); 1283 1.5 alnsn #else 1284 1.5 alnsn FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); 1285 1.5 alnsn return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); 1286 1.5 alnsn #endif 1287 1.5 alnsn case SLJIT_DIVMOD_UW: 1288 1.5 alnsn case SLJIT_DIVMOD_SW: 1289 1.5 alnsn FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); 1290 1.5 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1291 1.5 alnsn FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) : (op == SLJIT_DIVMOD_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); 1292 1.5 alnsn FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); 1293 1.5 alnsn #else 1294 1.5 alnsn FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); 1295 1.5 alnsn FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); 1296 1.5 alnsn #endif 1297 1.5 alnsn return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1)); 1298 1.5 alnsn case SLJIT_DIV_UW: 1299 1.5 alnsn case SLJIT_DIV_SW: 1300 1.5 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1301 1.5 alnsn return push_inst(compiler, (int_op ? (op == SLJIT_DIV_UW ? DIVWU : DIVW) : (op == SLJIT_DIV_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); 1302 1.5 alnsn #else 1303 1.5 alnsn return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); 1304 1.1 alnsn #endif 1305 1.1 alnsn } 1306 1.1 alnsn 1307 1.1 alnsn return SLJIT_SUCCESS; 1308 1.1 alnsn } 1309 1.1 alnsn 1310 1.2 alnsn #define EMIT_MOV(type, type_flags, type_cast) \ 1311 1.2 alnsn emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw) 1312 1.2 alnsn 1313 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, 1314 1.5 alnsn sljit_s32 dst, sljit_sw dstw, 1315 1.5 alnsn sljit_s32 src, sljit_sw srcw) 1316 1.1 alnsn { 1317 1.8 alnsn sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0; 1318 1.5 alnsn sljit_s32 op_flags = GET_ALL_FLAGS(op); 1319 1.1 alnsn 1320 1.1 alnsn CHECK_ERROR(); 1321 1.5 alnsn CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); 1322 1.1 alnsn ADJUST_LOCAL_OFFSET(dst, dstw); 1323 1.1 alnsn ADJUST_LOCAL_OFFSET(src, srcw); 1324 1.1 alnsn 1325 1.3 alnsn op = GET_OPCODE(op); 1326 1.3 alnsn if ((src & SLJIT_IMM) && srcw == 0) 1327 1.3 alnsn src = TMP_ZERO; 1328 1.3 alnsn 1329 1.8 alnsn if (GET_FLAG_TYPE(op_flags) == SLJIT_OVERFLOW || GET_FLAG_TYPE(op_flags) == SLJIT_NOT_OVERFLOW) 1330 1.3 alnsn FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); 1331 1.3 alnsn 1332 1.5 alnsn if (op_flags & SLJIT_I32_OP) { 1333 1.3 alnsn if (op < SLJIT_NOT) { 1334 1.3 alnsn if (FAST_IS_REG(src) && src == dst) { 1335 1.3 alnsn if (!TYPE_CAST_NEEDED(op)) 1336 1.3 alnsn return SLJIT_SUCCESS; 1337 1.3 alnsn } 1338 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1339 1.5 alnsn if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM)) 1340 1.5 alnsn op = SLJIT_MOV_U32; 1341 1.5 alnsn if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM)) 1342 1.5 alnsn op = SLJIT_MOVU_U32; 1343 1.5 alnsn if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM)) 1344 1.5 alnsn op = SLJIT_MOV_S32; 1345 1.5 alnsn if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM)) 1346 1.5 alnsn op = SLJIT_MOVU_S32; 1347 1.3 alnsn #endif 1348 1.3 alnsn } 1349 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1350 1.3 alnsn else { 1351 1.3 alnsn /* Most operations expect sign extended arguments. */ 1352 1.3 alnsn flags |= INT_DATA | SIGNED_DATA; 1353 1.3 alnsn if (src & SLJIT_IMM) 1354 1.5 alnsn srcw = (sljit_s32)srcw; 1355 1.3 alnsn } 1356 1.3 alnsn #endif 1357 1.1 alnsn } 1358 1.1 alnsn 1359 1.3 alnsn switch (op) { 1360 1.1 alnsn case SLJIT_MOV: 1361 1.3 alnsn case SLJIT_MOV_P: 1362 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 1363 1.5 alnsn case SLJIT_MOV_U32: 1364 1.5 alnsn case SLJIT_MOV_S32: 1365 1.3 alnsn #endif 1366 1.2 alnsn return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); 1367 1.1 alnsn 1368 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1369 1.5 alnsn case SLJIT_MOV_U32: 1370 1.5 alnsn return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32)); 1371 1.1 alnsn 1372 1.5 alnsn case SLJIT_MOV_S32: 1373 1.5 alnsn return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32)); 1374 1.3 alnsn #endif 1375 1.1 alnsn 1376 1.5 alnsn case SLJIT_MOV_U8: 1377 1.5 alnsn return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8)); 1378 1.1 alnsn 1379 1.5 alnsn case SLJIT_MOV_S8: 1380 1.5 alnsn return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8)); 1381 1.1 alnsn 1382 1.5 alnsn case SLJIT_MOV_U16: 1383 1.5 alnsn return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16)); 1384 1.1 alnsn 1385 1.5 alnsn case SLJIT_MOV_S16: 1386 1.5 alnsn return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16)); 1387 1.1 alnsn 1388 1.1 alnsn case SLJIT_MOVU: 1389 1.3 alnsn case SLJIT_MOVU_P: 1390 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 1391 1.5 alnsn case SLJIT_MOVU_U32: 1392 1.5 alnsn case SLJIT_MOVU_S32: 1393 1.3 alnsn #endif 1394 1.2 alnsn return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); 1395 1.1 alnsn 1396 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1397 1.5 alnsn case SLJIT_MOVU_U32: 1398 1.5 alnsn return EMIT_MOV(SLJIT_MOV_U32, INT_DATA | WRITE_BACK, (sljit_u32)); 1399 1.1 alnsn 1400 1.5 alnsn case SLJIT_MOVU_S32: 1401 1.5 alnsn return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s32)); 1402 1.3 alnsn #endif 1403 1.1 alnsn 1404 1.5 alnsn case SLJIT_MOVU_U8: 1405 1.5 alnsn return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, (sljit_u8)); 1406 1.1 alnsn 1407 1.5 alnsn case SLJIT_MOVU_S8: 1408 1.5 alnsn return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s8)); 1409 1.1 alnsn 1410 1.5 alnsn case SLJIT_MOVU_U16: 1411 1.5 alnsn return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, (sljit_u16)); 1412 1.1 alnsn 1413 1.5 alnsn case SLJIT_MOVU_S16: 1414 1.5 alnsn return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s16)); 1415 1.1 alnsn 1416 1.1 alnsn case SLJIT_NOT: 1417 1.2 alnsn return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw); 1418 1.1 alnsn 1419 1.1 alnsn case SLJIT_NEG: 1420 1.2 alnsn return emit_op(compiler, SLJIT_NEG, flags, dst, dstw, TMP_REG1, 0, src, srcw); 1421 1.1 alnsn 1422 1.1 alnsn case SLJIT_CLZ: 1423 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1424 1.5 alnsn return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_I32_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); 1425 1.1 alnsn #else 1426 1.2 alnsn return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw); 1427 1.1 alnsn #endif 1428 1.1 alnsn } 1429 1.1 alnsn 1430 1.1 alnsn return SLJIT_SUCCESS; 1431 1.1 alnsn } 1432 1.1 alnsn 1433 1.2 alnsn #undef EMIT_MOV 1434 1.2 alnsn 1435 1.1 alnsn #define TEST_SL_IMM(src, srcw) \ 1436 1.1 alnsn (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) 1437 1.1 alnsn 1438 1.1 alnsn #define TEST_UL_IMM(src, srcw) \ 1439 1.1 alnsn (((src) & SLJIT_IMM) && !((srcw) & ~0xffff)) 1440 1.1 alnsn 1441 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1442 1.1 alnsn #define TEST_SH_IMM(src, srcw) \ 1443 1.3 alnsn (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l) 1444 1.1 alnsn #else 1445 1.1 alnsn #define TEST_SH_IMM(src, srcw) \ 1446 1.1 alnsn (((src) & SLJIT_IMM) && !((srcw) & 0xffff)) 1447 1.1 alnsn #endif 1448 1.1 alnsn 1449 1.1 alnsn #define TEST_UH_IMM(src, srcw) \ 1450 1.1 alnsn (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000)) 1451 1.1 alnsn 1452 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1453 1.1 alnsn #define TEST_ADD_IMM(src, srcw) \ 1454 1.3 alnsn (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l) 1455 1.1 alnsn #else 1456 1.1 alnsn #define TEST_ADD_IMM(src, srcw) \ 1457 1.1 alnsn ((src) & SLJIT_IMM) 1458 1.1 alnsn #endif 1459 1.1 alnsn 1460 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1461 1.1 alnsn #define TEST_UI_IMM(src, srcw) \ 1462 1.1 alnsn (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff)) 1463 1.1 alnsn #else 1464 1.1 alnsn #define TEST_UI_IMM(src, srcw) \ 1465 1.1 alnsn ((src) & SLJIT_IMM) 1466 1.1 alnsn #endif 1467 1.1 alnsn 1468 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, 1469 1.5 alnsn sljit_s32 dst, sljit_sw dstw, 1470 1.5 alnsn sljit_s32 src1, sljit_sw src1w, 1471 1.5 alnsn sljit_s32 src2, sljit_sw src2w) 1472 1.1 alnsn { 1473 1.8 alnsn sljit_s32 flags = HAS_FLAGS(op) ? ALT_SET_FLAGS : 0; 1474 1.1 alnsn 1475 1.1 alnsn CHECK_ERROR(); 1476 1.5 alnsn CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); 1477 1.1 alnsn ADJUST_LOCAL_OFFSET(dst, dstw); 1478 1.1 alnsn ADJUST_LOCAL_OFFSET(src1, src1w); 1479 1.1 alnsn ADJUST_LOCAL_OFFSET(src2, src2w); 1480 1.1 alnsn 1481 1.1 alnsn if ((src1 & SLJIT_IMM) && src1w == 0) 1482 1.3 alnsn src1 = TMP_ZERO; 1483 1.1 alnsn if ((src2 & SLJIT_IMM) && src2w == 0) 1484 1.3 alnsn src2 = TMP_ZERO; 1485 1.1 alnsn 1486 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1487 1.5 alnsn if (op & SLJIT_I32_OP) { 1488 1.3 alnsn /* Most operations expect sign extended arguments. */ 1489 1.2 alnsn flags |= INT_DATA | SIGNED_DATA; 1490 1.1 alnsn if (src1 & SLJIT_IMM) 1491 1.5 alnsn src1w = (sljit_s32)(src1w); 1492 1.1 alnsn if (src2 & SLJIT_IMM) 1493 1.5 alnsn src2w = (sljit_s32)(src2w); 1494 1.8 alnsn if (HAS_FLAGS(op)) 1495 1.2 alnsn flags |= ALT_SIGN_EXT; 1496 1.1 alnsn } 1497 1.1 alnsn #endif 1498 1.8 alnsn if (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW || GET_FLAG_TYPE(op) == SLJIT_NOT_OVERFLOW) 1499 1.3 alnsn FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); 1500 1.3 alnsn if (src2 == TMP_REG2) 1501 1.3 alnsn flags |= ALT_KEEP_CACHE; 1502 1.1 alnsn 1503 1.1 alnsn switch (GET_OPCODE(op)) { 1504 1.1 alnsn case SLJIT_ADD: 1505 1.8 alnsn if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { 1506 1.1 alnsn if (TEST_SL_IMM(src2, src2w)) { 1507 1.1 alnsn compiler->imm = src2w & 0xffff; 1508 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); 1509 1.1 alnsn } 1510 1.1 alnsn if (TEST_SL_IMM(src1, src1w)) { 1511 1.1 alnsn compiler->imm = src1w & 0xffff; 1512 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); 1513 1.1 alnsn } 1514 1.1 alnsn if (TEST_SH_IMM(src2, src2w)) { 1515 1.1 alnsn compiler->imm = (src2w >> 16) & 0xffff; 1516 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); 1517 1.1 alnsn } 1518 1.1 alnsn if (TEST_SH_IMM(src1, src1w)) { 1519 1.1 alnsn compiler->imm = (src1w >> 16) & 0xffff; 1520 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); 1521 1.1 alnsn } 1522 1.1 alnsn /* Range between -1 and -32768 is covered above. */ 1523 1.1 alnsn if (TEST_ADD_IMM(src2, src2w)) { 1524 1.1 alnsn compiler->imm = src2w & 0xffffffff; 1525 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); 1526 1.1 alnsn } 1527 1.1 alnsn if (TEST_ADD_IMM(src1, src1w)) { 1528 1.1 alnsn compiler->imm = src1w & 0xffffffff; 1529 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0); 1530 1.1 alnsn } 1531 1.1 alnsn } 1532 1.8 alnsn if (HAS_FLAGS(op)) { 1533 1.1 alnsn if (TEST_SL_IMM(src2, src2w)) { 1534 1.1 alnsn compiler->imm = src2w & 0xffff; 1535 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); 1536 1.1 alnsn } 1537 1.1 alnsn if (TEST_SL_IMM(src1, src1w)) { 1538 1.1 alnsn compiler->imm = src1w & 0xffff; 1539 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); 1540 1.1 alnsn } 1541 1.1 alnsn } 1542 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags, dst, dstw, src1, src1w, src2, src2w); 1543 1.1 alnsn 1544 1.1 alnsn case SLJIT_ADDC: 1545 1.8 alnsn return emit_op(compiler, SLJIT_ADDC, flags, dst, dstw, src1, src1w, src2, src2w); 1546 1.1 alnsn 1547 1.1 alnsn case SLJIT_SUB: 1548 1.8 alnsn if (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_LESS_EQUAL) 1549 1.8 alnsn { 1550 1.8 alnsn if (dst == SLJIT_UNUSED) 1551 1.8 alnsn { 1552 1.8 alnsn if (TEST_UL_IMM(src2, src2w)) { 1553 1.8 alnsn compiler->imm = src2w & 0xffff; 1554 1.8 alnsn return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); 1555 1.8 alnsn } 1556 1.8 alnsn return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM5, dst, dstw, src1, src1w, src2, src2w); 1557 1.8 alnsn } 1558 1.8 alnsn 1559 1.8 alnsn if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= (SIMM_MAX + 1)) 1560 1.8 alnsn { 1561 1.8 alnsn compiler->imm = src2w; 1562 1.8 alnsn return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM6, dst, dstw, src1, src1w, TMP_REG2, 0); 1563 1.8 alnsn } 1564 1.8 alnsn return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM7, dst, dstw, src1, src1w, src2, src2w); 1565 1.8 alnsn } 1566 1.8 alnsn 1567 1.8 alnsn if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { 1568 1.1 alnsn if (TEST_SL_IMM(src2, -src2w)) { 1569 1.1 alnsn compiler->imm = (-src2w) & 0xffff; 1570 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); 1571 1.1 alnsn } 1572 1.1 alnsn if (TEST_SL_IMM(src1, src1w)) { 1573 1.1 alnsn compiler->imm = src1w & 0xffff; 1574 1.2 alnsn return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); 1575 1.1 alnsn } 1576 1.1 alnsn if (TEST_SH_IMM(src2, -src2w)) { 1577 1.1 alnsn compiler->imm = ((-src2w) >> 16) & 0xffff; 1578 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); 1579 1.1 alnsn } 1580 1.1 alnsn /* Range between -1 and -32768 is covered above. */ 1581 1.1 alnsn if (TEST_ADD_IMM(src2, -src2w)) { 1582 1.1 alnsn compiler->imm = -src2w & 0xffffffff; 1583 1.2 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); 1584 1.1 alnsn } 1585 1.1 alnsn } 1586 1.8 alnsn 1587 1.8 alnsn if (dst == SLJIT_UNUSED && GET_FLAG_TYPE(op) != GET_FLAG_TYPE(SLJIT_SET_CARRY) 1588 1.8 alnsn && GET_FLAG_TYPE(op) == SLJIT_OVERFLOW && GET_FLAG_TYPE(op) == SLJIT_NOT_OVERFLOW) { 1589 1.8 alnsn if (TEST_SL_IMM(src2, src2w)) { 1590 1.8 alnsn compiler->imm = src2w & 0xffff; 1591 1.8 alnsn return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); 1592 1.1 alnsn } 1593 1.8 alnsn return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w); 1594 1.1 alnsn } 1595 1.8 alnsn 1596 1.8 alnsn if (TEST_SL_IMM(src2, -src2w)) { 1597 1.8 alnsn compiler->imm = (-src2w) & 0xffff; 1598 1.8 alnsn return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); 1599 1.1 alnsn } 1600 1.5 alnsn /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */ 1601 1.8 alnsn return emit_op(compiler, SLJIT_SUB, flags, dst, dstw, src1, src1w, src2, src2w); 1602 1.1 alnsn 1603 1.1 alnsn case SLJIT_SUBC: 1604 1.8 alnsn return emit_op(compiler, SLJIT_SUBC, flags, dst, dstw, src1, src1w, src2, src2w); 1605 1.1 alnsn 1606 1.1 alnsn case SLJIT_MUL: 1607 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1608 1.5 alnsn if (op & SLJIT_I32_OP) 1609 1.2 alnsn flags |= ALT_FORM2; 1610 1.1 alnsn #endif 1611 1.8 alnsn if (!HAS_FLAGS(op)) { 1612 1.1 alnsn if (TEST_SL_IMM(src2, src2w)) { 1613 1.1 alnsn compiler->imm = src2w & 0xffff; 1614 1.2 alnsn return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); 1615 1.1 alnsn } 1616 1.1 alnsn if (TEST_SL_IMM(src1, src1w)) { 1617 1.1 alnsn compiler->imm = src1w & 0xffff; 1618 1.2 alnsn return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); 1619 1.1 alnsn } 1620 1.1 alnsn } 1621 1.8 alnsn else 1622 1.8 alnsn FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); 1623 1.2 alnsn return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w); 1624 1.1 alnsn 1625 1.1 alnsn case SLJIT_AND: 1626 1.1 alnsn case SLJIT_OR: 1627 1.1 alnsn case SLJIT_XOR: 1628 1.1 alnsn /* Commutative unsigned operations. */ 1629 1.8 alnsn if (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) { 1630 1.1 alnsn if (TEST_UL_IMM(src2, src2w)) { 1631 1.1 alnsn compiler->imm = src2w; 1632 1.2 alnsn return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); 1633 1.1 alnsn } 1634 1.1 alnsn if (TEST_UL_IMM(src1, src1w)) { 1635 1.1 alnsn compiler->imm = src1w; 1636 1.2 alnsn return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); 1637 1.1 alnsn } 1638 1.1 alnsn if (TEST_UH_IMM(src2, src2w)) { 1639 1.1 alnsn compiler->imm = (src2w >> 16) & 0xffff; 1640 1.2 alnsn return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); 1641 1.1 alnsn } 1642 1.1 alnsn if (TEST_UH_IMM(src1, src1w)) { 1643 1.1 alnsn compiler->imm = (src1w >> 16) & 0xffff; 1644 1.2 alnsn return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); 1645 1.1 alnsn } 1646 1.1 alnsn } 1647 1.8 alnsn if (GET_OPCODE(op) != SLJIT_AND && GET_OPCODE(op) != SLJIT_AND) { 1648 1.8 alnsn /* Unlike or and xor, and resets unwanted bits as well. */ 1649 1.1 alnsn if (TEST_UI_IMM(src2, src2w)) { 1650 1.1 alnsn compiler->imm = src2w; 1651 1.2 alnsn return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); 1652 1.1 alnsn } 1653 1.1 alnsn if (TEST_UI_IMM(src1, src1w)) { 1654 1.1 alnsn compiler->imm = src1w; 1655 1.2 alnsn return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); 1656 1.1 alnsn } 1657 1.1 alnsn } 1658 1.2 alnsn return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); 1659 1.1 alnsn 1660 1.1 alnsn case SLJIT_SHL: 1661 1.1 alnsn case SLJIT_LSHR: 1662 1.8 alnsn case SLJIT_ASHR: 1663 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1664 1.5 alnsn if (op & SLJIT_I32_OP) 1665 1.2 alnsn flags |= ALT_FORM2; 1666 1.1 alnsn #endif 1667 1.1 alnsn if (src2 & SLJIT_IMM) { 1668 1.1 alnsn compiler->imm = src2w; 1669 1.2 alnsn return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); 1670 1.1 alnsn } 1671 1.2 alnsn return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); 1672 1.1 alnsn } 1673 1.1 alnsn 1674 1.1 alnsn return SLJIT_SUCCESS; 1675 1.1 alnsn } 1676 1.1 alnsn 1677 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) 1678 1.1 alnsn { 1679 1.5 alnsn CHECK_REG_INDEX(check_sljit_get_register_index(reg)); 1680 1.1 alnsn return reg_map[reg]; 1681 1.1 alnsn } 1682 1.1 alnsn 1683 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) 1684 1.3 alnsn { 1685 1.5 alnsn CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); 1686 1.3 alnsn return reg; 1687 1.3 alnsn } 1688 1.3 alnsn 1689 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, 1690 1.5 alnsn void *instruction, sljit_s32 size) 1691 1.1 alnsn { 1692 1.1 alnsn CHECK_ERROR(); 1693 1.5 alnsn CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); 1694 1.1 alnsn 1695 1.1 alnsn return push_inst(compiler, *(sljit_ins*)instruction); 1696 1.1 alnsn } 1697 1.1 alnsn 1698 1.1 alnsn /* --------------------------------------------------------------------- */ 1699 1.1 alnsn /* Floating point operators */ 1700 1.1 alnsn /* --------------------------------------------------------------------- */ 1701 1.1 alnsn 1702 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) 1703 1.1 alnsn { 1704 1.3 alnsn #ifdef SLJIT_IS_FPU_AVAILABLE 1705 1.3 alnsn return SLJIT_IS_FPU_AVAILABLE; 1706 1.3 alnsn #else 1707 1.3 alnsn /* Available by default. */ 1708 1.1 alnsn return 1; 1709 1.3 alnsn #endif 1710 1.1 alnsn } 1711 1.1 alnsn 1712 1.5 alnsn #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6)) 1713 1.5 alnsn #define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double) 1714 1.3 alnsn 1715 1.5 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1716 1.5 alnsn #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw)) 1717 1.5 alnsn #else 1718 1.5 alnsn #define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw)) 1719 1.5 alnsn 1720 1.5 alnsn #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) 1721 1.5 alnsn #define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw)) 1722 1.5 alnsn #define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw)) 1723 1.5 alnsn #else 1724 1.5 alnsn #define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw)) 1725 1.5 alnsn #define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw)) 1726 1.5 alnsn #endif 1727 1.5 alnsn 1728 1.5 alnsn #endif /* SLJIT_CONFIG_PPC_64 */ 1729 1.5 alnsn 1730 1.5 alnsn static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, 1731 1.5 alnsn sljit_s32 dst, sljit_sw dstw, 1732 1.5 alnsn sljit_s32 src, sljit_sw srcw) 1733 1.1 alnsn { 1734 1.5 alnsn if (src & SLJIT_MEM) { 1735 1.5 alnsn /* We can ignore the temporary data store on the stack from caching point of view. */ 1736 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); 1737 1.5 alnsn src = TMP_FREG1; 1738 1.5 alnsn } 1739 1.1 alnsn 1740 1.5 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1741 1.5 alnsn op = GET_OPCODE(op); 1742 1.5 alnsn FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src))); 1743 1.1 alnsn 1744 1.5 alnsn if (dst == SLJIT_UNUSED) 1745 1.5 alnsn return SLJIT_SUCCESS; 1746 1.1 alnsn 1747 1.5 alnsn if (op == SLJIT_CONV_SW_FROM_F64) { 1748 1.5 alnsn if (FAST_IS_REG(dst)) { 1749 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0)); 1750 1.5 alnsn return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0); 1751 1.1 alnsn } 1752 1.5 alnsn return emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, 0, 0); 1753 1.5 alnsn } 1754 1.2 alnsn 1755 1.5 alnsn #else 1756 1.5 alnsn FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src))); 1757 1.5 alnsn 1758 1.5 alnsn if (dst == SLJIT_UNUSED) 1759 1.5 alnsn return SLJIT_SUCCESS; 1760 1.5 alnsn #endif 1761 1.5 alnsn 1762 1.5 alnsn if (FAST_IS_REG(dst)) { 1763 1.5 alnsn FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET)); 1764 1.5 alnsn FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1))); 1765 1.5 alnsn return emit_op_mem2(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0); 1766 1.5 alnsn } 1767 1.5 alnsn 1768 1.5 alnsn SLJIT_ASSERT(dst & SLJIT_MEM); 1769 1.5 alnsn 1770 1.5 alnsn if (dst & OFFS_REG_MASK) { 1771 1.5 alnsn dstw &= 0x3; 1772 1.5 alnsn if (dstw) { 1773 1.5 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) 1774 1.5 alnsn FAIL_IF(push_inst(compiler, RLWINM | S(OFFS_REG(dst)) | A(TMP_REG1) | (dstw << 11) | ((31 - dstw) << 1))); 1775 1.5 alnsn #else 1776 1.5 alnsn FAIL_IF(push_inst(compiler, RLDI(TMP_REG1, OFFS_REG(dst), dstw, 63 - dstw, 1))); 1777 1.5 alnsn #endif 1778 1.5 alnsn dstw = TMP_REG1; 1779 1.5 alnsn } 1780 1.5 alnsn else 1781 1.5 alnsn dstw = OFFS_REG(dst); 1782 1.5 alnsn } 1783 1.5 alnsn else { 1784 1.5 alnsn if ((dst & REG_MASK) && !dstw) { 1785 1.5 alnsn dstw = dst & REG_MASK; 1786 1.5 alnsn dst = 0; 1787 1.1 alnsn } 1788 1.5 alnsn else { 1789 1.5 alnsn /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */ 1790 1.5 alnsn FAIL_IF(load_immediate(compiler, TMP_REG1, dstw)); 1791 1.5 alnsn dstw = TMP_REG1; 1792 1.5 alnsn } 1793 1.5 alnsn } 1794 1.5 alnsn 1795 1.5 alnsn return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw)); 1796 1.5 alnsn } 1797 1.5 alnsn 1798 1.5 alnsn static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, 1799 1.5 alnsn sljit_s32 dst, sljit_sw dstw, 1800 1.5 alnsn sljit_s32 src, sljit_sw srcw) 1801 1.5 alnsn { 1802 1.5 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 1803 1.5 alnsn 1804 1.5 alnsn sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; 1805 1.5 alnsn 1806 1.5 alnsn if (src & SLJIT_IMM) { 1807 1.5 alnsn if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) 1808 1.5 alnsn srcw = (sljit_s32)srcw; 1809 1.5 alnsn FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); 1810 1.5 alnsn src = TMP_REG1; 1811 1.5 alnsn } 1812 1.5 alnsn else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) { 1813 1.5 alnsn if (FAST_IS_REG(src)) 1814 1.5 alnsn FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1))); 1815 1.5 alnsn else 1816 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); 1817 1.5 alnsn src = TMP_REG1; 1818 1.5 alnsn } 1819 1.5 alnsn 1820 1.5 alnsn if (FAST_IS_REG(src)) { 1821 1.5 alnsn 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)); 1822 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, dst, dstw)); 1823 1.5 alnsn } 1824 1.5 alnsn else 1825 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); 1826 1.5 alnsn 1827 1.5 alnsn FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); 1828 1.5 alnsn 1829 1.5 alnsn if (dst & SLJIT_MEM) 1830 1.5 alnsn return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); 1831 1.5 alnsn if (op & SLJIT_F32_OP) 1832 1.5 alnsn return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); 1833 1.5 alnsn return SLJIT_SUCCESS; 1834 1.5 alnsn 1835 1.5 alnsn #else 1836 1.5 alnsn 1837 1.5 alnsn sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; 1838 1.5 alnsn sljit_s32 invert_sign = 1; 1839 1.5 alnsn 1840 1.5 alnsn if (src & SLJIT_IMM) { 1841 1.5 alnsn FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000)); 1842 1.5 alnsn src = TMP_REG1; 1843 1.5 alnsn invert_sign = 0; 1844 1.5 alnsn } 1845 1.5 alnsn else if (!FAST_IS_REG(src)) { 1846 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW)); 1847 1.5 alnsn src = TMP_REG1; 1848 1.5 alnsn } 1849 1.5 alnsn 1850 1.5 alnsn /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31))) 1851 1.5 alnsn The double precision format has exactly 53 bit precision, so the lower 32 bit represents 1852 1.5 alnsn the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000 1853 1.5 alnsn to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating 1854 1.5 alnsn point value, we need to substract 2^53 + 2^31 from the constructed value. */ 1855 1.5 alnsn FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330)); 1856 1.5 alnsn if (invert_sign) 1857 1.5 alnsn FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000)); 1858 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); 1859 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI)); 1860 1.5 alnsn FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000)); 1861 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW)); 1862 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET)); 1863 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW)); 1864 1.5 alnsn 1865 1.5 alnsn FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2))); 1866 1.5 alnsn 1867 1.5 alnsn if (dst & SLJIT_MEM) 1868 1.5 alnsn return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); 1869 1.5 alnsn if (op & SLJIT_F32_OP) 1870 1.5 alnsn return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); 1871 1.5 alnsn return SLJIT_SUCCESS; 1872 1.2 alnsn 1873 1.5 alnsn #endif 1874 1.5 alnsn } 1875 1.5 alnsn 1876 1.5 alnsn static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, 1877 1.5 alnsn sljit_s32 src1, sljit_sw src1w, 1878 1.5 alnsn sljit_s32 src2, sljit_sw src2w) 1879 1.5 alnsn { 1880 1.5 alnsn if (src1 & SLJIT_MEM) { 1881 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); 1882 1.5 alnsn src1 = TMP_FREG1; 1883 1.5 alnsn } 1884 1.5 alnsn 1885 1.5 alnsn if (src2 & SLJIT_MEM) { 1886 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); 1887 1.5 alnsn src2 = TMP_FREG2; 1888 1.1 alnsn } 1889 1.1 alnsn 1890 1.5 alnsn return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2)); 1891 1.5 alnsn } 1892 1.5 alnsn 1893 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, 1894 1.5 alnsn sljit_s32 dst, sljit_sw dstw, 1895 1.5 alnsn sljit_s32 src, sljit_sw srcw) 1896 1.5 alnsn { 1897 1.5 alnsn sljit_s32 dst_r; 1898 1.5 alnsn 1899 1.5 alnsn CHECK_ERROR(); 1900 1.5 alnsn compiler->cache_arg = 0; 1901 1.5 alnsn compiler->cache_argw = 0; 1902 1.5 alnsn 1903 1.5 alnsn SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error); 1904 1.5 alnsn SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); 1905 1.5 alnsn 1906 1.5 alnsn if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) 1907 1.5 alnsn op ^= SLJIT_F32_OP; 1908 1.5 alnsn 1909 1.5 alnsn dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; 1910 1.1 alnsn 1911 1.3 alnsn if (src & SLJIT_MEM) { 1912 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw)); 1913 1.5 alnsn src = dst_r; 1914 1.1 alnsn } 1915 1.1 alnsn 1916 1.3 alnsn switch (GET_OPCODE(op)) { 1917 1.5 alnsn case SLJIT_CONV_F64_FROM_F32: 1918 1.5 alnsn op ^= SLJIT_F32_OP; 1919 1.5 alnsn if (op & SLJIT_F32_OP) { 1920 1.5 alnsn FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src))); 1921 1.1 alnsn break; 1922 1.5 alnsn } 1923 1.5 alnsn /* Fall through. */ 1924 1.5 alnsn case SLJIT_MOV_F64: 1925 1.5 alnsn if (src != dst_r) { 1926 1.5 alnsn if (dst_r != TMP_FREG1) 1927 1.5 alnsn FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src))); 1928 1.5 alnsn else 1929 1.5 alnsn dst_r = src; 1930 1.5 alnsn } 1931 1.5 alnsn break; 1932 1.5 alnsn case SLJIT_NEG_F64: 1933 1.5 alnsn FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src))); 1934 1.5 alnsn break; 1935 1.5 alnsn case SLJIT_ABS_F64: 1936 1.5 alnsn FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src))); 1937 1.5 alnsn break; 1938 1.1 alnsn } 1939 1.1 alnsn 1940 1.5 alnsn if (dst & SLJIT_MEM) 1941 1.5 alnsn FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0)); 1942 1.1 alnsn return SLJIT_SUCCESS; 1943 1.1 alnsn } 1944 1.1 alnsn 1945 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, 1946 1.5 alnsn sljit_s32 dst, sljit_sw dstw, 1947 1.5 alnsn sljit_s32 src1, sljit_sw src1w, 1948 1.5 alnsn sljit_s32 src2, sljit_sw src2w) 1949 1.1 alnsn { 1950 1.5 alnsn sljit_s32 dst_r, flags = 0; 1951 1.1 alnsn 1952 1.1 alnsn CHECK_ERROR(); 1953 1.5 alnsn CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); 1954 1.5 alnsn ADJUST_LOCAL_OFFSET(dst, dstw); 1955 1.5 alnsn ADJUST_LOCAL_OFFSET(src1, src1w); 1956 1.5 alnsn ADJUST_LOCAL_OFFSET(src2, src2w); 1957 1.1 alnsn 1958 1.1 alnsn compiler->cache_arg = 0; 1959 1.1 alnsn compiler->cache_argw = 0; 1960 1.1 alnsn 1961 1.5 alnsn dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2; 1962 1.2 alnsn 1963 1.3 alnsn if (src1 & SLJIT_MEM) { 1964 1.3 alnsn if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { 1965 1.2 alnsn FAIL_IF(compiler->error); 1966 1.2 alnsn src1 = TMP_FREG1; 1967 1.2 alnsn } else 1968 1.2 alnsn flags |= ALT_FORM1; 1969 1.2 alnsn } 1970 1.1 alnsn 1971 1.3 alnsn if (src2 & SLJIT_MEM) { 1972 1.3 alnsn if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { 1973 1.2 alnsn FAIL_IF(compiler->error); 1974 1.2 alnsn src2 = TMP_FREG2; 1975 1.2 alnsn } else 1976 1.2 alnsn flags |= ALT_FORM2; 1977 1.2 alnsn } 1978 1.2 alnsn 1979 1.2 alnsn if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) { 1980 1.2 alnsn if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { 1981 1.3 alnsn FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w)); 1982 1.3 alnsn FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); 1983 1.2 alnsn } 1984 1.2 alnsn else { 1985 1.3 alnsn FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); 1986 1.3 alnsn FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); 1987 1.2 alnsn } 1988 1.1 alnsn } 1989 1.2 alnsn else if (flags & ALT_FORM1) 1990 1.3 alnsn FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); 1991 1.2 alnsn else if (flags & ALT_FORM2) 1992 1.3 alnsn FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); 1993 1.1 alnsn 1994 1.2 alnsn if (flags & ALT_FORM1) 1995 1.1 alnsn src1 = TMP_FREG1; 1996 1.2 alnsn if (flags & ALT_FORM2) 1997 1.2 alnsn src2 = TMP_FREG2; 1998 1.1 alnsn 1999 1.3 alnsn switch (GET_OPCODE(op)) { 2000 1.5 alnsn case SLJIT_ADD_F64: 2001 1.5 alnsn FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2))); 2002 1.1 alnsn break; 2003 1.1 alnsn 2004 1.5 alnsn case SLJIT_SUB_F64: 2005 1.5 alnsn FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2))); 2006 1.1 alnsn break; 2007 1.1 alnsn 2008 1.5 alnsn case SLJIT_MUL_F64: 2009 1.5 alnsn FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); 2010 1.1 alnsn break; 2011 1.1 alnsn 2012 1.5 alnsn case SLJIT_DIV_F64: 2013 1.5 alnsn FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2))); 2014 1.1 alnsn break; 2015 1.1 alnsn } 2016 1.1 alnsn 2017 1.5 alnsn if (dst_r == TMP_FREG2) 2018 1.3 alnsn FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); 2019 1.1 alnsn 2020 1.1 alnsn return SLJIT_SUCCESS; 2021 1.1 alnsn } 2022 1.1 alnsn 2023 1.3 alnsn #undef FLOAT_DATA 2024 1.3 alnsn #undef SELECT_FOP 2025 1.3 alnsn 2026 1.1 alnsn /* --------------------------------------------------------------------- */ 2027 1.1 alnsn /* Other instructions */ 2028 1.1 alnsn /* --------------------------------------------------------------------- */ 2029 1.1 alnsn 2030 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) 2031 1.1 alnsn { 2032 1.1 alnsn CHECK_ERROR(); 2033 1.5 alnsn CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); 2034 1.1 alnsn ADJUST_LOCAL_OFFSET(dst, dstw); 2035 1.1 alnsn 2036 1.3 alnsn /* For UNUSED dst. Uncommon, but possible. */ 2037 1.3 alnsn if (dst == SLJIT_UNUSED) 2038 1.3 alnsn return SLJIT_SUCCESS; 2039 1.3 alnsn 2040 1.3 alnsn if (FAST_IS_REG(dst)) 2041 1.1 alnsn return push_inst(compiler, MFLR | D(dst)); 2042 1.1 alnsn 2043 1.3 alnsn /* Memory. */ 2044 1.3 alnsn FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); 2045 1.3 alnsn return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); 2046 1.1 alnsn } 2047 1.1 alnsn 2048 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) 2049 1.1 alnsn { 2050 1.1 alnsn CHECK_ERROR(); 2051 1.5 alnsn CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); 2052 1.1 alnsn ADJUST_LOCAL_OFFSET(src, srcw); 2053 1.1 alnsn 2054 1.3 alnsn if (FAST_IS_REG(src)) 2055 1.1 alnsn FAIL_IF(push_inst(compiler, MTLR | S(src))); 2056 1.1 alnsn else { 2057 1.1 alnsn if (src & SLJIT_MEM) 2058 1.1 alnsn FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); 2059 1.1 alnsn else if (src & SLJIT_IMM) 2060 1.1 alnsn FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); 2061 1.1 alnsn FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2))); 2062 1.1 alnsn } 2063 1.1 alnsn return push_inst(compiler, BLR); 2064 1.1 alnsn } 2065 1.1 alnsn 2066 1.1 alnsn /* --------------------------------------------------------------------- */ 2067 1.1 alnsn /* Conditional instructions */ 2068 1.1 alnsn /* --------------------------------------------------------------------- */ 2069 1.1 alnsn 2070 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) 2071 1.1 alnsn { 2072 1.1 alnsn struct sljit_label *label; 2073 1.1 alnsn 2074 1.1 alnsn CHECK_ERROR_PTR(); 2075 1.5 alnsn CHECK_PTR(check_sljit_emit_label(compiler)); 2076 1.1 alnsn 2077 1.1 alnsn if (compiler->last_label && compiler->last_label->size == compiler->size) 2078 1.1 alnsn return compiler->last_label; 2079 1.1 alnsn 2080 1.1 alnsn label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); 2081 1.1 alnsn PTR_FAIL_IF(!label); 2082 1.1 alnsn set_label(label, compiler); 2083 1.1 alnsn return label; 2084 1.1 alnsn } 2085 1.1 alnsn 2086 1.5 alnsn static sljit_ins get_bo_bi_flags(sljit_s32 type) 2087 1.1 alnsn { 2088 1.1 alnsn switch (type) { 2089 1.5 alnsn case SLJIT_EQUAL: 2090 1.1 alnsn return (12 << 21) | (2 << 16); 2091 1.1 alnsn 2092 1.5 alnsn case SLJIT_NOT_EQUAL: 2093 1.1 alnsn return (4 << 21) | (2 << 16); 2094 1.1 alnsn 2095 1.5 alnsn case SLJIT_LESS: 2096 1.8 alnsn case SLJIT_SIG_LESS: 2097 1.8 alnsn return (12 << 21) | (0 << 16); 2098 1.8 alnsn 2099 1.8 alnsn case SLJIT_GREATER_EQUAL: 2100 1.8 alnsn case SLJIT_SIG_GREATER_EQUAL: 2101 1.8 alnsn return (4 << 21) | (0 << 16); 2102 1.8 alnsn 2103 1.8 alnsn case SLJIT_GREATER: 2104 1.8 alnsn case SLJIT_SIG_GREATER: 2105 1.8 alnsn return (12 << 21) | (1 << 16); 2106 1.8 alnsn 2107 1.8 alnsn case SLJIT_LESS_EQUAL: 2108 1.8 alnsn case SLJIT_SIG_LESS_EQUAL: 2109 1.8 alnsn return (4 << 21) | (1 << 16); 2110 1.8 alnsn 2111 1.5 alnsn case SLJIT_LESS_F64: 2112 1.1 alnsn return (12 << 21) | ((4 + 0) << 16); 2113 1.1 alnsn 2114 1.5 alnsn case SLJIT_GREATER_EQUAL_F64: 2115 1.1 alnsn return (4 << 21) | ((4 + 0) << 16); 2116 1.1 alnsn 2117 1.5 alnsn case SLJIT_GREATER_F64: 2118 1.1 alnsn return (12 << 21) | ((4 + 1) << 16); 2119 1.1 alnsn 2120 1.5 alnsn case SLJIT_LESS_EQUAL_F64: 2121 1.1 alnsn return (4 << 21) | ((4 + 1) << 16); 2122 1.1 alnsn 2123 1.5 alnsn case SLJIT_OVERFLOW: 2124 1.5 alnsn case SLJIT_MUL_OVERFLOW: 2125 1.1 alnsn return (12 << 21) | (3 << 16); 2126 1.1 alnsn 2127 1.5 alnsn case SLJIT_NOT_OVERFLOW: 2128 1.5 alnsn case SLJIT_MUL_NOT_OVERFLOW: 2129 1.1 alnsn return (4 << 21) | (3 << 16); 2130 1.1 alnsn 2131 1.5 alnsn case SLJIT_EQUAL_F64: 2132 1.1 alnsn return (12 << 21) | ((4 + 2) << 16); 2133 1.1 alnsn 2134 1.5 alnsn case SLJIT_NOT_EQUAL_F64: 2135 1.1 alnsn return (4 << 21) | ((4 + 2) << 16); 2136 1.1 alnsn 2137 1.5 alnsn case SLJIT_UNORDERED_F64: 2138 1.1 alnsn return (12 << 21) | ((4 + 3) << 16); 2139 1.1 alnsn 2140 1.5 alnsn case SLJIT_ORDERED_F64: 2141 1.1 alnsn return (4 << 21) | ((4 + 3) << 16); 2142 1.1 alnsn 2143 1.1 alnsn default: 2144 1.1 alnsn SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); 2145 1.1 alnsn return (20 << 21); 2146 1.1 alnsn } 2147 1.1 alnsn } 2148 1.1 alnsn 2149 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) 2150 1.1 alnsn { 2151 1.1 alnsn struct sljit_jump *jump; 2152 1.1 alnsn sljit_ins bo_bi_flags; 2153 1.1 alnsn 2154 1.1 alnsn CHECK_ERROR_PTR(); 2155 1.5 alnsn CHECK_PTR(check_sljit_emit_jump(compiler, type)); 2156 1.1 alnsn 2157 1.2 alnsn bo_bi_flags = get_bo_bi_flags(type & 0xff); 2158 1.1 alnsn if (!bo_bi_flags) 2159 1.1 alnsn return NULL; 2160 1.1 alnsn 2161 1.1 alnsn jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 2162 1.1 alnsn PTR_FAIL_IF(!jump); 2163 1.1 alnsn set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); 2164 1.1 alnsn type &= 0xff; 2165 1.1 alnsn 2166 1.1 alnsn /* In PPC, we don't need to touch the arguments. */ 2167 1.3 alnsn if (type < SLJIT_JUMP) 2168 1.3 alnsn jump->flags |= IS_COND; 2169 1.3 alnsn #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) 2170 1.3 alnsn if (type >= SLJIT_CALL0) 2171 1.3 alnsn jump->flags |= IS_CALL; 2172 1.3 alnsn #endif 2173 1.1 alnsn 2174 1.3 alnsn PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0)); 2175 1.3 alnsn PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG))); 2176 1.1 alnsn jump->addr = compiler->size; 2177 1.1 alnsn PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0))); 2178 1.1 alnsn return jump; 2179 1.1 alnsn } 2180 1.1 alnsn 2181 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) 2182 1.1 alnsn { 2183 1.1 alnsn struct sljit_jump *jump = NULL; 2184 1.5 alnsn sljit_s32 src_r; 2185 1.1 alnsn 2186 1.1 alnsn CHECK_ERROR(); 2187 1.5 alnsn CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); 2188 1.1 alnsn ADJUST_LOCAL_OFFSET(src, srcw); 2189 1.1 alnsn 2190 1.3 alnsn if (FAST_IS_REG(src)) { 2191 1.3 alnsn #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) 2192 1.3 alnsn if (type >= SLJIT_CALL0) { 2193 1.3 alnsn FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src))); 2194 1.3 alnsn src_r = TMP_CALL_REG; 2195 1.3 alnsn } 2196 1.3 alnsn else 2197 1.3 alnsn src_r = src; 2198 1.3 alnsn #else 2199 1.1 alnsn src_r = src; 2200 1.3 alnsn #endif 2201 1.3 alnsn } else if (src & SLJIT_IMM) { 2202 1.1 alnsn jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); 2203 1.1 alnsn FAIL_IF(!jump); 2204 1.3 alnsn set_jump(jump, compiler, JUMP_ADDR); 2205 1.1 alnsn jump->u.target = srcw; 2206 1.3 alnsn #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) 2207 1.3 alnsn if (type >= SLJIT_CALL0) 2208 1.3 alnsn jump->flags |= IS_CALL; 2209 1.3 alnsn #endif 2210 1.3 alnsn FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0)); 2211 1.3 alnsn src_r = TMP_CALL_REG; 2212 1.1 alnsn } 2213 1.1 alnsn else { 2214 1.3 alnsn FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw)); 2215 1.3 alnsn src_r = TMP_CALL_REG; 2216 1.1 alnsn } 2217 1.1 alnsn 2218 1.1 alnsn FAIL_IF(push_inst(compiler, MTCTR | S(src_r))); 2219 1.1 alnsn if (jump) 2220 1.1 alnsn jump->addr = compiler->size; 2221 1.2 alnsn return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0)); 2222 1.1 alnsn } 2223 1.1 alnsn 2224 1.1 alnsn /* Get a bit from CR, all other bits are zeroed. */ 2225 1.1 alnsn #define GET_CR_BIT(bit, dst) \ 2226 1.1 alnsn FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1))); 2227 1.1 alnsn 2228 1.1 alnsn #define INVERT_BIT(dst) \ 2229 1.1 alnsn FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1)); 2230 1.1 alnsn 2231 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, 2232 1.5 alnsn sljit_s32 dst, sljit_sw dstw, 2233 1.5 alnsn sljit_s32 src, sljit_sw srcw, 2234 1.5 alnsn sljit_s32 type) 2235 1.3 alnsn { 2236 1.5 alnsn sljit_s32 reg, input_flags; 2237 1.5 alnsn sljit_s32 flags = GET_ALL_FLAGS(op); 2238 1.3 alnsn sljit_sw original_dstw = dstw; 2239 1.1 alnsn 2240 1.1 alnsn CHECK_ERROR(); 2241 1.5 alnsn CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); 2242 1.1 alnsn ADJUST_LOCAL_OFFSET(dst, dstw); 2243 1.1 alnsn 2244 1.1 alnsn if (dst == SLJIT_UNUSED) 2245 1.1 alnsn return SLJIT_SUCCESS; 2246 1.1 alnsn 2247 1.3 alnsn op = GET_OPCODE(op); 2248 1.3 alnsn reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2; 2249 1.3 alnsn 2250 1.3 alnsn compiler->cache_arg = 0; 2251 1.3 alnsn compiler->cache_argw = 0; 2252 1.3 alnsn if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { 2253 1.3 alnsn ADJUST_LOCAL_OFFSET(src, srcw); 2254 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 2255 1.5 alnsn input_flags = (flags & SLJIT_I32_OP) ? INT_DATA : WORD_DATA; 2256 1.3 alnsn #else 2257 1.3 alnsn input_flags = WORD_DATA; 2258 1.3 alnsn #endif 2259 1.3 alnsn FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); 2260 1.3 alnsn src = TMP_REG1; 2261 1.3 alnsn srcw = 0; 2262 1.3 alnsn } 2263 1.1 alnsn 2264 1.8 alnsn FAIL_IF(push_inst(compiler, MFCR | D(reg))); 2265 1.8 alnsn 2266 1.5 alnsn switch (type & 0xff) { 2267 1.5 alnsn case SLJIT_EQUAL: 2268 1.1 alnsn GET_CR_BIT(2, reg); 2269 1.1 alnsn break; 2270 1.1 alnsn 2271 1.5 alnsn case SLJIT_NOT_EQUAL: 2272 1.1 alnsn GET_CR_BIT(2, reg); 2273 1.1 alnsn INVERT_BIT(reg); 2274 1.1 alnsn break; 2275 1.1 alnsn 2276 1.5 alnsn case SLJIT_LESS: 2277 1.8 alnsn case SLJIT_SIG_LESS: 2278 1.8 alnsn GET_CR_BIT(0, reg); 2279 1.1 alnsn break; 2280 1.1 alnsn 2281 1.5 alnsn case SLJIT_GREATER_EQUAL: 2282 1.8 alnsn case SLJIT_SIG_GREATER_EQUAL: 2283 1.8 alnsn GET_CR_BIT(0, reg); 2284 1.1 alnsn INVERT_BIT(reg); 2285 1.1 alnsn break; 2286 1.1 alnsn 2287 1.5 alnsn case SLJIT_GREATER: 2288 1.8 alnsn case SLJIT_SIG_GREATER: 2289 1.8 alnsn GET_CR_BIT(1, reg); 2290 1.1 alnsn break; 2291 1.1 alnsn 2292 1.5 alnsn case SLJIT_LESS_EQUAL: 2293 1.8 alnsn case SLJIT_SIG_LESS_EQUAL: 2294 1.8 alnsn GET_CR_BIT(1, reg); 2295 1.1 alnsn INVERT_BIT(reg); 2296 1.1 alnsn break; 2297 1.1 alnsn 2298 1.8 alnsn case SLJIT_LESS_F64: 2299 1.8 alnsn GET_CR_BIT(4 + 0, reg); 2300 1.1 alnsn break; 2301 1.1 alnsn 2302 1.8 alnsn case SLJIT_GREATER_EQUAL_F64: 2303 1.8 alnsn GET_CR_BIT(4 + 0, reg); 2304 1.1 alnsn INVERT_BIT(reg); 2305 1.1 alnsn break; 2306 1.1 alnsn 2307 1.8 alnsn case SLJIT_GREATER_F64: 2308 1.8 alnsn GET_CR_BIT(4 + 1, reg); 2309 1.1 alnsn break; 2310 1.1 alnsn 2311 1.8 alnsn case SLJIT_LESS_EQUAL_F64: 2312 1.8 alnsn GET_CR_BIT(4 + 1, reg); 2313 1.1 alnsn INVERT_BIT(reg); 2314 1.1 alnsn break; 2315 1.1 alnsn 2316 1.5 alnsn case SLJIT_OVERFLOW: 2317 1.5 alnsn case SLJIT_MUL_OVERFLOW: 2318 1.1 alnsn GET_CR_BIT(3, reg); 2319 1.1 alnsn break; 2320 1.1 alnsn 2321 1.5 alnsn case SLJIT_NOT_OVERFLOW: 2322 1.5 alnsn case SLJIT_MUL_NOT_OVERFLOW: 2323 1.1 alnsn GET_CR_BIT(3, reg); 2324 1.1 alnsn INVERT_BIT(reg); 2325 1.1 alnsn break; 2326 1.1 alnsn 2327 1.5 alnsn case SLJIT_EQUAL_F64: 2328 1.1 alnsn GET_CR_BIT(4 + 2, reg); 2329 1.1 alnsn break; 2330 1.1 alnsn 2331 1.5 alnsn case SLJIT_NOT_EQUAL_F64: 2332 1.1 alnsn GET_CR_BIT(4 + 2, reg); 2333 1.1 alnsn INVERT_BIT(reg); 2334 1.1 alnsn break; 2335 1.1 alnsn 2336 1.5 alnsn case SLJIT_UNORDERED_F64: 2337 1.1 alnsn GET_CR_BIT(4 + 3, reg); 2338 1.1 alnsn break; 2339 1.1 alnsn 2340 1.5 alnsn case SLJIT_ORDERED_F64: 2341 1.1 alnsn GET_CR_BIT(4 + 3, reg); 2342 1.1 alnsn INVERT_BIT(reg); 2343 1.1 alnsn break; 2344 1.1 alnsn 2345 1.1 alnsn default: 2346 1.8 alnsn SLJIT_UNREACHABLE(); 2347 1.1 alnsn break; 2348 1.1 alnsn } 2349 1.1 alnsn 2350 1.3 alnsn if (op < SLJIT_ADD) { 2351 1.3 alnsn #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 2352 1.3 alnsn if (op == SLJIT_MOV) 2353 1.3 alnsn input_flags = WORD_DATA; 2354 1.3 alnsn else { 2355 1.5 alnsn op = SLJIT_MOV_U32; 2356 1.3 alnsn input_flags = INT_DATA; 2357 1.3 alnsn } 2358 1.3 alnsn #else 2359 1.3 alnsn op = SLJIT_MOV; 2360 1.3 alnsn input_flags = WORD_DATA; 2361 1.3 alnsn #endif 2362 1.3 alnsn if (reg != TMP_REG2) 2363 1.3 alnsn return SLJIT_SUCCESS; 2364 1.3 alnsn return emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); 2365 1.3 alnsn } 2366 1.1 alnsn 2367 1.5 alnsn #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ 2368 1.5 alnsn || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) 2369 1.3 alnsn compiler->skip_checks = 1; 2370 1.3 alnsn #endif 2371 1.3 alnsn return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0); 2372 1.1 alnsn } 2373 1.1 alnsn 2374 1.5 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) 2375 1.1 alnsn { 2376 1.1 alnsn struct sljit_const *const_; 2377 1.5 alnsn sljit_s32 reg; 2378 1.1 alnsn 2379 1.1 alnsn CHECK_ERROR_PTR(); 2380 1.5 alnsn CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); 2381 1.1 alnsn ADJUST_LOCAL_OFFSET(dst, dstw); 2382 1.1 alnsn 2383 1.1 alnsn const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); 2384 1.1 alnsn PTR_FAIL_IF(!const_); 2385 1.1 alnsn set_const(const_, compiler); 2386 1.1 alnsn 2387 1.3 alnsn reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; 2388 1.1 alnsn 2389 1.1 alnsn PTR_FAIL_IF(emit_const(compiler, reg, init_value)); 2390 1.1 alnsn 2391 1.1 alnsn if (dst & SLJIT_MEM) 2392 1.1 alnsn PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); 2393 1.1 alnsn return const_; 2394 1.1 alnsn } 2395