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 #include "tcg-has.h" 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, 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, 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, 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, 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, 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 default: 418 /* 419 * Canonicalize on extract, if valid. This aids x86 with its 420 * 2 operand MOVZBL and 2 operand AND, selecting the TCGOpcode 421 * which does not require matching operands. Other backends can 422 * trivially expand the extract to AND during code generation. 423 */ 424 if (!(arg2 & (arg2 + 1))) { 425 unsigned len = ctz32(~arg2); 426 if (TCG_TARGET_extract_valid(TCG_TYPE_I32, 0, len)) { 427 tcg_gen_extract_i32(ret, arg1, 0, len); 428 return; 429 } 430 } 431 break; 432 } 433 434 tcg_gen_and_i32(ret, arg1, tcg_constant_i32(arg2)); 435 } 436 437 void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 438 { 439 tcg_gen_op3_i32(INDEX_op_or, ret, arg1, arg2); 440 } 441 442 void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 443 { 444 /* Some cases can be optimized here. */ 445 if (arg2 == -1) { 446 tcg_gen_movi_i32(ret, -1); 447 } else if (arg2 == 0) { 448 tcg_gen_mov_i32(ret, arg1); 449 } else { 450 tcg_gen_or_i32(ret, arg1, tcg_constant_i32(arg2)); 451 } 452 } 453 454 void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 455 { 456 tcg_gen_op3_i32(INDEX_op_xor, ret, arg1, arg2); 457 } 458 459 void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 460 { 461 /* Some cases can be optimized here. */ 462 if (arg2 == 0) { 463 tcg_gen_mov_i32(ret, arg1); 464 } else if (arg2 == -1 && 465 tcg_op_supported(INDEX_op_not, TCG_TYPE_I32, 0)) { 466 /* Don't recurse with tcg_gen_not_i32. */ 467 tcg_gen_op2_i32(INDEX_op_not, ret, arg1); 468 } else { 469 tcg_gen_xor_i32(ret, arg1, tcg_constant_i32(arg2)); 470 } 471 } 472 473 void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg) 474 { 475 if (tcg_op_supported(INDEX_op_not, TCG_TYPE_I32, 0)) { 476 tcg_gen_op2_i32(INDEX_op_not, ret, arg); 477 } else { 478 tcg_gen_xori_i32(ret, arg, -1); 479 } 480 } 481 482 void tcg_gen_shl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 483 { 484 tcg_gen_op3_i32(INDEX_op_shl, ret, arg1, arg2); 485 } 486 487 void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 488 { 489 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 490 if (arg2 == 0) { 491 tcg_gen_mov_i32(ret, arg1); 492 } else { 493 tcg_gen_shl_i32(ret, arg1, tcg_constant_i32(arg2)); 494 } 495 } 496 497 void tcg_gen_shr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 498 { 499 tcg_gen_op3_i32(INDEX_op_shr, ret, arg1, arg2); 500 } 501 502 void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 503 { 504 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 505 if (arg2 == 0) { 506 tcg_gen_mov_i32(ret, arg1); 507 } else { 508 tcg_gen_shr_i32(ret, arg1, tcg_constant_i32(arg2)); 509 } 510 } 511 512 void tcg_gen_sar_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 513 { 514 tcg_gen_op3_i32(INDEX_op_sar, ret, arg1, arg2); 515 } 516 517 void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 518 { 519 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 520 if (arg2 == 0) { 521 tcg_gen_mov_i32(ret, arg1); 522 } else { 523 tcg_gen_sar_i32(ret, arg1, tcg_constant_i32(arg2)); 524 } 525 } 526 527 void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l) 528 { 529 if (cond == TCG_COND_ALWAYS) { 530 tcg_gen_br(l); 531 } else if (cond != TCG_COND_NEVER) { 532 TCGOp *op = tcg_gen_op4ii_i32(INDEX_op_brcond, 533 arg1, arg2, cond, label_arg(l)); 534 add_as_label_use(l, op); 535 } 536 } 537 538 void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l) 539 { 540 if (cond == TCG_COND_ALWAYS) { 541 tcg_gen_br(l); 542 } else if (cond != TCG_COND_NEVER) { 543 tcg_gen_brcond_i32(cond, arg1, tcg_constant_i32(arg2), l); 544 } 545 } 546 547 void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret, 548 TCGv_i32 arg1, TCGv_i32 arg2) 549 { 550 if (cond == TCG_COND_ALWAYS) { 551 tcg_gen_movi_i32(ret, 1); 552 } else if (cond == TCG_COND_NEVER) { 553 tcg_gen_movi_i32(ret, 0); 554 } else { 555 tcg_gen_op4i_i32(INDEX_op_setcond, ret, arg1, arg2, cond); 556 } 557 } 558 559 void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret, 560 TCGv_i32 arg1, int32_t arg2) 561 { 562 tcg_gen_setcond_i32(cond, ret, arg1, tcg_constant_i32(arg2)); 563 } 564 565 void tcg_gen_negsetcond_i32(TCGCond cond, TCGv_i32 ret, 566 TCGv_i32 arg1, TCGv_i32 arg2) 567 { 568 if (cond == TCG_COND_ALWAYS) { 569 tcg_gen_movi_i32(ret, -1); 570 } else if (cond == TCG_COND_NEVER) { 571 tcg_gen_movi_i32(ret, 0); 572 } else { 573 tcg_gen_op4i_i32(INDEX_op_negsetcond, ret, arg1, arg2, cond); 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, 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_op_supported(INDEX_op_divs, TCG_TYPE_I32, 0)) { 602 tcg_gen_op3_i32(INDEX_op_divs, ret, arg1, arg2); 603 } else if (tcg_op_supported(INDEX_op_divs2, TCG_TYPE_I32, 0)) { 604 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 605 tcg_gen_sari_i32(t0, arg1, 31); 606 tcg_gen_op5_i32(INDEX_op_divs2, 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_op_supported(INDEX_op_rems, TCG_TYPE_I32, 0)) { 616 tcg_gen_op3_i32(INDEX_op_rems, ret, arg1, arg2); 617 } else if (tcg_op_supported(INDEX_op_divs, TCG_TYPE_I32, 0)) { 618 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 619 tcg_gen_op3_i32(INDEX_op_divs, 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_op_supported(INDEX_op_divs2, TCG_TYPE_I32, 0)) { 624 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 625 tcg_gen_sari_i32(t0, arg1, 31); 626 tcg_gen_op5_i32(INDEX_op_divs2, 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_op_supported(INDEX_op_divu, TCG_TYPE_I32, 0)) { 636 tcg_gen_op3_i32(INDEX_op_divu, ret, arg1, arg2); 637 } else if (tcg_op_supported(INDEX_op_divu2, TCG_TYPE_I32, 0)) { 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, 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_op_supported(INDEX_op_remu, TCG_TYPE_I32, 0)) { 650 tcg_gen_op3_i32(INDEX_op_remu, ret, arg1, arg2); 651 } else if (tcg_op_supported(INDEX_op_divu, TCG_TYPE_I32, 0)) { 652 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 653 tcg_gen_op3_i32(INDEX_op_divu, 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_op_supported(INDEX_op_divu2, TCG_TYPE_I32, 0)) { 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, 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_op_supported(INDEX_op_andc, TCG_TYPE_I32, 0)) { 670 tcg_gen_op3_i32(INDEX_op_andc, 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_op_supported(INDEX_op_eqv, TCG_TYPE_I32, 0)) { 682 tcg_gen_op3_i32(INDEX_op_eqv, 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_op_supported(INDEX_op_nand, TCG_TYPE_I32, 0)) { 692 tcg_gen_op3_i32(INDEX_op_nand, 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_op_supported(INDEX_op_nor, TCG_TYPE_I32, 0)) { 702 tcg_gen_op3_i32(INDEX_op_nor, 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_op_supported(INDEX_op_orc, TCG_TYPE_I32, 0)) { 712 tcg_gen_op3_i32(INDEX_op_orc, 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_op_supported(INDEX_op_clz, TCG_TYPE_I32, 0)) { 724 tcg_gen_op3_i32(INDEX_op_clz, ret, arg1, arg2); 725 } else if (tcg_op_supported(INDEX_op_clz, TCG_TYPE_I64, 0)) { 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 TCGv_i32 z, t; 749 750 if (tcg_op_supported(INDEX_op_ctz, TCG_TYPE_I32, 0)) { 751 tcg_gen_op3_i32(INDEX_op_ctz, ret, arg1, arg2); 752 return; 753 } 754 if (tcg_op_supported(INDEX_op_ctz, TCG_TYPE_I64, 0)) { 755 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 756 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 757 tcg_gen_extu_i32_i64(t1, arg1); 758 tcg_gen_extu_i32_i64(t2, arg2); 759 tcg_gen_ctz_i64(t1, t1, t2); 760 tcg_gen_extrl_i64_i32(ret, t1); 761 tcg_temp_free_i64(t1); 762 tcg_temp_free_i64(t2); 763 return; 764 } 765 if (tcg_op_supported(INDEX_op_ctpop, TCG_TYPE_REG, 0)) { 766 t = tcg_temp_ebb_new_i32(); 767 tcg_gen_subi_i32(t, arg1, 1); 768 tcg_gen_andc_i32(t, t, arg1); 769 tcg_gen_ctpop_i32(t, t); 770 } else if (tcg_op_supported(INDEX_op_clz, TCG_TYPE_REG, 0)) { 771 t = tcg_temp_ebb_new_i32(); 772 tcg_gen_neg_i32(t, arg1); 773 tcg_gen_and_i32(t, t, arg1); 774 tcg_gen_clzi_i32(t, t, 32); 775 tcg_gen_xori_i32(t, t, 31); 776 } else { 777 gen_helper_ctz_i32(ret, arg1, arg2); 778 return; 779 } 780 781 z = tcg_constant_i32(0); 782 tcg_gen_movcond_i32(TCG_COND_EQ, ret, arg1, z, arg2, t); 783 tcg_temp_free_i32(t); 784 } 785 786 void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2) 787 { 788 if (arg2 == 32 789 && !tcg_op_supported(INDEX_op_ctz, TCG_TYPE_I32, 0) 790 && tcg_op_supported(INDEX_op_ctpop, TCG_TYPE_REG, 0)) { 791 /* This equivalence has the advantage of not requiring a fixup. */ 792 TCGv_i32 t = tcg_temp_ebb_new_i32(); 793 tcg_gen_subi_i32(t, arg1, 1); 794 tcg_gen_andc_i32(t, t, arg1); 795 tcg_gen_ctpop_i32(ret, t); 796 tcg_temp_free_i32(t); 797 } else { 798 tcg_gen_ctz_i32(ret, arg1, tcg_constant_i32(arg2)); 799 } 800 } 801 802 void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg) 803 { 804 if (tcg_op_supported(INDEX_op_clz, TCG_TYPE_REG, 0)) { 805 TCGv_i32 t = tcg_temp_ebb_new_i32(); 806 tcg_gen_sari_i32(t, arg, 31); 807 tcg_gen_xor_i32(t, t, arg); 808 tcg_gen_clzi_i32(t, t, 32); 809 tcg_gen_subi_i32(ret, t, 1); 810 tcg_temp_free_i32(t); 811 } else { 812 gen_helper_clrsb_i32(ret, arg); 813 } 814 } 815 816 void tcg_gen_ctpop_i32(TCGv_i32 ret, TCGv_i32 arg1) 817 { 818 if (tcg_op_supported(INDEX_op_ctpop, TCG_TYPE_I32, 0)) { 819 tcg_gen_op2_i32(INDEX_op_ctpop, ret, arg1); 820 } else if (tcg_op_supported(INDEX_op_ctpop, TCG_TYPE_I64, 0)) { 821 TCGv_i64 t = tcg_temp_ebb_new_i64(); 822 tcg_gen_extu_i32_i64(t, arg1); 823 tcg_gen_ctpop_i64(t, t); 824 tcg_gen_extrl_i64_i32(ret, t); 825 tcg_temp_free_i64(t); 826 } else { 827 gen_helper_ctpop_i32(ret, arg1); 828 } 829 } 830 831 void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 832 { 833 if (tcg_op_supported(INDEX_op_rotl, TCG_TYPE_I32, 0)) { 834 tcg_gen_op3_i32(INDEX_op_rotl, ret, arg1, arg2); 835 } else if (tcg_op_supported(INDEX_op_rotr, TCG_TYPE_I32, 0)) { 836 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 837 tcg_gen_neg_i32(t0, arg2); 838 tcg_gen_op3_i32(INDEX_op_rotr, ret, arg1, t0); 839 tcg_temp_free_i32(t0); 840 } else { 841 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 842 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 843 tcg_gen_shl_i32(t0, arg1, arg2); 844 tcg_gen_neg_i32(t1, arg2); 845 tcg_gen_shr_i32(t1, arg1, t1); 846 tcg_gen_or_i32(ret, t0, t1); 847 tcg_temp_free_i32(t0); 848 tcg_temp_free_i32(t1); 849 } 850 } 851 852 void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 853 { 854 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 855 /* some cases can be optimized here */ 856 if (arg2 == 0) { 857 tcg_gen_mov_i32(ret, arg1); 858 } else if (tcg_op_supported(INDEX_op_rotl, TCG_TYPE_I32, 0)) { 859 TCGv_i32 t0 = tcg_constant_i32(arg2); 860 tcg_gen_op3_i32(INDEX_op_rotl, ret, arg1, t0); 861 } else if (tcg_op_supported(INDEX_op_rotr, TCG_TYPE_I32, 0)) { 862 TCGv_i32 t0 = tcg_constant_i32(32 - arg2); 863 tcg_gen_op3_i32(INDEX_op_rotr, ret, arg1, t0); 864 } else { 865 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 866 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 867 tcg_gen_shli_i32(t0, arg1, arg2); 868 tcg_gen_shri_i32(t1, arg1, 32 - arg2); 869 tcg_gen_or_i32(ret, t0, t1); 870 tcg_temp_free_i32(t0); 871 tcg_temp_free_i32(t1); 872 } 873 } 874 875 void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 876 { 877 if (tcg_op_supported(INDEX_op_rotr, TCG_TYPE_I32, 0)) { 878 tcg_gen_op3_i32(INDEX_op_rotr, ret, arg1, arg2); 879 } else if (tcg_op_supported(INDEX_op_rotl, TCG_TYPE_I32, 0)) { 880 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 881 tcg_gen_neg_i32(t0, arg2); 882 tcg_gen_op3_i32(INDEX_op_rotl, ret, arg1, t0); 883 tcg_temp_free_i32(t0); 884 } else { 885 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 886 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 887 tcg_gen_shr_i32(t0, arg1, arg2); 888 tcg_gen_neg_i32(t1, arg2); 889 tcg_gen_shl_i32(t1, arg1, t1); 890 tcg_gen_or_i32(ret, t0, t1); 891 tcg_temp_free_i32(t0); 892 tcg_temp_free_i32(t1); 893 } 894 } 895 896 void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 897 { 898 tcg_debug_assert(arg2 >= 0 && arg2 < 32); 899 tcg_gen_rotli_i32(ret, arg1, -arg2 & 31); 900 } 901 902 void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2, 903 unsigned int ofs, unsigned int len) 904 { 905 uint32_t mask; 906 TCGv_i32 t1; 907 908 tcg_debug_assert(ofs < 32); 909 tcg_debug_assert(len > 0); 910 tcg_debug_assert(len <= 32); 911 tcg_debug_assert(ofs + len <= 32); 912 913 if (len == 32) { 914 tcg_gen_mov_i32(ret, arg2); 915 return; 916 } 917 if (TCG_TARGET_deposit_valid(TCG_TYPE_I32, ofs, len)) { 918 tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len); 919 return; 920 } 921 922 t1 = tcg_temp_ebb_new_i32(); 923 924 if (TCG_TARGET_HAS_extract2_i32) { 925 if (ofs + len == 32) { 926 tcg_gen_shli_i32(t1, arg1, len); 927 tcg_gen_extract2_i32(ret, t1, arg2, len); 928 goto done; 929 } 930 if (ofs == 0) { 931 tcg_gen_extract2_i32(ret, arg1, arg2, len); 932 tcg_gen_rotli_i32(ret, ret, len); 933 goto done; 934 } 935 } 936 937 mask = (1u << len) - 1; 938 if (ofs + len < 32) { 939 tcg_gen_andi_i32(t1, arg2, mask); 940 tcg_gen_shli_i32(t1, t1, ofs); 941 } else { 942 tcg_gen_shli_i32(t1, arg2, ofs); 943 } 944 tcg_gen_andi_i32(ret, arg1, ~(mask << ofs)); 945 tcg_gen_or_i32(ret, ret, t1); 946 done: 947 tcg_temp_free_i32(t1); 948 } 949 950 void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg, 951 unsigned int ofs, unsigned int len) 952 { 953 tcg_debug_assert(ofs < 32); 954 tcg_debug_assert(len > 0); 955 tcg_debug_assert(len <= 32); 956 tcg_debug_assert(ofs + len <= 32); 957 958 if (ofs + len == 32) { 959 tcg_gen_shli_i32(ret, arg, ofs); 960 } else if (ofs == 0) { 961 tcg_gen_andi_i32(ret, arg, (1u << len) - 1); 962 } else if (TCG_TARGET_deposit_valid(TCG_TYPE_I32, ofs, len)) { 963 TCGv_i32 zero = tcg_constant_i32(0); 964 tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len); 965 } else { 966 /* 967 * To help two-operand hosts we prefer to zero-extend first, 968 * which allows ARG to stay live. 969 */ 970 if (TCG_TARGET_extract_valid(TCG_TYPE_I32, 0, len)) { 971 tcg_gen_extract_i32(ret, arg, 0, len); 972 tcg_gen_shli_i32(ret, ret, ofs); 973 return; 974 } 975 /* Otherwise prefer zero-extension over AND for code size. */ 976 if (TCG_TARGET_extract_valid(TCG_TYPE_I32, 0, ofs + len)) { 977 tcg_gen_shli_i32(ret, arg, ofs); 978 tcg_gen_extract_i32(ret, ret, 0, ofs + len); 979 return; 980 } 981 tcg_gen_andi_i32(ret, arg, (1u << len) - 1); 982 tcg_gen_shli_i32(ret, ret, ofs); 983 } 984 } 985 986 void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg, 987 unsigned int ofs, unsigned int len) 988 { 989 tcg_debug_assert(ofs < 32); 990 tcg_debug_assert(len > 0); 991 tcg_debug_assert(len <= 32); 992 tcg_debug_assert(ofs + len <= 32); 993 994 /* Canonicalize certain special cases, even if extract is supported. */ 995 if (ofs + len == 32) { 996 tcg_gen_shri_i32(ret, arg, 32 - len); 997 return; 998 } 999 1000 if (TCG_TARGET_extract_valid(TCG_TYPE_I32, ofs, len)) { 1001 tcg_gen_op4ii_i32(INDEX_op_extract, ret, arg, ofs, len); 1002 return; 1003 } 1004 if (ofs == 0) { 1005 tcg_gen_andi_i32(ret, arg, (1u << len) - 1); 1006 return; 1007 } 1008 1009 /* Assume that zero-extension, if available, is cheaper than a shift. */ 1010 if (TCG_TARGET_extract_valid(TCG_TYPE_I32, 0, ofs + len)) { 1011 tcg_gen_op4ii_i32(INDEX_op_extract, ret, arg, 0, ofs + len); 1012 tcg_gen_shri_i32(ret, ret, ofs); 1013 return; 1014 } 1015 1016 /* ??? Ideally we'd know what values are available for immediate AND. 1017 Assume that 8 bits are available, plus the special case of 16, 1018 so that we get ext8u, ext16u. */ 1019 switch (len) { 1020 case 1 ... 8: case 16: 1021 tcg_gen_shri_i32(ret, arg, ofs); 1022 tcg_gen_andi_i32(ret, ret, (1u << len) - 1); 1023 break; 1024 default: 1025 tcg_gen_shli_i32(ret, arg, 32 - len - ofs); 1026 tcg_gen_shri_i32(ret, ret, 32 - len); 1027 break; 1028 } 1029 } 1030 1031 void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg, 1032 unsigned int ofs, unsigned int len) 1033 { 1034 tcg_debug_assert(ofs < 32); 1035 tcg_debug_assert(len > 0); 1036 tcg_debug_assert(len <= 32); 1037 tcg_debug_assert(ofs + len <= 32); 1038 1039 /* Canonicalize certain special cases, even if extract is supported. */ 1040 if (ofs + len == 32) { 1041 tcg_gen_sari_i32(ret, arg, 32 - len); 1042 return; 1043 } 1044 1045 if (TCG_TARGET_sextract_valid(TCG_TYPE_I32, ofs, len)) { 1046 tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len); 1047 return; 1048 } 1049 1050 /* Assume that sign-extension, if available, is cheaper than a shift. */ 1051 if (TCG_TARGET_sextract_valid(TCG_TYPE_I32, 0, ofs + len)) { 1052 tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, 0, ofs + len); 1053 tcg_gen_sari_i32(ret, ret, ofs); 1054 return; 1055 } 1056 if (TCG_TARGET_sextract_valid(TCG_TYPE_I32, 0, len)) { 1057 tcg_gen_shri_i32(ret, arg, ofs); 1058 tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, ret, 0, len); 1059 return; 1060 } 1061 1062 tcg_gen_shli_i32(ret, arg, 32 - len - ofs); 1063 tcg_gen_sari_i32(ret, ret, 32 - len); 1064 } 1065 1066 /* 1067 * Extract 32-bits from a 64-bit input, ah:al, starting from ofs. 1068 * Unlike tcg_gen_extract_i32 above, len is fixed at 32. 1069 */ 1070 void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah, 1071 unsigned int ofs) 1072 { 1073 tcg_debug_assert(ofs <= 32); 1074 if (ofs == 0) { 1075 tcg_gen_mov_i32(ret, al); 1076 } else if (ofs == 32) { 1077 tcg_gen_mov_i32(ret, ah); 1078 } else if (al == ah) { 1079 tcg_gen_rotri_i32(ret, al, ofs); 1080 } else if (TCG_TARGET_HAS_extract2_i32) { 1081 tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs); 1082 } else { 1083 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1084 tcg_gen_shri_i32(t0, al, ofs); 1085 tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs); 1086 tcg_temp_free_i32(t0); 1087 } 1088 } 1089 1090 void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1, 1091 TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2) 1092 { 1093 if (cond == TCG_COND_ALWAYS) { 1094 tcg_gen_mov_i32(ret, v1); 1095 } else if (cond == TCG_COND_NEVER) { 1096 tcg_gen_mov_i32(ret, v2); 1097 } else { 1098 tcg_gen_op6i_i32(INDEX_op_movcond, ret, c1, c2, v1, v2, cond); 1099 } 1100 } 1101 1102 void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al, 1103 TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh) 1104 { 1105 if (TCG_TARGET_HAS_add2_i32) { 1106 tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh); 1107 } else { 1108 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1109 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1110 tcg_gen_concat_i32_i64(t0, al, ah); 1111 tcg_gen_concat_i32_i64(t1, bl, bh); 1112 tcg_gen_add_i64(t0, t0, t1); 1113 tcg_gen_extr_i64_i32(rl, rh, t0); 1114 tcg_temp_free_i64(t0); 1115 tcg_temp_free_i64(t1); 1116 } 1117 } 1118 1119 void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al, 1120 TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh) 1121 { 1122 if (TCG_TARGET_HAS_sub2_i32) { 1123 tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh); 1124 } else { 1125 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1126 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1127 tcg_gen_concat_i32_i64(t0, al, ah); 1128 tcg_gen_concat_i32_i64(t1, bl, bh); 1129 tcg_gen_sub_i64(t0, t0, t1); 1130 tcg_gen_extr_i64_i32(rl, rh, t0); 1131 tcg_temp_free_i64(t0); 1132 tcg_temp_free_i64(t1); 1133 } 1134 } 1135 1136 void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 1137 { 1138 if (tcg_op_supported(INDEX_op_mulu2, TCG_TYPE_I32, 0)) { 1139 tcg_gen_op4_i32(INDEX_op_mulu2, rl, rh, arg1, arg2); 1140 } else if (tcg_op_supported(INDEX_op_muluh, TCG_TYPE_I32, 0)) { 1141 TCGv_i32 t = tcg_temp_ebb_new_i32(); 1142 tcg_gen_op3_i32(INDEX_op_mul, t, arg1, arg2); 1143 tcg_gen_op3_i32(INDEX_op_muluh, rh, arg1, arg2); 1144 tcg_gen_mov_i32(rl, t); 1145 tcg_temp_free_i32(t); 1146 } else if (TCG_TARGET_REG_BITS == 64) { 1147 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1148 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1149 tcg_gen_extu_i32_i64(t0, arg1); 1150 tcg_gen_extu_i32_i64(t1, arg2); 1151 tcg_gen_mul_i64(t0, t0, t1); 1152 tcg_gen_extr_i64_i32(rl, rh, t0); 1153 tcg_temp_free_i64(t0); 1154 tcg_temp_free_i64(t1); 1155 } else { 1156 g_assert_not_reached(); 1157 } 1158 } 1159 1160 void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 1161 { 1162 if (tcg_op_supported(INDEX_op_muls2, TCG_TYPE_I32, 0)) { 1163 tcg_gen_op4_i32(INDEX_op_muls2, rl, rh, arg1, arg2); 1164 } else if (tcg_op_supported(INDEX_op_mulsh, TCG_TYPE_I32, 0)) { 1165 TCGv_i32 t = tcg_temp_ebb_new_i32(); 1166 tcg_gen_op3_i32(INDEX_op_mul, t, arg1, arg2); 1167 tcg_gen_op3_i32(INDEX_op_mulsh, rh, arg1, arg2); 1168 tcg_gen_mov_i32(rl, t); 1169 tcg_temp_free_i32(t); 1170 } else if (TCG_TARGET_REG_BITS == 32) { 1171 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1172 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1173 TCGv_i32 t2 = tcg_temp_ebb_new_i32(); 1174 TCGv_i32 t3 = tcg_temp_ebb_new_i32(); 1175 tcg_gen_mulu2_i32(t0, t1, arg1, arg2); 1176 /* Adjust for negative inputs. */ 1177 tcg_gen_sari_i32(t2, arg1, 31); 1178 tcg_gen_sari_i32(t3, arg2, 31); 1179 tcg_gen_and_i32(t2, t2, arg2); 1180 tcg_gen_and_i32(t3, t3, arg1); 1181 tcg_gen_sub_i32(rh, t1, t2); 1182 tcg_gen_sub_i32(rh, rh, t3); 1183 tcg_gen_mov_i32(rl, t0); 1184 tcg_temp_free_i32(t0); 1185 tcg_temp_free_i32(t1); 1186 tcg_temp_free_i32(t2); 1187 tcg_temp_free_i32(t3); 1188 } else { 1189 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1190 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1191 tcg_gen_ext_i32_i64(t0, arg1); 1192 tcg_gen_ext_i32_i64(t1, arg2); 1193 tcg_gen_mul_i64(t0, t0, t1); 1194 tcg_gen_extr_i64_i32(rl, rh, t0); 1195 tcg_temp_free_i64(t0); 1196 tcg_temp_free_i64(t1); 1197 } 1198 } 1199 1200 void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 1201 { 1202 if (TCG_TARGET_REG_BITS == 32) { 1203 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1204 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1205 TCGv_i32 t2 = tcg_temp_ebb_new_i32(); 1206 tcg_gen_mulu2_i32(t0, t1, arg1, arg2); 1207 /* Adjust for negative input for the signed arg1. */ 1208 tcg_gen_sari_i32(t2, arg1, 31); 1209 tcg_gen_and_i32(t2, t2, arg2); 1210 tcg_gen_sub_i32(rh, t1, t2); 1211 tcg_gen_mov_i32(rl, t0); 1212 tcg_temp_free_i32(t0); 1213 tcg_temp_free_i32(t1); 1214 tcg_temp_free_i32(t2); 1215 } else { 1216 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1217 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 1218 tcg_gen_ext_i32_i64(t0, arg1); 1219 tcg_gen_extu_i32_i64(t1, arg2); 1220 tcg_gen_mul_i64(t0, t0, t1); 1221 tcg_gen_extr_i64_i32(rl, rh, t0); 1222 tcg_temp_free_i64(t0); 1223 tcg_temp_free_i64(t1); 1224 } 1225 } 1226 1227 void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg) 1228 { 1229 tcg_gen_sextract_i32(ret, arg, 0, 8); 1230 } 1231 1232 void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg) 1233 { 1234 tcg_gen_sextract_i32(ret, arg, 0, 16); 1235 } 1236 1237 void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg) 1238 { 1239 tcg_gen_extract_i32(ret, arg, 0, 8); 1240 } 1241 1242 void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg) 1243 { 1244 tcg_gen_extract_i32(ret, arg, 0, 16); 1245 } 1246 1247 /* 1248 * bswap16_i32: 16-bit byte swap on the low bits of a 32-bit value. 1249 * 1250 * Byte pattern: xxab -> yyba 1251 * 1252 * With TCG_BSWAP_IZ, x == zero, else undefined. 1253 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined. 1254 */ 1255 void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags) 1256 { 1257 /* Only one extension flag may be present. */ 1258 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ)); 1259 1260 if (tcg_op_supported(INDEX_op_bswap16, TCG_TYPE_I32, 0)) { 1261 tcg_gen_op3i_i32(INDEX_op_bswap16, ret, arg, flags); 1262 } else { 1263 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1264 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1265 1266 /* arg = ..ab (IZ) xxab (!IZ) */ 1267 tcg_gen_shri_i32(t0, arg, 8); /* t0 = ...a (IZ) .xxa (!IZ) */ 1268 if (!(flags & TCG_BSWAP_IZ)) { 1269 tcg_gen_ext8u_i32(t0, t0); /* t0 = ...a */ 1270 } 1271 1272 if (flags & TCG_BSWAP_OS) { 1273 tcg_gen_shli_i32(t1, arg, 24); /* t1 = b... */ 1274 tcg_gen_sari_i32(t1, t1, 16); /* t1 = ssb. */ 1275 } else if (flags & TCG_BSWAP_OZ) { 1276 tcg_gen_ext8u_i32(t1, arg); /* t1 = ...b */ 1277 tcg_gen_shli_i32(t1, t1, 8); /* t1 = ..b. */ 1278 } else { 1279 tcg_gen_shli_i32(t1, arg, 8); /* t1 = xab. */ 1280 } 1281 1282 tcg_gen_or_i32(ret, t0, t1); /* ret = ..ba (OZ) */ 1283 /* = ssba (OS) */ 1284 /* = xaba (no flag) */ 1285 tcg_temp_free_i32(t0); 1286 tcg_temp_free_i32(t1); 1287 } 1288 } 1289 1290 /* 1291 * bswap32_i32: 32-bit byte swap on a 32-bit value. 1292 * 1293 * Byte pattern: abcd -> dcba 1294 */ 1295 void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg) 1296 { 1297 if (tcg_op_supported(INDEX_op_bswap32, TCG_TYPE_I32, 0)) { 1298 tcg_gen_op3i_i32(INDEX_op_bswap32, ret, arg, 0); 1299 } else { 1300 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1301 TCGv_i32 t1 = tcg_temp_ebb_new_i32(); 1302 TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff); 1303 1304 /* arg = abcd */ 1305 tcg_gen_shri_i32(t0, arg, 8); /* t0 = .abc */ 1306 tcg_gen_and_i32(t1, arg, t2); /* t1 = .b.d */ 1307 tcg_gen_and_i32(t0, t0, t2); /* t0 = .a.c */ 1308 tcg_gen_shli_i32(t1, t1, 8); /* t1 = b.d. */ 1309 tcg_gen_or_i32(ret, t0, t1); /* ret = badc */ 1310 1311 tcg_gen_shri_i32(t0, ret, 16); /* t0 = ..ba */ 1312 tcg_gen_shli_i32(t1, ret, 16); /* t1 = dc.. */ 1313 tcg_gen_or_i32(ret, t0, t1); /* ret = dcba */ 1314 1315 tcg_temp_free_i32(t0); 1316 tcg_temp_free_i32(t1); 1317 } 1318 } 1319 1320 /* 1321 * hswap_i32: Swap 16-bit halfwords within a 32-bit value. 1322 * 1323 * Byte pattern: abcd -> cdab 1324 */ 1325 void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg) 1326 { 1327 /* Swapping 2 16-bit elements is a rotate. */ 1328 tcg_gen_rotli_i32(ret, arg, 16); 1329 } 1330 1331 void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1332 { 1333 tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b); 1334 } 1335 1336 void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1337 { 1338 tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b); 1339 } 1340 1341 void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1342 { 1343 tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a); 1344 } 1345 1346 void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) 1347 { 1348 tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a); 1349 } 1350 1351 void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a) 1352 { 1353 TCGv_i32 t = tcg_temp_ebb_new_i32(); 1354 1355 tcg_gen_sari_i32(t, a, 31); 1356 tcg_gen_xor_i32(ret, a, t); 1357 tcg_gen_sub_i32(ret, ret, t); 1358 tcg_temp_free_i32(t); 1359 } 1360 1361 void tcg_gen_ld8u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1362 { 1363 tcg_gen_ldst_op_i32(INDEX_op_ld8u_i32, ret, arg2, offset); 1364 } 1365 1366 void tcg_gen_ld8s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1367 { 1368 tcg_gen_ldst_op_i32(INDEX_op_ld8s_i32, ret, arg2, offset); 1369 } 1370 1371 void tcg_gen_ld16u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1372 { 1373 tcg_gen_ldst_op_i32(INDEX_op_ld16u_i32, ret, arg2, offset); 1374 } 1375 1376 void tcg_gen_ld16s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1377 { 1378 tcg_gen_ldst_op_i32(INDEX_op_ld16s_i32, ret, arg2, offset); 1379 } 1380 1381 void tcg_gen_ld_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset) 1382 { 1383 tcg_gen_ldst_op_i32(INDEX_op_ld_i32, ret, arg2, offset); 1384 } 1385 1386 void tcg_gen_st8_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset) 1387 { 1388 tcg_gen_ldst_op_i32(INDEX_op_st8_i32, arg1, arg2, offset); 1389 } 1390 1391 void tcg_gen_st16_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset) 1392 { 1393 tcg_gen_ldst_op_i32(INDEX_op_st16_i32, arg1, arg2, offset); 1394 } 1395 1396 void tcg_gen_st_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset) 1397 { 1398 tcg_gen_ldst_op_i32(INDEX_op_st_i32, arg1, arg2, offset); 1399 } 1400 1401 1402 /* 64-bit ops */ 1403 1404 void tcg_gen_discard_i64(TCGv_i64 arg) 1405 { 1406 if (TCG_TARGET_REG_BITS == 64) { 1407 tcg_gen_op1_i64(INDEX_op_discard, TCG_TYPE_I64, arg); 1408 } else { 1409 tcg_gen_discard_i32(TCGV_LOW(arg)); 1410 tcg_gen_discard_i32(TCGV_HIGH(arg)); 1411 } 1412 } 1413 1414 void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg) 1415 { 1416 if (ret == arg) { 1417 return; 1418 } 1419 if (TCG_TARGET_REG_BITS == 64) { 1420 tcg_gen_op2_i64(INDEX_op_mov, ret, arg); 1421 } else { 1422 TCGTemp *ts = tcgv_i64_temp(arg); 1423 1424 /* Canonicalize TCGv_i64 TEMP_CONST into TCGv_i32 TEMP_CONST. */ 1425 if (ts->kind == TEMP_CONST) { 1426 tcg_gen_movi_i64(ret, ts->val); 1427 } else { 1428 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1429 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 1430 } 1431 } 1432 } 1433 1434 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg) 1435 { 1436 if (TCG_TARGET_REG_BITS == 64) { 1437 tcg_gen_mov_i64(ret, tcg_constant_i64(arg)); 1438 } else { 1439 tcg_gen_movi_i32(TCGV_LOW(ret), arg); 1440 tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32); 1441 } 1442 } 1443 1444 void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1445 { 1446 if (TCG_TARGET_REG_BITS == 64) { 1447 tcg_gen_ldst_op_i64(INDEX_op_ld8u_i64, ret, arg2, offset); 1448 } else { 1449 tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset); 1450 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1451 } 1452 } 1453 1454 void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1455 { 1456 if (TCG_TARGET_REG_BITS == 64) { 1457 tcg_gen_ldst_op_i64(INDEX_op_ld8s_i64, ret, arg2, offset); 1458 } else { 1459 tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset); 1460 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1461 } 1462 } 1463 1464 void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1465 { 1466 if (TCG_TARGET_REG_BITS == 64) { 1467 tcg_gen_ldst_op_i64(INDEX_op_ld16u_i64, ret, arg2, offset); 1468 } else { 1469 tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset); 1470 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1471 } 1472 } 1473 1474 void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1475 { 1476 if (TCG_TARGET_REG_BITS == 64) { 1477 tcg_gen_ldst_op_i64(INDEX_op_ld16s_i64, ret, arg2, offset); 1478 } else { 1479 tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset); 1480 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1481 } 1482 } 1483 1484 void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1485 { 1486 if (TCG_TARGET_REG_BITS == 64) { 1487 tcg_gen_ldst_op_i64(INDEX_op_ld32u_i64, ret, arg2, offset); 1488 } else { 1489 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 1490 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1491 } 1492 } 1493 1494 void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1495 { 1496 if (TCG_TARGET_REG_BITS == 64) { 1497 tcg_gen_ldst_op_i64(INDEX_op_ld32s_i64, ret, arg2, offset); 1498 } else { 1499 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 1500 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1501 } 1502 } 1503 1504 void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 1505 { 1506 /* 1507 * For 32-bit host, since arg2 and ret have different types, 1508 * they cannot be the same temporary -- no chance of overlap. 1509 */ 1510 if (TCG_TARGET_REG_BITS == 64) { 1511 tcg_gen_ldst_op_i64(INDEX_op_ld_i64, ret, arg2, offset); 1512 } else if (HOST_BIG_ENDIAN) { 1513 tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset); 1514 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4); 1515 } else { 1516 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 1517 tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4); 1518 } 1519 } 1520 1521 void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1522 { 1523 if (TCG_TARGET_REG_BITS == 64) { 1524 tcg_gen_ldst_op_i64(INDEX_op_st8_i64, arg1, arg2, offset); 1525 } else { 1526 tcg_gen_st8_i32(TCGV_LOW(arg1), arg2, offset); 1527 } 1528 } 1529 1530 void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1531 { 1532 if (TCG_TARGET_REG_BITS == 64) { 1533 tcg_gen_ldst_op_i64(INDEX_op_st16_i64, arg1, arg2, offset); 1534 } else { 1535 tcg_gen_st16_i32(TCGV_LOW(arg1), arg2, offset); 1536 } 1537 } 1538 1539 void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1540 { 1541 if (TCG_TARGET_REG_BITS == 64) { 1542 tcg_gen_ldst_op_i64(INDEX_op_st32_i64, arg1, arg2, offset); 1543 } else { 1544 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset); 1545 } 1546 } 1547 1548 void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 1549 { 1550 if (TCG_TARGET_REG_BITS == 64) { 1551 tcg_gen_ldst_op_i64(INDEX_op_st_i64, arg1, arg2, offset); 1552 } else if (HOST_BIG_ENDIAN) { 1553 tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset); 1554 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4); 1555 } else { 1556 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset); 1557 tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4); 1558 } 1559 } 1560 1561 void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1562 { 1563 if (TCG_TARGET_REG_BITS == 64) { 1564 tcg_gen_op3_i64(INDEX_op_add, ret, arg1, arg2); 1565 } else { 1566 tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1), 1567 TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2)); 1568 } 1569 } 1570 1571 void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1572 { 1573 if (TCG_TARGET_REG_BITS == 64) { 1574 tcg_gen_op3_i64(INDEX_op_sub, ret, arg1, arg2); 1575 } else { 1576 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1), 1577 TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2)); 1578 } 1579 } 1580 1581 void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1582 { 1583 if (TCG_TARGET_REG_BITS == 64) { 1584 tcg_gen_op3_i64(INDEX_op_and, ret, arg1, arg2); 1585 } else { 1586 tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1587 tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1588 } 1589 } 1590 1591 void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1592 { 1593 if (TCG_TARGET_REG_BITS == 64) { 1594 tcg_gen_op3_i64(INDEX_op_or, ret, arg1, arg2); 1595 } else { 1596 tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1597 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1598 } 1599 } 1600 1601 void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1602 { 1603 if (TCG_TARGET_REG_BITS == 64) { 1604 tcg_gen_op3_i64(INDEX_op_xor, ret, arg1, arg2); 1605 } else { 1606 tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1607 tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1608 } 1609 } 1610 1611 void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1612 { 1613 if (TCG_TARGET_REG_BITS == 64) { 1614 tcg_gen_op3_i64(INDEX_op_shl, ret, arg1, arg2); 1615 } else { 1616 gen_helper_shl_i64(ret, arg1, arg2); 1617 } 1618 } 1619 1620 void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1621 { 1622 if (TCG_TARGET_REG_BITS == 64) { 1623 tcg_gen_op3_i64(INDEX_op_shr, ret, arg1, arg2); 1624 } else { 1625 gen_helper_shr_i64(ret, arg1, arg2); 1626 } 1627 } 1628 1629 void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1630 { 1631 if (TCG_TARGET_REG_BITS == 64) { 1632 tcg_gen_op3_i64(INDEX_op_sar, ret, arg1, arg2); 1633 } else { 1634 gen_helper_sar_i64(ret, arg1, arg2); 1635 } 1636 } 1637 1638 void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1639 { 1640 TCGv_i64 t0; 1641 TCGv_i32 t1; 1642 1643 if (TCG_TARGET_REG_BITS == 64) { 1644 tcg_gen_op3_i64(INDEX_op_mul, ret, arg1, arg2); 1645 return; 1646 } 1647 1648 1649 t0 = tcg_temp_ebb_new_i64(); 1650 t1 = tcg_temp_ebb_new_i32(); 1651 1652 tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0), 1653 TCGV_LOW(arg1), TCGV_LOW(arg2)); 1654 1655 tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2)); 1656 tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 1657 tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2)); 1658 tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 1659 1660 tcg_gen_mov_i64(ret, t0); 1661 tcg_temp_free_i64(t0); 1662 tcg_temp_free_i32(t1); 1663 } 1664 1665 void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1666 { 1667 /* some cases can be optimized here */ 1668 if (arg2 == 0) { 1669 tcg_gen_mov_i64(ret, arg1); 1670 } else if (TCG_TARGET_REG_BITS == 64) { 1671 tcg_gen_add_i64(ret, arg1, tcg_constant_i64(arg2)); 1672 } else { 1673 tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1674 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1675 tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32)); 1676 } 1677 } 1678 1679 void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2) 1680 { 1681 if (arg1 == 0) { 1682 tcg_gen_neg_i64(ret, arg2); 1683 } else if (TCG_TARGET_REG_BITS == 64) { 1684 tcg_gen_sub_i64(ret, tcg_constant_i64(arg1), arg2); 1685 } else { 1686 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1687 tcg_constant_i32(arg1), tcg_constant_i32(arg1 >> 32), 1688 TCGV_LOW(arg2), TCGV_HIGH(arg2)); 1689 } 1690 } 1691 1692 void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1693 { 1694 tcg_gen_addi_i64(ret, arg1, -arg2); 1695 } 1696 1697 void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg) 1698 { 1699 if (TCG_TARGET_REG_BITS == 64) { 1700 tcg_gen_op2_i64(INDEX_op_neg, ret, arg); 1701 } else { 1702 TCGv_i32 zero = tcg_constant_i32(0); 1703 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), 1704 zero, zero, TCGV_LOW(arg), TCGV_HIGH(arg)); 1705 } 1706 } 1707 1708 void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1709 { 1710 if (TCG_TARGET_REG_BITS == 32) { 1711 tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 1712 tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 1713 return; 1714 } 1715 1716 /* Some cases can be optimized here. */ 1717 switch (arg2) { 1718 case 0: 1719 tcg_gen_movi_i64(ret, 0); 1720 return; 1721 case -1: 1722 tcg_gen_mov_i64(ret, arg1); 1723 return; 1724 default: 1725 /* 1726 * Canonicalize on extract, if valid. This aids x86 with its 1727 * 2 operand MOVZBL and 2 operand AND, selecting the TCGOpcode 1728 * which does not require matching operands. Other backends can 1729 * trivially expand the extract to AND during code generation. 1730 */ 1731 if (!(arg2 & (arg2 + 1))) { 1732 unsigned len = ctz64(~arg2); 1733 if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, len)) { 1734 tcg_gen_extract_i64(ret, arg1, 0, len); 1735 return; 1736 } 1737 } 1738 break; 1739 } 1740 1741 tcg_gen_and_i64(ret, arg1, tcg_constant_i64(arg2)); 1742 } 1743 1744 void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1745 { 1746 if (TCG_TARGET_REG_BITS == 32) { 1747 tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 1748 tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 1749 return; 1750 } 1751 /* Some cases can be optimized here. */ 1752 if (arg2 == -1) { 1753 tcg_gen_movi_i64(ret, -1); 1754 } else if (arg2 == 0) { 1755 tcg_gen_mov_i64(ret, arg1); 1756 } else { 1757 tcg_gen_or_i64(ret, arg1, tcg_constant_i64(arg2)); 1758 } 1759 } 1760 1761 void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1762 { 1763 if (TCG_TARGET_REG_BITS == 32) { 1764 tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 1765 tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 1766 return; 1767 } 1768 /* Some cases can be optimized here. */ 1769 if (arg2 == 0) { 1770 tcg_gen_mov_i64(ret, arg1); 1771 } else if (arg2 == -1 && 1772 tcg_op_supported(INDEX_op_not, TCG_TYPE_I64, 0)) { 1773 /* Don't recurse with tcg_gen_not_i64. */ 1774 tcg_gen_op2_i64(INDEX_op_not, ret, arg1); 1775 } else { 1776 tcg_gen_xor_i64(ret, arg1, tcg_constant_i64(arg2)); 1777 } 1778 } 1779 1780 static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, 1781 unsigned c, bool right, bool arith) 1782 { 1783 tcg_debug_assert(c < 64); 1784 if (c == 0) { 1785 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 1786 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 1787 } else if (c >= 32) { 1788 c -= 32; 1789 if (right) { 1790 if (arith) { 1791 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1792 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31); 1793 } else { 1794 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1795 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1796 } 1797 } else { 1798 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c); 1799 tcg_gen_movi_i32(TCGV_LOW(ret), 0); 1800 } 1801 } else if (right) { 1802 if (TCG_TARGET_HAS_extract2_i32) { 1803 tcg_gen_extract2_i32(TCGV_LOW(ret), 1804 TCGV_LOW(arg1), TCGV_HIGH(arg1), c); 1805 } else { 1806 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c); 1807 tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(ret), 1808 TCGV_HIGH(arg1), 32 - c, c); 1809 } 1810 if (arith) { 1811 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c); 1812 } else { 1813 tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c); 1814 } 1815 } else { 1816 if (TCG_TARGET_HAS_extract2_i32) { 1817 tcg_gen_extract2_i32(TCGV_HIGH(ret), 1818 TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c); 1819 } else { 1820 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 1821 tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c); 1822 tcg_gen_deposit_i32(TCGV_HIGH(ret), t0, 1823 TCGV_HIGH(arg1), c, 32 - c); 1824 tcg_temp_free_i32(t0); 1825 } 1826 tcg_gen_shli_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c); 1827 } 1828 } 1829 1830 void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1831 { 1832 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 1833 if (TCG_TARGET_REG_BITS == 32) { 1834 tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0); 1835 } else if (arg2 == 0) { 1836 tcg_gen_mov_i64(ret, arg1); 1837 } else { 1838 tcg_gen_shl_i64(ret, arg1, tcg_constant_i64(arg2)); 1839 } 1840 } 1841 1842 void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1843 { 1844 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 1845 if (TCG_TARGET_REG_BITS == 32) { 1846 tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0); 1847 } else if (arg2 == 0) { 1848 tcg_gen_mov_i64(ret, arg1); 1849 } else { 1850 tcg_gen_shr_i64(ret, arg1, tcg_constant_i64(arg2)); 1851 } 1852 } 1853 1854 void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1855 { 1856 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 1857 if (TCG_TARGET_REG_BITS == 32) { 1858 tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1); 1859 } else if (arg2 == 0) { 1860 tcg_gen_mov_i64(ret, arg1); 1861 } else { 1862 tcg_gen_sar_i64(ret, arg1, tcg_constant_i64(arg2)); 1863 } 1864 } 1865 1866 void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l) 1867 { 1868 if (cond == TCG_COND_ALWAYS) { 1869 tcg_gen_br(l); 1870 } else if (cond != TCG_COND_NEVER) { 1871 TCGOp *op; 1872 if (TCG_TARGET_REG_BITS == 32) { 1873 op = tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1), 1874 TCGV_HIGH(arg1), TCGV_LOW(arg2), 1875 TCGV_HIGH(arg2), cond, label_arg(l)); 1876 } else { 1877 op = tcg_gen_op4ii_i64(INDEX_op_brcond, arg1, arg2, cond, 1878 label_arg(l)); 1879 } 1880 add_as_label_use(l, op); 1881 } 1882 } 1883 1884 void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l) 1885 { 1886 if (TCG_TARGET_REG_BITS == 64) { 1887 tcg_gen_brcond_i64(cond, arg1, tcg_constant_i64(arg2), l); 1888 } else if (cond == TCG_COND_ALWAYS) { 1889 tcg_gen_br(l); 1890 } else if (cond != TCG_COND_NEVER) { 1891 TCGOp *op = tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, 1892 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1893 tcg_constant_i32(arg2), 1894 tcg_constant_i32(arg2 >> 32), 1895 cond, label_arg(l)); 1896 add_as_label_use(l, op); 1897 } 1898 } 1899 1900 void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret, 1901 TCGv_i64 arg1, TCGv_i64 arg2) 1902 { 1903 if (cond == TCG_COND_ALWAYS) { 1904 tcg_gen_movi_i64(ret, 1); 1905 } else if (cond == TCG_COND_NEVER) { 1906 tcg_gen_movi_i64(ret, 0); 1907 } else { 1908 if (TCG_TARGET_REG_BITS == 32) { 1909 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 1910 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1911 TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); 1912 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1913 } else { 1914 tcg_gen_op4i_i64(INDEX_op_setcond, ret, arg1, arg2, cond); 1915 } 1916 } 1917 } 1918 1919 void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret, 1920 TCGv_i64 arg1, int64_t arg2) 1921 { 1922 if (TCG_TARGET_REG_BITS == 64) { 1923 tcg_gen_setcond_i64(cond, ret, arg1, tcg_constant_i64(arg2)); 1924 } else if (cond == TCG_COND_ALWAYS) { 1925 tcg_gen_movi_i64(ret, 1); 1926 } else if (cond == TCG_COND_NEVER) { 1927 tcg_gen_movi_i64(ret, 0); 1928 } else { 1929 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 1930 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1931 tcg_constant_i32(arg2), 1932 tcg_constant_i32(arg2 >> 32), cond); 1933 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1934 } 1935 } 1936 1937 void tcg_gen_negsetcondi_i64(TCGCond cond, TCGv_i64 ret, 1938 TCGv_i64 arg1, int64_t arg2) 1939 { 1940 tcg_gen_negsetcond_i64(cond, ret, arg1, tcg_constant_i64(arg2)); 1941 } 1942 1943 void tcg_gen_negsetcond_i64(TCGCond cond, TCGv_i64 ret, 1944 TCGv_i64 arg1, TCGv_i64 arg2) 1945 { 1946 if (cond == TCG_COND_ALWAYS) { 1947 tcg_gen_movi_i64(ret, -1); 1948 } else if (cond == TCG_COND_NEVER) { 1949 tcg_gen_movi_i64(ret, 0); 1950 } else if (TCG_TARGET_REG_BITS == 64) { 1951 tcg_gen_op4i_i64(INDEX_op_negsetcond, ret, arg1, arg2, cond); 1952 } else { 1953 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 1954 TCGV_LOW(arg1), TCGV_HIGH(arg1), 1955 TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); 1956 tcg_gen_neg_i32(TCGV_LOW(ret), TCGV_LOW(ret)); 1957 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_LOW(ret)); 1958 } 1959 } 1960 1961 void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1962 { 1963 if (arg2 == 0) { 1964 tcg_gen_movi_i64(ret, 0); 1965 } else if (is_power_of_2(arg2)) { 1966 tcg_gen_shli_i64(ret, arg1, ctz64(arg2)); 1967 } else { 1968 tcg_gen_mul_i64(ret, arg1, tcg_constant_i64(arg2)); 1969 } 1970 } 1971 1972 void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1973 { 1974 if (tcg_op_supported(INDEX_op_divs, TCG_TYPE_I64, 0)) { 1975 tcg_gen_op3_i64(INDEX_op_divs, ret, arg1, arg2); 1976 } else if (tcg_op_supported(INDEX_op_divs2, TCG_TYPE_I64, 0)) { 1977 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1978 tcg_gen_sari_i64(t0, arg1, 63); 1979 tcg_gen_op5_i64(INDEX_op_divs2, ret, t0, arg1, t0, arg2); 1980 tcg_temp_free_i64(t0); 1981 } else { 1982 gen_helper_div_i64(ret, arg1, arg2); 1983 } 1984 } 1985 1986 void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1987 { 1988 if (tcg_op_supported(INDEX_op_rems, TCG_TYPE_I64, 0)) { 1989 tcg_gen_op3_i64(INDEX_op_rems, ret, arg1, arg2); 1990 } else if (tcg_op_supported(INDEX_op_divs, TCG_TYPE_I64, 0)) { 1991 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1992 tcg_gen_op3_i64(INDEX_op_divs, t0, arg1, arg2); 1993 tcg_gen_mul_i64(t0, t0, arg2); 1994 tcg_gen_sub_i64(ret, arg1, t0); 1995 tcg_temp_free_i64(t0); 1996 } else if (tcg_op_supported(INDEX_op_divs2, TCG_TYPE_I64, 0)) { 1997 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 1998 tcg_gen_sari_i64(t0, arg1, 63); 1999 tcg_gen_op5_i64(INDEX_op_divs2, t0, ret, arg1, t0, arg2); 2000 tcg_temp_free_i64(t0); 2001 } else { 2002 gen_helper_rem_i64(ret, arg1, arg2); 2003 } 2004 } 2005 2006 void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2007 { 2008 if (tcg_op_supported(INDEX_op_divu, TCG_TYPE_I64, 0)) { 2009 tcg_gen_op3_i64(INDEX_op_divu, ret, arg1, arg2); 2010 } else if (tcg_op_supported(INDEX_op_divu2, TCG_TYPE_I64, 0)) { 2011 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2012 TCGv_i64 zero = tcg_constant_i64(0); 2013 tcg_gen_op5_i64(INDEX_op_divu2, ret, t0, arg1, zero, arg2); 2014 tcg_temp_free_i64(t0); 2015 } else { 2016 gen_helper_divu_i64(ret, arg1, arg2); 2017 } 2018 } 2019 2020 void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2021 { 2022 if (tcg_op_supported(INDEX_op_remu, TCG_TYPE_I64, 0)) { 2023 tcg_gen_op3_i64(INDEX_op_remu, ret, arg1, arg2); 2024 } else if (tcg_op_supported(INDEX_op_divu, TCG_TYPE_I64, 0)) { 2025 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2026 tcg_gen_op3_i64(INDEX_op_divu, t0, arg1, arg2); 2027 tcg_gen_mul_i64(t0, t0, arg2); 2028 tcg_gen_sub_i64(ret, arg1, t0); 2029 tcg_temp_free_i64(t0); 2030 } else if (tcg_op_supported(INDEX_op_divu2, TCG_TYPE_I64, 0)) { 2031 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2032 TCGv_i64 zero = tcg_constant_i64(0); 2033 tcg_gen_op5_i64(INDEX_op_divu2, t0, ret, arg1, zero, arg2); 2034 tcg_temp_free_i64(t0); 2035 } else { 2036 gen_helper_remu_i64(ret, arg1, arg2); 2037 } 2038 } 2039 2040 void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg) 2041 { 2042 tcg_gen_sextract_i64(ret, arg, 0, 8); 2043 } 2044 2045 void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg) 2046 { 2047 tcg_gen_sextract_i64(ret, arg, 0, 16); 2048 } 2049 2050 void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg) 2051 { 2052 tcg_gen_sextract_i64(ret, arg, 0, 32); 2053 } 2054 2055 void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg) 2056 { 2057 tcg_gen_extract_i64(ret, arg, 0, 8); 2058 } 2059 2060 void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg) 2061 { 2062 tcg_gen_extract_i64(ret, arg, 0, 16); 2063 } 2064 2065 void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg) 2066 { 2067 tcg_gen_extract_i64(ret, arg, 0, 32); 2068 } 2069 2070 /* 2071 * bswap16_i64: 16-bit byte swap on the low bits of a 64-bit value. 2072 * 2073 * Byte pattern: xxxxxxxxab -> yyyyyyyyba 2074 * 2075 * With TCG_BSWAP_IZ, x == zero, else undefined. 2076 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined. 2077 */ 2078 void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags) 2079 { 2080 /* Only one extension flag may be present. */ 2081 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ)); 2082 2083 if (TCG_TARGET_REG_BITS == 32) { 2084 tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg), flags); 2085 if (flags & TCG_BSWAP_OS) { 2086 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2087 } else { 2088 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2089 } 2090 } else if (tcg_op_supported(INDEX_op_bswap16, TCG_TYPE_I64, 0)) { 2091 tcg_gen_op3i_i64(INDEX_op_bswap16, ret, arg, flags); 2092 } else { 2093 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2094 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2095 2096 /* arg = ......ab or xxxxxxab */ 2097 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .......a or .xxxxxxa */ 2098 if (!(flags & TCG_BSWAP_IZ)) { 2099 tcg_gen_ext8u_i64(t0, t0); /* t0 = .......a */ 2100 } 2101 2102 if (flags & TCG_BSWAP_OS) { 2103 tcg_gen_shli_i64(t1, arg, 56); /* t1 = b....... */ 2104 tcg_gen_sari_i64(t1, t1, 48); /* t1 = ssssssb. */ 2105 } else if (flags & TCG_BSWAP_OZ) { 2106 tcg_gen_ext8u_i64(t1, arg); /* t1 = .......b */ 2107 tcg_gen_shli_i64(t1, t1, 8); /* t1 = ......b. */ 2108 } else { 2109 tcg_gen_shli_i64(t1, arg, 8); /* t1 = xxxxxab. */ 2110 } 2111 2112 tcg_gen_or_i64(ret, t0, t1); /* ret = ......ba (OZ) */ 2113 /* ssssssba (OS) */ 2114 /* xxxxxaba (no flag) */ 2115 tcg_temp_free_i64(t0); 2116 tcg_temp_free_i64(t1); 2117 } 2118 } 2119 2120 /* 2121 * bswap32_i64: 32-bit byte swap on the low bits of a 64-bit value. 2122 * 2123 * Byte pattern: xxxxabcd -> yyyydcba 2124 * 2125 * With TCG_BSWAP_IZ, x == zero, else undefined. 2126 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined. 2127 */ 2128 void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags) 2129 { 2130 /* Only one extension flag may be present. */ 2131 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ)); 2132 2133 if (TCG_TARGET_REG_BITS == 32) { 2134 tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2135 if (flags & TCG_BSWAP_OS) { 2136 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2137 } else { 2138 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2139 } 2140 } else if (tcg_op_supported(INDEX_op_bswap32, TCG_TYPE_I64, 0)) { 2141 tcg_gen_op3i_i64(INDEX_op_bswap32, ret, arg, flags); 2142 } else { 2143 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2144 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2145 TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff); 2146 2147 /* arg = xxxxabcd */ 2148 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .xxxxabc */ 2149 tcg_gen_and_i64(t1, arg, t2); /* t1 = .....b.d */ 2150 tcg_gen_and_i64(t0, t0, t2); /* t0 = .....a.c */ 2151 tcg_gen_shli_i64(t1, t1, 8); /* t1 = ....b.d. */ 2152 tcg_gen_or_i64(ret, t0, t1); /* ret = ....badc */ 2153 2154 tcg_gen_shli_i64(t1, ret, 48); /* t1 = dc...... */ 2155 tcg_gen_shri_i64(t0, ret, 16); /* t0 = ......ba */ 2156 if (flags & TCG_BSWAP_OS) { 2157 tcg_gen_sari_i64(t1, t1, 32); /* t1 = ssssdc.. */ 2158 } else { 2159 tcg_gen_shri_i64(t1, t1, 32); /* t1 = ....dc.. */ 2160 } 2161 tcg_gen_or_i64(ret, t0, t1); /* ret = ssssdcba (OS) */ 2162 /* ....dcba (else) */ 2163 2164 tcg_temp_free_i64(t0); 2165 tcg_temp_free_i64(t1); 2166 } 2167 } 2168 2169 /* 2170 * bswap64_i64: 64-bit byte swap on a 64-bit value. 2171 * 2172 * Byte pattern: abcdefgh -> hgfedcba 2173 */ 2174 void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) 2175 { 2176 if (TCG_TARGET_REG_BITS == 32) { 2177 TCGv_i32 t0, t1; 2178 t0 = tcg_temp_ebb_new_i32(); 2179 t1 = tcg_temp_ebb_new_i32(); 2180 2181 tcg_gen_bswap32_i32(t0, TCGV_LOW(arg)); 2182 tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg)); 2183 tcg_gen_mov_i32(TCGV_LOW(ret), t1); 2184 tcg_gen_mov_i32(TCGV_HIGH(ret), t0); 2185 tcg_temp_free_i32(t0); 2186 tcg_temp_free_i32(t1); 2187 } else if (tcg_op_supported(INDEX_op_bswap64, TCG_TYPE_I64, 0)) { 2188 tcg_gen_op3i_i64(INDEX_op_bswap64, ret, arg, 0); 2189 } else { 2190 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2191 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2192 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 2193 2194 /* arg = abcdefgh */ 2195 tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull); 2196 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .abcdefg */ 2197 tcg_gen_and_i64(t1, arg, t2); /* t1 = .b.d.f.h */ 2198 tcg_gen_and_i64(t0, t0, t2); /* t0 = .a.c.e.g */ 2199 tcg_gen_shli_i64(t1, t1, 8); /* t1 = b.d.f.h. */ 2200 tcg_gen_or_i64(ret, t0, t1); /* ret = badcfehg */ 2201 2202 tcg_gen_movi_i64(t2, 0x0000ffff0000ffffull); 2203 tcg_gen_shri_i64(t0, ret, 16); /* t0 = ..badcfe */ 2204 tcg_gen_and_i64(t1, ret, t2); /* t1 = ..dc..hg */ 2205 tcg_gen_and_i64(t0, t0, t2); /* t0 = ..ba..fe */ 2206 tcg_gen_shli_i64(t1, t1, 16); /* t1 = dc..hg.. */ 2207 tcg_gen_or_i64(ret, t0, t1); /* ret = dcbahgfe */ 2208 2209 tcg_gen_shri_i64(t0, ret, 32); /* t0 = ....dcba */ 2210 tcg_gen_shli_i64(t1, ret, 32); /* t1 = hgfe.... */ 2211 tcg_gen_or_i64(ret, t0, t1); /* ret = hgfedcba */ 2212 2213 tcg_temp_free_i64(t0); 2214 tcg_temp_free_i64(t1); 2215 tcg_temp_free_i64(t2); 2216 } 2217 } 2218 2219 /* 2220 * hswap_i64: Swap 16-bit halfwords within a 64-bit value. 2221 * See also include/qemu/bitops.h, hswap64. 2222 * 2223 * Byte pattern: abcdefgh -> ghefcdab 2224 */ 2225 void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg) 2226 { 2227 uint64_t m = 0x0000ffff0000ffffull; 2228 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2229 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2230 2231 /* arg = abcdefgh */ 2232 tcg_gen_rotli_i64(t1, arg, 32); /* t1 = efghabcd */ 2233 tcg_gen_andi_i64(t0, t1, m); /* t0 = ..gh..cd */ 2234 tcg_gen_shli_i64(t0, t0, 16); /* t0 = gh..cd.. */ 2235 tcg_gen_shri_i64(t1, t1, 16); /* t1 = ..efghab */ 2236 tcg_gen_andi_i64(t1, t1, m); /* t1 = ..ef..ab */ 2237 tcg_gen_or_i64(ret, t0, t1); /* ret = ghefcdab */ 2238 2239 tcg_temp_free_i64(t0); 2240 tcg_temp_free_i64(t1); 2241 } 2242 2243 /* 2244 * wswap_i64: Swap 32-bit words within a 64-bit value. 2245 * 2246 * Byte pattern: abcdefgh -> efghabcd 2247 */ 2248 void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg) 2249 { 2250 /* Swapping 2 32-bit elements is a rotate. */ 2251 tcg_gen_rotli_i64(ret, arg, 32); 2252 } 2253 2254 void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg) 2255 { 2256 if (TCG_TARGET_REG_BITS == 32) { 2257 tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2258 tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 2259 } else if (tcg_op_supported(INDEX_op_not, TCG_TYPE_I64, 0)) { 2260 tcg_gen_op2_i64(INDEX_op_not, ret, arg); 2261 } else { 2262 tcg_gen_xori_i64(ret, arg, -1); 2263 } 2264 } 2265 2266 void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2267 { 2268 if (TCG_TARGET_REG_BITS == 32) { 2269 tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2270 tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2271 } else if (tcg_op_supported(INDEX_op_andc, TCG_TYPE_I64, 0)) { 2272 tcg_gen_op3_i64(INDEX_op_andc, ret, arg1, arg2); 2273 } else { 2274 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2275 tcg_gen_not_i64(t0, arg2); 2276 tcg_gen_and_i64(ret, arg1, t0); 2277 tcg_temp_free_i64(t0); 2278 } 2279 } 2280 2281 void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2282 { 2283 if (TCG_TARGET_REG_BITS == 32) { 2284 tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2285 tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2286 } else if (tcg_op_supported(INDEX_op_eqv, TCG_TYPE_I64, 0)) { 2287 tcg_gen_op3_i64(INDEX_op_eqv, ret, arg1, arg2); 2288 } else { 2289 tcg_gen_xor_i64(ret, arg1, arg2); 2290 tcg_gen_not_i64(ret, ret); 2291 } 2292 } 2293 2294 void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2295 { 2296 if (TCG_TARGET_REG_BITS == 32) { 2297 tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2298 tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2299 } else if (tcg_op_supported(INDEX_op_nand, TCG_TYPE_I64, 0)) { 2300 tcg_gen_op3_i64(INDEX_op_nand, ret, arg1, arg2); 2301 } else { 2302 tcg_gen_and_i64(ret, arg1, arg2); 2303 tcg_gen_not_i64(ret, ret); 2304 } 2305 } 2306 2307 void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2308 { 2309 if (TCG_TARGET_REG_BITS == 32) { 2310 tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2311 tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2312 } else if (tcg_op_supported(INDEX_op_nor, TCG_TYPE_I64, 0)) { 2313 tcg_gen_op3_i64(INDEX_op_nor, ret, arg1, arg2); 2314 } else { 2315 tcg_gen_or_i64(ret, arg1, arg2); 2316 tcg_gen_not_i64(ret, ret); 2317 } 2318 } 2319 2320 void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2321 { 2322 if (TCG_TARGET_REG_BITS == 32) { 2323 tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 2324 tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 2325 } else if (tcg_op_supported(INDEX_op_orc, TCG_TYPE_I64, 0)) { 2326 tcg_gen_op3_i64(INDEX_op_orc, ret, arg1, arg2); 2327 } else { 2328 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2329 tcg_gen_not_i64(t0, arg2); 2330 tcg_gen_or_i64(ret, arg1, t0); 2331 tcg_temp_free_i64(t0); 2332 } 2333 } 2334 2335 void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2336 { 2337 if (tcg_op_supported(INDEX_op_clz, TCG_TYPE_I64, 0)) { 2338 tcg_gen_op3_i64(INDEX_op_clz, ret, arg1, arg2); 2339 } else { 2340 gen_helper_clz_i64(ret, arg1, arg2); 2341 } 2342 } 2343 2344 void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) 2345 { 2346 if (TCG_TARGET_REG_BITS == 32 2347 && arg2 <= 0xffffffffu 2348 && tcg_op_supported(INDEX_op_clz, TCG_TYPE_I32, 0)) { 2349 TCGv_i32 t = tcg_temp_ebb_new_i32(); 2350 tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32); 2351 tcg_gen_addi_i32(t, t, 32); 2352 tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t); 2353 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2354 tcg_temp_free_i32(t); 2355 } else { 2356 tcg_gen_clz_i64(ret, arg1, tcg_constant_i64(arg2)); 2357 } 2358 } 2359 2360 void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2361 { 2362 TCGv_i64 z, t; 2363 2364 if (tcg_op_supported(INDEX_op_ctz, TCG_TYPE_I64, 0)) { 2365 tcg_gen_op3_i64(INDEX_op_ctz, ret, arg1, arg2); 2366 return; 2367 } 2368 if (tcg_op_supported(INDEX_op_ctpop, TCG_TYPE_I64, 0)) { 2369 t = tcg_temp_ebb_new_i64(); 2370 tcg_gen_subi_i64(t, arg1, 1); 2371 tcg_gen_andc_i64(t, t, arg1); 2372 tcg_gen_ctpop_i64(t, t); 2373 } else if (tcg_op_supported(INDEX_op_clz, TCG_TYPE_I64, 0)) { 2374 t = tcg_temp_ebb_new_i64(); 2375 tcg_gen_neg_i64(t, arg1); 2376 tcg_gen_and_i64(t, t, arg1); 2377 tcg_gen_clzi_i64(t, t, 64); 2378 tcg_gen_xori_i64(t, t, 63); 2379 } else { 2380 gen_helper_ctz_i64(ret, arg1, arg2); 2381 return; 2382 } 2383 2384 z = tcg_constant_i64(0); 2385 tcg_gen_movcond_i64(TCG_COND_EQ, ret, arg1, z, arg2, t); 2386 tcg_temp_free_i64(t); 2387 } 2388 2389 void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) 2390 { 2391 if (TCG_TARGET_REG_BITS == 32 2392 && arg2 <= 0xffffffffu 2393 && tcg_op_supported(INDEX_op_ctz, TCG_TYPE_I32, 0)) { 2394 TCGv_i32 t32 = tcg_temp_ebb_new_i32(); 2395 tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32); 2396 tcg_gen_addi_i32(t32, t32, 32); 2397 tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32); 2398 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2399 tcg_temp_free_i32(t32); 2400 } else if (arg2 == 64 2401 && !tcg_op_supported(INDEX_op_ctz, TCG_TYPE_I64, 0) 2402 && tcg_op_supported(INDEX_op_ctpop, TCG_TYPE_I64, 0)) { 2403 /* This equivalence has the advantage of not requiring a fixup. */ 2404 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2405 tcg_gen_subi_i64(t, arg1, 1); 2406 tcg_gen_andc_i64(t, t, arg1); 2407 tcg_gen_ctpop_i64(ret, t); 2408 tcg_temp_free_i64(t); 2409 } else { 2410 tcg_gen_ctz_i64(ret, arg1, tcg_constant_i64(arg2)); 2411 } 2412 } 2413 2414 void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg) 2415 { 2416 if (tcg_op_supported(INDEX_op_clz, TCG_TYPE_I64, 0)) { 2417 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2418 tcg_gen_sari_i64(t, arg, 63); 2419 tcg_gen_xor_i64(t, t, arg); 2420 tcg_gen_clzi_i64(t, t, 64); 2421 tcg_gen_subi_i64(ret, t, 1); 2422 tcg_temp_free_i64(t); 2423 } else { 2424 gen_helper_clrsb_i64(ret, arg); 2425 } 2426 } 2427 2428 void tcg_gen_ctpop_i64(TCGv_i64 ret, TCGv_i64 arg1) 2429 { 2430 if (TCG_TARGET_REG_BITS == 64) { 2431 if (tcg_op_supported(INDEX_op_ctpop, TCG_TYPE_I64, 0)) { 2432 tcg_gen_op2_i64(INDEX_op_ctpop, ret, arg1); 2433 return; 2434 } 2435 } else { 2436 if (tcg_op_supported(INDEX_op_ctpop, TCG_TYPE_I32, 0)) { 2437 tcg_gen_ctpop_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 2438 tcg_gen_ctpop_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 2439 tcg_gen_add_i32(TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret)); 2440 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2441 return; 2442 } 2443 } 2444 gen_helper_ctpop_i64(ret, arg1); 2445 } 2446 2447 void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2448 { 2449 if (tcg_op_supported(INDEX_op_rotl, TCG_TYPE_I64, 0)) { 2450 tcg_gen_op3_i64(INDEX_op_rotl, ret, arg1, arg2); 2451 } else if (tcg_op_supported(INDEX_op_rotl, TCG_TYPE_I64, 0)) { 2452 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2453 tcg_gen_neg_i64(t0, arg2); 2454 tcg_gen_op3_i64(INDEX_op_rotr, ret, arg1, t0); 2455 tcg_temp_free_i64(t0); 2456 } else { 2457 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2458 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2459 tcg_gen_shl_i64(t0, arg1, arg2); 2460 tcg_gen_neg_i64(t1, arg2); 2461 tcg_gen_shr_i64(t1, arg1, t1); 2462 tcg_gen_or_i64(ret, t0, t1); 2463 tcg_temp_free_i64(t0); 2464 tcg_temp_free_i64(t1); 2465 } 2466 } 2467 2468 void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 2469 { 2470 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 2471 /* some cases can be optimized here */ 2472 if (arg2 == 0) { 2473 tcg_gen_mov_i64(ret, arg1); 2474 } else if (tcg_op_supported(INDEX_op_rotl, TCG_TYPE_I64, 0)) { 2475 TCGv_i64 t0 = tcg_constant_i64(arg2); 2476 tcg_gen_op3_i64(INDEX_op_rotl, ret, arg1, t0); 2477 } else if (tcg_op_supported(INDEX_op_rotr, TCG_TYPE_I64, 0)) { 2478 TCGv_i64 t0 = tcg_constant_i64(64 - arg2); 2479 tcg_gen_op3_i64(INDEX_op_rotr, ret, arg1, t0); 2480 } else { 2481 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2482 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2483 tcg_gen_shli_i64(t0, arg1, arg2); 2484 tcg_gen_shri_i64(t1, arg1, 64 - arg2); 2485 tcg_gen_or_i64(ret, t0, t1); 2486 tcg_temp_free_i64(t0); 2487 tcg_temp_free_i64(t1); 2488 } 2489 } 2490 2491 void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 2492 { 2493 if (tcg_op_supported(INDEX_op_rotr, TCG_TYPE_I64, 0)) { 2494 tcg_gen_op3_i64(INDEX_op_rotr, ret, arg1, arg2); 2495 } else if (tcg_op_supported(INDEX_op_rotl, TCG_TYPE_I64, 0)) { 2496 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2497 tcg_gen_neg_i64(t0, arg2); 2498 tcg_gen_op3_i64(INDEX_op_rotl, ret, arg1, t0); 2499 tcg_temp_free_i64(t0); 2500 } else { 2501 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2502 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2503 tcg_gen_shr_i64(t0, arg1, arg2); 2504 tcg_gen_neg_i64(t1, arg2); 2505 tcg_gen_shl_i64(t1, arg1, t1); 2506 tcg_gen_or_i64(ret, t0, t1); 2507 tcg_temp_free_i64(t0); 2508 tcg_temp_free_i64(t1); 2509 } 2510 } 2511 2512 void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 2513 { 2514 tcg_debug_assert(arg2 >= 0 && arg2 < 64); 2515 tcg_gen_rotli_i64(ret, arg1, -arg2 & 63); 2516 } 2517 2518 void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2, 2519 unsigned int ofs, unsigned int len) 2520 { 2521 uint64_t mask; 2522 TCGv_i64 t1; 2523 2524 tcg_debug_assert(ofs < 64); 2525 tcg_debug_assert(len > 0); 2526 tcg_debug_assert(len <= 64); 2527 tcg_debug_assert(ofs + len <= 64); 2528 2529 if (len == 64) { 2530 tcg_gen_mov_i64(ret, arg2); 2531 return; 2532 } 2533 2534 if (TCG_TARGET_REG_BITS == 64) { 2535 if (TCG_TARGET_deposit_valid(TCG_TYPE_I64, ofs, len)) { 2536 tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len); 2537 return; 2538 } 2539 } else { 2540 if (ofs >= 32) { 2541 tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 2542 TCGV_LOW(arg2), ofs - 32, len); 2543 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 2544 return; 2545 } 2546 if (ofs + len <= 32) { 2547 tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1), 2548 TCGV_LOW(arg2), ofs, len); 2549 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 2550 return; 2551 } 2552 } 2553 2554 t1 = tcg_temp_ebb_new_i64(); 2555 2556 if (TCG_TARGET_HAS_extract2_i64) { 2557 if (ofs + len == 64) { 2558 tcg_gen_shli_i64(t1, arg1, len); 2559 tcg_gen_extract2_i64(ret, t1, arg2, len); 2560 goto done; 2561 } 2562 if (ofs == 0) { 2563 tcg_gen_extract2_i64(ret, arg1, arg2, len); 2564 tcg_gen_rotli_i64(ret, ret, len); 2565 goto done; 2566 } 2567 } 2568 2569 mask = (1ull << len) - 1; 2570 if (ofs + len < 64) { 2571 tcg_gen_andi_i64(t1, arg2, mask); 2572 tcg_gen_shli_i64(t1, t1, ofs); 2573 } else { 2574 tcg_gen_shli_i64(t1, arg2, ofs); 2575 } 2576 tcg_gen_andi_i64(ret, arg1, ~(mask << ofs)); 2577 tcg_gen_or_i64(ret, ret, t1); 2578 done: 2579 tcg_temp_free_i64(t1); 2580 } 2581 2582 void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg, 2583 unsigned int ofs, unsigned int len) 2584 { 2585 tcg_debug_assert(ofs < 64); 2586 tcg_debug_assert(len > 0); 2587 tcg_debug_assert(len <= 64); 2588 tcg_debug_assert(ofs + len <= 64); 2589 2590 if (ofs + len == 64) { 2591 tcg_gen_shli_i64(ret, arg, ofs); 2592 } else if (ofs == 0) { 2593 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1); 2594 } else if (TCG_TARGET_REG_BITS == 64 && 2595 TCG_TARGET_deposit_valid(TCG_TYPE_I64, ofs, len)) { 2596 TCGv_i64 zero = tcg_constant_i64(0); 2597 tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len); 2598 } else { 2599 if (TCG_TARGET_REG_BITS == 32) { 2600 if (ofs >= 32) { 2601 tcg_gen_deposit_z_i32(TCGV_HIGH(ret), TCGV_LOW(arg), 2602 ofs - 32, len); 2603 tcg_gen_movi_i32(TCGV_LOW(ret), 0); 2604 return; 2605 } 2606 if (ofs + len <= 32) { 2607 tcg_gen_deposit_z_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); 2608 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2609 return; 2610 } 2611 } 2612 /* 2613 * To help two-operand hosts we prefer to zero-extend first, 2614 * which allows ARG to stay live. 2615 */ 2616 if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, len)) { 2617 tcg_gen_extract_i64(ret, arg, 0, len); 2618 tcg_gen_shli_i64(ret, ret, ofs); 2619 return; 2620 } 2621 /* Otherwise prefer zero-extension over AND for code size. */ 2622 if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, ofs + len)) { 2623 tcg_gen_shli_i64(ret, arg, ofs); 2624 tcg_gen_extract_i64(ret, ret, 0, ofs + len); 2625 return; 2626 } 2627 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1); 2628 tcg_gen_shli_i64(ret, ret, ofs); 2629 } 2630 } 2631 2632 void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg, 2633 unsigned int ofs, unsigned int len) 2634 { 2635 tcg_debug_assert(ofs < 64); 2636 tcg_debug_assert(len > 0); 2637 tcg_debug_assert(len <= 64); 2638 tcg_debug_assert(ofs + len <= 64); 2639 2640 /* Canonicalize certain special cases, even if extract is supported. */ 2641 if (ofs + len == 64) { 2642 tcg_gen_shri_i64(ret, arg, 64 - len); 2643 return; 2644 } 2645 2646 if (TCG_TARGET_REG_BITS == 32) { 2647 /* Look for a 32-bit extract within one of the two words. */ 2648 if (ofs >= 32) { 2649 tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len); 2650 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2651 return; 2652 } 2653 if (ofs + len <= 32) { 2654 tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); 2655 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2656 return; 2657 } 2658 2659 /* The field is split across two words. */ 2660 tcg_gen_extract2_i32(TCGV_LOW(ret), TCGV_LOW(arg), 2661 TCGV_HIGH(arg), ofs); 2662 if (len <= 32) { 2663 tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(ret), 0, len); 2664 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2665 } else { 2666 tcg_gen_extract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 2667 ofs, len - 32); 2668 } 2669 return; 2670 } 2671 2672 if (TCG_TARGET_extract_valid(TCG_TYPE_I64, ofs, len)) { 2673 tcg_gen_op4ii_i64(INDEX_op_extract, ret, arg, ofs, len); 2674 return; 2675 } 2676 if (ofs == 0) { 2677 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1); 2678 return; 2679 } 2680 2681 /* Assume that zero-extension, if available, is cheaper than a shift. */ 2682 if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, ofs + len)) { 2683 tcg_gen_op4ii_i64(INDEX_op_extract, ret, arg, 0, ofs + len); 2684 tcg_gen_shri_i64(ret, ret, ofs); 2685 return; 2686 } 2687 2688 /* ??? Ideally we'd know what values are available for immediate AND. 2689 Assume that 8 bits are available, plus the special cases of 16 and 32, 2690 so that we get ext8u, ext16u, and ext32u. */ 2691 switch (len) { 2692 case 1 ... 8: case 16: case 32: 2693 tcg_gen_shri_i64(ret, arg, ofs); 2694 tcg_gen_andi_i64(ret, ret, (1ull << len) - 1); 2695 break; 2696 default: 2697 tcg_gen_shli_i64(ret, arg, 64 - len - ofs); 2698 tcg_gen_shri_i64(ret, ret, 64 - len); 2699 break; 2700 } 2701 } 2702 2703 void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg, 2704 unsigned int ofs, unsigned int len) 2705 { 2706 tcg_debug_assert(ofs < 64); 2707 tcg_debug_assert(len > 0); 2708 tcg_debug_assert(len <= 64); 2709 tcg_debug_assert(ofs + len <= 64); 2710 2711 /* Canonicalize certain special cases, even if sextract is supported. */ 2712 if (ofs + len == 64) { 2713 tcg_gen_sari_i64(ret, arg, 64 - len); 2714 return; 2715 } 2716 2717 if (TCG_TARGET_REG_BITS == 32) { 2718 /* Look for a 32-bit extract within one of the two words. */ 2719 if (ofs >= 32) { 2720 tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len); 2721 } else if (ofs + len <= 32) { 2722 tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); 2723 } else if (ofs == 0) { 2724 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 2725 tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32); 2726 return; 2727 } else if (len > 32) { 2728 TCGv_i32 t = tcg_temp_ebb_new_i32(); 2729 /* Extract the bits for the high word normally. */ 2730 tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32); 2731 /* Shift the field down for the low part. */ 2732 tcg_gen_shri_i64(ret, arg, ofs); 2733 /* Overwrite the shift into the high part. */ 2734 tcg_gen_mov_i32(TCGV_HIGH(ret), t); 2735 tcg_temp_free_i32(t); 2736 return; 2737 } else { 2738 /* Shift the field down for the low part, such that the 2739 field sits at the MSB. */ 2740 tcg_gen_shri_i64(ret, arg, ofs + len - 32); 2741 /* Shift the field down from the MSB, sign extending. */ 2742 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_LOW(ret), 32 - len); 2743 } 2744 /* Sign-extend the field from 32 bits. */ 2745 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 2746 return; 2747 } 2748 2749 if (TCG_TARGET_sextract_valid(TCG_TYPE_I64, ofs, len)) { 2750 tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len); 2751 return; 2752 } 2753 2754 /* Assume that sign-extension, if available, is cheaper than a shift. */ 2755 if (TCG_TARGET_sextract_valid(TCG_TYPE_I64, 0, ofs + len)) { 2756 tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, 0, ofs + len); 2757 tcg_gen_sari_i64(ret, ret, ofs); 2758 return; 2759 } 2760 if (TCG_TARGET_sextract_valid(TCG_TYPE_I64, 0, len)) { 2761 tcg_gen_shri_i64(ret, arg, ofs); 2762 tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, ret, 0, len); 2763 return; 2764 } 2765 2766 tcg_gen_shli_i64(ret, arg, 64 - len - ofs); 2767 tcg_gen_sari_i64(ret, ret, 64 - len); 2768 } 2769 2770 /* 2771 * Extract 64 bits from a 128-bit input, ah:al, starting from ofs. 2772 * Unlike tcg_gen_extract_i64 above, len is fixed at 64. 2773 */ 2774 void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah, 2775 unsigned int ofs) 2776 { 2777 tcg_debug_assert(ofs <= 64); 2778 if (ofs == 0) { 2779 tcg_gen_mov_i64(ret, al); 2780 } else if (ofs == 64) { 2781 tcg_gen_mov_i64(ret, ah); 2782 } else if (al == ah) { 2783 tcg_gen_rotri_i64(ret, al, ofs); 2784 } else if (TCG_TARGET_HAS_extract2_i64) { 2785 tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs); 2786 } else { 2787 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2788 tcg_gen_shri_i64(t0, al, ofs); 2789 tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs); 2790 tcg_temp_free_i64(t0); 2791 } 2792 } 2793 2794 void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1, 2795 TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2) 2796 { 2797 if (cond == TCG_COND_ALWAYS) { 2798 tcg_gen_mov_i64(ret, v1); 2799 } else if (cond == TCG_COND_NEVER) { 2800 tcg_gen_mov_i64(ret, v2); 2801 } else if (TCG_TARGET_REG_BITS == 64) { 2802 tcg_gen_op6i_i64(INDEX_op_movcond, ret, c1, c2, v1, v2, cond); 2803 } else { 2804 TCGv_i32 t0 = tcg_temp_ebb_new_i32(); 2805 TCGv_i32 zero = tcg_constant_i32(0); 2806 2807 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0, 2808 TCGV_LOW(c1), TCGV_HIGH(c1), 2809 TCGV_LOW(c2), TCGV_HIGH(c2), cond); 2810 2811 tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, zero, 2812 TCGV_LOW(v1), TCGV_LOW(v2)); 2813 tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, zero, 2814 TCGV_HIGH(v1), TCGV_HIGH(v2)); 2815 2816 tcg_temp_free_i32(t0); 2817 } 2818 } 2819 2820 void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 2821 TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 2822 { 2823 if (TCG_TARGET_HAS_add2_i64) { 2824 tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh); 2825 } else { 2826 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2827 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2828 tcg_gen_add_i64(t0, al, bl); 2829 tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al); 2830 tcg_gen_add_i64(rh, ah, bh); 2831 tcg_gen_add_i64(rh, rh, t1); 2832 tcg_gen_mov_i64(rl, t0); 2833 tcg_temp_free_i64(t0); 2834 tcg_temp_free_i64(t1); 2835 } 2836 } 2837 2838 void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 2839 TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 2840 { 2841 if (TCG_TARGET_HAS_sub2_i64) { 2842 tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh); 2843 } else { 2844 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2845 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2846 tcg_gen_sub_i64(t0, al, bl); 2847 tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl); 2848 tcg_gen_sub_i64(rh, ah, bh); 2849 tcg_gen_sub_i64(rh, rh, t1); 2850 tcg_gen_mov_i64(rl, t0); 2851 tcg_temp_free_i64(t0); 2852 tcg_temp_free_i64(t1); 2853 } 2854 } 2855 2856 void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 2857 { 2858 if (tcg_op_supported(INDEX_op_mulu2, TCG_TYPE_I64, 0)) { 2859 tcg_gen_op4_i64(INDEX_op_mulu2, rl, rh, arg1, arg2); 2860 } else if (tcg_op_supported(INDEX_op_muluh, TCG_TYPE_I64, 0)) { 2861 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2862 tcg_gen_op3_i64(INDEX_op_mul, t, arg1, arg2); 2863 tcg_gen_op3_i64(INDEX_op_muluh, rh, arg1, arg2); 2864 tcg_gen_mov_i64(rl, t); 2865 tcg_temp_free_i64(t); 2866 } else { 2867 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2868 tcg_gen_mul_i64(t0, arg1, arg2); 2869 gen_helper_muluh_i64(rh, arg1, arg2); 2870 tcg_gen_mov_i64(rl, t0); 2871 tcg_temp_free_i64(t0); 2872 } 2873 } 2874 2875 void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 2876 { 2877 if (tcg_op_supported(INDEX_op_muls2, TCG_TYPE_I64, 0)) { 2878 tcg_gen_op4_i64(INDEX_op_muls2, rl, rh, arg1, arg2); 2879 } else if (tcg_op_supported(INDEX_op_mulsh, TCG_TYPE_I64, 0)) { 2880 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2881 tcg_gen_op3_i64(INDEX_op_mul, t, arg1, arg2); 2882 tcg_gen_op3_i64(INDEX_op_mulsh, rh, arg1, arg2); 2883 tcg_gen_mov_i64(rl, t); 2884 tcg_temp_free_i64(t); 2885 } else if (tcg_op_supported(INDEX_op_mulu2, TCG_TYPE_I64, 0) || 2886 tcg_op_supported(INDEX_op_muluh, TCG_TYPE_I64, 0)) { 2887 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2888 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2889 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 2890 TCGv_i64 t3 = tcg_temp_ebb_new_i64(); 2891 tcg_gen_mulu2_i64(t0, t1, arg1, arg2); 2892 /* Adjust for negative inputs. */ 2893 tcg_gen_sari_i64(t2, arg1, 63); 2894 tcg_gen_sari_i64(t3, arg2, 63); 2895 tcg_gen_and_i64(t2, t2, arg2); 2896 tcg_gen_and_i64(t3, t3, arg1); 2897 tcg_gen_sub_i64(rh, t1, t2); 2898 tcg_gen_sub_i64(rh, rh, t3); 2899 tcg_gen_mov_i64(rl, t0); 2900 tcg_temp_free_i64(t0); 2901 tcg_temp_free_i64(t1); 2902 tcg_temp_free_i64(t2); 2903 tcg_temp_free_i64(t3); 2904 } else { 2905 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2906 tcg_gen_mul_i64(t0, arg1, arg2); 2907 gen_helper_mulsh_i64(rh, arg1, arg2); 2908 tcg_gen_mov_i64(rl, t0); 2909 tcg_temp_free_i64(t0); 2910 } 2911 } 2912 2913 void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 2914 { 2915 TCGv_i64 t0 = tcg_temp_ebb_new_i64(); 2916 TCGv_i64 t1 = tcg_temp_ebb_new_i64(); 2917 TCGv_i64 t2 = tcg_temp_ebb_new_i64(); 2918 tcg_gen_mulu2_i64(t0, t1, arg1, arg2); 2919 /* Adjust for negative input for the signed arg1. */ 2920 tcg_gen_sari_i64(t2, arg1, 63); 2921 tcg_gen_and_i64(t2, t2, arg2); 2922 tcg_gen_sub_i64(rh, t1, t2); 2923 tcg_gen_mov_i64(rl, t0); 2924 tcg_temp_free_i64(t0); 2925 tcg_temp_free_i64(t1); 2926 tcg_temp_free_i64(t2); 2927 } 2928 2929 void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 2930 { 2931 tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b); 2932 } 2933 2934 void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 2935 { 2936 tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b); 2937 } 2938 2939 void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 2940 { 2941 tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a); 2942 } 2943 2944 void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b) 2945 { 2946 tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a); 2947 } 2948 2949 void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a) 2950 { 2951 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2952 2953 tcg_gen_sari_i64(t, a, 63); 2954 tcg_gen_xor_i64(ret, a, t); 2955 tcg_gen_sub_i64(ret, ret, t); 2956 tcg_temp_free_i64(t); 2957 } 2958 2959 /* Size changing operations. */ 2960 2961 void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg) 2962 { 2963 if (TCG_TARGET_REG_BITS == 32) { 2964 tcg_gen_mov_i32(ret, TCGV_LOW(arg)); 2965 } else if (TCG_TARGET_HAS_extr_i64_i32) { 2966 tcg_gen_op2(INDEX_op_extrl_i64_i32, TCG_TYPE_I32, 2967 tcgv_i32_arg(ret), tcgv_i64_arg(arg)); 2968 } else { 2969 tcg_gen_mov_i32(ret, (TCGv_i32)arg); 2970 } 2971 } 2972 2973 void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg) 2974 { 2975 if (TCG_TARGET_REG_BITS == 32) { 2976 tcg_gen_mov_i32(ret, TCGV_HIGH(arg)); 2977 } else if (TCG_TARGET_HAS_extr_i64_i32) { 2978 tcg_gen_op2(INDEX_op_extrh_i64_i32, TCG_TYPE_I32, 2979 tcgv_i32_arg(ret), tcgv_i64_arg(arg)); 2980 } else { 2981 TCGv_i64 t = tcg_temp_ebb_new_i64(); 2982 tcg_gen_shri_i64(t, arg, 32); 2983 tcg_gen_mov_i32(ret, (TCGv_i32)t); 2984 tcg_temp_free_i64(t); 2985 } 2986 } 2987 2988 void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 2989 { 2990 if (TCG_TARGET_REG_BITS == 32) { 2991 tcg_gen_mov_i32(TCGV_LOW(ret), arg); 2992 tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 2993 } else { 2994 tcg_gen_op2(INDEX_op_extu_i32_i64, TCG_TYPE_I64, 2995 tcgv_i64_arg(ret), tcgv_i32_arg(arg)); 2996 } 2997 } 2998 2999 void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 3000 { 3001 if (TCG_TARGET_REG_BITS == 32) { 3002 tcg_gen_mov_i32(TCGV_LOW(ret), arg); 3003 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 3004 } else { 3005 tcg_gen_op2(INDEX_op_ext_i32_i64, TCG_TYPE_I64, 3006 tcgv_i64_arg(ret), tcgv_i32_arg(arg)); 3007 } 3008 } 3009 3010 void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high) 3011 { 3012 TCGv_i64 tmp; 3013 3014 if (TCG_TARGET_REG_BITS == 32) { 3015 tcg_gen_mov_i32(TCGV_LOW(dest), low); 3016 tcg_gen_mov_i32(TCGV_HIGH(dest), high); 3017 return; 3018 } 3019 3020 tmp = tcg_temp_ebb_new_i64(); 3021 /* These extensions are only needed for type correctness. 3022 We may be able to do better given target specific information. */ 3023 tcg_gen_extu_i32_i64(tmp, high); 3024 tcg_gen_extu_i32_i64(dest, low); 3025 /* If deposit is available, use it. Otherwise use the extra 3026 knowledge that we have of the zero-extensions above. */ 3027 if (TCG_TARGET_deposit_valid(TCG_TYPE_I64, 32, 32)) { 3028 tcg_gen_deposit_i64(dest, dest, tmp, 32, 32); 3029 } else { 3030 tcg_gen_shli_i64(tmp, tmp, 32); 3031 tcg_gen_or_i64(dest, dest, tmp); 3032 } 3033 tcg_temp_free_i64(tmp); 3034 } 3035 3036 void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg) 3037 { 3038 if (TCG_TARGET_REG_BITS == 32) { 3039 tcg_gen_mov_i32(lo, TCGV_LOW(arg)); 3040 tcg_gen_mov_i32(hi, TCGV_HIGH(arg)); 3041 } else { 3042 tcg_gen_extrl_i64_i32(lo, arg); 3043 tcg_gen_extrh_i64_i32(hi, arg); 3044 } 3045 } 3046 3047 void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg) 3048 { 3049 tcg_gen_ext32u_i64(lo, arg); 3050 tcg_gen_shri_i64(hi, arg, 32); 3051 } 3052 3053 void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 hi) 3054 { 3055 tcg_gen_deposit_i64(ret, lo, hi, 32, 32); 3056 } 3057 3058 void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg) 3059 { 3060 tcg_gen_mov_i64(lo, TCGV128_LOW(arg)); 3061 tcg_gen_mov_i64(hi, TCGV128_HIGH(arg)); 3062 } 3063 3064 void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi) 3065 { 3066 tcg_gen_mov_i64(TCGV128_LOW(ret), lo); 3067 tcg_gen_mov_i64(TCGV128_HIGH(ret), hi); 3068 } 3069 3070 void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src) 3071 { 3072 if (dst != src) { 3073 tcg_gen_mov_i64(TCGV128_LOW(dst), TCGV128_LOW(src)); 3074 tcg_gen_mov_i64(TCGV128_HIGH(dst), TCGV128_HIGH(src)); 3075 } 3076 } 3077 3078 void tcg_gen_ld_i128(TCGv_i128 ret, TCGv_ptr base, tcg_target_long offset) 3079 { 3080 if (HOST_BIG_ENDIAN) { 3081 tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset); 3082 tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset + 8); 3083 } else { 3084 tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset); 3085 tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset + 8); 3086 } 3087 } 3088 3089 void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, tcg_target_long offset) 3090 { 3091 if (HOST_BIG_ENDIAN) { 3092 tcg_gen_st_i64(TCGV128_HIGH(val), base, offset); 3093 tcg_gen_st_i64(TCGV128_LOW(val), base, offset + 8); 3094 } else { 3095 tcg_gen_st_i64(TCGV128_LOW(val), base, offset); 3096 tcg_gen_st_i64(TCGV128_HIGH(val), base, offset + 8); 3097 } 3098 } 3099 3100 /* QEMU specific operations. */ 3101 3102 void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx) 3103 { 3104 /* 3105 * Let the jit code return the read-only version of the 3106 * TranslationBlock, so that we minimize the pc-relative 3107 * distance of the address of the exit_tb code to TB. 3108 * This will improve utilization of pc-relative address loads. 3109 * 3110 * TODO: Move this to translator_loop, so that all const 3111 * TranslationBlock pointers refer to read-only memory. 3112 * This requires coordination with targets that do not use 3113 * the translator_loop. 3114 */ 3115 uintptr_t val = (uintptr_t)tcg_splitwx_to_rx((void *)tb) + idx; 3116 3117 if (tb == NULL) { 3118 tcg_debug_assert(idx == 0); 3119 } else if (idx <= TB_EXIT_IDXMAX) { 3120 #ifdef CONFIG_DEBUG_TCG 3121 /* This is an exit following a goto_tb. Verify that we have 3122 seen this numbered exit before, via tcg_gen_goto_tb. */ 3123 tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx)); 3124 #endif 3125 } else { 3126 /* This is an exit via the exitreq label. */ 3127 tcg_debug_assert(idx == TB_EXIT_REQUESTED); 3128 } 3129 3130 tcg_gen_op1i(INDEX_op_exit_tb, 0, val); 3131 } 3132 3133 void tcg_gen_goto_tb(unsigned idx) 3134 { 3135 /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */ 3136 tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB)); 3137 /* We only support two chained exits. */ 3138 tcg_debug_assert(idx <= TB_EXIT_IDXMAX); 3139 #ifdef CONFIG_DEBUG_TCG 3140 /* Verify that we haven't seen this numbered exit before. */ 3141 tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0); 3142 tcg_ctx->goto_tb_issue_mask |= 1 << idx; 3143 #endif 3144 plugin_gen_disable_mem_helpers(); 3145 tcg_gen_op1i(INDEX_op_goto_tb, 0, idx); 3146 } 3147 3148 void tcg_gen_lookup_and_goto_ptr(void) 3149 { 3150 TCGv_ptr ptr; 3151 3152 if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) { 3153 tcg_gen_exit_tb(NULL, 0); 3154 return; 3155 } 3156 3157 plugin_gen_disable_mem_helpers(); 3158 ptr = tcg_temp_ebb_new_ptr(); 3159 gen_helper_lookup_tb_ptr(ptr, tcg_env); 3160 tcg_gen_op1i(INDEX_op_goto_ptr, TCG_TYPE_PTR, tcgv_ptr_arg(ptr)); 3161 tcg_temp_free_ptr(ptr); 3162 } 3163