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 /* 1039 * bswap16_i32: 16-bit byte swap on the low bits of a 32-bit value. 1040 * 1041 * Byte pattern: xxab -> yyba 1042 * 1043 * With TCG_BSWAP_IZ, x == zero, else undefined. 1044 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined. 1045 */ 1046 void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags) 1047 { 1048 /* Only one extension flag may be present. */ 1049 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ)); 1050 1051 if (TCG_TARGET_HAS_bswap16_i32) { 1052 tcg_gen_op3i_i32(INDEX_op_bswap16_i32, ret, arg, flags); 1053 } else { 1054 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1055 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1056 1057 /* arg = ..ab (IZ) xxab (!IZ) */ 1058 tcg_gen_shri_i32(t0, arg, 8); /* t0 = ...a (IZ) .xxa (!IZ) */ 1059 if (!(flags & TCG_BSWAP_IZ)) { 1060 tcg_gen_ext8u_i32(t0, t0); /* t0 = ...a */ 1061 } 1062 1063 if (flags & TCG_BSWAP_OS) { 1064 tcg_gen_shli_i32(t1, arg, 24); /* t1 = b... */ 1065 tcg_gen_sari_i32(t1, t1, 16); /* t1 = ssb. */ 1066 } else if (flags & TCG_BSWAP_OZ) { 1067 tcg_gen_ext8u_i32(t1, arg); /* t1 = ...b */ 1068 tcg_gen_shli_i32(t1, t1, 8); /* t1 = ..b. */ 1069 } else { 1070 tcg_gen_shli_i32(t1, arg, 8); /* t1 = xab. */ 1071 } 1072 1073 tcg_gen_or_i32(ret, t0, t1); /* ret = ..ba (OZ) */ 1074 /* = ssba (OS) */ 1075 /* = xaba (no flag) */ 1076 tcg_temp_free_i32(t0); 1077 tcg_temp_free_i32(t1); 1078 } 1079 } 1080 1081 /* 1082 * bswap32_i32: 32-bit byte swap on a 32-bit value. 1083 * 1084 * Byte pattern: abcd -> dcba 1085 */ 1086 void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg) 1087 { 1088 if (TCG_TARGET_HAS_bswap32_i32) { 1089 tcg_gen_op3i_i32(INDEX_op_bswap32_i32, ret, arg, 0); 1090 } else { 1091 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1092 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1093 TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff); 1094 1095 /* arg = abcd */ 1096 tcg_gen_shri_i32(t0, arg, 8); /* t0 = .abc */ 1097 tcg_gen_and_i32(t1, arg, t2); /* t1 = .b.d */ 1098 tcg_gen_and_i32(t0, t0, t2); /* t0 = .a.c */ 1099 tcg_gen_shli_i32(t1, t1, 8); /* t1 = b.d. */ 1100 tcg_gen_or_i32(ret, t0, t1); /* ret = badc */ 1101 1102 tcg_gen_shri_i32(t0, ret, 16); /* t0 = ..ba */ 1103 tcg_gen_shli_i32(t1, ret, 16); /* t1 = dc.. */ 1104 tcg_gen_or_i32(ret, t0, t1); /* ret = dcba */ 1105 1106 tcg_temp_free_i32(t0); 1107 tcg_temp_free_i32(t1); 1108 } 1109 } 1110 1111 void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg) 1112 { 1113 /* Swapping 2 16-bit elements is a rotate. */ 1114 tcg_gen_rotli_i32(ret, arg, 16); 1115 } 1116 1117 void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1118 { 1119 tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b); 1120 } 1121 1122 void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1123 { 1124 tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b); 1125 } 1126 1127 void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1128 { 1129 tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a); 1130 } 1131 1132 void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1133 { 1134 tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a); 1135 } 1136 1137 void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a) 1138 { 1139 TCGv_i32 t = tcg_temp_ebb_new_i32(); 1140 1141 tcg_gen_sari_i32(t, a, 31); 1142 tcg_gen_xor_i32(ret, a, t); 1143 tcg_gen_sub_i32(ret, ret, t); 1144 tcg_temp_free_i32(t); 1145 } 1146 1147 /* 64-bit ops */ 1148 1149 #if TCG_TARGET_REG_BITS == 32 1150 /* These are all inline for TCG_TARGET_REG_BITS == 64. */ 1151 1152 void tcg_gen_discard_i64(TCGv_i64 arg) 1153 { 1154 tcg_gen_discard_i32(TCGV_LOW(arg)); 1155 tcg_gen_discard_i32(TCGV_HIGH(arg)); 1156 } 1157 1158 void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg) 1159 { 1160 TCGTemp *ts = tcgv_i64_temp(arg); 1161 1162 /* Canonicalize TCGv_i64 TEMP_CONST into TCGv_i32 TEMP_CONST. */ 1163 if (ts->kind == TEMP_CONST) { 1164 tcg_gen_movi_i64(ret, ts->val); 1165 } else { 1166 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1167 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 1168 } 1169 } 1170 1171 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg) 1172 { 1173 tcg_gen_movi_i32(TCGV_LOW(ret), arg); 1174 tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32); 1175 } 1176 1177 void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1178 { 1179 tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset); 1180 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1181 } 1182 1183 void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1184 { 1185 tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset); 1186 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1187 } 1188 1189 void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1190 { 1191 tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset); 1192 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1193 } 1194 1195 void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1196 { 1197 tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset); 1198 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1199 } 1200 1201 void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1202 { 1203 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 1204 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1205 } 1206 1207 void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1208 { 1209 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 1210 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1211 } 1212 1213 void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1214 { 1215 /* Since arg2 and ret have different types, 1216 they cannot be the same temporary */ 1217 #if HOST_BIG_ENDIAN 1218 tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset); 1219 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4); 1220 #else 1221 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 1222 tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4); 1223 #endif 1224 } 1225 1226 void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1227 { 1228 tcg_gen_st8_i32(TCGV_LOW(arg1), arg2, offset); 1229 } 1230 1231 void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1232 { 1233 tcg_gen_st16_i32(TCGV_LOW(arg1), arg2, offset); 1234 } 1235 1236 void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1237 { 1238 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset); 1239 } 1240 1241 void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1242 { 1243 #if HOST_BIG_ENDIAN 1244 tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset); 1245 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4); 1246 #else 1247 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset); 1248 tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4); 1249 #endif 1250 } 1251 1252 void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1253 { 1254 tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1), 1255 TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2)); 1256 } 1257 1258 void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1259 { 1260 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1), 1261 TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2)); 1262 } 1263 1264 void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1265 { 1266 tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1267 tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1268 } 1269 1270 void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1271 { 1272 tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1273 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1274 } 1275 1276 void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1277 { 1278 tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1279 tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1280 } 1281 1282 void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1283 { 1284 gen_helper_shl_i64(ret, arg1, arg2); 1285 } 1286 1287 void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1288 { 1289 gen_helper_shr_i64(ret, arg1, arg2); 1290 } 1291 1292 void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1293 { 1294 gen_helper_sar_i64(ret, arg1, arg2); 1295 } 1296 1297 void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1298 { 1299 TCGv_i64 t0; 1300 TCGv_i32 t1; 1301 1302 t0 = tcg_temp_ebb_new_i64(); 1303 t1 = tcg_temp_ebb_new_i32(); 1304 1305 tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0), 1306 TCGV_LOW(arg1), TCGV_LOW(arg2)); 1307 1308 tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2)); 1309 tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 1310 tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2)); 1311 tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 1312 1313 tcg_gen_mov_i64(ret, t0); 1314 tcg_temp_free_i64(t0); 1315 tcg_temp_free_i32(t1); 1316 } 1317 1318 #else 1319 1320 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg) 1321 { 1322 tcg_gen_mov_i64(ret, tcg_constant_i64(arg)); 1323 } 1324 1325 #endif /* TCG_TARGET_REG_SIZE == 32 */ 1326 1327 void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1328 { 1329 /* some cases can be optimized here */ 1330 if (arg2 == 0) { 1331 tcg_gen_mov_i64(ret, arg1); 1332 } else if (TCG_TARGET_REG_BITS == 64) { 1333 tcg_gen_add_i64(ret, arg1, tcg_constant_i64(arg2)); 1334 } else { 1335 tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1336 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1337 tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32)); 1338 } 1339 } 1340 1341 void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2) 1342 { 1343 if (arg1 == 0 && TCG_TARGET_HAS_neg_i64) { 1344 /* Don't recurse with tcg_gen_neg_i64. */ 1345 tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg2); 1346 } else if (TCG_TARGET_REG_BITS == 64) { 1347 tcg_gen_sub_i64(ret, tcg_constant_i64(arg1), arg2); 1348 } else { 1349 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1350 tcg_constant_i32(arg1), tcg_constant_i32(arg1 >> 32), 1351 TCGV_LOW(arg2), TCGV_HIGH(arg2)); 1352 } 1353 } 1354 1355 void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1356 { 1357 /* some cases can be optimized here */ 1358 if (arg2 == 0) { 1359 tcg_gen_mov_i64(ret, arg1); 1360 } else if (TCG_TARGET_REG_BITS == 64) { 1361 tcg_gen_sub_i64(ret, arg1, tcg_constant_i64(arg2)); 1362 } else { 1363 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1364 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1365 tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32)); 1366 } 1367 } 1368 1369 void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1370 { 1371 if (TCG_TARGET_REG_BITS == 32) { 1372 tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 1373 tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 1374 return; 1375 } 1376 1377 /* Some cases can be optimized here. */ 1378 switch (arg2) { 1379 case 0: 1380 tcg_gen_movi_i64(ret, 0); 1381 return; 1382 case -1: 1383 tcg_gen_mov_i64(ret, arg1); 1384 return; 1385 case 0xff: 1386 /* Don't recurse with tcg_gen_ext8u_i64. */ 1387 if (TCG_TARGET_HAS_ext8u_i64) { 1388 tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1); 1389 return; 1390 } 1391 break; 1392 case 0xffff: 1393 if (TCG_TARGET_HAS_ext16u_i64) { 1394 tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1); 1395 return; 1396 } 1397 break; 1398 case 0xffffffffu: 1399 if (TCG_TARGET_HAS_ext32u_i64) { 1400 tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1); 1401 return; 1402 } 1403 break; 1404 } 1405 1406 tcg_gen_and_i64(ret, arg1, tcg_constant_i64(arg2)); 1407 } 1408 1409 void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1410 { 1411 if (TCG_TARGET_REG_BITS == 32) { 1412 tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 1413 tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 1414 return; 1415 } 1416 /* Some cases can be optimized here. */ 1417 if (arg2 == -1) { 1418 tcg_gen_movi_i64(ret, -1); 1419 } else if (arg2 == 0) { 1420 tcg_gen_mov_i64(ret, arg1); 1421 } else { 1422 tcg_gen_or_i64(ret, arg1, tcg_constant_i64(arg2)); 1423 } 1424 } 1425 1426 void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1427 { 1428 if (TCG_TARGET_REG_BITS == 32) { 1429 tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 1430 tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 1431 return; 1432 } 1433 /* Some cases can be optimized here. */ 1434 if (arg2 == 0) { 1435 tcg_gen_mov_i64(ret, arg1); 1436 } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) { 1437 /* Don't recurse with tcg_gen_not_i64. */ 1438 tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1); 1439 } else { 1440 tcg_gen_xor_i64(ret, arg1, tcg_constant_i64(arg2)); 1441 } 1442 } 1443 1444 static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, 1445 unsigned c, bool right, bool arith) 1446 { 1447 tcg_debug_assert(c < 64); 1448 if (c == 0) { 1449 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 1450 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 1451 } else if (c >= 32) { 1452 c -= 32; 1453 if (right) { 1454 if (arith) { 1455 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1456 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31); 1457 } else { 1458 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1459 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1460 } 1461 } else { 1462 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c); 1463 tcg_gen_movi_i32(TCGV_LOW(ret), 0); 1464 } 1465 } else if (right) { 1466 if (TCG_TARGET_HAS_extract2_i32) { 1467 tcg_gen_extract2_i32(TCGV_LOW(ret), 1468 TCGV_LOW(arg1), TCGV_HIGH(arg1), c); 1469 } else { 1470 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c); 1471 tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(ret), 1472 TCGV_HIGH(arg1), 32 - c, c); 1473 } 1474 if (arith) { 1475 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c); 1476 } else { 1477 tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c); 1478 } 1479 } else { 1480 if (TCG_TARGET_HAS_extract2_i32) { 1481 tcg_gen_extract2_i32(TCGV_HIGH(ret), 1482 TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c); 1483 } else { 1484 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1485 tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c); 1486 tcg_gen_deposit_i32(TCGV_HIGH(ret), t0, 1487 TCGV_HIGH(arg1), c, 32 - c); 1488 tcg_temp_free_i32(t0); 1489 } 1490 tcg_gen_shli_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c); 1491 } 1492 } 1493 1494 void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1495 { 1496 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 1497 if (TCG_TARGET_REG_BITS == 32) { 1498 tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0); 1499 } else if (arg2 == 0) { 1500 tcg_gen_mov_i64(ret, arg1); 1501 } else { 1502 tcg_gen_shl_i64(ret, arg1, tcg_constant_i64(arg2)); 1503 } 1504 } 1505 1506 void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1507 { 1508 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 1509 if (TCG_TARGET_REG_BITS == 32) { 1510 tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0); 1511 } else if (arg2 == 0) { 1512 tcg_gen_mov_i64(ret, arg1); 1513 } else { 1514 tcg_gen_shr_i64(ret, arg1, tcg_constant_i64(arg2)); 1515 } 1516 } 1517 1518 void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1519 { 1520 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 1521 if (TCG_TARGET_REG_BITS == 32) { 1522 tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1); 1523 } else if (arg2 == 0) { 1524 tcg_gen_mov_i64(ret, arg1); 1525 } else { 1526 tcg_gen_sar_i64(ret, arg1, tcg_constant_i64(arg2)); 1527 } 1528 } 1529 1530 void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l) 1531 { 1532 if (cond == TCG_COND_ALWAYS) { 1533 tcg_gen_br(l); 1534 } else if (cond != TCG_COND_NEVER) { 1535 if (TCG_TARGET_REG_BITS == 32) { 1536 tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1), 1537 TCGV_HIGH(arg1), TCGV_LOW(arg2), 1538 TCGV_HIGH(arg2), cond, label_arg(l)); 1539 } else { 1540 tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, 1541 label_arg(l)); 1542 } 1543 add_last_as_label_use(l); 1544 } 1545 } 1546 1547 void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l) 1548 { 1549 if (TCG_TARGET_REG_BITS == 64) { 1550 tcg_gen_brcond_i64(cond, arg1, tcg_constant_i64(arg2), l); 1551 } else if (cond == TCG_COND_ALWAYS) { 1552 tcg_gen_br(l); 1553 } else if (cond != TCG_COND_NEVER) { 1554 tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, 1555 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1556 tcg_constant_i32(arg2), 1557 tcg_constant_i32(arg2 >> 32), 1558 cond, label_arg(l)); 1559 add_last_as_label_use(l); 1560 } 1561 } 1562 1563 void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret, 1564 TCGv_i64 arg1, TCGv_i64 arg2) 1565 { 1566 if (cond == TCG_COND_ALWAYS) { 1567 tcg_gen_movi_i64(ret, 1); 1568 } else if (cond == TCG_COND_NEVER) { 1569 tcg_gen_movi_i64(ret, 0); 1570 } else { 1571 if (TCG_TARGET_REG_BITS == 32) { 1572 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 1573 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1574 TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); 1575 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1576 } else { 1577 tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond); 1578 } 1579 } 1580 } 1581 1582 void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret, 1583 TCGv_i64 arg1, int64_t arg2) 1584 { 1585 if (TCG_TARGET_REG_BITS == 64) { 1586 tcg_gen_setcond_i64(cond, ret, arg1, tcg_constant_i64(arg2)); 1587 } else 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 { 1592 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 1593 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1594 tcg_constant_i32(arg2), 1595 tcg_constant_i32(arg2 >> 32), cond); 1596 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1597 } 1598 } 1599 1600 void tcg_gen_negsetcond_i64(TCGCond cond, TCGv_i64 ret, 1601 TCGv_i64 arg1, TCGv_i64 arg2) 1602 { 1603 if (cond == TCG_COND_ALWAYS) { 1604 tcg_gen_movi_i64(ret, -1); 1605 } else if (cond == TCG_COND_NEVER) { 1606 tcg_gen_movi_i64(ret, 0); 1607 } else if (TCG_TARGET_HAS_negsetcond_i64) { 1608 tcg_gen_op4i_i64(INDEX_op_negsetcond_i64, ret, arg1, arg2, cond); 1609 } else if (TCG_TARGET_REG_BITS == 32) { 1610 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 1611 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1612 TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); 1613 tcg_gen_neg_i32(TCGV_LOW(ret), TCGV_LOW(ret)); 1614 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_LOW(ret)); 1615 } else { 1616 tcg_gen_setcond_i64(cond, ret, arg1, arg2); 1617 tcg_gen_neg_i64(ret, ret); 1618 } 1619 } 1620 1621 void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1622 { 1623 if (arg2 == 0) { 1624 tcg_gen_movi_i64(ret, 0); 1625 } else if (is_power_of_2(arg2)) { 1626 tcg_gen_shli_i64(ret, arg1, ctz64(arg2)); 1627 } else { 1628 tcg_gen_mul_i64(ret, arg1, tcg_constant_i64(arg2)); 1629 } 1630 } 1631 1632 void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1633 { 1634 if (TCG_TARGET_HAS_div_i64) { 1635 tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2); 1636 } else if (TCG_TARGET_HAS_div2_i64) { 1637 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1638 tcg_gen_sari_i64(t0, arg1, 63); 1639 tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2); 1640 tcg_temp_free_i64(t0); 1641 } else { 1642 gen_helper_div_i64(ret, arg1, arg2); 1643 } 1644 } 1645 1646 void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1647 { 1648 if (TCG_TARGET_HAS_rem_i64) { 1649 tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2); 1650 } else if (TCG_TARGET_HAS_div_i64) { 1651 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1652 tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2); 1653 tcg_gen_mul_i64(t0, t0, arg2); 1654 tcg_gen_sub_i64(ret, arg1, t0); 1655 tcg_temp_free_i64(t0); 1656 } else if (TCG_TARGET_HAS_div2_i64) { 1657 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1658 tcg_gen_sari_i64(t0, arg1, 63); 1659 tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2); 1660 tcg_temp_free_i64(t0); 1661 } else { 1662 gen_helper_rem_i64(ret, arg1, arg2); 1663 } 1664 } 1665 1666 void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1667 { 1668 if (TCG_TARGET_HAS_div_i64) { 1669 tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2); 1670 } else if (TCG_TARGET_HAS_div2_i64) { 1671 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1672 tcg_gen_movi_i64(t0, 0); 1673 tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2); 1674 tcg_temp_free_i64(t0); 1675 } else { 1676 gen_helper_divu_i64(ret, arg1, arg2); 1677 } 1678 } 1679 1680 void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1681 { 1682 if (TCG_TARGET_HAS_rem_i64) { 1683 tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2); 1684 } else if (TCG_TARGET_HAS_div_i64) { 1685 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1686 tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2); 1687 tcg_gen_mul_i64(t0, t0, arg2); 1688 tcg_gen_sub_i64(ret, arg1, t0); 1689 tcg_temp_free_i64(t0); 1690 } else if (TCG_TARGET_HAS_div2_i64) { 1691 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1692 tcg_gen_movi_i64(t0, 0); 1693 tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2); 1694 tcg_temp_free_i64(t0); 1695 } else { 1696 gen_helper_remu_i64(ret, arg1, arg2); 1697 } 1698 } 1699 1700 void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg) 1701 { 1702 if (TCG_TARGET_REG_BITS == 32) { 1703 tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1704 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1705 } else if (TCG_TARGET_HAS_ext8s_i64) { 1706 tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg); 1707 } else { 1708 tcg_gen_shli_i64(ret, arg, 56); 1709 tcg_gen_sari_i64(ret, ret, 56); 1710 } 1711 } 1712 1713 void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg) 1714 { 1715 if (TCG_TARGET_REG_BITS == 32) { 1716 tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1717 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1718 } else if (TCG_TARGET_HAS_ext16s_i64) { 1719 tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg); 1720 } else { 1721 tcg_gen_shli_i64(ret, arg, 48); 1722 tcg_gen_sari_i64(ret, ret, 48); 1723 } 1724 } 1725 1726 void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg) 1727 { 1728 if (TCG_TARGET_REG_BITS == 32) { 1729 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1730 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1731 } else if (TCG_TARGET_HAS_ext32s_i64) { 1732 tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg); 1733 } else { 1734 tcg_gen_shli_i64(ret, arg, 32); 1735 tcg_gen_sari_i64(ret, ret, 32); 1736 } 1737 } 1738 1739 void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg) 1740 { 1741 if (TCG_TARGET_REG_BITS == 32) { 1742 tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1743 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1744 } else if (TCG_TARGET_HAS_ext8u_i64) { 1745 tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg); 1746 } else { 1747 tcg_gen_andi_i64(ret, arg, 0xffu); 1748 } 1749 } 1750 1751 void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg) 1752 { 1753 if (TCG_TARGET_REG_BITS == 32) { 1754 tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1755 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1756 } else if (TCG_TARGET_HAS_ext16u_i64) { 1757 tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg); 1758 } else { 1759 tcg_gen_andi_i64(ret, arg, 0xffffu); 1760 } 1761 } 1762 1763 void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg) 1764 { 1765 if (TCG_TARGET_REG_BITS == 32) { 1766 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1767 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1768 } else if (TCG_TARGET_HAS_ext32u_i64) { 1769 tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg); 1770 } else { 1771 tcg_gen_andi_i64(ret, arg, 0xffffffffu); 1772 } 1773 } 1774 1775 /* 1776 * bswap16_i64: 16-bit byte swap on the low bits of a 64-bit value. 1777 * 1778 * Byte pattern: xxxxxxxxab -> yyyyyyyyba 1779 * 1780 * With TCG_BSWAP_IZ, x == zero, else undefined. 1781 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined. 1782 */ 1783 void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags) 1784 { 1785 /* Only one extension flag may be present. */ 1786 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ)); 1787 1788 if (TCG_TARGET_REG_BITS == 32) { 1789 tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg), flags); 1790 if (flags & TCG_BSWAP_OS) { 1791 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1792 } else { 1793 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1794 } 1795 } else if (TCG_TARGET_HAS_bswap16_i64) { 1796 tcg_gen_op3i_i64(INDEX_op_bswap16_i64, ret, arg, flags); 1797 } else { 1798 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1799 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1800 1801 /* arg = ......ab or xxxxxxab */ 1802 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .......a or .xxxxxxa */ 1803 if (!(flags & TCG_BSWAP_IZ)) { 1804 tcg_gen_ext8u_i64(t0, t0); /* t0 = .......a */ 1805 } 1806 1807 if (flags & TCG_BSWAP_OS) { 1808 tcg_gen_shli_i64(t1, arg, 56); /* t1 = b....... */ 1809 tcg_gen_sari_i64(t1, t1, 48); /* t1 = ssssssb. */ 1810 } else if (flags & TCG_BSWAP_OZ) { 1811 tcg_gen_ext8u_i64(t1, arg); /* t1 = .......b */ 1812 tcg_gen_shli_i64(t1, t1, 8); /* t1 = ......b. */ 1813 } else { 1814 tcg_gen_shli_i64(t1, arg, 8); /* t1 = xxxxxab. */ 1815 } 1816 1817 tcg_gen_or_i64(ret, t0, t1); /* ret = ......ba (OZ) */ 1818 /* ssssssba (OS) */ 1819 /* xxxxxaba (no flag) */ 1820 tcg_temp_free_i64(t0); 1821 tcg_temp_free_i64(t1); 1822 } 1823 } 1824 1825 void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags) 1826 { 1827 /* Only one extension flag may be present. */ 1828 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ)); 1829 1830 if (TCG_TARGET_REG_BITS == 32) { 1831 tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1832 if (flags & TCG_BSWAP_OS) { 1833 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1834 } else { 1835 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1836 } 1837 } else if (TCG_TARGET_HAS_bswap32_i64) { 1838 tcg_gen_op3i_i64(INDEX_op_bswap32_i64, ret, arg, flags); 1839 } else { 1840 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1841 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1842 TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff); 1843 1844 /* arg = xxxxabcd */ 1845 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .xxxxabc */ 1846 tcg_gen_and_i64(t1, arg, t2); /* t1 = .....b.d */ 1847 tcg_gen_and_i64(t0, t0, t2); /* t0 = .....a.c */ 1848 tcg_gen_shli_i64(t1, t1, 8); /* t1 = ....b.d. */ 1849 tcg_gen_or_i64(ret, t0, t1); /* ret = ....badc */ 1850 1851 tcg_gen_shli_i64(t1, ret, 48); /* t1 = dc...... */ 1852 tcg_gen_shri_i64(t0, ret, 16); /* t0 = ......ba */ 1853 if (flags & TCG_BSWAP_OS) { 1854 tcg_gen_sari_i64(t1, t1, 32); /* t1 = ssssdc.. */ 1855 } else { 1856 tcg_gen_shri_i64(t1, t1, 32); /* t1 = ....dc.. */ 1857 } 1858 tcg_gen_or_i64(ret, t0, t1); /* ret = ssssdcba */ 1859 1860 tcg_temp_free_i64(t0); 1861 tcg_temp_free_i64(t1); 1862 } 1863 } 1864 1865 void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) 1866 { 1867 if (TCG_TARGET_REG_BITS == 32) { 1868 TCGv_i32 t0, t1; 1869 t0 = tcg_temp_ebb_new_i32(); 1870 t1 = tcg_temp_ebb_new_i32(); 1871 1872 tcg_gen_bswap32_i32(t0, TCGV_LOW(arg)); 1873 tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg)); 1874 tcg_gen_mov_i32(TCGV_LOW(ret), t1); 1875 tcg_gen_mov_i32(TCGV_HIGH(ret), t0); 1876 tcg_temp_free_i32(t0); 1877 tcg_temp_free_i32(t1); 1878 } else if (TCG_TARGET_HAS_bswap64_i64) { 1879 tcg_gen_op3i_i64(INDEX_op_bswap64_i64, ret, arg, 0); 1880 } else { 1881 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1882 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1883 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 1884 1885 /* arg = abcdefgh */ 1886 tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull); 1887 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .abcdefg */ 1888 tcg_gen_and_i64(t1, arg, t2); /* t1 = .b.d.f.h */ 1889 tcg_gen_and_i64(t0, t0, t2); /* t0 = .a.c.e.g */ 1890 tcg_gen_shli_i64(t1, t1, 8); /* t1 = b.d.f.h. */ 1891 tcg_gen_or_i64(ret, t0, t1); /* ret = badcfehg */ 1892 1893 tcg_gen_movi_i64(t2, 0x0000ffff0000ffffull); 1894 tcg_gen_shri_i64(t0, ret, 16); /* t0 = ..badcfe */ 1895 tcg_gen_and_i64(t1, ret, t2); /* t1 = ..dc..hg */ 1896 tcg_gen_and_i64(t0, t0, t2); /* t0 = ..ba..fe */ 1897 tcg_gen_shli_i64(t1, t1, 16); /* t1 = dc..hg.. */ 1898 tcg_gen_or_i64(ret, t0, t1); /* ret = dcbahgfe */ 1899 1900 tcg_gen_shri_i64(t0, ret, 32); /* t0 = ....dcba */ 1901 tcg_gen_shli_i64(t1, ret, 32); /* t1 = hgfe.... */ 1902 tcg_gen_or_i64(ret, t0, t1); /* ret = hgfedcba */ 1903 1904 tcg_temp_free_i64(t0); 1905 tcg_temp_free_i64(t1); 1906 tcg_temp_free_i64(t2); 1907 } 1908 } 1909 1910 void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg) 1911 { 1912 uint64_t m = 0x0000ffff0000ffffull; 1913 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1914 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1915 1916 /* See include/qemu/bitops.h, hswap64. */ 1917 tcg_gen_rotli_i64(t1, arg, 32); 1918 tcg_gen_andi_i64(t0, t1, m); 1919 tcg_gen_shli_i64(t0, t0, 16); 1920 tcg_gen_shri_i64(t1, t1, 16); 1921 tcg_gen_andi_i64(t1, t1, m); 1922 tcg_gen_or_i64(ret, t0, t1); 1923 1924 tcg_temp_free_i64(t0); 1925 tcg_temp_free_i64(t1); 1926 } 1927 1928 void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg) 1929 { 1930 /* Swapping 2 32-bit elements is a rotate. */ 1931 tcg_gen_rotli_i64(ret, arg, 32); 1932 } 1933 1934 void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg) 1935 { 1936 if (TCG_TARGET_REG_BITS == 32) { 1937 tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1938 tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 1939 } else if (TCG_TARGET_HAS_not_i64) { 1940 tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg); 1941 } else { 1942 tcg_gen_xori_i64(ret, arg, -1); 1943 } 1944 } 1945 1946 void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1947 { 1948 if (TCG_TARGET_REG_BITS == 32) { 1949 tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1950 tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1951 } else if (TCG_TARGET_HAS_andc_i64) { 1952 tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2); 1953 } else { 1954 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1955 tcg_gen_not_i64(t0, arg2); 1956 tcg_gen_and_i64(ret, arg1, t0); 1957 tcg_temp_free_i64(t0); 1958 } 1959 } 1960 1961 void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1962 { 1963 if (TCG_TARGET_REG_BITS == 32) { 1964 tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1965 tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1966 } else if (TCG_TARGET_HAS_eqv_i64) { 1967 tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2); 1968 } else { 1969 tcg_gen_xor_i64(ret, arg1, arg2); 1970 tcg_gen_not_i64(ret, ret); 1971 } 1972 } 1973 1974 void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1975 { 1976 if (TCG_TARGET_REG_BITS == 32) { 1977 tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1978 tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1979 } else if (TCG_TARGET_HAS_nand_i64) { 1980 tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2); 1981 } else { 1982 tcg_gen_and_i64(ret, arg1, arg2); 1983 tcg_gen_not_i64(ret, ret); 1984 } 1985 } 1986 1987 void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1988 { 1989 if (TCG_TARGET_REG_BITS == 32) { 1990 tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1991 tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1992 } else if (TCG_TARGET_HAS_nor_i64) { 1993 tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2); 1994 } else { 1995 tcg_gen_or_i64(ret, arg1, arg2); 1996 tcg_gen_not_i64(ret, ret); 1997 } 1998 } 1999 2000 void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2001 { 2002 if (TCG_TARGET_REG_BITS == 32) { 2003 tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2004 tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2005 } else if (TCG_TARGET_HAS_orc_i64) { 2006 tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2); 2007 } else { 2008 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2009 tcg_gen_not_i64(t0, arg2); 2010 tcg_gen_or_i64(ret, arg1, t0); 2011 tcg_temp_free_i64(t0); 2012 } 2013 } 2014 2015 void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2016 { 2017 if (TCG_TARGET_HAS_clz_i64) { 2018 tcg_gen_op3_i64(INDEX_op_clz_i64, ret, arg1, arg2); 2019 } else { 2020 gen_helper_clz_i64(ret, arg1, arg2); 2021 } 2022 } 2023 2024 void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) 2025 { 2026 if (TCG_TARGET_REG_BITS == 32 2027 && TCG_TARGET_HAS_clz_i32 2028 && arg2 <= 0xffffffffu) { 2029 TCGv_i32 t = tcg_temp_ebb_new_i32(); 2030 tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32); 2031 tcg_gen_addi_i32(t, t, 32); 2032 tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t); 2033 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2034 tcg_temp_free_i32(t); 2035 } else { 2036 tcg_gen_clz_i64(ret, arg1, tcg_constant_i64(arg2)); 2037 } 2038 } 2039 2040 void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2041 { 2042 if (TCG_TARGET_HAS_ctz_i64) { 2043 tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2); 2044 } else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) { 2045 TCGv_i64 z, t = tcg_temp_ebb_new_i64(); 2046 2047 if (TCG_TARGET_HAS_ctpop_i64) { 2048 tcg_gen_subi_i64(t, arg1, 1); 2049 tcg_gen_andc_i64(t, t, arg1); 2050 tcg_gen_ctpop_i64(t, t); 2051 } else { 2052 /* Since all non-x86 hosts have clz(0) == 64, don't fight it. */ 2053 tcg_gen_neg_i64(t, arg1); 2054 tcg_gen_and_i64(t, t, arg1); 2055 tcg_gen_clzi_i64(t, t, 64); 2056 tcg_gen_xori_i64(t, t, 63); 2057 } 2058 z = tcg_constant_i64(0); 2059 tcg_gen_movcond_i64(TCG_COND_EQ, ret, arg1, z, arg2, t); 2060 tcg_temp_free_i64(t); 2061 tcg_temp_free_i64(z); 2062 } else { 2063 gen_helper_ctz_i64(ret, arg1, arg2); 2064 } 2065 } 2066 2067 void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) 2068 { 2069 if (TCG_TARGET_REG_BITS == 32 2070 && TCG_TARGET_HAS_ctz_i32 2071 && arg2 <= 0xffffffffu) { 2072 TCGv_i32 t32 = tcg_temp_ebb_new_i32(); 2073 tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32); 2074 tcg_gen_addi_i32(t32, t32, 32); 2075 tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32); 2076 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2077 tcg_temp_free_i32(t32); 2078 } else if (!TCG_TARGET_HAS_ctz_i64 2079 && TCG_TARGET_HAS_ctpop_i64 2080 && arg2 == 64) { 2081 /* This equivalence has the advantage of not requiring a fixup. */ 2082 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2083 tcg_gen_subi_i64(t, arg1, 1); 2084 tcg_gen_andc_i64(t, t, arg1); 2085 tcg_gen_ctpop_i64(ret, t); 2086 tcg_temp_free_i64(t); 2087 } else { 2088 tcg_gen_ctz_i64(ret, arg1, tcg_constant_i64(arg2)); 2089 } 2090 } 2091 2092 void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg) 2093 { 2094 if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) { 2095 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2096 tcg_gen_sari_i64(t, arg, 63); 2097 tcg_gen_xor_i64(t, t, arg); 2098 tcg_gen_clzi_i64(t, t, 64); 2099 tcg_gen_subi_i64(ret, t, 1); 2100 tcg_temp_free_i64(t); 2101 } else { 2102 gen_helper_clrsb_i64(ret, arg); 2103 } 2104 } 2105 2106 void tcg_gen_ctpop_i64(TCGv_i64 ret, TCGv_i64 arg1) 2107 { 2108 if (TCG_TARGET_HAS_ctpop_i64) { 2109 tcg_gen_op2_i64(INDEX_op_ctpop_i64, ret, arg1); 2110 } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_ctpop_i32) { 2111 tcg_gen_ctpop_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 2112 tcg_gen_ctpop_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 2113 tcg_gen_add_i32(TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret)); 2114 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2115 } else { 2116 gen_helper_ctpop_i64(ret, arg1); 2117 } 2118 } 2119 2120 void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2121 { 2122 if (TCG_TARGET_HAS_rot_i64) { 2123 tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2); 2124 } else { 2125 TCGv_i64 t0, t1; 2126 t0 = tcg_temp_ebb_new_i64(); 2127 t1 = tcg_temp_ebb_new_i64(); 2128 tcg_gen_shl_i64(t0, arg1, arg2); 2129 tcg_gen_subfi_i64(t1, 64, arg2); 2130 tcg_gen_shr_i64(t1, arg1, t1); 2131 tcg_gen_or_i64(ret, t0, t1); 2132 tcg_temp_free_i64(t0); 2133 tcg_temp_free_i64(t1); 2134 } 2135 } 2136 2137 void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 2138 { 2139 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 2140 /* some cases can be optimized here */ 2141 if (arg2 == 0) { 2142 tcg_gen_mov_i64(ret, arg1); 2143 } else if (TCG_TARGET_HAS_rot_i64) { 2144 tcg_gen_rotl_i64(ret, arg1, tcg_constant_i64(arg2)); 2145 } else { 2146 TCGv_i64 t0, t1; 2147 t0 = tcg_temp_ebb_new_i64(); 2148 t1 = tcg_temp_ebb_new_i64(); 2149 tcg_gen_shli_i64(t0, arg1, arg2); 2150 tcg_gen_shri_i64(t1, arg1, 64 - arg2); 2151 tcg_gen_or_i64(ret, t0, t1); 2152 tcg_temp_free_i64(t0); 2153 tcg_temp_free_i64(t1); 2154 } 2155 } 2156 2157 void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2158 { 2159 if (TCG_TARGET_HAS_rot_i64) { 2160 tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2); 2161 } else { 2162 TCGv_i64 t0, t1; 2163 t0 = tcg_temp_ebb_new_i64(); 2164 t1 = tcg_temp_ebb_new_i64(); 2165 tcg_gen_shr_i64(t0, arg1, arg2); 2166 tcg_gen_subfi_i64(t1, 64, arg2); 2167 tcg_gen_shl_i64(t1, arg1, t1); 2168 tcg_gen_or_i64(ret, t0, t1); 2169 tcg_temp_free_i64(t0); 2170 tcg_temp_free_i64(t1); 2171 } 2172 } 2173 2174 void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 2175 { 2176 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 2177 /* some cases can be optimized here */ 2178 if (arg2 == 0) { 2179 tcg_gen_mov_i64(ret, arg1); 2180 } else { 2181 tcg_gen_rotli_i64(ret, arg1, 64 - arg2); 2182 } 2183 } 2184 2185 void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2, 2186 unsigned int ofs, unsigned int len) 2187 { 2188 uint64_t mask; 2189 TCGv_i64 t1; 2190 2191 tcg_debug_assert(ofs < 64); 2192 tcg_debug_assert(len > 0); 2193 tcg_debug_assert(len <= 64); 2194 tcg_debug_assert(ofs + len <= 64); 2195 2196 if (len == 64) { 2197 tcg_gen_mov_i64(ret, arg2); 2198 return; 2199 } 2200 if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) { 2201 tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len); 2202 return; 2203 } 2204 2205 if (TCG_TARGET_REG_BITS == 32) { 2206 if (ofs >= 32) { 2207 tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 2208 TCGV_LOW(arg2), ofs - 32, len); 2209 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 2210 return; 2211 } 2212 if (ofs + len <= 32) { 2213 tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1), 2214 TCGV_LOW(arg2), ofs, len); 2215 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 2216 return; 2217 } 2218 } 2219 2220 t1 = tcg_temp_ebb_new_i64(); 2221 2222 if (TCG_TARGET_HAS_extract2_i64) { 2223 if (ofs + len == 64) { 2224 tcg_gen_shli_i64(t1, arg1, len); 2225 tcg_gen_extract2_i64(ret, t1, arg2, len); 2226 goto done; 2227 } 2228 if (ofs == 0) { 2229 tcg_gen_extract2_i64(ret, arg1, arg2, len); 2230 tcg_gen_rotli_i64(ret, ret, len); 2231 goto done; 2232 } 2233 } 2234 2235 mask = (1ull << len) - 1; 2236 if (ofs + len < 64) { 2237 tcg_gen_andi_i64(t1, arg2, mask); 2238 tcg_gen_shli_i64(t1, t1, ofs); 2239 } else { 2240 tcg_gen_shli_i64(t1, arg2, ofs); 2241 } 2242 tcg_gen_andi_i64(ret, arg1, ~(mask << ofs)); 2243 tcg_gen_or_i64(ret, ret, t1); 2244 done: 2245 tcg_temp_free_i64(t1); 2246 } 2247 2248 void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg, 2249 unsigned int ofs, unsigned int len) 2250 { 2251 tcg_debug_assert(ofs < 64); 2252 tcg_debug_assert(len > 0); 2253 tcg_debug_assert(len <= 64); 2254 tcg_debug_assert(ofs + len <= 64); 2255 2256 if (ofs + len == 64) { 2257 tcg_gen_shli_i64(ret, arg, ofs); 2258 } else if (ofs == 0) { 2259 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1); 2260 } else if (TCG_TARGET_HAS_deposit_i64 2261 && TCG_TARGET_deposit_i64_valid(ofs, len)) { 2262 TCGv_i64 zero = tcg_constant_i64(0); 2263 tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len); 2264 } else { 2265 if (TCG_TARGET_REG_BITS == 32) { 2266 if (ofs >= 32) { 2267 tcg_gen_deposit_z_i32(TCGV_HIGH(ret), TCGV_LOW(arg), 2268 ofs - 32, len); 2269 tcg_gen_movi_i32(TCGV_LOW(ret), 0); 2270 return; 2271 } 2272 if (ofs + len <= 32) { 2273 tcg_gen_deposit_z_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); 2274 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2275 return; 2276 } 2277 } 2278 /* To help two-operand hosts we prefer to zero-extend first, 2279 which allows ARG to stay live. */ 2280 switch (len) { 2281 case 32: 2282 if (TCG_TARGET_HAS_ext32u_i64) { 2283 tcg_gen_ext32u_i64(ret, arg); 2284 tcg_gen_shli_i64(ret, ret, ofs); 2285 return; 2286 } 2287 break; 2288 case 16: 2289 if (TCG_TARGET_HAS_ext16u_i64) { 2290 tcg_gen_ext16u_i64(ret, arg); 2291 tcg_gen_shli_i64(ret, ret, ofs); 2292 return; 2293 } 2294 break; 2295 case 8: 2296 if (TCG_TARGET_HAS_ext8u_i64) { 2297 tcg_gen_ext8u_i64(ret, arg); 2298 tcg_gen_shli_i64(ret, ret, ofs); 2299 return; 2300 } 2301 break; 2302 } 2303 /* Otherwise prefer zero-extension over AND for code size. */ 2304 switch (ofs + len) { 2305 case 32: 2306 if (TCG_TARGET_HAS_ext32u_i64) { 2307 tcg_gen_shli_i64(ret, arg, ofs); 2308 tcg_gen_ext32u_i64(ret, ret); 2309 return; 2310 } 2311 break; 2312 case 16: 2313 if (TCG_TARGET_HAS_ext16u_i64) { 2314 tcg_gen_shli_i64(ret, arg, ofs); 2315 tcg_gen_ext16u_i64(ret, ret); 2316 return; 2317 } 2318 break; 2319 case 8: 2320 if (TCG_TARGET_HAS_ext8u_i64) { 2321 tcg_gen_shli_i64(ret, arg, ofs); 2322 tcg_gen_ext8u_i64(ret, ret); 2323 return; 2324 } 2325 break; 2326 } 2327 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1); 2328 tcg_gen_shli_i64(ret, ret, ofs); 2329 } 2330 } 2331 2332 void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg, 2333 unsigned int ofs, unsigned int len) 2334 { 2335 tcg_debug_assert(ofs < 64); 2336 tcg_debug_assert(len > 0); 2337 tcg_debug_assert(len <= 64); 2338 tcg_debug_assert(ofs + len <= 64); 2339 2340 /* Canonicalize certain special cases, even if extract is supported. */ 2341 if (ofs + len == 64) { 2342 tcg_gen_shri_i64(ret, arg, 64 - len); 2343 return; 2344 } 2345 if (ofs == 0) { 2346 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1); 2347 return; 2348 } 2349 2350 if (TCG_TARGET_REG_BITS == 32) { 2351 /* Look for a 32-bit extract within one of the two words. */ 2352 if (ofs >= 32) { 2353 tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len); 2354 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2355 return; 2356 } 2357 if (ofs + len <= 32) { 2358 tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); 2359 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2360 return; 2361 } 2362 /* The field is split across two words. One double-word 2363 shift is better than two double-word shifts. */ 2364 goto do_shift_and; 2365 } 2366 2367 if (TCG_TARGET_HAS_extract_i64 2368 && TCG_TARGET_extract_i64_valid(ofs, len)) { 2369 tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len); 2370 return; 2371 } 2372 2373 /* Assume that zero-extension, if available, is cheaper than a shift. */ 2374 switch (ofs + len) { 2375 case 32: 2376 if (TCG_TARGET_HAS_ext32u_i64) { 2377 tcg_gen_ext32u_i64(ret, arg); 2378 tcg_gen_shri_i64(ret, ret, ofs); 2379 return; 2380 } 2381 break; 2382 case 16: 2383 if (TCG_TARGET_HAS_ext16u_i64) { 2384 tcg_gen_ext16u_i64(ret, arg); 2385 tcg_gen_shri_i64(ret, ret, ofs); 2386 return; 2387 } 2388 break; 2389 case 8: 2390 if (TCG_TARGET_HAS_ext8u_i64) { 2391 tcg_gen_ext8u_i64(ret, arg); 2392 tcg_gen_shri_i64(ret, ret, ofs); 2393 return; 2394 } 2395 break; 2396 } 2397 2398 /* ??? Ideally we'd know what values are available for immediate AND. 2399 Assume that 8 bits are available, plus the special cases of 16 and 32, 2400 so that we get ext8u, ext16u, and ext32u. */ 2401 switch (len) { 2402 case 1 ... 8: case 16: case 32: 2403 do_shift_and: 2404 tcg_gen_shri_i64(ret, arg, ofs); 2405 tcg_gen_andi_i64(ret, ret, (1ull << len) - 1); 2406 break; 2407 default: 2408 tcg_gen_shli_i64(ret, arg, 64 - len - ofs); 2409 tcg_gen_shri_i64(ret, ret, 64 - len); 2410 break; 2411 } 2412 } 2413 2414 void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg, 2415 unsigned int ofs, unsigned int len) 2416 { 2417 tcg_debug_assert(ofs < 64); 2418 tcg_debug_assert(len > 0); 2419 tcg_debug_assert(len <= 64); 2420 tcg_debug_assert(ofs + len <= 64); 2421 2422 /* Canonicalize certain special cases, even if sextract is supported. */ 2423 if (ofs + len == 64) { 2424 tcg_gen_sari_i64(ret, arg, 64 - len); 2425 return; 2426 } 2427 if (ofs == 0) { 2428 switch (len) { 2429 case 32: 2430 tcg_gen_ext32s_i64(ret, arg); 2431 return; 2432 case 16: 2433 tcg_gen_ext16s_i64(ret, arg); 2434 return; 2435 case 8: 2436 tcg_gen_ext8s_i64(ret, arg); 2437 return; 2438 } 2439 } 2440 2441 if (TCG_TARGET_REG_BITS == 32) { 2442 /* Look for a 32-bit extract within one of the two words. */ 2443 if (ofs >= 32) { 2444 tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len); 2445 } else if (ofs + len <= 32) { 2446 tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); 2447 } else if (ofs == 0) { 2448 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2449 tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32); 2450 return; 2451 } else if (len > 32) { 2452 TCGv_i32 t = tcg_temp_ebb_new_i32(); 2453 /* Extract the bits for the high word normally. */ 2454 tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32); 2455 /* Shift the field down for the low part. */ 2456 tcg_gen_shri_i64(ret, arg, ofs); 2457 /* Overwrite the shift into the high part. */ 2458 tcg_gen_mov_i32(TCGV_HIGH(ret), t); 2459 tcg_temp_free_i32(t); 2460 return; 2461 } else { 2462 /* Shift the field down for the low part, such that the 2463 field sits at the MSB. */ 2464 tcg_gen_shri_i64(ret, arg, ofs + len - 32); 2465 /* Shift the field down from the MSB, sign extending. */ 2466 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_LOW(ret), 32 - len); 2467 } 2468 /* Sign-extend the field from 32 bits. */ 2469 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2470 return; 2471 } 2472 2473 if (TCG_TARGET_HAS_sextract_i64 2474 && TCG_TARGET_extract_i64_valid(ofs, len)) { 2475 tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len); 2476 return; 2477 } 2478 2479 /* Assume that sign-extension, if available, is cheaper than a shift. */ 2480 switch (ofs + len) { 2481 case 32: 2482 if (TCG_TARGET_HAS_ext32s_i64) { 2483 tcg_gen_ext32s_i64(ret, arg); 2484 tcg_gen_sari_i64(ret, ret, ofs); 2485 return; 2486 } 2487 break; 2488 case 16: 2489 if (TCG_TARGET_HAS_ext16s_i64) { 2490 tcg_gen_ext16s_i64(ret, arg); 2491 tcg_gen_sari_i64(ret, ret, ofs); 2492 return; 2493 } 2494 break; 2495 case 8: 2496 if (TCG_TARGET_HAS_ext8s_i64) { 2497 tcg_gen_ext8s_i64(ret, arg); 2498 tcg_gen_sari_i64(ret, ret, ofs); 2499 return; 2500 } 2501 break; 2502 } 2503 switch (len) { 2504 case 32: 2505 if (TCG_TARGET_HAS_ext32s_i64) { 2506 tcg_gen_shri_i64(ret, arg, ofs); 2507 tcg_gen_ext32s_i64(ret, ret); 2508 return; 2509 } 2510 break; 2511 case 16: 2512 if (TCG_TARGET_HAS_ext16s_i64) { 2513 tcg_gen_shri_i64(ret, arg, ofs); 2514 tcg_gen_ext16s_i64(ret, ret); 2515 return; 2516 } 2517 break; 2518 case 8: 2519 if (TCG_TARGET_HAS_ext8s_i64) { 2520 tcg_gen_shri_i64(ret, arg, ofs); 2521 tcg_gen_ext8s_i64(ret, ret); 2522 return; 2523 } 2524 break; 2525 } 2526 tcg_gen_shli_i64(ret, arg, 64 - len - ofs); 2527 tcg_gen_sari_i64(ret, ret, 64 - len); 2528 } 2529 2530 /* 2531 * Extract 64 bits from a 128-bit input, ah:al, starting from ofs. 2532 * Unlike tcg_gen_extract_i64 above, len is fixed at 64. 2533 */ 2534 void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah, 2535 unsigned int ofs) 2536 { 2537 tcg_debug_assert(ofs <= 64); 2538 if (ofs == 0) { 2539 tcg_gen_mov_i64(ret, al); 2540 } else if (ofs == 64) { 2541 tcg_gen_mov_i64(ret, ah); 2542 } else if (al == ah) { 2543 tcg_gen_rotri_i64(ret, al, ofs); 2544 } else if (TCG_TARGET_HAS_extract2_i64) { 2545 tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs); 2546 } else { 2547 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2548 tcg_gen_shri_i64(t0, al, ofs); 2549 tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs); 2550 tcg_temp_free_i64(t0); 2551 } 2552 } 2553 2554 void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1, 2555 TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2) 2556 { 2557 if (cond == TCG_COND_ALWAYS) { 2558 tcg_gen_mov_i64(ret, v1); 2559 } else if (cond == TCG_COND_NEVER) { 2560 tcg_gen_mov_i64(ret, v2); 2561 } else if (TCG_TARGET_REG_BITS == 32) { 2562 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 2563 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 2564 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0, 2565 TCGV_LOW(c1), TCGV_HIGH(c1), 2566 TCGV_LOW(c2), TCGV_HIGH(c2), cond); 2567 2568 if (TCG_TARGET_HAS_movcond_i32) { 2569 tcg_gen_movi_i32(t1, 0); 2570 tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, t1, 2571 TCGV_LOW(v1), TCGV_LOW(v2)); 2572 tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, t1, 2573 TCGV_HIGH(v1), TCGV_HIGH(v2)); 2574 } else { 2575 tcg_gen_neg_i32(t0, t0); 2576 2577 tcg_gen_and_i32(t1, TCGV_LOW(v1), t0); 2578 tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0); 2579 tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1); 2580 2581 tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0); 2582 tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0); 2583 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1); 2584 } 2585 tcg_temp_free_i32(t0); 2586 tcg_temp_free_i32(t1); 2587 } else if (TCG_TARGET_HAS_movcond_i64) { 2588 tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond); 2589 } else { 2590 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2591 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2592 tcg_gen_negsetcond_i64(cond, t0, c1, c2); 2593 tcg_gen_and_i64(t1, v1, t0); 2594 tcg_gen_andc_i64(ret, v2, t0); 2595 tcg_gen_or_i64(ret, ret, t1); 2596 tcg_temp_free_i64(t0); 2597 tcg_temp_free_i64(t1); 2598 } 2599 } 2600 2601 void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 2602 TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 2603 { 2604 if (TCG_TARGET_HAS_add2_i64) { 2605 tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh); 2606 } else { 2607 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2608 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2609 tcg_gen_add_i64(t0, al, bl); 2610 tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al); 2611 tcg_gen_add_i64(rh, ah, bh); 2612 tcg_gen_add_i64(rh, rh, t1); 2613 tcg_gen_mov_i64(rl, t0); 2614 tcg_temp_free_i64(t0); 2615 tcg_temp_free_i64(t1); 2616 } 2617 } 2618 2619 void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 2620 TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 2621 { 2622 if (TCG_TARGET_HAS_sub2_i64) { 2623 tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh); 2624 } else { 2625 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2626 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2627 tcg_gen_sub_i64(t0, al, bl); 2628 tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl); 2629 tcg_gen_sub_i64(rh, ah, bh); 2630 tcg_gen_sub_i64(rh, rh, t1); 2631 tcg_gen_mov_i64(rl, t0); 2632 tcg_temp_free_i64(t0); 2633 tcg_temp_free_i64(t1); 2634 } 2635 } 2636 2637 void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 2638 { 2639 if (TCG_TARGET_HAS_mulu2_i64) { 2640 tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2); 2641 } else if (TCG_TARGET_HAS_muluh_i64) { 2642 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2643 tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); 2644 tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2); 2645 tcg_gen_mov_i64(rl, t); 2646 tcg_temp_free_i64(t); 2647 } else { 2648 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2649 tcg_gen_mul_i64(t0, arg1, arg2); 2650 gen_helper_muluh_i64(rh, arg1, arg2); 2651 tcg_gen_mov_i64(rl, t0); 2652 tcg_temp_free_i64(t0); 2653 } 2654 } 2655 2656 void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 2657 { 2658 if (TCG_TARGET_HAS_muls2_i64) { 2659 tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2); 2660 } else if (TCG_TARGET_HAS_mulsh_i64) { 2661 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2662 tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); 2663 tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2); 2664 tcg_gen_mov_i64(rl, t); 2665 tcg_temp_free_i64(t); 2666 } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) { 2667 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2668 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2669 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 2670 TCGv_i64 t3 = tcg_temp_ebb_new_i64(); 2671 tcg_gen_mulu2_i64(t0, t1, arg1, arg2); 2672 /* Adjust for negative inputs. */ 2673 tcg_gen_sari_i64(t2, arg1, 63); 2674 tcg_gen_sari_i64(t3, arg2, 63); 2675 tcg_gen_and_i64(t2, t2, arg2); 2676 tcg_gen_and_i64(t3, t3, arg1); 2677 tcg_gen_sub_i64(rh, t1, t2); 2678 tcg_gen_sub_i64(rh, rh, t3); 2679 tcg_gen_mov_i64(rl, t0); 2680 tcg_temp_free_i64(t0); 2681 tcg_temp_free_i64(t1); 2682 tcg_temp_free_i64(t2); 2683 tcg_temp_free_i64(t3); 2684 } else { 2685 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2686 tcg_gen_mul_i64(t0, arg1, arg2); 2687 gen_helper_mulsh_i64(rh, arg1, arg2); 2688 tcg_gen_mov_i64(rl, t0); 2689 tcg_temp_free_i64(t0); 2690 } 2691 } 2692 2693 void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 2694 { 2695 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2696 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2697 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 2698 tcg_gen_mulu2_i64(t0, t1, arg1, arg2); 2699 /* Adjust for negative input for the signed arg1. */ 2700 tcg_gen_sari_i64(t2, arg1, 63); 2701 tcg_gen_and_i64(t2, t2, arg2); 2702 tcg_gen_sub_i64(rh, t1, t2); 2703 tcg_gen_mov_i64(rl, t0); 2704 tcg_temp_free_i64(t0); 2705 tcg_temp_free_i64(t1); 2706 tcg_temp_free_i64(t2); 2707 } 2708 2709 void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 2710 { 2711 tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b); 2712 } 2713 2714 void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 2715 { 2716 tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b); 2717 } 2718 2719 void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 2720 { 2721 tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a); 2722 } 2723 2724 void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 2725 { 2726 tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a); 2727 } 2728 2729 void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a) 2730 { 2731 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2732 2733 tcg_gen_sari_i64(t, a, 63); 2734 tcg_gen_xor_i64(ret, a, t); 2735 tcg_gen_sub_i64(ret, ret, t); 2736 tcg_temp_free_i64(t); 2737 } 2738 2739 /* Size changing operations. */ 2740 2741 void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg) 2742 { 2743 if (TCG_TARGET_REG_BITS == 32) { 2744 tcg_gen_mov_i32(ret, TCGV_LOW(arg)); 2745 } else if (TCG_TARGET_HAS_extr_i64_i32) { 2746 tcg_gen_op2(INDEX_op_extrl_i64_i32, 2747 tcgv_i32_arg(ret), tcgv_i64_arg(arg)); 2748 } else { 2749 tcg_gen_mov_i32(ret, (TCGv_i32)arg); 2750 } 2751 } 2752 2753 void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg) 2754 { 2755 if (TCG_TARGET_REG_BITS == 32) { 2756 tcg_gen_mov_i32(ret, TCGV_HIGH(arg)); 2757 } else if (TCG_TARGET_HAS_extr_i64_i32) { 2758 tcg_gen_op2(INDEX_op_extrh_i64_i32, 2759 tcgv_i32_arg(ret), tcgv_i64_arg(arg)); 2760 } else { 2761 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2762 tcg_gen_shri_i64(t, arg, 32); 2763 tcg_gen_mov_i32(ret, (TCGv_i32)t); 2764 tcg_temp_free_i64(t); 2765 } 2766 } 2767 2768 void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 2769 { 2770 if (TCG_TARGET_REG_BITS == 32) { 2771 tcg_gen_mov_i32(TCGV_LOW(ret), arg); 2772 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2773 } else { 2774 tcg_gen_op2(INDEX_op_extu_i32_i64, 2775 tcgv_i64_arg(ret), tcgv_i32_arg(arg)); 2776 } 2777 } 2778 2779 void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 2780 { 2781 if (TCG_TARGET_REG_BITS == 32) { 2782 tcg_gen_mov_i32(TCGV_LOW(ret), arg); 2783 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2784 } else { 2785 tcg_gen_op2(INDEX_op_ext_i32_i64, 2786 tcgv_i64_arg(ret), tcgv_i32_arg(arg)); 2787 } 2788 } 2789 2790 void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high) 2791 { 2792 TCGv_i64 tmp; 2793 2794 if (TCG_TARGET_REG_BITS == 32) { 2795 tcg_gen_mov_i32(TCGV_LOW(dest), low); 2796 tcg_gen_mov_i32(TCGV_HIGH(dest), high); 2797 return; 2798 } 2799 2800 tmp = tcg_temp_ebb_new_i64(); 2801 /* These extensions are only needed for type correctness. 2802 We may be able to do better given target specific information. */ 2803 tcg_gen_extu_i32_i64(tmp, high); 2804 tcg_gen_extu_i32_i64(dest, low); 2805 /* If deposit is available, use it. Otherwise use the extra 2806 knowledge that we have of the zero-extensions above. */ 2807 if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) { 2808 tcg_gen_deposit_i64(dest, dest, tmp, 32, 32); 2809 } else { 2810 tcg_gen_shli_i64(tmp, tmp, 32); 2811 tcg_gen_or_i64(dest, dest, tmp); 2812 } 2813 tcg_temp_free_i64(tmp); 2814 } 2815 2816 void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg) 2817 { 2818 if (TCG_TARGET_REG_BITS == 32) { 2819 tcg_gen_mov_i32(lo, TCGV_LOW(arg)); 2820 tcg_gen_mov_i32(hi, TCGV_HIGH(arg)); 2821 } else { 2822 tcg_gen_extrl_i64_i32(lo, arg); 2823 tcg_gen_extrh_i64_i32(hi, arg); 2824 } 2825 } 2826 2827 void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg) 2828 { 2829 tcg_gen_ext32u_i64(lo, arg); 2830 tcg_gen_shri_i64(hi, arg, 32); 2831 } 2832 2833 void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg) 2834 { 2835 tcg_gen_mov_i64(lo, TCGV128_LOW(arg)); 2836 tcg_gen_mov_i64(hi, TCGV128_HIGH(arg)); 2837 } 2838 2839 void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi) 2840 { 2841 tcg_gen_mov_i64(TCGV128_LOW(ret), lo); 2842 tcg_gen_mov_i64(TCGV128_HIGH(ret), hi); 2843 } 2844 2845 void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src) 2846 { 2847 if (dst != src) { 2848 tcg_gen_mov_i64(TCGV128_LOW(dst), TCGV128_LOW(src)); 2849 tcg_gen_mov_i64(TCGV128_HIGH(dst), TCGV128_HIGH(src)); 2850 } 2851 } 2852 2853 /* QEMU specific operations. */ 2854 2855 void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx) 2856 { 2857 /* 2858 * Let the jit code return the read-only version of the 2859 * TranslationBlock, so that we minimize the pc-relative 2860 * distance of the address of the exit_tb code to TB. 2861 * This will improve utilization of pc-relative address loads. 2862 * 2863 * TODO: Move this to translator_loop, so that all const 2864 * TranslationBlock pointers refer to read-only memory. 2865 * This requires coordination with targets that do not use 2866 * the translator_loop. 2867 */ 2868 uintptr_t val = (uintptr_t)tcg_splitwx_to_rx((void *)tb) + idx; 2869 2870 if (tb == NULL) { 2871 tcg_debug_assert(idx == 0); 2872 } else if (idx <= TB_EXIT_IDXMAX) { 2873 #ifdef CONFIG_DEBUG_TCG 2874 /* This is an exit following a goto_tb. Verify that we have 2875 seen this numbered exit before, via tcg_gen_goto_tb. */ 2876 tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx)); 2877 #endif 2878 } else { 2879 /* This is an exit via the exitreq label. */ 2880 tcg_debug_assert(idx == TB_EXIT_REQUESTED); 2881 } 2882 2883 tcg_gen_op1i(INDEX_op_exit_tb, val); 2884 } 2885 2886 void tcg_gen_goto_tb(unsigned idx) 2887 { 2888 /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */ 2889 tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB)); 2890 /* We only support two chained exits. */ 2891 tcg_debug_assert(idx <= TB_EXIT_IDXMAX); 2892 #ifdef CONFIG_DEBUG_TCG 2893 /* Verify that we haven't seen this numbered exit before. */ 2894 tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0); 2895 tcg_ctx->goto_tb_issue_mask |= 1 << idx; 2896 #endif 2897 plugin_gen_disable_mem_helpers(); 2898 tcg_gen_op1i(INDEX_op_goto_tb, idx); 2899 } 2900 2901 void tcg_gen_lookup_and_goto_ptr(void) 2902 { 2903 TCGv_ptr ptr; 2904 2905 if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) { 2906 tcg_gen_exit_tb(NULL, 0); 2907 return; 2908 } 2909 2910 plugin_gen_disable_mem_helpers(); 2911 ptr = tcg_temp_ebb_new_ptr(); 2912 gen_helper_lookup_tb_ptr(ptr, cpu_env); 2913 tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr)); 2914 tcg_temp_free_ptr(ptr); 2915 } 2916