1 /* 2 * Tiny Code Generator for QEMU 3 * 4 * Copyright (c) 2008 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "tcg/tcg.h" 27 #include "tcg/tcg-temp-internal.h" 28 #include "tcg/tcg-op-common.h" 29 #include "exec/translation-block.h" 30 #include "exec/plugin-gen.h" 31 #include "tcg-internal.h" 32 33 34 /* 35 * Encourage the compiler to tail-call to a function, rather than inlining. 36 * Minimizes code size across 99 bottles of beer on the wall. 37 */ 38 #define NI __attribute__((noinline)) 39 40 void NI tcg_gen_op1(TCGOpcode opc, TCGArg a1) 41 { 42 TCGOp *op = tcg_emit_op(opc, 1); 43 op->args[0] = a1; 44 } 45 46 void NI tcg_gen_op2(TCGOpcode opc, TCGArg a1, TCGArg a2) 47 { 48 TCGOp *op = tcg_emit_op(opc, 2); 49 op->args[0] = a1; 50 op->args[1] = a2; 51 } 52 53 void NI tcg_gen_op3(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3) 54 { 55 TCGOp *op = tcg_emit_op(opc, 3); 56 op->args[0] = a1; 57 op->args[1] = a2; 58 op->args[2] = a3; 59 } 60 61 void NI tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3, TCGArg a4) 62 { 63 TCGOp *op = tcg_emit_op(opc, 4); 64 op->args[0] = a1; 65 op->args[1] = a2; 66 op->args[2] = a3; 67 op->args[3] = a4; 68 } 69 70 void NI tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3, 71 TCGArg a4, TCGArg a5) 72 { 73 TCGOp *op = tcg_emit_op(opc, 5); 74 op->args[0] = a1; 75 op->args[1] = a2; 76 op->args[2] = a3; 77 op->args[3] = a4; 78 op->args[4] = a5; 79 } 80 81 void NI tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3, 82 TCGArg a4, TCGArg a5, TCGArg a6) 83 { 84 TCGOp *op = tcg_emit_op(opc, 6); 85 op->args[0] = a1; 86 op->args[1] = a2; 87 op->args[2] = a3; 88 op->args[3] = a4; 89 op->args[4] = a5; 90 op->args[5] = a6; 91 } 92 93 /* 94 * With CONFIG_DEBUG_TCG, tcgv_*_tmp via tcgv_*_arg, is an out-of-line 95 * assertion check. Force tail calls to avoid too much code expansion. 96 */ 97 #ifdef CONFIG_DEBUG_TCG 98 # define DNI NI 99 #else 100 # define DNI 101 #endif 102 103 static void DNI tcg_gen_op1_i32(TCGOpcode opc, TCGv_i32 a1) 104 { 105 tcg_gen_op1(opc, tcgv_i32_arg(a1)); 106 } 107 108 static void DNI tcg_gen_op1_i64(TCGOpcode opc, TCGv_i64 a1) 109 { 110 tcg_gen_op1(opc, tcgv_i64_arg(a1)); 111 } 112 113 static void DNI tcg_gen_op1i(TCGOpcode opc, TCGArg a1) 114 { 115 tcg_gen_op1(opc, a1); 116 } 117 118 static void DNI tcg_gen_op2_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2) 119 { 120 tcg_gen_op2(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2)); 121 } 122 123 static void DNI tcg_gen_op2_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2) 124 { 125 tcg_gen_op2(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2)); 126 } 127 128 static void DNI tcg_gen_op3_i32(TCGOpcode opc, TCGv_i32 a1, 129 TCGv_i32 a2, TCGv_i32 a3) 130 { 131 tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), tcgv_i32_arg(a3)); 132 } 133 134 static void DNI tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 a1, 135 TCGv_i64 a2, TCGv_i64 a3) 136 { 137 tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), tcgv_i64_arg(a3)); 138 } 139 140 static void DNI tcg_gen_op3i_i32(TCGOpcode opc, TCGv_i32 a1, 141 TCGv_i32 a2, TCGArg a3) 142 { 143 tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3); 144 } 145 146 static void DNI tcg_gen_op3i_i64(TCGOpcode opc, TCGv_i64 a1, 147 TCGv_i64 a2, TCGArg a3) 148 { 149 tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3); 150 } 151 152 static void DNI tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val, 153 TCGv_ptr base, TCGArg offset) 154 { 155 tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_ptr_arg(base), offset); 156 } 157 158 static void DNI tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val, 159 TCGv_ptr base, TCGArg offset) 160 { 161 tcg_gen_op3(opc, tcgv_i64_arg(val), tcgv_ptr_arg(base), offset); 162 } 163 164 static void DNI tcg_gen_op4_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2, 165 TCGv_i32 a3, TCGv_i32 a4) 166 { 167 tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), 168 tcgv_i32_arg(a3), tcgv_i32_arg(a4)); 169 } 170 171 static void DNI tcg_gen_op4_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2, 172 TCGv_i64 a3, TCGv_i64 a4) 173 { 174 tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), 175 tcgv_i64_arg(a3), tcgv_i64_arg(a4)); 176 } 177 178 static void DNI tcg_gen_op4i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2, 179 TCGv_i32 a3, TCGArg a4) 180 { 181 tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), 182 tcgv_i32_arg(a3), a4); 183 } 184 185 static void DNI tcg_gen_op4i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2, 186 TCGv_i64 a3, TCGArg a4) 187 { 188 tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), 189 tcgv_i64_arg(a3), a4); 190 } 191 192 static void DNI tcg_gen_op4ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2, 193 TCGArg a3, TCGArg a4) 194 { 195 tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3, a4); 196 } 197 198 static void DNI tcg_gen_op4ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2, 199 TCGArg a3, TCGArg a4) 200 { 201 tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3, a4); 202 } 203 204 static void DNI tcg_gen_op5_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2, 205 TCGv_i32 a3, TCGv_i32 a4, TCGv_i32 a5) 206 { 207 tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), 208 tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5)); 209 } 210 211 static void DNI tcg_gen_op5_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2, 212 TCGv_i64 a3, TCGv_i64 a4, TCGv_i64 a5) 213 { 214 tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), 215 tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5)); 216 } 217 218 static void DNI tcg_gen_op5ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2, 219 TCGv_i32 a3, TCGArg a4, TCGArg a5) 220 { 221 tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), 222 tcgv_i32_arg(a3), a4, a5); 223 } 224 225 static void DNI tcg_gen_op5ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2, 226 TCGv_i64 a3, TCGArg a4, TCGArg a5) 227 { 228 tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), 229 tcgv_i64_arg(a3), a4, a5); 230 } 231 232 static void DNI tcg_gen_op6_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2, 233 TCGv_i32 a3, TCGv_i32 a4, 234 TCGv_i32 a5, TCGv_i32 a6) 235 { 236 tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), 237 tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5), 238 tcgv_i32_arg(a6)); 239 } 240 241 static void DNI tcg_gen_op6_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2, 242 TCGv_i64 a3, TCGv_i64 a4, 243 TCGv_i64 a5, TCGv_i64 a6) 244 { 245 tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), 246 tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5), 247 tcgv_i64_arg(a6)); 248 } 249 250 static void DNI tcg_gen_op6i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2, 251 TCGv_i32 a3, TCGv_i32 a4, 252 TCGv_i32 a5, TCGArg a6) 253 { 254 tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), 255 tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5), a6); 256 } 257 258 static void DNI tcg_gen_op6i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2, 259 TCGv_i64 a3, TCGv_i64 a4, 260 TCGv_i64 a5, TCGArg a6) 261 { 262 tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), 263 tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5), a6); 264 } 265 266 static void DNI tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2, 267 TCGv_i32 a3, TCGv_i32 a4, 268 TCGArg a5, TCGArg a6) 269 { 270 tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), 271 tcgv_i32_arg(a3), tcgv_i32_arg(a4), a5, a6); 272 } 273 274 /* Generic ops. */ 275 276 void gen_set_label(TCGLabel *l) 277 { 278 l->present = 1; 279 tcg_gen_op1(INDEX_op_set_label, label_arg(l)); 280 } 281 282 static void add_last_as_label_use(TCGLabel *l) 283 { 284 TCGLabelUse *u = tcg_malloc(sizeof(TCGLabelUse)); 285 286 u->op = tcg_last_op(); 287 QSIMPLEQ_INSERT_TAIL(&l->branches, u, next); 288 } 289 290 void tcg_gen_br(TCGLabel *l) 291 { 292 tcg_gen_op1(INDEX_op_br, label_arg(l)); 293 add_last_as_label_use(l); 294 } 295 296 void tcg_gen_mb(TCGBar mb_type) 297 { 298 #ifdef CONFIG_USER_ONLY 299 bool parallel = tcg_ctx->gen_tb->cflags & CF_PARALLEL; 300 #else 301 /* 302 * It is tempting to elide the barrier in a uniprocessor context. 303 * However, even with a single cpu we have i/o threads running in 304 * parallel, and lack of memory order can result in e.g. virtio 305 * queue entries being read incorrectly. 306 */ 307 bool parallel = true; 308 #endif 309 310 if (parallel) { 311 tcg_gen_op1(INDEX_op_mb, mb_type); 312 } 313 } 314 315 void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr) 316 { 317 tcg_gen_op3(INDEX_op_plugin_cb_start, from, type, wr); 318 } 319 320 void tcg_gen_plugin_cb_end(void) 321 { 322 tcg_emit_op(INDEX_op_plugin_cb_end, 0); 323 } 324 325 /* 32 bit ops */ 326 327 void tcg_gen_discard_i32(TCGv_i32 arg) 328 { 329 tcg_gen_op1_i32(INDEX_op_discard, arg); 330 } 331 332 void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg) 333 { 334 if (ret != arg) { 335 tcg_gen_op2_i32(INDEX_op_mov_i32, ret, arg); 336 } 337 } 338 339 void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg) 340 { 341 tcg_gen_mov_i32(ret, tcg_constant_i32(arg)); 342 } 343 344 void tcg_gen_add_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 345 { 346 tcg_gen_op3_i32(INDEX_op_add_i32, ret, arg1, arg2); 347 } 348 349 void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 350 { 351 /* some cases can be optimized here */ 352 if (arg2 == 0) { 353 tcg_gen_mov_i32(ret, arg1); 354 } else { 355 tcg_gen_add_i32(ret, arg1, tcg_constant_i32(arg2)); 356 } 357 } 358 359 void tcg_gen_sub_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 360 { 361 tcg_gen_op3_i32(INDEX_op_sub_i32, ret, arg1, arg2); 362 } 363 364 void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2) 365 { 366 if (arg1 == 0) { 367 tcg_gen_neg_i32(ret, arg2); 368 } else { 369 tcg_gen_sub_i32(ret, tcg_constant_i32(arg1), arg2); 370 } 371 } 372 373 void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 374 { 375 /* some cases can be optimized here */ 376 if (arg2 == 0) { 377 tcg_gen_mov_i32(ret, arg1); 378 } else { 379 tcg_gen_sub_i32(ret, arg1, tcg_constant_i32(arg2)); 380 } 381 } 382 383 void tcg_gen_neg_i32(TCGv_i32 ret, TCGv_i32 arg) 384 { 385 tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg); 386 } 387 388 void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 389 { 390 tcg_gen_op3_i32(INDEX_op_and_i32, ret, arg1, arg2); 391 } 392 393 void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 394 { 395 /* Some cases can be optimized here. */ 396 switch (arg2) { 397 case 0: 398 tcg_gen_movi_i32(ret, 0); 399 return; 400 case -1: 401 tcg_gen_mov_i32(ret, arg1); 402 return; 403 case 0xff: 404 /* Don't recurse with tcg_gen_ext8u_i32. */ 405 if (TCG_TARGET_HAS_ext8u_i32) { 406 tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1); 407 return; 408 } 409 break; 410 case 0xffff: 411 if (TCG_TARGET_HAS_ext16u_i32) { 412 tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1); 413 return; 414 } 415 break; 416 } 417 418 tcg_gen_and_i32(ret, arg1, tcg_constant_i32(arg2)); 419 } 420 421 void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 422 { 423 tcg_gen_op3_i32(INDEX_op_or_i32, ret, arg1, arg2); 424 } 425 426 void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 427 { 428 /* Some cases can be optimized here. */ 429 if (arg2 == -1) { 430 tcg_gen_movi_i32(ret, -1); 431 } else if (arg2 == 0) { 432 tcg_gen_mov_i32(ret, arg1); 433 } else { 434 tcg_gen_or_i32(ret, arg1, tcg_constant_i32(arg2)); 435 } 436 } 437 438 void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 439 { 440 tcg_gen_op3_i32(INDEX_op_xor_i32, ret, arg1, arg2); 441 } 442 443 void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 444 { 445 /* Some cases can be optimized here. */ 446 if (arg2 == 0) { 447 tcg_gen_mov_i32(ret, arg1); 448 } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) { 449 /* Don't recurse with tcg_gen_not_i32. */ 450 tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1); 451 } else { 452 tcg_gen_xor_i32(ret, arg1, tcg_constant_i32(arg2)); 453 } 454 } 455 456 void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg) 457 { 458 if (TCG_TARGET_HAS_not_i32) { 459 tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg); 460 } else { 461 tcg_gen_xori_i32(ret, arg, -1); 462 } 463 } 464 465 void tcg_gen_shl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 466 { 467 tcg_gen_op3_i32(INDEX_op_shl_i32, ret, arg1, arg2); 468 } 469 470 void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 471 { 472 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 473 if (arg2 == 0) { 474 tcg_gen_mov_i32(ret, arg1); 475 } else { 476 tcg_gen_shl_i32(ret, arg1, tcg_constant_i32(arg2)); 477 } 478 } 479 480 void tcg_gen_shr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 481 { 482 tcg_gen_op3_i32(INDEX_op_shr_i32, ret, arg1, arg2); 483 } 484 485 void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 486 { 487 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 488 if (arg2 == 0) { 489 tcg_gen_mov_i32(ret, arg1); 490 } else { 491 tcg_gen_shr_i32(ret, arg1, tcg_constant_i32(arg2)); 492 } 493 } 494 495 void tcg_gen_sar_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 496 { 497 tcg_gen_op3_i32(INDEX_op_sar_i32, ret, arg1, arg2); 498 } 499 500 void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 501 { 502 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 503 if (arg2 == 0) { 504 tcg_gen_mov_i32(ret, arg1); 505 } else { 506 tcg_gen_sar_i32(ret, arg1, tcg_constant_i32(arg2)); 507 } 508 } 509 510 void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l) 511 { 512 if (cond == TCG_COND_ALWAYS) { 513 tcg_gen_br(l); 514 } else if (cond != TCG_COND_NEVER) { 515 tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l)); 516 add_last_as_label_use(l); 517 } 518 } 519 520 void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l) 521 { 522 if (cond == TCG_COND_ALWAYS) { 523 tcg_gen_br(l); 524 } else if (cond != TCG_COND_NEVER) { 525 tcg_gen_brcond_i32(cond, arg1, tcg_constant_i32(arg2), l); 526 } 527 } 528 529 void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret, 530 TCGv_i32 arg1, TCGv_i32 arg2) 531 { 532 if (cond == TCG_COND_ALWAYS) { 533 tcg_gen_movi_i32(ret, 1); 534 } else if (cond == TCG_COND_NEVER) { 535 tcg_gen_movi_i32(ret, 0); 536 } else { 537 tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond); 538 } 539 } 540 541 void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret, 542 TCGv_i32 arg1, int32_t arg2) 543 { 544 tcg_gen_setcond_i32(cond, ret, arg1, tcg_constant_i32(arg2)); 545 } 546 547 void tcg_gen_negsetcond_i32(TCGCond cond, TCGv_i32 ret, 548 TCGv_i32 arg1, TCGv_i32 arg2) 549 { 550 if (cond == TCG_COND_ALWAYS) { 551 tcg_gen_movi_i32(ret, -1); 552 } else if (cond == TCG_COND_NEVER) { 553 tcg_gen_movi_i32(ret, 0); 554 } else if (TCG_TARGET_HAS_negsetcond_i32) { 555 tcg_gen_op4i_i32(INDEX_op_negsetcond_i32, ret, arg1, arg2, cond); 556 } else { 557 tcg_gen_setcond_i32(cond, ret, arg1, arg2); 558 tcg_gen_neg_i32(ret, ret); 559 } 560 } 561 562 void tcg_gen_negsetcondi_i32(TCGCond cond, TCGv_i32 ret, 563 TCGv_i32 arg1, int32_t arg2) 564 { 565 tcg_gen_negsetcond_i32(cond, ret, arg1, tcg_constant_i32(arg2)); 566 } 567 568 void tcg_gen_mul_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 569 { 570 tcg_gen_op3_i32(INDEX_op_mul_i32, ret, arg1, arg2); 571 } 572 573 void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 574 { 575 if (arg2 == 0) { 576 tcg_gen_movi_i32(ret, 0); 577 } else if (is_power_of_2(arg2)) { 578 tcg_gen_shli_i32(ret, arg1, ctz32(arg2)); 579 } else { 580 tcg_gen_mul_i32(ret, arg1, tcg_constant_i32(arg2)); 581 } 582 } 583 584 void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 585 { 586 if (TCG_TARGET_HAS_div_i32) { 587 tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2); 588 } else if (TCG_TARGET_HAS_div2_i32) { 589 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 590 tcg_gen_sari_i32(t0, arg1, 31); 591 tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2); 592 tcg_temp_free_i32(t0); 593 } else { 594 gen_helper_div_i32(ret, arg1, arg2); 595 } 596 } 597 598 void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 599 { 600 if (TCG_TARGET_HAS_rem_i32) { 601 tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2); 602 } else if (TCG_TARGET_HAS_div_i32) { 603 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 604 tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2); 605 tcg_gen_mul_i32(t0, t0, arg2); 606 tcg_gen_sub_i32(ret, arg1, t0); 607 tcg_temp_free_i32(t0); 608 } else if (TCG_TARGET_HAS_div2_i32) { 609 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 610 tcg_gen_sari_i32(t0, arg1, 31); 611 tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2); 612 tcg_temp_free_i32(t0); 613 } else { 614 gen_helper_rem_i32(ret, arg1, arg2); 615 } 616 } 617 618 void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 619 { 620 if (TCG_TARGET_HAS_div_i32) { 621 tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2); 622 } else if (TCG_TARGET_HAS_div2_i32) { 623 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 624 TCGv_i32 zero = tcg_constant_i32(0); 625 tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, zero, arg2); 626 tcg_temp_free_i32(t0); 627 } else { 628 gen_helper_divu_i32(ret, arg1, arg2); 629 } 630 } 631 632 void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 633 { 634 if (TCG_TARGET_HAS_rem_i32) { 635 tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2); 636 } else if (TCG_TARGET_HAS_div_i32) { 637 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 638 tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2); 639 tcg_gen_mul_i32(t0, t0, arg2); 640 tcg_gen_sub_i32(ret, arg1, t0); 641 tcg_temp_free_i32(t0); 642 } else if (TCG_TARGET_HAS_div2_i32) { 643 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 644 TCGv_i32 zero = tcg_constant_i32(0); 645 tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, zero, arg2); 646 tcg_temp_free_i32(t0); 647 } else { 648 gen_helper_remu_i32(ret, arg1, arg2); 649 } 650 } 651 652 void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 653 { 654 if (TCG_TARGET_HAS_andc_i32) { 655 tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2); 656 } else { 657 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 658 tcg_gen_not_i32(t0, arg2); 659 tcg_gen_and_i32(ret, arg1, t0); 660 tcg_temp_free_i32(t0); 661 } 662 } 663 664 void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 665 { 666 if (TCG_TARGET_HAS_eqv_i32) { 667 tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2); 668 } else { 669 tcg_gen_xor_i32(ret, arg1, arg2); 670 tcg_gen_not_i32(ret, ret); 671 } 672 } 673 674 void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 675 { 676 if (TCG_TARGET_HAS_nand_i32) { 677 tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2); 678 } else { 679 tcg_gen_and_i32(ret, arg1, arg2); 680 tcg_gen_not_i32(ret, ret); 681 } 682 } 683 684 void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 685 { 686 if (TCG_TARGET_HAS_nor_i32) { 687 tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2); 688 } else { 689 tcg_gen_or_i32(ret, arg1, arg2); 690 tcg_gen_not_i32(ret, ret); 691 } 692 } 693 694 void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 695 { 696 if (TCG_TARGET_HAS_orc_i32) { 697 tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2); 698 } else { 699 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 700 tcg_gen_not_i32(t0, arg2); 701 tcg_gen_or_i32(ret, arg1, t0); 702 tcg_temp_free_i32(t0); 703 } 704 } 705 706 void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 707 { 708 if (TCG_TARGET_HAS_clz_i32) { 709 tcg_gen_op3_i32(INDEX_op_clz_i32, ret, arg1, arg2); 710 } else if (TCG_TARGET_HAS_clz_i64) { 711 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 712 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 713 tcg_gen_extu_i32_i64(t1, arg1); 714 tcg_gen_extu_i32_i64(t2, arg2); 715 tcg_gen_addi_i64(t2, t2, 32); 716 tcg_gen_clz_i64(t1, t1, t2); 717 tcg_gen_extrl_i64_i32(ret, t1); 718 tcg_temp_free_i64(t1); 719 tcg_temp_free_i64(t2); 720 tcg_gen_subi_i32(ret, ret, 32); 721 } else { 722 gen_helper_clz_i32(ret, arg1, arg2); 723 } 724 } 725 726 void tcg_gen_clzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2) 727 { 728 tcg_gen_clz_i32(ret, arg1, tcg_constant_i32(arg2)); 729 } 730 731 void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 732 { 733 if (TCG_TARGET_HAS_ctz_i32) { 734 tcg_gen_op3_i32(INDEX_op_ctz_i32, ret, arg1, arg2); 735 } else if (TCG_TARGET_HAS_ctz_i64) { 736 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 737 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 738 tcg_gen_extu_i32_i64(t1, arg1); 739 tcg_gen_extu_i32_i64(t2, arg2); 740 tcg_gen_ctz_i64(t1, t1, t2); 741 tcg_gen_extrl_i64_i32(ret, t1); 742 tcg_temp_free_i64(t1); 743 tcg_temp_free_i64(t2); 744 } else if (TCG_TARGET_HAS_ctpop_i32 745 || TCG_TARGET_HAS_ctpop_i64 746 || TCG_TARGET_HAS_clz_i32 747 || TCG_TARGET_HAS_clz_i64) { 748 TCGv_i32 z, t = tcg_temp_ebb_new_i32(); 749 750 if (TCG_TARGET_HAS_ctpop_i32 || TCG_TARGET_HAS_ctpop_i64) { 751 tcg_gen_subi_i32(t, arg1, 1); 752 tcg_gen_andc_i32(t, t, arg1); 753 tcg_gen_ctpop_i32(t, t); 754 } else { 755 /* Since all non-x86 hosts have clz(0) == 32, don't fight it. */ 756 tcg_gen_neg_i32(t, arg1); 757 tcg_gen_and_i32(t, t, arg1); 758 tcg_gen_clzi_i32(t, t, 32); 759 tcg_gen_xori_i32(t, t, 31); 760 } 761 z = tcg_constant_i32(0); 762 tcg_gen_movcond_i32(TCG_COND_EQ, ret, arg1, z, arg2, t); 763 tcg_temp_free_i32(t); 764 } else { 765 gen_helper_ctz_i32(ret, arg1, arg2); 766 } 767 } 768 769 void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2) 770 { 771 if (!TCG_TARGET_HAS_ctz_i32 && TCG_TARGET_HAS_ctpop_i32 && arg2 == 32) { 772 /* This equivalence has the advantage of not requiring a fixup. */ 773 TCGv_i32 t = tcg_temp_ebb_new_i32(); 774 tcg_gen_subi_i32(t, arg1, 1); 775 tcg_gen_andc_i32(t, t, arg1); 776 tcg_gen_ctpop_i32(ret, t); 777 tcg_temp_free_i32(t); 778 } else { 779 tcg_gen_ctz_i32(ret, arg1, tcg_constant_i32(arg2)); 780 } 781 } 782 783 void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg) 784 { 785 if (TCG_TARGET_HAS_clz_i32) { 786 TCGv_i32 t = tcg_temp_ebb_new_i32(); 787 tcg_gen_sari_i32(t, arg, 31); 788 tcg_gen_xor_i32(t, t, arg); 789 tcg_gen_clzi_i32(t, t, 32); 790 tcg_gen_subi_i32(ret, t, 1); 791 tcg_temp_free_i32(t); 792 } else { 793 gen_helper_clrsb_i32(ret, arg); 794 } 795 } 796 797 void tcg_gen_ctpop_i32(TCGv_i32 ret, TCGv_i32 arg1) 798 { 799 if (TCG_TARGET_HAS_ctpop_i32) { 800 tcg_gen_op2_i32(INDEX_op_ctpop_i32, ret, arg1); 801 } else if (TCG_TARGET_HAS_ctpop_i64) { 802 TCGv_i64 t = tcg_temp_ebb_new_i64(); 803 tcg_gen_extu_i32_i64(t, arg1); 804 tcg_gen_ctpop_i64(t, t); 805 tcg_gen_extrl_i64_i32(ret, t); 806 tcg_temp_free_i64(t); 807 } else { 808 gen_helper_ctpop_i32(ret, arg1); 809 } 810 } 811 812 void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 813 { 814 if (TCG_TARGET_HAS_rot_i32) { 815 tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2); 816 } else { 817 TCGv_i32 t0, t1; 818 819 t0 = tcg_temp_ebb_new_i32(); 820 t1 = tcg_temp_ebb_new_i32(); 821 tcg_gen_shl_i32(t0, arg1, arg2); 822 tcg_gen_subfi_i32(t1, 32, arg2); 823 tcg_gen_shr_i32(t1, arg1, t1); 824 tcg_gen_or_i32(ret, t0, t1); 825 tcg_temp_free_i32(t0); 826 tcg_temp_free_i32(t1); 827 } 828 } 829 830 void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 831 { 832 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 833 /* some cases can be optimized here */ 834 if (arg2 == 0) { 835 tcg_gen_mov_i32(ret, arg1); 836 } else if (TCG_TARGET_HAS_rot_i32) { 837 tcg_gen_rotl_i32(ret, arg1, tcg_constant_i32(arg2)); 838 } else { 839 TCGv_i32 t0, t1; 840 t0 = tcg_temp_ebb_new_i32(); 841 t1 = tcg_temp_ebb_new_i32(); 842 tcg_gen_shli_i32(t0, arg1, arg2); 843 tcg_gen_shri_i32(t1, arg1, 32 - arg2); 844 tcg_gen_or_i32(ret, t0, t1); 845 tcg_temp_free_i32(t0); 846 tcg_temp_free_i32(t1); 847 } 848 } 849 850 void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 851 { 852 if (TCG_TARGET_HAS_rot_i32) { 853 tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2); 854 } else { 855 TCGv_i32 t0, t1; 856 857 t0 = tcg_temp_ebb_new_i32(); 858 t1 = tcg_temp_ebb_new_i32(); 859 tcg_gen_shr_i32(t0, arg1, arg2); 860 tcg_gen_subfi_i32(t1, 32, arg2); 861 tcg_gen_shl_i32(t1, arg1, t1); 862 tcg_gen_or_i32(ret, t0, t1); 863 tcg_temp_free_i32(t0); 864 tcg_temp_free_i32(t1); 865 } 866 } 867 868 void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 869 { 870 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 871 /* some cases can be optimized here */ 872 if (arg2 == 0) { 873 tcg_gen_mov_i32(ret, arg1); 874 } else { 875 tcg_gen_rotli_i32(ret, arg1, 32 - arg2); 876 } 877 } 878 879 void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2, 880 unsigned int ofs, unsigned int len) 881 { 882 uint32_t mask; 883 TCGv_i32 t1; 884 885 tcg_debug_assert(ofs < 32); 886 tcg_debug_assert(len > 0); 887 tcg_debug_assert(len <= 32); 888 tcg_debug_assert(ofs + len <= 32); 889 890 if (len == 32) { 891 tcg_gen_mov_i32(ret, arg2); 892 return; 893 } 894 if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) { 895 tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len); 896 return; 897 } 898 899 t1 = tcg_temp_ebb_new_i32(); 900 901 if (TCG_TARGET_HAS_extract2_i32) { 902 if (ofs + len == 32) { 903 tcg_gen_shli_i32(t1, arg1, len); 904 tcg_gen_extract2_i32(ret, t1, arg2, len); 905 goto done; 906 } 907 if (ofs == 0) { 908 tcg_gen_extract2_i32(ret, arg1, arg2, len); 909 tcg_gen_rotli_i32(ret, ret, len); 910 goto done; 911 } 912 } 913 914 mask = (1u << len) - 1; 915 if (ofs + len < 32) { 916 tcg_gen_andi_i32(t1, arg2, mask); 917 tcg_gen_shli_i32(t1, t1, ofs); 918 } else { 919 tcg_gen_shli_i32(t1, arg2, ofs); 920 } 921 tcg_gen_andi_i32(ret, arg1, ~(mask << ofs)); 922 tcg_gen_or_i32(ret, ret, t1); 923 done: 924 tcg_temp_free_i32(t1); 925 } 926 927 void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg, 928 unsigned int ofs, unsigned int len) 929 { 930 tcg_debug_assert(ofs < 32); 931 tcg_debug_assert(len > 0); 932 tcg_debug_assert(len <= 32); 933 tcg_debug_assert(ofs + len <= 32); 934 935 if (ofs + len == 32) { 936 tcg_gen_shli_i32(ret, arg, ofs); 937 } else if (ofs == 0) { 938 tcg_gen_andi_i32(ret, arg, (1u << len) - 1); 939 } else if (TCG_TARGET_HAS_deposit_i32 940 && TCG_TARGET_deposit_i32_valid(ofs, len)) { 941 TCGv_i32 zero = tcg_constant_i32(0); 942 tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len); 943 } else { 944 /* To help two-operand hosts we prefer to zero-extend first, 945 which allows ARG to stay live. */ 946 switch (len) { 947 case 16: 948 if (TCG_TARGET_HAS_ext16u_i32) { 949 tcg_gen_ext16u_i32(ret, arg); 950 tcg_gen_shli_i32(ret, ret, ofs); 951 return; 952 } 953 break; 954 case 8: 955 if (TCG_TARGET_HAS_ext8u_i32) { 956 tcg_gen_ext8u_i32(ret, arg); 957 tcg_gen_shli_i32(ret, ret, ofs); 958 return; 959 } 960 break; 961 } 962 /* Otherwise prefer zero-extension over AND for code size. */ 963 switch (ofs + len) { 964 case 16: 965 if (TCG_TARGET_HAS_ext16u_i32) { 966 tcg_gen_shli_i32(ret, arg, ofs); 967 tcg_gen_ext16u_i32(ret, ret); 968 return; 969 } 970 break; 971 case 8: 972 if (TCG_TARGET_HAS_ext8u_i32) { 973 tcg_gen_shli_i32(ret, arg, ofs); 974 tcg_gen_ext8u_i32(ret, ret); 975 return; 976 } 977 break; 978 } 979 tcg_gen_andi_i32(ret, arg, (1u << len) - 1); 980 tcg_gen_shli_i32(ret, ret, ofs); 981 } 982 } 983 984 void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg, 985 unsigned int ofs, unsigned int len) 986 { 987 tcg_debug_assert(ofs < 32); 988 tcg_debug_assert(len > 0); 989 tcg_debug_assert(len <= 32); 990 tcg_debug_assert(ofs + len <= 32); 991 992 /* Canonicalize certain special cases, even if extract is supported. */ 993 if (ofs + len == 32) { 994 tcg_gen_shri_i32(ret, arg, 32 - len); 995 return; 996 } 997 if (ofs == 0) { 998 tcg_gen_andi_i32(ret, arg, (1u << len) - 1); 999 return; 1000 } 1001 1002 if (TCG_TARGET_HAS_extract_i32 1003 && TCG_TARGET_extract_i32_valid(ofs, len)) { 1004 tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, ofs, len); 1005 return; 1006 } 1007 1008 /* Assume that zero-extension, if available, is cheaper than a shift. */ 1009 switch (ofs + len) { 1010 case 16: 1011 if (TCG_TARGET_HAS_ext16u_i32) { 1012 tcg_gen_ext16u_i32(ret, arg); 1013 tcg_gen_shri_i32(ret, ret, ofs); 1014 return; 1015 } 1016 break; 1017 case 8: 1018 if (TCG_TARGET_HAS_ext8u_i32) { 1019 tcg_gen_ext8u_i32(ret, arg); 1020 tcg_gen_shri_i32(ret, ret, ofs); 1021 return; 1022 } 1023 break; 1024 } 1025 1026 /* ??? Ideally we'd know what values are available for immediate AND. 1027 Assume that 8 bits are available, plus the special case of 16, 1028 so that we get ext8u, ext16u. */ 1029 switch (len) { 1030 case 1 ... 8: case 16: 1031 tcg_gen_shri_i32(ret, arg, ofs); 1032 tcg_gen_andi_i32(ret, ret, (1u << len) - 1); 1033 break; 1034 default: 1035 tcg_gen_shli_i32(ret, arg, 32 - len - ofs); 1036 tcg_gen_shri_i32(ret, ret, 32 - len); 1037 break; 1038 } 1039 } 1040 1041 void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg, 1042 unsigned int ofs, unsigned int len) 1043 { 1044 tcg_debug_assert(ofs < 32); 1045 tcg_debug_assert(len > 0); 1046 tcg_debug_assert(len <= 32); 1047 tcg_debug_assert(ofs + len <= 32); 1048 1049 /* Canonicalize certain special cases, even if extract is supported. */ 1050 if (ofs + len == 32) { 1051 tcg_gen_sari_i32(ret, arg, 32 - len); 1052 return; 1053 } 1054 if (ofs == 0) { 1055 switch (len) { 1056 case 16: 1057 tcg_gen_ext16s_i32(ret, arg); 1058 return; 1059 case 8: 1060 tcg_gen_ext8s_i32(ret, arg); 1061 return; 1062 } 1063 } 1064 1065 if (TCG_TARGET_HAS_sextract_i32 1066 && TCG_TARGET_extract_i32_valid(ofs, len)) { 1067 tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len); 1068 return; 1069 } 1070 1071 /* Assume that sign-extension, if available, is cheaper than a shift. */ 1072 switch (ofs + len) { 1073 case 16: 1074 if (TCG_TARGET_HAS_ext16s_i32) { 1075 tcg_gen_ext16s_i32(ret, arg); 1076 tcg_gen_sari_i32(ret, ret, ofs); 1077 return; 1078 } 1079 break; 1080 case 8: 1081 if (TCG_TARGET_HAS_ext8s_i32) { 1082 tcg_gen_ext8s_i32(ret, arg); 1083 tcg_gen_sari_i32(ret, ret, ofs); 1084 return; 1085 } 1086 break; 1087 } 1088 switch (len) { 1089 case 16: 1090 if (TCG_TARGET_HAS_ext16s_i32) { 1091 tcg_gen_shri_i32(ret, arg, ofs); 1092 tcg_gen_ext16s_i32(ret, ret); 1093 return; 1094 } 1095 break; 1096 case 8: 1097 if (TCG_TARGET_HAS_ext8s_i32) { 1098 tcg_gen_shri_i32(ret, arg, ofs); 1099 tcg_gen_ext8s_i32(ret, ret); 1100 return; 1101 } 1102 break; 1103 } 1104 1105 tcg_gen_shli_i32(ret, arg, 32 - len - ofs); 1106 tcg_gen_sari_i32(ret, ret, 32 - len); 1107 } 1108 1109 /* 1110 * Extract 32-bits from a 64-bit input, ah:al, starting from ofs. 1111 * Unlike tcg_gen_extract_i32 above, len is fixed at 32. 1112 */ 1113 void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah, 1114 unsigned int ofs) 1115 { 1116 tcg_debug_assert(ofs <= 32); 1117 if (ofs == 0) { 1118 tcg_gen_mov_i32(ret, al); 1119 } else if (ofs == 32) { 1120 tcg_gen_mov_i32(ret, ah); 1121 } else if (al == ah) { 1122 tcg_gen_rotri_i32(ret, al, ofs); 1123 } else if (TCG_TARGET_HAS_extract2_i32) { 1124 tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs); 1125 } else { 1126 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1127 tcg_gen_shri_i32(t0, al, ofs); 1128 tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs); 1129 tcg_temp_free_i32(t0); 1130 } 1131 } 1132 1133 void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1, 1134 TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2) 1135 { 1136 if (cond == TCG_COND_ALWAYS) { 1137 tcg_gen_mov_i32(ret, v1); 1138 } else if (cond == TCG_COND_NEVER) { 1139 tcg_gen_mov_i32(ret, v2); 1140 } else { 1141 tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond); 1142 } 1143 } 1144 1145 void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al, 1146 TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh) 1147 { 1148 if (TCG_TARGET_HAS_add2_i32) { 1149 tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh); 1150 } else { 1151 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1152 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1153 tcg_gen_concat_i32_i64(t0, al, ah); 1154 tcg_gen_concat_i32_i64(t1, bl, bh); 1155 tcg_gen_add_i64(t0, t0, t1); 1156 tcg_gen_extr_i64_i32(rl, rh, t0); 1157 tcg_temp_free_i64(t0); 1158 tcg_temp_free_i64(t1); 1159 } 1160 } 1161 1162 void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al, 1163 TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh) 1164 { 1165 if (TCG_TARGET_HAS_sub2_i32) { 1166 tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh); 1167 } else { 1168 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1169 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1170 tcg_gen_concat_i32_i64(t0, al, ah); 1171 tcg_gen_concat_i32_i64(t1, bl, bh); 1172 tcg_gen_sub_i64(t0, t0, t1); 1173 tcg_gen_extr_i64_i32(rl, rh, t0); 1174 tcg_temp_free_i64(t0); 1175 tcg_temp_free_i64(t1); 1176 } 1177 } 1178 1179 void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 1180 { 1181 if (TCG_TARGET_HAS_mulu2_i32) { 1182 tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2); 1183 } else if (TCG_TARGET_HAS_muluh_i32) { 1184 TCGv_i32 t = tcg_temp_ebb_new_i32(); 1185 tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2); 1186 tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2); 1187 tcg_gen_mov_i32(rl, t); 1188 tcg_temp_free_i32(t); 1189 } else if (TCG_TARGET_REG_BITS == 64) { 1190 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1191 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1192 tcg_gen_extu_i32_i64(t0, arg1); 1193 tcg_gen_extu_i32_i64(t1, arg2); 1194 tcg_gen_mul_i64(t0, t0, t1); 1195 tcg_gen_extr_i64_i32(rl, rh, t0); 1196 tcg_temp_free_i64(t0); 1197 tcg_temp_free_i64(t1); 1198 } else { 1199 qemu_build_not_reached(); 1200 } 1201 } 1202 1203 void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 1204 { 1205 if (TCG_TARGET_HAS_muls2_i32) { 1206 tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2); 1207 } else if (TCG_TARGET_HAS_mulsh_i32) { 1208 TCGv_i32 t = tcg_temp_ebb_new_i32(); 1209 tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2); 1210 tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2); 1211 tcg_gen_mov_i32(rl, t); 1212 tcg_temp_free_i32(t); 1213 } else if (TCG_TARGET_REG_BITS == 32) { 1214 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1215 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1216 TCGv_i32 t2 = tcg_temp_ebb_new_i32(); 1217 TCGv_i32 t3 = tcg_temp_ebb_new_i32(); 1218 tcg_gen_mulu2_i32(t0, t1, arg1, arg2); 1219 /* Adjust for negative inputs. */ 1220 tcg_gen_sari_i32(t2, arg1, 31); 1221 tcg_gen_sari_i32(t3, arg2, 31); 1222 tcg_gen_and_i32(t2, t2, arg2); 1223 tcg_gen_and_i32(t3, t3, arg1); 1224 tcg_gen_sub_i32(rh, t1, t2); 1225 tcg_gen_sub_i32(rh, rh, t3); 1226 tcg_gen_mov_i32(rl, t0); 1227 tcg_temp_free_i32(t0); 1228 tcg_temp_free_i32(t1); 1229 tcg_temp_free_i32(t2); 1230 tcg_temp_free_i32(t3); 1231 } else { 1232 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1233 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1234 tcg_gen_ext_i32_i64(t0, arg1); 1235 tcg_gen_ext_i32_i64(t1, arg2); 1236 tcg_gen_mul_i64(t0, t0, t1); 1237 tcg_gen_extr_i64_i32(rl, rh, t0); 1238 tcg_temp_free_i64(t0); 1239 tcg_temp_free_i64(t1); 1240 } 1241 } 1242 1243 void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 1244 { 1245 if (TCG_TARGET_REG_BITS == 32) { 1246 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1247 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1248 TCGv_i32 t2 = tcg_temp_ebb_new_i32(); 1249 tcg_gen_mulu2_i32(t0, t1, arg1, arg2); 1250 /* Adjust for negative input for the signed arg1. */ 1251 tcg_gen_sari_i32(t2, arg1, 31); 1252 tcg_gen_and_i32(t2, t2, arg2); 1253 tcg_gen_sub_i32(rh, t1, t2); 1254 tcg_gen_mov_i32(rl, t0); 1255 tcg_temp_free_i32(t0); 1256 tcg_temp_free_i32(t1); 1257 tcg_temp_free_i32(t2); 1258 } else { 1259 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1260 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1261 tcg_gen_ext_i32_i64(t0, arg1); 1262 tcg_gen_extu_i32_i64(t1, arg2); 1263 tcg_gen_mul_i64(t0, t0, t1); 1264 tcg_gen_extr_i64_i32(rl, rh, t0); 1265 tcg_temp_free_i64(t0); 1266 tcg_temp_free_i64(t1); 1267 } 1268 } 1269 1270 void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg) 1271 { 1272 if (TCG_TARGET_HAS_ext8s_i32) { 1273 tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg); 1274 } else { 1275 tcg_gen_shli_i32(ret, arg, 24); 1276 tcg_gen_sari_i32(ret, ret, 24); 1277 } 1278 } 1279 1280 void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg) 1281 { 1282 if (TCG_TARGET_HAS_ext16s_i32) { 1283 tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg); 1284 } else { 1285 tcg_gen_shli_i32(ret, arg, 16); 1286 tcg_gen_sari_i32(ret, ret, 16); 1287 } 1288 } 1289 1290 void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg) 1291 { 1292 if (TCG_TARGET_HAS_ext8u_i32) { 1293 tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg); 1294 } else { 1295 tcg_gen_andi_i32(ret, arg, 0xffu); 1296 } 1297 } 1298 1299 void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg) 1300 { 1301 if (TCG_TARGET_HAS_ext16u_i32) { 1302 tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg); 1303 } else { 1304 tcg_gen_andi_i32(ret, arg, 0xffffu); 1305 } 1306 } 1307 1308 /* 1309 * bswap16_i32: 16-bit byte swap on the low bits of a 32-bit value. 1310 * 1311 * Byte pattern: xxab -> yyba 1312 * 1313 * With TCG_BSWAP_IZ, x == zero, else undefined. 1314 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined. 1315 */ 1316 void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags) 1317 { 1318 /* Only one extension flag may be present. */ 1319 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ)); 1320 1321 if (TCG_TARGET_HAS_bswap16_i32) { 1322 tcg_gen_op3i_i32(INDEX_op_bswap16_i32, ret, arg, flags); 1323 } else { 1324 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1325 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1326 1327 /* arg = ..ab (IZ) xxab (!IZ) */ 1328 tcg_gen_shri_i32(t0, arg, 8); /* t0 = ...a (IZ) .xxa (!IZ) */ 1329 if (!(flags & TCG_BSWAP_IZ)) { 1330 tcg_gen_ext8u_i32(t0, t0); /* t0 = ...a */ 1331 } 1332 1333 if (flags & TCG_BSWAP_OS) { 1334 tcg_gen_shli_i32(t1, arg, 24); /* t1 = b... */ 1335 tcg_gen_sari_i32(t1, t1, 16); /* t1 = ssb. */ 1336 } else if (flags & TCG_BSWAP_OZ) { 1337 tcg_gen_ext8u_i32(t1, arg); /* t1 = ...b */ 1338 tcg_gen_shli_i32(t1, t1, 8); /* t1 = ..b. */ 1339 } else { 1340 tcg_gen_shli_i32(t1, arg, 8); /* t1 = xab. */ 1341 } 1342 1343 tcg_gen_or_i32(ret, t0, t1); /* ret = ..ba (OZ) */ 1344 /* = ssba (OS) */ 1345 /* = xaba (no flag) */ 1346 tcg_temp_free_i32(t0); 1347 tcg_temp_free_i32(t1); 1348 } 1349 } 1350 1351 /* 1352 * bswap32_i32: 32-bit byte swap on a 32-bit value. 1353 * 1354 * Byte pattern: abcd -> dcba 1355 */ 1356 void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg) 1357 { 1358 if (TCG_TARGET_HAS_bswap32_i32) { 1359 tcg_gen_op3i_i32(INDEX_op_bswap32_i32, ret, arg, 0); 1360 } else { 1361 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1362 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1363 TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff); 1364 1365 /* arg = abcd */ 1366 tcg_gen_shri_i32(t0, arg, 8); /* t0 = .abc */ 1367 tcg_gen_and_i32(t1, arg, t2); /* t1 = .b.d */ 1368 tcg_gen_and_i32(t0, t0, t2); /* t0 = .a.c */ 1369 tcg_gen_shli_i32(t1, t1, 8); /* t1 = b.d. */ 1370 tcg_gen_or_i32(ret, t0, t1); /* ret = badc */ 1371 1372 tcg_gen_shri_i32(t0, ret, 16); /* t0 = ..ba */ 1373 tcg_gen_shli_i32(t1, ret, 16); /* t1 = dc.. */ 1374 tcg_gen_or_i32(ret, t0, t1); /* ret = dcba */ 1375 1376 tcg_temp_free_i32(t0); 1377 tcg_temp_free_i32(t1); 1378 } 1379 } 1380 1381 /* 1382 * hswap_i32: Swap 16-bit halfwords within a 32-bit value. 1383 * 1384 * Byte pattern: abcd -> cdab 1385 */ 1386 void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg) 1387 { 1388 /* Swapping 2 16-bit elements is a rotate. */ 1389 tcg_gen_rotli_i32(ret, arg, 16); 1390 } 1391 1392 void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1393 { 1394 tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b); 1395 } 1396 1397 void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1398 { 1399 tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b); 1400 } 1401 1402 void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1403 { 1404 tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a); 1405 } 1406 1407 void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1408 { 1409 tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a); 1410 } 1411 1412 void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a) 1413 { 1414 TCGv_i32 t = tcg_temp_ebb_new_i32(); 1415 1416 tcg_gen_sari_i32(t, a, 31); 1417 tcg_gen_xor_i32(ret, a, t); 1418 tcg_gen_sub_i32(ret, ret, t); 1419 tcg_temp_free_i32(t); 1420 } 1421 1422 void tcg_gen_ld8u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1423 { 1424 tcg_gen_ldst_op_i32(INDEX_op_ld8u_i32, ret, arg2, offset); 1425 } 1426 1427 void tcg_gen_ld8s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1428 { 1429 tcg_gen_ldst_op_i32(INDEX_op_ld8s_i32, ret, arg2, offset); 1430 } 1431 1432 void tcg_gen_ld16u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1433 { 1434 tcg_gen_ldst_op_i32(INDEX_op_ld16u_i32, ret, arg2, offset); 1435 } 1436 1437 void tcg_gen_ld16s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1438 { 1439 tcg_gen_ldst_op_i32(INDEX_op_ld16s_i32, ret, arg2, offset); 1440 } 1441 1442 void tcg_gen_ld_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1443 { 1444 tcg_gen_ldst_op_i32(INDEX_op_ld_i32, ret, arg2, offset); 1445 } 1446 1447 void tcg_gen_st8_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset) 1448 { 1449 tcg_gen_ldst_op_i32(INDEX_op_st8_i32, arg1, arg2, offset); 1450 } 1451 1452 void tcg_gen_st16_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset) 1453 { 1454 tcg_gen_ldst_op_i32(INDEX_op_st16_i32, arg1, arg2, offset); 1455 } 1456 1457 void tcg_gen_st_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset) 1458 { 1459 tcg_gen_ldst_op_i32(INDEX_op_st_i32, arg1, arg2, offset); 1460 } 1461 1462 1463 /* 64-bit ops */ 1464 1465 void tcg_gen_discard_i64(TCGv_i64 arg) 1466 { 1467 if (TCG_TARGET_REG_BITS == 64) { 1468 tcg_gen_op1_i64(INDEX_op_discard, arg); 1469 } else { 1470 tcg_gen_discard_i32(TCGV_LOW(arg)); 1471 tcg_gen_discard_i32(TCGV_HIGH(arg)); 1472 } 1473 } 1474 1475 void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg) 1476 { 1477 if (ret == arg) { 1478 return; 1479 } 1480 if (TCG_TARGET_REG_BITS == 64) { 1481 tcg_gen_op2_i64(INDEX_op_mov_i64, ret, arg); 1482 } else { 1483 TCGTemp *ts = tcgv_i64_temp(arg); 1484 1485 /* Canonicalize TCGv_i64 TEMP_CONST into TCGv_i32 TEMP_CONST. */ 1486 if (ts->kind == TEMP_CONST) { 1487 tcg_gen_movi_i64(ret, ts->val); 1488 } else { 1489 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1490 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 1491 } 1492 } 1493 } 1494 1495 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg) 1496 { 1497 if (TCG_TARGET_REG_BITS == 64) { 1498 tcg_gen_mov_i64(ret, tcg_constant_i64(arg)); 1499 } else { 1500 tcg_gen_movi_i32(TCGV_LOW(ret), arg); 1501 tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32); 1502 } 1503 } 1504 1505 void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1506 { 1507 if (TCG_TARGET_REG_BITS == 64) { 1508 tcg_gen_ldst_op_i64(INDEX_op_ld8u_i64, ret, arg2, offset); 1509 } else { 1510 tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset); 1511 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1512 } 1513 } 1514 1515 void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1516 { 1517 if (TCG_TARGET_REG_BITS == 64) { 1518 tcg_gen_ldst_op_i64(INDEX_op_ld8s_i64, ret, arg2, offset); 1519 } else { 1520 tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset); 1521 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1522 } 1523 } 1524 1525 void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1526 { 1527 if (TCG_TARGET_REG_BITS == 64) { 1528 tcg_gen_ldst_op_i64(INDEX_op_ld16u_i64, ret, arg2, offset); 1529 } else { 1530 tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset); 1531 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1532 } 1533 } 1534 1535 void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1536 { 1537 if (TCG_TARGET_REG_BITS == 64) { 1538 tcg_gen_ldst_op_i64(INDEX_op_ld16s_i64, ret, arg2, offset); 1539 } else { 1540 tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset); 1541 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1542 } 1543 } 1544 1545 void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1546 { 1547 if (TCG_TARGET_REG_BITS == 64) { 1548 tcg_gen_ldst_op_i64(INDEX_op_ld32u_i64, ret, arg2, offset); 1549 } else { 1550 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 1551 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1552 } 1553 } 1554 1555 void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1556 { 1557 if (TCG_TARGET_REG_BITS == 64) { 1558 tcg_gen_ldst_op_i64(INDEX_op_ld32s_i64, ret, arg2, offset); 1559 } else { 1560 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 1561 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1562 } 1563 } 1564 1565 void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1566 { 1567 /* 1568 * For 32-bit host, since arg2 and ret have different types, 1569 * they cannot be the same temporary -- no chance of overlap. 1570 */ 1571 if (TCG_TARGET_REG_BITS == 64) { 1572 tcg_gen_ldst_op_i64(INDEX_op_ld_i64, ret, arg2, offset); 1573 } else if (HOST_BIG_ENDIAN) { 1574 tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset); 1575 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4); 1576 } else { 1577 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 1578 tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4); 1579 } 1580 } 1581 1582 void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1583 { 1584 if (TCG_TARGET_REG_BITS == 64) { 1585 tcg_gen_ldst_op_i64(INDEX_op_st8_i64, arg1, arg2, offset); 1586 } else { 1587 tcg_gen_st8_i32(TCGV_LOW(arg1), arg2, offset); 1588 } 1589 } 1590 1591 void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1592 { 1593 if (TCG_TARGET_REG_BITS == 64) { 1594 tcg_gen_ldst_op_i64(INDEX_op_st16_i64, arg1, arg2, offset); 1595 } else { 1596 tcg_gen_st16_i32(TCGV_LOW(arg1), arg2, offset); 1597 } 1598 } 1599 1600 void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1601 { 1602 if (TCG_TARGET_REG_BITS == 64) { 1603 tcg_gen_ldst_op_i64(INDEX_op_st32_i64, arg1, arg2, offset); 1604 } else { 1605 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset); 1606 } 1607 } 1608 1609 void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1610 { 1611 if (TCG_TARGET_REG_BITS == 64) { 1612 tcg_gen_ldst_op_i64(INDEX_op_st_i64, arg1, arg2, offset); 1613 } else if (HOST_BIG_ENDIAN) { 1614 tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset); 1615 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4); 1616 } else { 1617 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset); 1618 tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4); 1619 } 1620 } 1621 1622 void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1623 { 1624 if (TCG_TARGET_REG_BITS == 64) { 1625 tcg_gen_op3_i64(INDEX_op_add_i64, ret, arg1, arg2); 1626 } else { 1627 tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1), 1628 TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2)); 1629 } 1630 } 1631 1632 void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1633 { 1634 if (TCG_TARGET_REG_BITS == 64) { 1635 tcg_gen_op3_i64(INDEX_op_sub_i64, ret, arg1, arg2); 1636 } else { 1637 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1), 1638 TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2)); 1639 } 1640 } 1641 1642 void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1643 { 1644 if (TCG_TARGET_REG_BITS == 64) { 1645 tcg_gen_op3_i64(INDEX_op_and_i64, ret, arg1, arg2); 1646 } else { 1647 tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1648 tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1649 } 1650 } 1651 1652 void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1653 { 1654 if (TCG_TARGET_REG_BITS == 64) { 1655 tcg_gen_op3_i64(INDEX_op_or_i64, ret, arg1, arg2); 1656 } else { 1657 tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1658 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1659 } 1660 } 1661 1662 void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1663 { 1664 if (TCG_TARGET_REG_BITS == 64) { 1665 tcg_gen_op3_i64(INDEX_op_xor_i64, ret, arg1, arg2); 1666 } else { 1667 tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1668 tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1669 } 1670 } 1671 1672 void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1673 { 1674 if (TCG_TARGET_REG_BITS == 64) { 1675 tcg_gen_op3_i64(INDEX_op_shl_i64, ret, arg1, arg2); 1676 } else { 1677 gen_helper_shl_i64(ret, arg1, arg2); 1678 } 1679 } 1680 1681 void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1682 { 1683 if (TCG_TARGET_REG_BITS == 64) { 1684 tcg_gen_op3_i64(INDEX_op_shr_i64, ret, arg1, arg2); 1685 } else { 1686 gen_helper_shr_i64(ret, arg1, arg2); 1687 } 1688 } 1689 1690 void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1691 { 1692 if (TCG_TARGET_REG_BITS == 64) { 1693 tcg_gen_op3_i64(INDEX_op_sar_i64, ret, arg1, arg2); 1694 } else { 1695 gen_helper_sar_i64(ret, arg1, arg2); 1696 } 1697 } 1698 1699 void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1700 { 1701 TCGv_i64 t0; 1702 TCGv_i32 t1; 1703 1704 if (TCG_TARGET_REG_BITS == 64) { 1705 tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2); 1706 return; 1707 } 1708 1709 1710 t0 = tcg_temp_ebb_new_i64(); 1711 t1 = tcg_temp_ebb_new_i32(); 1712 1713 tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0), 1714 TCGV_LOW(arg1), TCGV_LOW(arg2)); 1715 1716 tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2)); 1717 tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 1718 tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2)); 1719 tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 1720 1721 tcg_gen_mov_i64(ret, t0); 1722 tcg_temp_free_i64(t0); 1723 tcg_temp_free_i32(t1); 1724 } 1725 1726 void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1727 { 1728 /* some cases can be optimized here */ 1729 if (arg2 == 0) { 1730 tcg_gen_mov_i64(ret, arg1); 1731 } else if (TCG_TARGET_REG_BITS == 64) { 1732 tcg_gen_add_i64(ret, arg1, tcg_constant_i64(arg2)); 1733 } else { 1734 tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1735 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1736 tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32)); 1737 } 1738 } 1739 1740 void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2) 1741 { 1742 if (arg1 == 0) { 1743 tcg_gen_neg_i64(ret, arg2); 1744 } else if (TCG_TARGET_REG_BITS == 64) { 1745 tcg_gen_sub_i64(ret, tcg_constant_i64(arg1), arg2); 1746 } else { 1747 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1748 tcg_constant_i32(arg1), tcg_constant_i32(arg1 >> 32), 1749 TCGV_LOW(arg2), TCGV_HIGH(arg2)); 1750 } 1751 } 1752 1753 void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1754 { 1755 /* some cases can be optimized here */ 1756 if (arg2 == 0) { 1757 tcg_gen_mov_i64(ret, arg1); 1758 } else if (TCG_TARGET_REG_BITS == 64) { 1759 tcg_gen_sub_i64(ret, arg1, tcg_constant_i64(arg2)); 1760 } else { 1761 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1762 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1763 tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32)); 1764 } 1765 } 1766 1767 void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg) 1768 { 1769 if (TCG_TARGET_REG_BITS == 64) { 1770 tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg); 1771 } else { 1772 TCGv_i32 zero = tcg_constant_i32(0); 1773 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1774 zero, zero, TCGV_LOW(arg), TCGV_HIGH(arg)); 1775 } 1776 } 1777 1778 void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1779 { 1780 if (TCG_TARGET_REG_BITS == 32) { 1781 tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 1782 tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 1783 return; 1784 } 1785 1786 /* Some cases can be optimized here. */ 1787 switch (arg2) { 1788 case 0: 1789 tcg_gen_movi_i64(ret, 0); 1790 return; 1791 case -1: 1792 tcg_gen_mov_i64(ret, arg1); 1793 return; 1794 case 0xff: 1795 /* Don't recurse with tcg_gen_ext8u_i64. */ 1796 if (TCG_TARGET_HAS_ext8u_i64) { 1797 tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1); 1798 return; 1799 } 1800 break; 1801 case 0xffff: 1802 if (TCG_TARGET_HAS_ext16u_i64) { 1803 tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1); 1804 return; 1805 } 1806 break; 1807 case 0xffffffffu: 1808 if (TCG_TARGET_HAS_ext32u_i64) { 1809 tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1); 1810 return; 1811 } 1812 break; 1813 } 1814 1815 tcg_gen_and_i64(ret, arg1, tcg_constant_i64(arg2)); 1816 } 1817 1818 void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1819 { 1820 if (TCG_TARGET_REG_BITS == 32) { 1821 tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 1822 tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 1823 return; 1824 } 1825 /* Some cases can be optimized here. */ 1826 if (arg2 == -1) { 1827 tcg_gen_movi_i64(ret, -1); 1828 } else if (arg2 == 0) { 1829 tcg_gen_mov_i64(ret, arg1); 1830 } else { 1831 tcg_gen_or_i64(ret, arg1, tcg_constant_i64(arg2)); 1832 } 1833 } 1834 1835 void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1836 { 1837 if (TCG_TARGET_REG_BITS == 32) { 1838 tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 1839 tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 1840 return; 1841 } 1842 /* Some cases can be optimized here. */ 1843 if (arg2 == 0) { 1844 tcg_gen_mov_i64(ret, arg1); 1845 } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) { 1846 /* Don't recurse with tcg_gen_not_i64. */ 1847 tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1); 1848 } else { 1849 tcg_gen_xor_i64(ret, arg1, tcg_constant_i64(arg2)); 1850 } 1851 } 1852 1853 static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, 1854 unsigned c, bool right, bool arith) 1855 { 1856 tcg_debug_assert(c < 64); 1857 if (c == 0) { 1858 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 1859 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 1860 } else if (c >= 32) { 1861 c -= 32; 1862 if (right) { 1863 if (arith) { 1864 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1865 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31); 1866 } else { 1867 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1868 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1869 } 1870 } else { 1871 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c); 1872 tcg_gen_movi_i32(TCGV_LOW(ret), 0); 1873 } 1874 } else if (right) { 1875 if (TCG_TARGET_HAS_extract2_i32) { 1876 tcg_gen_extract2_i32(TCGV_LOW(ret), 1877 TCGV_LOW(arg1), TCGV_HIGH(arg1), c); 1878 } else { 1879 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c); 1880 tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(ret), 1881 TCGV_HIGH(arg1), 32 - c, c); 1882 } 1883 if (arith) { 1884 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c); 1885 } else { 1886 tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c); 1887 } 1888 } else { 1889 if (TCG_TARGET_HAS_extract2_i32) { 1890 tcg_gen_extract2_i32(TCGV_HIGH(ret), 1891 TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c); 1892 } else { 1893 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1894 tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c); 1895 tcg_gen_deposit_i32(TCGV_HIGH(ret), t0, 1896 TCGV_HIGH(arg1), c, 32 - c); 1897 tcg_temp_free_i32(t0); 1898 } 1899 tcg_gen_shli_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c); 1900 } 1901 } 1902 1903 void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1904 { 1905 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 1906 if (TCG_TARGET_REG_BITS == 32) { 1907 tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0); 1908 } else if (arg2 == 0) { 1909 tcg_gen_mov_i64(ret, arg1); 1910 } else { 1911 tcg_gen_shl_i64(ret, arg1, tcg_constant_i64(arg2)); 1912 } 1913 } 1914 1915 void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1916 { 1917 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 1918 if (TCG_TARGET_REG_BITS == 32) { 1919 tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0); 1920 } else if (arg2 == 0) { 1921 tcg_gen_mov_i64(ret, arg1); 1922 } else { 1923 tcg_gen_shr_i64(ret, arg1, tcg_constant_i64(arg2)); 1924 } 1925 } 1926 1927 void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1928 { 1929 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 1930 if (TCG_TARGET_REG_BITS == 32) { 1931 tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1); 1932 } else if (arg2 == 0) { 1933 tcg_gen_mov_i64(ret, arg1); 1934 } else { 1935 tcg_gen_sar_i64(ret, arg1, tcg_constant_i64(arg2)); 1936 } 1937 } 1938 1939 void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l) 1940 { 1941 if (cond == TCG_COND_ALWAYS) { 1942 tcg_gen_br(l); 1943 } else if (cond != TCG_COND_NEVER) { 1944 if (TCG_TARGET_REG_BITS == 32) { 1945 tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1), 1946 TCGV_HIGH(arg1), TCGV_LOW(arg2), 1947 TCGV_HIGH(arg2), cond, label_arg(l)); 1948 } else { 1949 tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, 1950 label_arg(l)); 1951 } 1952 add_last_as_label_use(l); 1953 } 1954 } 1955 1956 void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l) 1957 { 1958 if (TCG_TARGET_REG_BITS == 64) { 1959 tcg_gen_brcond_i64(cond, arg1, tcg_constant_i64(arg2), l); 1960 } else if (cond == TCG_COND_ALWAYS) { 1961 tcg_gen_br(l); 1962 } else if (cond != TCG_COND_NEVER) { 1963 tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, 1964 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1965 tcg_constant_i32(arg2), 1966 tcg_constant_i32(arg2 >> 32), 1967 cond, label_arg(l)); 1968 add_last_as_label_use(l); 1969 } 1970 } 1971 1972 void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret, 1973 TCGv_i64 arg1, TCGv_i64 arg2) 1974 { 1975 if (cond == TCG_COND_ALWAYS) { 1976 tcg_gen_movi_i64(ret, 1); 1977 } else if (cond == TCG_COND_NEVER) { 1978 tcg_gen_movi_i64(ret, 0); 1979 } else { 1980 if (TCG_TARGET_REG_BITS == 32) { 1981 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 1982 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1983 TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); 1984 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1985 } else { 1986 tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond); 1987 } 1988 } 1989 } 1990 1991 void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret, 1992 TCGv_i64 arg1, int64_t arg2) 1993 { 1994 if (TCG_TARGET_REG_BITS == 64) { 1995 tcg_gen_setcond_i64(cond, ret, arg1, tcg_constant_i64(arg2)); 1996 } else if (cond == TCG_COND_ALWAYS) { 1997 tcg_gen_movi_i64(ret, 1); 1998 } else if (cond == TCG_COND_NEVER) { 1999 tcg_gen_movi_i64(ret, 0); 2000 } else { 2001 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 2002 TCGV_LOW(arg1), TCGV_HIGH(arg1), 2003 tcg_constant_i32(arg2), 2004 tcg_constant_i32(arg2 >> 32), cond); 2005 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2006 } 2007 } 2008 2009 void tcg_gen_negsetcondi_i64(TCGCond cond, TCGv_i64 ret, 2010 TCGv_i64 arg1, int64_t arg2) 2011 { 2012 tcg_gen_negsetcond_i64(cond, ret, arg1, tcg_constant_i64(arg2)); 2013 } 2014 2015 void tcg_gen_negsetcond_i64(TCGCond cond, TCGv_i64 ret, 2016 TCGv_i64 arg1, TCGv_i64 arg2) 2017 { 2018 if (cond == TCG_COND_ALWAYS) { 2019 tcg_gen_movi_i64(ret, -1); 2020 } else if (cond == TCG_COND_NEVER) { 2021 tcg_gen_movi_i64(ret, 0); 2022 } else if (TCG_TARGET_HAS_negsetcond_i64) { 2023 tcg_gen_op4i_i64(INDEX_op_negsetcond_i64, ret, arg1, arg2, cond); 2024 } else if (TCG_TARGET_REG_BITS == 32) { 2025 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 2026 TCGV_LOW(arg1), TCGV_HIGH(arg1), 2027 TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); 2028 tcg_gen_neg_i32(TCGV_LOW(ret), TCGV_LOW(ret)); 2029 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_LOW(ret)); 2030 } else { 2031 tcg_gen_setcond_i64(cond, ret, arg1, arg2); 2032 tcg_gen_neg_i64(ret, ret); 2033 } 2034 } 2035 2036 void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 2037 { 2038 if (arg2 == 0) { 2039 tcg_gen_movi_i64(ret, 0); 2040 } else if (is_power_of_2(arg2)) { 2041 tcg_gen_shli_i64(ret, arg1, ctz64(arg2)); 2042 } else { 2043 tcg_gen_mul_i64(ret, arg1, tcg_constant_i64(arg2)); 2044 } 2045 } 2046 2047 void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2048 { 2049 if (TCG_TARGET_HAS_div_i64) { 2050 tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2); 2051 } else if (TCG_TARGET_HAS_div2_i64) { 2052 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2053 tcg_gen_sari_i64(t0, arg1, 63); 2054 tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2); 2055 tcg_temp_free_i64(t0); 2056 } else { 2057 gen_helper_div_i64(ret, arg1, arg2); 2058 } 2059 } 2060 2061 void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2062 { 2063 if (TCG_TARGET_HAS_rem_i64) { 2064 tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2); 2065 } else if (TCG_TARGET_HAS_div_i64) { 2066 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2067 tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2); 2068 tcg_gen_mul_i64(t0, t0, arg2); 2069 tcg_gen_sub_i64(ret, arg1, t0); 2070 tcg_temp_free_i64(t0); 2071 } else if (TCG_TARGET_HAS_div2_i64) { 2072 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2073 tcg_gen_sari_i64(t0, arg1, 63); 2074 tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2); 2075 tcg_temp_free_i64(t0); 2076 } else { 2077 gen_helper_rem_i64(ret, arg1, arg2); 2078 } 2079 } 2080 2081 void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2082 { 2083 if (TCG_TARGET_HAS_div_i64) { 2084 tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2); 2085 } else if (TCG_TARGET_HAS_div2_i64) { 2086 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2087 TCGv_i64 zero = tcg_constant_i64(0); 2088 tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, zero, arg2); 2089 tcg_temp_free_i64(t0); 2090 } else { 2091 gen_helper_divu_i64(ret, arg1, arg2); 2092 } 2093 } 2094 2095 void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2096 { 2097 if (TCG_TARGET_HAS_rem_i64) { 2098 tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2); 2099 } else if (TCG_TARGET_HAS_div_i64) { 2100 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2101 tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2); 2102 tcg_gen_mul_i64(t0, t0, arg2); 2103 tcg_gen_sub_i64(ret, arg1, t0); 2104 tcg_temp_free_i64(t0); 2105 } else if (TCG_TARGET_HAS_div2_i64) { 2106 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2107 TCGv_i64 zero = tcg_constant_i64(0); 2108 tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, zero, arg2); 2109 tcg_temp_free_i64(t0); 2110 } else { 2111 gen_helper_remu_i64(ret, arg1, arg2); 2112 } 2113 } 2114 2115 void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg) 2116 { 2117 if (TCG_TARGET_REG_BITS == 32) { 2118 tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2119 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2120 } else if (TCG_TARGET_HAS_ext8s_i64) { 2121 tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg); 2122 } else { 2123 tcg_gen_shli_i64(ret, arg, 56); 2124 tcg_gen_sari_i64(ret, ret, 56); 2125 } 2126 } 2127 2128 void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg) 2129 { 2130 if (TCG_TARGET_REG_BITS == 32) { 2131 tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2132 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2133 } else if (TCG_TARGET_HAS_ext16s_i64) { 2134 tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg); 2135 } else { 2136 tcg_gen_shli_i64(ret, arg, 48); 2137 tcg_gen_sari_i64(ret, ret, 48); 2138 } 2139 } 2140 2141 void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg) 2142 { 2143 if (TCG_TARGET_REG_BITS == 32) { 2144 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2145 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2146 } else if (TCG_TARGET_HAS_ext32s_i64) { 2147 tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg); 2148 } else { 2149 tcg_gen_shli_i64(ret, arg, 32); 2150 tcg_gen_sari_i64(ret, ret, 32); 2151 } 2152 } 2153 2154 void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg) 2155 { 2156 if (TCG_TARGET_REG_BITS == 32) { 2157 tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2158 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2159 } else if (TCG_TARGET_HAS_ext8u_i64) { 2160 tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg); 2161 } else { 2162 tcg_gen_andi_i64(ret, arg, 0xffu); 2163 } 2164 } 2165 2166 void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg) 2167 { 2168 if (TCG_TARGET_REG_BITS == 32) { 2169 tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2170 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2171 } else if (TCG_TARGET_HAS_ext16u_i64) { 2172 tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg); 2173 } else { 2174 tcg_gen_andi_i64(ret, arg, 0xffffu); 2175 } 2176 } 2177 2178 void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg) 2179 { 2180 if (TCG_TARGET_REG_BITS == 32) { 2181 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2182 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2183 } else if (TCG_TARGET_HAS_ext32u_i64) { 2184 tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg); 2185 } else { 2186 tcg_gen_andi_i64(ret, arg, 0xffffffffu); 2187 } 2188 } 2189 2190 /* 2191 * bswap16_i64: 16-bit byte swap on the low bits of a 64-bit value. 2192 * 2193 * Byte pattern: xxxxxxxxab -> yyyyyyyyba 2194 * 2195 * With TCG_BSWAP_IZ, x == zero, else undefined. 2196 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined. 2197 */ 2198 void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags) 2199 { 2200 /* Only one extension flag may be present. */ 2201 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ)); 2202 2203 if (TCG_TARGET_REG_BITS == 32) { 2204 tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg), flags); 2205 if (flags & TCG_BSWAP_OS) { 2206 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2207 } else { 2208 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2209 } 2210 } else if (TCG_TARGET_HAS_bswap16_i64) { 2211 tcg_gen_op3i_i64(INDEX_op_bswap16_i64, ret, arg, flags); 2212 } else { 2213 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2214 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2215 2216 /* arg = ......ab or xxxxxxab */ 2217 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .......a or .xxxxxxa */ 2218 if (!(flags & TCG_BSWAP_IZ)) { 2219 tcg_gen_ext8u_i64(t0, t0); /* t0 = .......a */ 2220 } 2221 2222 if (flags & TCG_BSWAP_OS) { 2223 tcg_gen_shli_i64(t1, arg, 56); /* t1 = b....... */ 2224 tcg_gen_sari_i64(t1, t1, 48); /* t1 = ssssssb. */ 2225 } else if (flags & TCG_BSWAP_OZ) { 2226 tcg_gen_ext8u_i64(t1, arg); /* t1 = .......b */ 2227 tcg_gen_shli_i64(t1, t1, 8); /* t1 = ......b. */ 2228 } else { 2229 tcg_gen_shli_i64(t1, arg, 8); /* t1 = xxxxxab. */ 2230 } 2231 2232 tcg_gen_or_i64(ret, t0, t1); /* ret = ......ba (OZ) */ 2233 /* ssssssba (OS) */ 2234 /* xxxxxaba (no flag) */ 2235 tcg_temp_free_i64(t0); 2236 tcg_temp_free_i64(t1); 2237 } 2238 } 2239 2240 /* 2241 * bswap32_i64: 32-bit byte swap on the low bits of a 64-bit value. 2242 * 2243 * Byte pattern: xxxxabcd -> yyyydcba 2244 * 2245 * With TCG_BSWAP_IZ, x == zero, else undefined. 2246 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined. 2247 */ 2248 void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags) 2249 { 2250 /* Only one extension flag may be present. */ 2251 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ)); 2252 2253 if (TCG_TARGET_REG_BITS == 32) { 2254 tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2255 if (flags & TCG_BSWAP_OS) { 2256 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2257 } else { 2258 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2259 } 2260 } else if (TCG_TARGET_HAS_bswap32_i64) { 2261 tcg_gen_op3i_i64(INDEX_op_bswap32_i64, ret, arg, flags); 2262 } else { 2263 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2264 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2265 TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff); 2266 2267 /* arg = xxxxabcd */ 2268 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .xxxxabc */ 2269 tcg_gen_and_i64(t1, arg, t2); /* t1 = .....b.d */ 2270 tcg_gen_and_i64(t0, t0, t2); /* t0 = .....a.c */ 2271 tcg_gen_shli_i64(t1, t1, 8); /* t1 = ....b.d. */ 2272 tcg_gen_or_i64(ret, t0, t1); /* ret = ....badc */ 2273 2274 tcg_gen_shli_i64(t1, ret, 48); /* t1 = dc...... */ 2275 tcg_gen_shri_i64(t0, ret, 16); /* t0 = ......ba */ 2276 if (flags & TCG_BSWAP_OS) { 2277 tcg_gen_sari_i64(t1, t1, 32); /* t1 = ssssdc.. */ 2278 } else { 2279 tcg_gen_shri_i64(t1, t1, 32); /* t1 = ....dc.. */ 2280 } 2281 tcg_gen_or_i64(ret, t0, t1); /* ret = ssssdcba (OS) */ 2282 /* ....dcba (else) */ 2283 2284 tcg_temp_free_i64(t0); 2285 tcg_temp_free_i64(t1); 2286 } 2287 } 2288 2289 /* 2290 * bswap64_i64: 64-bit byte swap on a 64-bit value. 2291 * 2292 * Byte pattern: abcdefgh -> hgfedcba 2293 */ 2294 void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) 2295 { 2296 if (TCG_TARGET_REG_BITS == 32) { 2297 TCGv_i32 t0, t1; 2298 t0 = tcg_temp_ebb_new_i32(); 2299 t1 = tcg_temp_ebb_new_i32(); 2300 2301 tcg_gen_bswap32_i32(t0, TCGV_LOW(arg)); 2302 tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg)); 2303 tcg_gen_mov_i32(TCGV_LOW(ret), t1); 2304 tcg_gen_mov_i32(TCGV_HIGH(ret), t0); 2305 tcg_temp_free_i32(t0); 2306 tcg_temp_free_i32(t1); 2307 } else if (TCG_TARGET_HAS_bswap64_i64) { 2308 tcg_gen_op3i_i64(INDEX_op_bswap64_i64, ret, arg, 0); 2309 } else { 2310 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2311 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2312 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 2313 2314 /* arg = abcdefgh */ 2315 tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull); 2316 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .abcdefg */ 2317 tcg_gen_and_i64(t1, arg, t2); /* t1 = .b.d.f.h */ 2318 tcg_gen_and_i64(t0, t0, t2); /* t0 = .a.c.e.g */ 2319 tcg_gen_shli_i64(t1, t1, 8); /* t1 = b.d.f.h. */ 2320 tcg_gen_or_i64(ret, t0, t1); /* ret = badcfehg */ 2321 2322 tcg_gen_movi_i64(t2, 0x0000ffff0000ffffull); 2323 tcg_gen_shri_i64(t0, ret, 16); /* t0 = ..badcfe */ 2324 tcg_gen_and_i64(t1, ret, t2); /* t1 = ..dc..hg */ 2325 tcg_gen_and_i64(t0, t0, t2); /* t0 = ..ba..fe */ 2326 tcg_gen_shli_i64(t1, t1, 16); /* t1 = dc..hg.. */ 2327 tcg_gen_or_i64(ret, t0, t1); /* ret = dcbahgfe */ 2328 2329 tcg_gen_shri_i64(t0, ret, 32); /* t0 = ....dcba */ 2330 tcg_gen_shli_i64(t1, ret, 32); /* t1 = hgfe.... */ 2331 tcg_gen_or_i64(ret, t0, t1); /* ret = hgfedcba */ 2332 2333 tcg_temp_free_i64(t0); 2334 tcg_temp_free_i64(t1); 2335 tcg_temp_free_i64(t2); 2336 } 2337 } 2338 2339 /* 2340 * hswap_i64: Swap 16-bit halfwords within a 64-bit value. 2341 * See also include/qemu/bitops.h, hswap64. 2342 * 2343 * Byte pattern: abcdefgh -> ghefcdab 2344 */ 2345 void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg) 2346 { 2347 uint64_t m = 0x0000ffff0000ffffull; 2348 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2349 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2350 2351 /* arg = abcdefgh */ 2352 tcg_gen_rotli_i64(t1, arg, 32); /* t1 = efghabcd */ 2353 tcg_gen_andi_i64(t0, t1, m); /* t0 = ..gh..cd */ 2354 tcg_gen_shli_i64(t0, t0, 16); /* t0 = gh..cd.. */ 2355 tcg_gen_shri_i64(t1, t1, 16); /* t1 = ..efghab */ 2356 tcg_gen_andi_i64(t1, t1, m); /* t1 = ..ef..ab */ 2357 tcg_gen_or_i64(ret, t0, t1); /* ret = ghefcdab */ 2358 2359 tcg_temp_free_i64(t0); 2360 tcg_temp_free_i64(t1); 2361 } 2362 2363 /* 2364 * wswap_i64: Swap 32-bit words within a 64-bit value. 2365 * 2366 * Byte pattern: abcdefgh -> efghabcd 2367 */ 2368 void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg) 2369 { 2370 /* Swapping 2 32-bit elements is a rotate. */ 2371 tcg_gen_rotli_i64(ret, arg, 32); 2372 } 2373 2374 void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg) 2375 { 2376 if (TCG_TARGET_REG_BITS == 32) { 2377 tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2378 tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 2379 } else if (TCG_TARGET_HAS_not_i64) { 2380 tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg); 2381 } else { 2382 tcg_gen_xori_i64(ret, arg, -1); 2383 } 2384 } 2385 2386 void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2387 { 2388 if (TCG_TARGET_REG_BITS == 32) { 2389 tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2390 tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2391 } else if (TCG_TARGET_HAS_andc_i64) { 2392 tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2); 2393 } else { 2394 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2395 tcg_gen_not_i64(t0, arg2); 2396 tcg_gen_and_i64(ret, arg1, t0); 2397 tcg_temp_free_i64(t0); 2398 } 2399 } 2400 2401 void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2402 { 2403 if (TCG_TARGET_REG_BITS == 32) { 2404 tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2405 tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2406 } else if (TCG_TARGET_HAS_eqv_i64) { 2407 tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2); 2408 } else { 2409 tcg_gen_xor_i64(ret, arg1, arg2); 2410 tcg_gen_not_i64(ret, ret); 2411 } 2412 } 2413 2414 void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2415 { 2416 if (TCG_TARGET_REG_BITS == 32) { 2417 tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2418 tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2419 } else if (TCG_TARGET_HAS_nand_i64) { 2420 tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2); 2421 } else { 2422 tcg_gen_and_i64(ret, arg1, arg2); 2423 tcg_gen_not_i64(ret, ret); 2424 } 2425 } 2426 2427 void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2428 { 2429 if (TCG_TARGET_REG_BITS == 32) { 2430 tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2431 tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2432 } else if (TCG_TARGET_HAS_nor_i64) { 2433 tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2); 2434 } else { 2435 tcg_gen_or_i64(ret, arg1, arg2); 2436 tcg_gen_not_i64(ret, ret); 2437 } 2438 } 2439 2440 void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2441 { 2442 if (TCG_TARGET_REG_BITS == 32) { 2443 tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2444 tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2445 } else if (TCG_TARGET_HAS_orc_i64) { 2446 tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2); 2447 } else { 2448 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2449 tcg_gen_not_i64(t0, arg2); 2450 tcg_gen_or_i64(ret, arg1, t0); 2451 tcg_temp_free_i64(t0); 2452 } 2453 } 2454 2455 void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2456 { 2457 if (TCG_TARGET_HAS_clz_i64) { 2458 tcg_gen_op3_i64(INDEX_op_clz_i64, ret, arg1, arg2); 2459 } else { 2460 gen_helper_clz_i64(ret, arg1, arg2); 2461 } 2462 } 2463 2464 void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) 2465 { 2466 if (TCG_TARGET_REG_BITS == 32 2467 && TCG_TARGET_HAS_clz_i32 2468 && arg2 <= 0xffffffffu) { 2469 TCGv_i32 t = tcg_temp_ebb_new_i32(); 2470 tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32); 2471 tcg_gen_addi_i32(t, t, 32); 2472 tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t); 2473 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2474 tcg_temp_free_i32(t); 2475 } else { 2476 tcg_gen_clz_i64(ret, arg1, tcg_constant_i64(arg2)); 2477 } 2478 } 2479 2480 void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2481 { 2482 if (TCG_TARGET_HAS_ctz_i64) { 2483 tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2); 2484 } else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) { 2485 TCGv_i64 z, t = tcg_temp_ebb_new_i64(); 2486 2487 if (TCG_TARGET_HAS_ctpop_i64) { 2488 tcg_gen_subi_i64(t, arg1, 1); 2489 tcg_gen_andc_i64(t, t, arg1); 2490 tcg_gen_ctpop_i64(t, t); 2491 } else { 2492 /* Since all non-x86 hosts have clz(0) == 64, don't fight it. */ 2493 tcg_gen_neg_i64(t, arg1); 2494 tcg_gen_and_i64(t, t, arg1); 2495 tcg_gen_clzi_i64(t, t, 64); 2496 tcg_gen_xori_i64(t, t, 63); 2497 } 2498 z = tcg_constant_i64(0); 2499 tcg_gen_movcond_i64(TCG_COND_EQ, ret, arg1, z, arg2, t); 2500 tcg_temp_free_i64(t); 2501 tcg_temp_free_i64(z); 2502 } else { 2503 gen_helper_ctz_i64(ret, arg1, arg2); 2504 } 2505 } 2506 2507 void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) 2508 { 2509 if (TCG_TARGET_REG_BITS == 32 2510 && TCG_TARGET_HAS_ctz_i32 2511 && arg2 <= 0xffffffffu) { 2512 TCGv_i32 t32 = tcg_temp_ebb_new_i32(); 2513 tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32); 2514 tcg_gen_addi_i32(t32, t32, 32); 2515 tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32); 2516 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2517 tcg_temp_free_i32(t32); 2518 } else if (!TCG_TARGET_HAS_ctz_i64 2519 && TCG_TARGET_HAS_ctpop_i64 2520 && arg2 == 64) { 2521 /* This equivalence has the advantage of not requiring a fixup. */ 2522 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2523 tcg_gen_subi_i64(t, arg1, 1); 2524 tcg_gen_andc_i64(t, t, arg1); 2525 tcg_gen_ctpop_i64(ret, t); 2526 tcg_temp_free_i64(t); 2527 } else { 2528 tcg_gen_ctz_i64(ret, arg1, tcg_constant_i64(arg2)); 2529 } 2530 } 2531 2532 void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg) 2533 { 2534 if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) { 2535 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2536 tcg_gen_sari_i64(t, arg, 63); 2537 tcg_gen_xor_i64(t, t, arg); 2538 tcg_gen_clzi_i64(t, t, 64); 2539 tcg_gen_subi_i64(ret, t, 1); 2540 tcg_temp_free_i64(t); 2541 } else { 2542 gen_helper_clrsb_i64(ret, arg); 2543 } 2544 } 2545 2546 void tcg_gen_ctpop_i64(TCGv_i64 ret, TCGv_i64 arg1) 2547 { 2548 if (TCG_TARGET_HAS_ctpop_i64) { 2549 tcg_gen_op2_i64(INDEX_op_ctpop_i64, ret, arg1); 2550 } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_ctpop_i32) { 2551 tcg_gen_ctpop_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 2552 tcg_gen_ctpop_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 2553 tcg_gen_add_i32(TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret)); 2554 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2555 } else { 2556 gen_helper_ctpop_i64(ret, arg1); 2557 } 2558 } 2559 2560 void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2561 { 2562 if (TCG_TARGET_HAS_rot_i64) { 2563 tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2); 2564 } else { 2565 TCGv_i64 t0, t1; 2566 t0 = tcg_temp_ebb_new_i64(); 2567 t1 = tcg_temp_ebb_new_i64(); 2568 tcg_gen_shl_i64(t0, arg1, arg2); 2569 tcg_gen_subfi_i64(t1, 64, arg2); 2570 tcg_gen_shr_i64(t1, arg1, t1); 2571 tcg_gen_or_i64(ret, t0, t1); 2572 tcg_temp_free_i64(t0); 2573 tcg_temp_free_i64(t1); 2574 } 2575 } 2576 2577 void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 2578 { 2579 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 2580 /* some cases can be optimized here */ 2581 if (arg2 == 0) { 2582 tcg_gen_mov_i64(ret, arg1); 2583 } else if (TCG_TARGET_HAS_rot_i64) { 2584 tcg_gen_rotl_i64(ret, arg1, tcg_constant_i64(arg2)); 2585 } else { 2586 TCGv_i64 t0, t1; 2587 t0 = tcg_temp_ebb_new_i64(); 2588 t1 = tcg_temp_ebb_new_i64(); 2589 tcg_gen_shli_i64(t0, arg1, arg2); 2590 tcg_gen_shri_i64(t1, arg1, 64 - arg2); 2591 tcg_gen_or_i64(ret, t0, t1); 2592 tcg_temp_free_i64(t0); 2593 tcg_temp_free_i64(t1); 2594 } 2595 } 2596 2597 void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2598 { 2599 if (TCG_TARGET_HAS_rot_i64) { 2600 tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2); 2601 } else { 2602 TCGv_i64 t0, t1; 2603 t0 = tcg_temp_ebb_new_i64(); 2604 t1 = tcg_temp_ebb_new_i64(); 2605 tcg_gen_shr_i64(t0, arg1, arg2); 2606 tcg_gen_subfi_i64(t1, 64, arg2); 2607 tcg_gen_shl_i64(t1, arg1, t1); 2608 tcg_gen_or_i64(ret, t0, t1); 2609 tcg_temp_free_i64(t0); 2610 tcg_temp_free_i64(t1); 2611 } 2612 } 2613 2614 void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 2615 { 2616 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 2617 /* some cases can be optimized here */ 2618 if (arg2 == 0) { 2619 tcg_gen_mov_i64(ret, arg1); 2620 } else { 2621 tcg_gen_rotli_i64(ret, arg1, 64 - arg2); 2622 } 2623 } 2624 2625 void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2, 2626 unsigned int ofs, unsigned int len) 2627 { 2628 uint64_t mask; 2629 TCGv_i64 t1; 2630 2631 tcg_debug_assert(ofs < 64); 2632 tcg_debug_assert(len > 0); 2633 tcg_debug_assert(len <= 64); 2634 tcg_debug_assert(ofs + len <= 64); 2635 2636 if (len == 64) { 2637 tcg_gen_mov_i64(ret, arg2); 2638 return; 2639 } 2640 if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) { 2641 tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len); 2642 return; 2643 } 2644 2645 if (TCG_TARGET_REG_BITS == 32) { 2646 if (ofs >= 32) { 2647 tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 2648 TCGV_LOW(arg2), ofs - 32, len); 2649 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 2650 return; 2651 } 2652 if (ofs + len <= 32) { 2653 tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1), 2654 TCGV_LOW(arg2), ofs, len); 2655 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 2656 return; 2657 } 2658 } 2659 2660 t1 = tcg_temp_ebb_new_i64(); 2661 2662 if (TCG_TARGET_HAS_extract2_i64) { 2663 if (ofs + len == 64) { 2664 tcg_gen_shli_i64(t1, arg1, len); 2665 tcg_gen_extract2_i64(ret, t1, arg2, len); 2666 goto done; 2667 } 2668 if (ofs == 0) { 2669 tcg_gen_extract2_i64(ret, arg1, arg2, len); 2670 tcg_gen_rotli_i64(ret, ret, len); 2671 goto done; 2672 } 2673 } 2674 2675 mask = (1ull << len) - 1; 2676 if (ofs + len < 64) { 2677 tcg_gen_andi_i64(t1, arg2, mask); 2678 tcg_gen_shli_i64(t1, t1, ofs); 2679 } else { 2680 tcg_gen_shli_i64(t1, arg2, ofs); 2681 } 2682 tcg_gen_andi_i64(ret, arg1, ~(mask << ofs)); 2683 tcg_gen_or_i64(ret, ret, t1); 2684 done: 2685 tcg_temp_free_i64(t1); 2686 } 2687 2688 void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg, 2689 unsigned int ofs, unsigned int len) 2690 { 2691 tcg_debug_assert(ofs < 64); 2692 tcg_debug_assert(len > 0); 2693 tcg_debug_assert(len <= 64); 2694 tcg_debug_assert(ofs + len <= 64); 2695 2696 if (ofs + len == 64) { 2697 tcg_gen_shli_i64(ret, arg, ofs); 2698 } else if (ofs == 0) { 2699 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1); 2700 } else if (TCG_TARGET_HAS_deposit_i64 2701 && TCG_TARGET_deposit_i64_valid(ofs, len)) { 2702 TCGv_i64 zero = tcg_constant_i64(0); 2703 tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len); 2704 } else { 2705 if (TCG_TARGET_REG_BITS == 32) { 2706 if (ofs >= 32) { 2707 tcg_gen_deposit_z_i32(TCGV_HIGH(ret), TCGV_LOW(arg), 2708 ofs - 32, len); 2709 tcg_gen_movi_i32(TCGV_LOW(ret), 0); 2710 return; 2711 } 2712 if (ofs + len <= 32) { 2713 tcg_gen_deposit_z_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); 2714 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2715 return; 2716 } 2717 } 2718 /* To help two-operand hosts we prefer to zero-extend first, 2719 which allows ARG to stay live. */ 2720 switch (len) { 2721 case 32: 2722 if (TCG_TARGET_HAS_ext32u_i64) { 2723 tcg_gen_ext32u_i64(ret, arg); 2724 tcg_gen_shli_i64(ret, ret, ofs); 2725 return; 2726 } 2727 break; 2728 case 16: 2729 if (TCG_TARGET_HAS_ext16u_i64) { 2730 tcg_gen_ext16u_i64(ret, arg); 2731 tcg_gen_shli_i64(ret, ret, ofs); 2732 return; 2733 } 2734 break; 2735 case 8: 2736 if (TCG_TARGET_HAS_ext8u_i64) { 2737 tcg_gen_ext8u_i64(ret, arg); 2738 tcg_gen_shli_i64(ret, ret, ofs); 2739 return; 2740 } 2741 break; 2742 } 2743 /* Otherwise prefer zero-extension over AND for code size. */ 2744 switch (ofs + len) { 2745 case 32: 2746 if (TCG_TARGET_HAS_ext32u_i64) { 2747 tcg_gen_shli_i64(ret, arg, ofs); 2748 tcg_gen_ext32u_i64(ret, ret); 2749 return; 2750 } 2751 break; 2752 case 16: 2753 if (TCG_TARGET_HAS_ext16u_i64) { 2754 tcg_gen_shli_i64(ret, arg, ofs); 2755 tcg_gen_ext16u_i64(ret, ret); 2756 return; 2757 } 2758 break; 2759 case 8: 2760 if (TCG_TARGET_HAS_ext8u_i64) { 2761 tcg_gen_shli_i64(ret, arg, ofs); 2762 tcg_gen_ext8u_i64(ret, ret); 2763 return; 2764 } 2765 break; 2766 } 2767 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1); 2768 tcg_gen_shli_i64(ret, ret, ofs); 2769 } 2770 } 2771 2772 void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg, 2773 unsigned int ofs, unsigned int len) 2774 { 2775 tcg_debug_assert(ofs < 64); 2776 tcg_debug_assert(len > 0); 2777 tcg_debug_assert(len <= 64); 2778 tcg_debug_assert(ofs + len <= 64); 2779 2780 /* Canonicalize certain special cases, even if extract is supported. */ 2781 if (ofs + len == 64) { 2782 tcg_gen_shri_i64(ret, arg, 64 - len); 2783 return; 2784 } 2785 if (ofs == 0) { 2786 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1); 2787 return; 2788 } 2789 2790 if (TCG_TARGET_REG_BITS == 32) { 2791 /* Look for a 32-bit extract within one of the two words. */ 2792 if (ofs >= 32) { 2793 tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len); 2794 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2795 return; 2796 } 2797 if (ofs + len <= 32) { 2798 tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); 2799 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2800 return; 2801 } 2802 /* The field is split across two words. One double-word 2803 shift is better than two double-word shifts. */ 2804 goto do_shift_and; 2805 } 2806 2807 if (TCG_TARGET_HAS_extract_i64 2808 && TCG_TARGET_extract_i64_valid(ofs, len)) { 2809 tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len); 2810 return; 2811 } 2812 2813 /* Assume that zero-extension, if available, is cheaper than a shift. */ 2814 switch (ofs + len) { 2815 case 32: 2816 if (TCG_TARGET_HAS_ext32u_i64) { 2817 tcg_gen_ext32u_i64(ret, arg); 2818 tcg_gen_shri_i64(ret, ret, ofs); 2819 return; 2820 } 2821 break; 2822 case 16: 2823 if (TCG_TARGET_HAS_ext16u_i64) { 2824 tcg_gen_ext16u_i64(ret, arg); 2825 tcg_gen_shri_i64(ret, ret, ofs); 2826 return; 2827 } 2828 break; 2829 case 8: 2830 if (TCG_TARGET_HAS_ext8u_i64) { 2831 tcg_gen_ext8u_i64(ret, arg); 2832 tcg_gen_shri_i64(ret, ret, ofs); 2833 return; 2834 } 2835 break; 2836 } 2837 2838 /* ??? Ideally we'd know what values are available for immediate AND. 2839 Assume that 8 bits are available, plus the special cases of 16 and 32, 2840 so that we get ext8u, ext16u, and ext32u. */ 2841 switch (len) { 2842 case 1 ... 8: case 16: case 32: 2843 do_shift_and: 2844 tcg_gen_shri_i64(ret, arg, ofs); 2845 tcg_gen_andi_i64(ret, ret, (1ull << len) - 1); 2846 break; 2847 default: 2848 tcg_gen_shli_i64(ret, arg, 64 - len - ofs); 2849 tcg_gen_shri_i64(ret, ret, 64 - len); 2850 break; 2851 } 2852 } 2853 2854 void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg, 2855 unsigned int ofs, unsigned int len) 2856 { 2857 tcg_debug_assert(ofs < 64); 2858 tcg_debug_assert(len > 0); 2859 tcg_debug_assert(len <= 64); 2860 tcg_debug_assert(ofs + len <= 64); 2861 2862 /* Canonicalize certain special cases, even if sextract is supported. */ 2863 if (ofs + len == 64) { 2864 tcg_gen_sari_i64(ret, arg, 64 - len); 2865 return; 2866 } 2867 if (ofs == 0) { 2868 switch (len) { 2869 case 32: 2870 tcg_gen_ext32s_i64(ret, arg); 2871 return; 2872 case 16: 2873 tcg_gen_ext16s_i64(ret, arg); 2874 return; 2875 case 8: 2876 tcg_gen_ext8s_i64(ret, arg); 2877 return; 2878 } 2879 } 2880 2881 if (TCG_TARGET_REG_BITS == 32) { 2882 /* Look for a 32-bit extract within one of the two words. */ 2883 if (ofs >= 32) { 2884 tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len); 2885 } else if (ofs + len <= 32) { 2886 tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); 2887 } else if (ofs == 0) { 2888 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2889 tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32); 2890 return; 2891 } else if (len > 32) { 2892 TCGv_i32 t = tcg_temp_ebb_new_i32(); 2893 /* Extract the bits for the high word normally. */ 2894 tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32); 2895 /* Shift the field down for the low part. */ 2896 tcg_gen_shri_i64(ret, arg, ofs); 2897 /* Overwrite the shift into the high part. */ 2898 tcg_gen_mov_i32(TCGV_HIGH(ret), t); 2899 tcg_temp_free_i32(t); 2900 return; 2901 } else { 2902 /* Shift the field down for the low part, such that the 2903 field sits at the MSB. */ 2904 tcg_gen_shri_i64(ret, arg, ofs + len - 32); 2905 /* Shift the field down from the MSB, sign extending. */ 2906 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_LOW(ret), 32 - len); 2907 } 2908 /* Sign-extend the field from 32 bits. */ 2909 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2910 return; 2911 } 2912 2913 if (TCG_TARGET_HAS_sextract_i64 2914 && TCG_TARGET_extract_i64_valid(ofs, len)) { 2915 tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len); 2916 return; 2917 } 2918 2919 /* Assume that sign-extension, if available, is cheaper than a shift. */ 2920 switch (ofs + len) { 2921 case 32: 2922 if (TCG_TARGET_HAS_ext32s_i64) { 2923 tcg_gen_ext32s_i64(ret, arg); 2924 tcg_gen_sari_i64(ret, ret, ofs); 2925 return; 2926 } 2927 break; 2928 case 16: 2929 if (TCG_TARGET_HAS_ext16s_i64) { 2930 tcg_gen_ext16s_i64(ret, arg); 2931 tcg_gen_sari_i64(ret, ret, ofs); 2932 return; 2933 } 2934 break; 2935 case 8: 2936 if (TCG_TARGET_HAS_ext8s_i64) { 2937 tcg_gen_ext8s_i64(ret, arg); 2938 tcg_gen_sari_i64(ret, ret, ofs); 2939 return; 2940 } 2941 break; 2942 } 2943 switch (len) { 2944 case 32: 2945 if (TCG_TARGET_HAS_ext32s_i64) { 2946 tcg_gen_shri_i64(ret, arg, ofs); 2947 tcg_gen_ext32s_i64(ret, ret); 2948 return; 2949 } 2950 break; 2951 case 16: 2952 if (TCG_TARGET_HAS_ext16s_i64) { 2953 tcg_gen_shri_i64(ret, arg, ofs); 2954 tcg_gen_ext16s_i64(ret, ret); 2955 return; 2956 } 2957 break; 2958 case 8: 2959 if (TCG_TARGET_HAS_ext8s_i64) { 2960 tcg_gen_shri_i64(ret, arg, ofs); 2961 tcg_gen_ext8s_i64(ret, ret); 2962 return; 2963 } 2964 break; 2965 } 2966 tcg_gen_shli_i64(ret, arg, 64 - len - ofs); 2967 tcg_gen_sari_i64(ret, ret, 64 - len); 2968 } 2969 2970 /* 2971 * Extract 64 bits from a 128-bit input, ah:al, starting from ofs. 2972 * Unlike tcg_gen_extract_i64 above, len is fixed at 64. 2973 */ 2974 void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah, 2975 unsigned int ofs) 2976 { 2977 tcg_debug_assert(ofs <= 64); 2978 if (ofs == 0) { 2979 tcg_gen_mov_i64(ret, al); 2980 } else if (ofs == 64) { 2981 tcg_gen_mov_i64(ret, ah); 2982 } else if (al == ah) { 2983 tcg_gen_rotri_i64(ret, al, ofs); 2984 } else if (TCG_TARGET_HAS_extract2_i64) { 2985 tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs); 2986 } else { 2987 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2988 tcg_gen_shri_i64(t0, al, ofs); 2989 tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs); 2990 tcg_temp_free_i64(t0); 2991 } 2992 } 2993 2994 void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1, 2995 TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2) 2996 { 2997 if (cond == TCG_COND_ALWAYS) { 2998 tcg_gen_mov_i64(ret, v1); 2999 } else if (cond == TCG_COND_NEVER) { 3000 tcg_gen_mov_i64(ret, v2); 3001 } else if (TCG_TARGET_REG_BITS == 64) { 3002 tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond); 3003 } else { 3004 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 3005 TCGv_i32 zero = tcg_constant_i32(0); 3006 3007 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0, 3008 TCGV_LOW(c1), TCGV_HIGH(c1), 3009 TCGV_LOW(c2), TCGV_HIGH(c2), cond); 3010 3011 tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, zero, 3012 TCGV_LOW(v1), TCGV_LOW(v2)); 3013 tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, zero, 3014 TCGV_HIGH(v1), TCGV_HIGH(v2)); 3015 3016 tcg_temp_free_i32(t0); 3017 } 3018 } 3019 3020 void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 3021 TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 3022 { 3023 if (TCG_TARGET_HAS_add2_i64) { 3024 tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh); 3025 } else { 3026 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 3027 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 3028 tcg_gen_add_i64(t0, al, bl); 3029 tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al); 3030 tcg_gen_add_i64(rh, ah, bh); 3031 tcg_gen_add_i64(rh, rh, t1); 3032 tcg_gen_mov_i64(rl, t0); 3033 tcg_temp_free_i64(t0); 3034 tcg_temp_free_i64(t1); 3035 } 3036 } 3037 3038 void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 3039 TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 3040 { 3041 if (TCG_TARGET_HAS_sub2_i64) { 3042 tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh); 3043 } else { 3044 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 3045 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 3046 tcg_gen_sub_i64(t0, al, bl); 3047 tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl); 3048 tcg_gen_sub_i64(rh, ah, bh); 3049 tcg_gen_sub_i64(rh, rh, t1); 3050 tcg_gen_mov_i64(rl, t0); 3051 tcg_temp_free_i64(t0); 3052 tcg_temp_free_i64(t1); 3053 } 3054 } 3055 3056 void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 3057 { 3058 if (TCG_TARGET_HAS_mulu2_i64) { 3059 tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2); 3060 } else if (TCG_TARGET_HAS_muluh_i64) { 3061 TCGv_i64 t = tcg_temp_ebb_new_i64(); 3062 tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); 3063 tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2); 3064 tcg_gen_mov_i64(rl, t); 3065 tcg_temp_free_i64(t); 3066 } else { 3067 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 3068 tcg_gen_mul_i64(t0, arg1, arg2); 3069 gen_helper_muluh_i64(rh, arg1, arg2); 3070 tcg_gen_mov_i64(rl, t0); 3071 tcg_temp_free_i64(t0); 3072 } 3073 } 3074 3075 void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 3076 { 3077 if (TCG_TARGET_HAS_muls2_i64) { 3078 tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2); 3079 } else if (TCG_TARGET_HAS_mulsh_i64) { 3080 TCGv_i64 t = tcg_temp_ebb_new_i64(); 3081 tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); 3082 tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2); 3083 tcg_gen_mov_i64(rl, t); 3084 tcg_temp_free_i64(t); 3085 } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) { 3086 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 3087 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 3088 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 3089 TCGv_i64 t3 = tcg_temp_ebb_new_i64(); 3090 tcg_gen_mulu2_i64(t0, t1, arg1, arg2); 3091 /* Adjust for negative inputs. */ 3092 tcg_gen_sari_i64(t2, arg1, 63); 3093 tcg_gen_sari_i64(t3, arg2, 63); 3094 tcg_gen_and_i64(t2, t2, arg2); 3095 tcg_gen_and_i64(t3, t3, arg1); 3096 tcg_gen_sub_i64(rh, t1, t2); 3097 tcg_gen_sub_i64(rh, rh, t3); 3098 tcg_gen_mov_i64(rl, t0); 3099 tcg_temp_free_i64(t0); 3100 tcg_temp_free_i64(t1); 3101 tcg_temp_free_i64(t2); 3102 tcg_temp_free_i64(t3); 3103 } else { 3104 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 3105 tcg_gen_mul_i64(t0, arg1, arg2); 3106 gen_helper_mulsh_i64(rh, arg1, arg2); 3107 tcg_gen_mov_i64(rl, t0); 3108 tcg_temp_free_i64(t0); 3109 } 3110 } 3111 3112 void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 3113 { 3114 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 3115 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 3116 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 3117 tcg_gen_mulu2_i64(t0, t1, arg1, arg2); 3118 /* Adjust for negative input for the signed arg1. */ 3119 tcg_gen_sari_i64(t2, arg1, 63); 3120 tcg_gen_and_i64(t2, t2, arg2); 3121 tcg_gen_sub_i64(rh, t1, t2); 3122 tcg_gen_mov_i64(rl, t0); 3123 tcg_temp_free_i64(t0); 3124 tcg_temp_free_i64(t1); 3125 tcg_temp_free_i64(t2); 3126 } 3127 3128 void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 3129 { 3130 tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b); 3131 } 3132 3133 void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 3134 { 3135 tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b); 3136 } 3137 3138 void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 3139 { 3140 tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a); 3141 } 3142 3143 void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 3144 { 3145 tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a); 3146 } 3147 3148 void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a) 3149 { 3150 TCGv_i64 t = tcg_temp_ebb_new_i64(); 3151 3152 tcg_gen_sari_i64(t, a, 63); 3153 tcg_gen_xor_i64(ret, a, t); 3154 tcg_gen_sub_i64(ret, ret, t); 3155 tcg_temp_free_i64(t); 3156 } 3157 3158 /* Size changing operations. */ 3159 3160 void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg) 3161 { 3162 if (TCG_TARGET_REG_BITS == 32) { 3163 tcg_gen_mov_i32(ret, TCGV_LOW(arg)); 3164 } else if (TCG_TARGET_HAS_extr_i64_i32) { 3165 tcg_gen_op2(INDEX_op_extrl_i64_i32, 3166 tcgv_i32_arg(ret), tcgv_i64_arg(arg)); 3167 } else { 3168 tcg_gen_mov_i32(ret, (TCGv_i32)arg); 3169 } 3170 } 3171 3172 void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg) 3173 { 3174 if (TCG_TARGET_REG_BITS == 32) { 3175 tcg_gen_mov_i32(ret, TCGV_HIGH(arg)); 3176 } else if (TCG_TARGET_HAS_extr_i64_i32) { 3177 tcg_gen_op2(INDEX_op_extrh_i64_i32, 3178 tcgv_i32_arg(ret), tcgv_i64_arg(arg)); 3179 } else { 3180 TCGv_i64 t = tcg_temp_ebb_new_i64(); 3181 tcg_gen_shri_i64(t, arg, 32); 3182 tcg_gen_mov_i32(ret, (TCGv_i32)t); 3183 tcg_temp_free_i64(t); 3184 } 3185 } 3186 3187 void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 3188 { 3189 if (TCG_TARGET_REG_BITS == 32) { 3190 tcg_gen_mov_i32(TCGV_LOW(ret), arg); 3191 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 3192 } else { 3193 tcg_gen_op2(INDEX_op_extu_i32_i64, 3194 tcgv_i64_arg(ret), tcgv_i32_arg(arg)); 3195 } 3196 } 3197 3198 void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 3199 { 3200 if (TCG_TARGET_REG_BITS == 32) { 3201 tcg_gen_mov_i32(TCGV_LOW(ret), arg); 3202 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 3203 } else { 3204 tcg_gen_op2(INDEX_op_ext_i32_i64, 3205 tcgv_i64_arg(ret), tcgv_i32_arg(arg)); 3206 } 3207 } 3208 3209 void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high) 3210 { 3211 TCGv_i64 tmp; 3212 3213 if (TCG_TARGET_REG_BITS == 32) { 3214 tcg_gen_mov_i32(TCGV_LOW(dest), low); 3215 tcg_gen_mov_i32(TCGV_HIGH(dest), high); 3216 return; 3217 } 3218 3219 tmp = tcg_temp_ebb_new_i64(); 3220 /* These extensions are only needed for type correctness. 3221 We may be able to do better given target specific information. */ 3222 tcg_gen_extu_i32_i64(tmp, high); 3223 tcg_gen_extu_i32_i64(dest, low); 3224 /* If deposit is available, use it. Otherwise use the extra 3225 knowledge that we have of the zero-extensions above. */ 3226 if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) { 3227 tcg_gen_deposit_i64(dest, dest, tmp, 32, 32); 3228 } else { 3229 tcg_gen_shli_i64(tmp, tmp, 32); 3230 tcg_gen_or_i64(dest, dest, tmp); 3231 } 3232 tcg_temp_free_i64(tmp); 3233 } 3234 3235 void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg) 3236 { 3237 if (TCG_TARGET_REG_BITS == 32) { 3238 tcg_gen_mov_i32(lo, TCGV_LOW(arg)); 3239 tcg_gen_mov_i32(hi, TCGV_HIGH(arg)); 3240 } else { 3241 tcg_gen_extrl_i64_i32(lo, arg); 3242 tcg_gen_extrh_i64_i32(hi, arg); 3243 } 3244 } 3245 3246 void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg) 3247 { 3248 tcg_gen_ext32u_i64(lo, arg); 3249 tcg_gen_shri_i64(hi, arg, 32); 3250 } 3251 3252 void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 hi) 3253 { 3254 tcg_gen_deposit_i64(ret, lo, hi, 32, 32); 3255 } 3256 3257 void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg) 3258 { 3259 tcg_gen_mov_i64(lo, TCGV128_LOW(arg)); 3260 tcg_gen_mov_i64(hi, TCGV128_HIGH(arg)); 3261 } 3262 3263 void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi) 3264 { 3265 tcg_gen_mov_i64(TCGV128_LOW(ret), lo); 3266 tcg_gen_mov_i64(TCGV128_HIGH(ret), hi); 3267 } 3268 3269 void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src) 3270 { 3271 if (dst != src) { 3272 tcg_gen_mov_i64(TCGV128_LOW(dst), TCGV128_LOW(src)); 3273 tcg_gen_mov_i64(TCGV128_HIGH(dst), TCGV128_HIGH(src)); 3274 } 3275 } 3276 3277 void tcg_gen_ld_i128(TCGv_i128 ret, TCGv_ptr base, tcg_target_long offset) 3278 { 3279 if (HOST_BIG_ENDIAN) { 3280 tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset); 3281 tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset + 8); 3282 } else { 3283 tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset); 3284 tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset + 8); 3285 } 3286 } 3287 3288 void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, tcg_target_long offset) 3289 { 3290 if (HOST_BIG_ENDIAN) { 3291 tcg_gen_st_i64(TCGV128_HIGH(val), base, offset); 3292 tcg_gen_st_i64(TCGV128_LOW(val), base, offset + 8); 3293 } else { 3294 tcg_gen_st_i64(TCGV128_LOW(val), base, offset); 3295 tcg_gen_st_i64(TCGV128_HIGH(val), base, offset + 8); 3296 } 3297 } 3298 3299 /* QEMU specific operations. */ 3300 3301 void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx) 3302 { 3303 /* 3304 * Let the jit code return the read-only version of the 3305 * TranslationBlock, so that we minimize the pc-relative 3306 * distance of the address of the exit_tb code to TB. 3307 * This will improve utilization of pc-relative address loads. 3308 * 3309 * TODO: Move this to translator_loop, so that all const 3310 * TranslationBlock pointers refer to read-only memory. 3311 * This requires coordination with targets that do not use 3312 * the translator_loop. 3313 */ 3314 uintptr_t val = (uintptr_t)tcg_splitwx_to_rx((void *)tb) + idx; 3315 3316 if (tb == NULL) { 3317 tcg_debug_assert(idx == 0); 3318 } else if (idx <= TB_EXIT_IDXMAX) { 3319 #ifdef CONFIG_DEBUG_TCG 3320 /* This is an exit following a goto_tb. Verify that we have 3321 seen this numbered exit before, via tcg_gen_goto_tb. */ 3322 tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx)); 3323 #endif 3324 } else { 3325 /* This is an exit via the exitreq label. */ 3326 tcg_debug_assert(idx == TB_EXIT_REQUESTED); 3327 } 3328 3329 tcg_gen_op1i(INDEX_op_exit_tb, val); 3330 } 3331 3332 void tcg_gen_goto_tb(unsigned idx) 3333 { 3334 /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */ 3335 tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB)); 3336 /* We only support two chained exits. */ 3337 tcg_debug_assert(idx <= TB_EXIT_IDXMAX); 3338 #ifdef CONFIG_DEBUG_TCG 3339 /* Verify that we haven't seen this numbered exit before. */ 3340 tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0); 3341 tcg_ctx->goto_tb_issue_mask |= 1 << idx; 3342 #endif 3343 plugin_gen_disable_mem_helpers(); 3344 tcg_gen_op1i(INDEX_op_goto_tb, idx); 3345 } 3346 3347 void tcg_gen_lookup_and_goto_ptr(void) 3348 { 3349 TCGv_ptr ptr; 3350 3351 if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) { 3352 tcg_gen_exit_tb(NULL, 0); 3353 return; 3354 } 3355 3356 plugin_gen_disable_mem_helpers(); 3357 ptr = tcg_temp_ebb_new_ptr(); 3358 gen_helper_lookup_tb_ptr(ptr, tcg_env); 3359 tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr)); 3360 tcg_temp_free_ptr(ptr); 3361 } 3362