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