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