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