1951c6300SRichard Henderson /* 2951c6300SRichard Henderson * Tiny Code Generator for QEMU 3951c6300SRichard Henderson * 4951c6300SRichard Henderson * Copyright (c) 2008 Fabrice Bellard 5951c6300SRichard Henderson * 6951c6300SRichard Henderson * Permission is hereby granted, free of charge, to any person obtaining a copy 7951c6300SRichard Henderson * of this software and associated documentation files (the "Software"), to deal 8951c6300SRichard Henderson * in the Software without restriction, including without limitation the rights 9951c6300SRichard Henderson * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10951c6300SRichard Henderson * copies of the Software, and to permit persons to whom the Software is 11951c6300SRichard Henderson * furnished to do so, subject to the following conditions: 12951c6300SRichard Henderson * 13951c6300SRichard Henderson * The above copyright notice and this permission notice shall be included in 14951c6300SRichard Henderson * all copies or substantial portions of the Software. 15951c6300SRichard Henderson * 16951c6300SRichard Henderson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17951c6300SRichard Henderson * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18951c6300SRichard Henderson * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19951c6300SRichard Henderson * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20951c6300SRichard Henderson * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21951c6300SRichard Henderson * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22951c6300SRichard Henderson * THE SOFTWARE. 23951c6300SRichard Henderson */ 24951c6300SRichard Henderson 25951c6300SRichard Henderson #include "tcg.h" 26951c6300SRichard Henderson #include "tcg-op.h" 27951c6300SRichard Henderson 28*3a13c3f3SRichard Henderson /* Reduce the number of ifdefs below. This assumes that all uses of 29*3a13c3f3SRichard Henderson TCGV_HIGH and TCGV_LOW are properly protected by a conditional that 30*3a13c3f3SRichard Henderson the compiler can eliminate. */ 31*3a13c3f3SRichard Henderson #if TCG_TARGET_REG_BITS == 64 32*3a13c3f3SRichard Henderson extern TCGv_i32 TCGV_LOW_link_error(TCGv_i64); 33*3a13c3f3SRichard Henderson extern TCGv_i32 TCGV_HIGH_link_error(TCGv_i64); 34*3a13c3f3SRichard Henderson #define TCGV_LOW TCGV_LOW_link_error 35*3a13c3f3SRichard Henderson #define TCGV_HIGH TCGV_HIGH_link_error 36*3a13c3f3SRichard Henderson #endif 37951c6300SRichard Henderson 38951c6300SRichard Henderson void tcg_gen_op0(TCGContext *ctx, TCGOpcode opc) 39951c6300SRichard Henderson { 40951c6300SRichard Henderson *ctx->gen_opc_ptr++ = opc; 41951c6300SRichard Henderson } 42951c6300SRichard Henderson 43951c6300SRichard Henderson void tcg_gen_op1(TCGContext *ctx, TCGOpcode opc, TCGArg a1) 44951c6300SRichard Henderson { 45951c6300SRichard Henderson uint16_t *op = ctx->gen_opc_ptr; 46951c6300SRichard Henderson TCGArg *opp = ctx->gen_opparam_ptr; 47951c6300SRichard Henderson 48951c6300SRichard Henderson op[0] = opc; 49951c6300SRichard Henderson opp[0] = a1; 50951c6300SRichard Henderson 51951c6300SRichard Henderson ctx->gen_opc_ptr = op + 1; 52951c6300SRichard Henderson ctx->gen_opparam_ptr = opp + 1; 53951c6300SRichard Henderson } 54951c6300SRichard Henderson 55951c6300SRichard Henderson void tcg_gen_op2(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2) 56951c6300SRichard Henderson { 57951c6300SRichard Henderson uint16_t *op = ctx->gen_opc_ptr; 58951c6300SRichard Henderson TCGArg *opp = ctx->gen_opparam_ptr; 59951c6300SRichard Henderson 60951c6300SRichard Henderson op[0] = opc; 61951c6300SRichard Henderson opp[0] = a1; 62951c6300SRichard Henderson opp[1] = a2; 63951c6300SRichard Henderson 64951c6300SRichard Henderson ctx->gen_opc_ptr = op + 1; 65951c6300SRichard Henderson ctx->gen_opparam_ptr = opp + 2; 66951c6300SRichard Henderson } 67951c6300SRichard Henderson 68951c6300SRichard Henderson void tcg_gen_op3(TCGContext *ctx, TCGOpcode opc, TCGArg a1, 69951c6300SRichard Henderson TCGArg a2, TCGArg a3) 70951c6300SRichard Henderson { 71951c6300SRichard Henderson uint16_t *op = ctx->gen_opc_ptr; 72951c6300SRichard Henderson TCGArg *opp = ctx->gen_opparam_ptr; 73951c6300SRichard Henderson 74951c6300SRichard Henderson op[0] = opc; 75951c6300SRichard Henderson opp[0] = a1; 76951c6300SRichard Henderson opp[1] = a2; 77951c6300SRichard Henderson opp[2] = a3; 78951c6300SRichard Henderson 79951c6300SRichard Henderson ctx->gen_opc_ptr = op + 1; 80951c6300SRichard Henderson ctx->gen_opparam_ptr = opp + 3; 81951c6300SRichard Henderson } 82951c6300SRichard Henderson 83951c6300SRichard Henderson void tcg_gen_op4(TCGContext *ctx, TCGOpcode opc, TCGArg a1, 84951c6300SRichard Henderson TCGArg a2, TCGArg a3, TCGArg a4) 85951c6300SRichard Henderson { 86951c6300SRichard Henderson uint16_t *op = ctx->gen_opc_ptr; 87951c6300SRichard Henderson TCGArg *opp = ctx->gen_opparam_ptr; 88951c6300SRichard Henderson 89951c6300SRichard Henderson op[0] = opc; 90951c6300SRichard Henderson opp[0] = a1; 91951c6300SRichard Henderson opp[1] = a2; 92951c6300SRichard Henderson opp[2] = a3; 93951c6300SRichard Henderson opp[3] = a4; 94951c6300SRichard Henderson 95951c6300SRichard Henderson ctx->gen_opc_ptr = op + 1; 96951c6300SRichard Henderson ctx->gen_opparam_ptr = opp + 4; 97951c6300SRichard Henderson } 98951c6300SRichard Henderson 99951c6300SRichard Henderson void tcg_gen_op5(TCGContext *ctx, TCGOpcode opc, TCGArg a1, 100951c6300SRichard Henderson TCGArg a2, TCGArg a3, TCGArg a4, TCGArg a5) 101951c6300SRichard Henderson { 102951c6300SRichard Henderson uint16_t *op = ctx->gen_opc_ptr; 103951c6300SRichard Henderson TCGArg *opp = ctx->gen_opparam_ptr; 104951c6300SRichard Henderson 105951c6300SRichard Henderson op[0] = opc; 106951c6300SRichard Henderson opp[0] = a1; 107951c6300SRichard Henderson opp[1] = a2; 108951c6300SRichard Henderson opp[2] = a3; 109951c6300SRichard Henderson opp[3] = a4; 110951c6300SRichard Henderson opp[4] = a5; 111951c6300SRichard Henderson 112951c6300SRichard Henderson ctx->gen_opc_ptr = op + 1; 113951c6300SRichard Henderson ctx->gen_opparam_ptr = opp + 5; 114951c6300SRichard Henderson } 115951c6300SRichard Henderson 116951c6300SRichard Henderson void tcg_gen_op6(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2, 117951c6300SRichard Henderson TCGArg a3, TCGArg a4, TCGArg a5, TCGArg a6) 118951c6300SRichard Henderson { 119951c6300SRichard Henderson uint16_t *op = ctx->gen_opc_ptr; 120951c6300SRichard Henderson TCGArg *opp = ctx->gen_opparam_ptr; 121951c6300SRichard Henderson 122951c6300SRichard Henderson op[0] = opc; 123951c6300SRichard Henderson opp[0] = a1; 124951c6300SRichard Henderson opp[1] = a2; 125951c6300SRichard Henderson opp[2] = a3; 126951c6300SRichard Henderson opp[3] = a4; 127951c6300SRichard Henderson opp[4] = a5; 128951c6300SRichard Henderson opp[5] = a6; 129951c6300SRichard Henderson 130951c6300SRichard Henderson ctx->gen_opc_ptr = op + 1; 131951c6300SRichard Henderson ctx->gen_opparam_ptr = opp + 6; 132951c6300SRichard Henderson } 133951c6300SRichard Henderson 134951c6300SRichard Henderson /* 32 bit ops */ 135951c6300SRichard Henderson 136951c6300SRichard Henderson void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 137951c6300SRichard Henderson { 138951c6300SRichard Henderson /* some cases can be optimized here */ 139951c6300SRichard Henderson if (arg2 == 0) { 140951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 141951c6300SRichard Henderson } else { 142951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 143951c6300SRichard Henderson tcg_gen_add_i32(ret, arg1, t0); 144951c6300SRichard Henderson tcg_temp_free_i32(t0); 145951c6300SRichard Henderson } 146951c6300SRichard Henderson } 147951c6300SRichard Henderson 148951c6300SRichard Henderson void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2) 149951c6300SRichard Henderson { 150951c6300SRichard Henderson if (arg1 == 0 && TCG_TARGET_HAS_neg_i32) { 151951c6300SRichard Henderson /* Don't recurse with tcg_gen_neg_i32. */ 152951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg2); 153951c6300SRichard Henderson } else { 154951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg1); 155951c6300SRichard Henderson tcg_gen_sub_i32(ret, t0, arg2); 156951c6300SRichard Henderson tcg_temp_free_i32(t0); 157951c6300SRichard Henderson } 158951c6300SRichard Henderson } 159951c6300SRichard Henderson 160951c6300SRichard Henderson void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 161951c6300SRichard Henderson { 162951c6300SRichard Henderson /* some cases can be optimized here */ 163951c6300SRichard Henderson if (arg2 == 0) { 164951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 165951c6300SRichard Henderson } else { 166951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 167951c6300SRichard Henderson tcg_gen_sub_i32(ret, arg1, t0); 168951c6300SRichard Henderson tcg_temp_free_i32(t0); 169951c6300SRichard Henderson } 170951c6300SRichard Henderson } 171951c6300SRichard Henderson 172951c6300SRichard Henderson void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2) 173951c6300SRichard Henderson { 174951c6300SRichard Henderson TCGv_i32 t0; 175951c6300SRichard Henderson /* Some cases can be optimized here. */ 176951c6300SRichard Henderson switch (arg2) { 177951c6300SRichard Henderson case 0: 178951c6300SRichard Henderson tcg_gen_movi_i32(ret, 0); 179951c6300SRichard Henderson return; 180951c6300SRichard Henderson case 0xffffffffu: 181951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 182951c6300SRichard Henderson return; 183951c6300SRichard Henderson case 0xffu: 184951c6300SRichard Henderson /* Don't recurse with tcg_gen_ext8u_i32. */ 185951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8u_i32) { 186951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1); 187951c6300SRichard Henderson return; 188951c6300SRichard Henderson } 189951c6300SRichard Henderson break; 190951c6300SRichard Henderson case 0xffffu: 191951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16u_i32) { 192951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1); 193951c6300SRichard Henderson return; 194951c6300SRichard Henderson } 195951c6300SRichard Henderson break; 196951c6300SRichard Henderson } 197951c6300SRichard Henderson t0 = tcg_const_i32(arg2); 198951c6300SRichard Henderson tcg_gen_and_i32(ret, arg1, t0); 199951c6300SRichard Henderson tcg_temp_free_i32(t0); 200951c6300SRichard Henderson } 201951c6300SRichard Henderson 202951c6300SRichard Henderson void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 203951c6300SRichard Henderson { 204951c6300SRichard Henderson /* Some cases can be optimized here. */ 205951c6300SRichard Henderson if (arg2 == -1) { 206951c6300SRichard Henderson tcg_gen_movi_i32(ret, -1); 207951c6300SRichard Henderson } else if (arg2 == 0) { 208951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 209951c6300SRichard Henderson } else { 210951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 211951c6300SRichard Henderson tcg_gen_or_i32(ret, arg1, t0); 212951c6300SRichard Henderson tcg_temp_free_i32(t0); 213951c6300SRichard Henderson } 214951c6300SRichard Henderson } 215951c6300SRichard Henderson 216951c6300SRichard Henderson void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 217951c6300SRichard Henderson { 218951c6300SRichard Henderson /* Some cases can be optimized here. */ 219951c6300SRichard Henderson if (arg2 == 0) { 220951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 221951c6300SRichard Henderson } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) { 222951c6300SRichard Henderson /* Don't recurse with tcg_gen_not_i32. */ 223951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1); 224951c6300SRichard Henderson } else { 225951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 226951c6300SRichard Henderson tcg_gen_xor_i32(ret, arg1, t0); 227951c6300SRichard Henderson tcg_temp_free_i32(t0); 228951c6300SRichard Henderson } 229951c6300SRichard Henderson } 230951c6300SRichard Henderson 231951c6300SRichard Henderson void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 232951c6300SRichard Henderson { 233951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 234951c6300SRichard Henderson if (arg2 == 0) { 235951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 236951c6300SRichard Henderson } else { 237951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 238951c6300SRichard Henderson tcg_gen_shl_i32(ret, arg1, t0); 239951c6300SRichard Henderson tcg_temp_free_i32(t0); 240951c6300SRichard Henderson } 241951c6300SRichard Henderson } 242951c6300SRichard Henderson 243951c6300SRichard Henderson void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 244951c6300SRichard Henderson { 245951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 246951c6300SRichard Henderson if (arg2 == 0) { 247951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 248951c6300SRichard Henderson } else { 249951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 250951c6300SRichard Henderson tcg_gen_shr_i32(ret, arg1, t0); 251951c6300SRichard Henderson tcg_temp_free_i32(t0); 252951c6300SRichard Henderson } 253951c6300SRichard Henderson } 254951c6300SRichard Henderson 255951c6300SRichard Henderson void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 256951c6300SRichard Henderson { 257951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 258951c6300SRichard Henderson if (arg2 == 0) { 259951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 260951c6300SRichard Henderson } else { 261951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 262951c6300SRichard Henderson tcg_gen_sar_i32(ret, arg1, t0); 263951c6300SRichard Henderson tcg_temp_free_i32(t0); 264951c6300SRichard Henderson } 265951c6300SRichard Henderson } 266951c6300SRichard Henderson 267951c6300SRichard Henderson void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, int label) 268951c6300SRichard Henderson { 269951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 270951c6300SRichard Henderson tcg_gen_br(label); 271951c6300SRichard Henderson } else if (cond != TCG_COND_NEVER) { 272951c6300SRichard Henderson tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label); 273951c6300SRichard Henderson } 274951c6300SRichard Henderson } 275951c6300SRichard Henderson 276951c6300SRichard Henderson void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, int label) 277951c6300SRichard Henderson { 278951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 279951c6300SRichard Henderson tcg_gen_brcond_i32(cond, arg1, t0, label); 280951c6300SRichard Henderson tcg_temp_free_i32(t0); 281951c6300SRichard Henderson } 282951c6300SRichard Henderson 283951c6300SRichard Henderson void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret, 284951c6300SRichard Henderson TCGv_i32 arg1, TCGv_i32 arg2) 285951c6300SRichard Henderson { 286951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 287951c6300SRichard Henderson tcg_gen_movi_i32(ret, 1); 288951c6300SRichard Henderson } else if (cond == TCG_COND_NEVER) { 289951c6300SRichard Henderson tcg_gen_movi_i32(ret, 0); 290951c6300SRichard Henderson } else { 291951c6300SRichard Henderson tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond); 292951c6300SRichard Henderson } 293951c6300SRichard Henderson } 294951c6300SRichard Henderson 295951c6300SRichard Henderson void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret, 296951c6300SRichard Henderson TCGv_i32 arg1, int32_t arg2) 297951c6300SRichard Henderson { 298951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 299951c6300SRichard Henderson tcg_gen_setcond_i32(cond, ret, arg1, t0); 300951c6300SRichard Henderson tcg_temp_free_i32(t0); 301951c6300SRichard Henderson } 302951c6300SRichard Henderson 303951c6300SRichard Henderson void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 304951c6300SRichard Henderson { 305951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 306951c6300SRichard Henderson tcg_gen_mul_i32(ret, arg1, t0); 307951c6300SRichard Henderson tcg_temp_free_i32(t0); 308951c6300SRichard Henderson } 309951c6300SRichard Henderson 310951c6300SRichard Henderson void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 311951c6300SRichard Henderson { 312951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i32) { 313951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2); 314951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) { 315951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 316951c6300SRichard Henderson tcg_gen_sari_i32(t0, arg1, 31); 317951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2); 318951c6300SRichard Henderson tcg_temp_free_i32(t0); 319951c6300SRichard Henderson } else { 320951c6300SRichard Henderson gen_helper_div_i32(ret, arg1, arg2); 321951c6300SRichard Henderson } 322951c6300SRichard Henderson } 323951c6300SRichard Henderson 324951c6300SRichard Henderson void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 325951c6300SRichard Henderson { 326951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i32) { 327951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2); 328951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i32) { 329951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 330951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2); 331951c6300SRichard Henderson tcg_gen_mul_i32(t0, t0, arg2); 332951c6300SRichard Henderson tcg_gen_sub_i32(ret, arg1, t0); 333951c6300SRichard Henderson tcg_temp_free_i32(t0); 334951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) { 335951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 336951c6300SRichard Henderson tcg_gen_sari_i32(t0, arg1, 31); 337951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2); 338951c6300SRichard Henderson tcg_temp_free_i32(t0); 339951c6300SRichard Henderson } else { 340951c6300SRichard Henderson gen_helper_rem_i32(ret, arg1, arg2); 341951c6300SRichard Henderson } 342951c6300SRichard Henderson } 343951c6300SRichard Henderson 344951c6300SRichard Henderson void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 345951c6300SRichard Henderson { 346951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i32) { 347951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2); 348951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) { 349951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 350951c6300SRichard Henderson tcg_gen_movi_i32(t0, 0); 351951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2); 352951c6300SRichard Henderson tcg_temp_free_i32(t0); 353951c6300SRichard Henderson } else { 354951c6300SRichard Henderson gen_helper_divu_i32(ret, arg1, arg2); 355951c6300SRichard Henderson } 356951c6300SRichard Henderson } 357951c6300SRichard Henderson 358951c6300SRichard Henderson void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 359951c6300SRichard Henderson { 360951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i32) { 361951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2); 362951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i32) { 363951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 364951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2); 365951c6300SRichard Henderson tcg_gen_mul_i32(t0, t0, arg2); 366951c6300SRichard Henderson tcg_gen_sub_i32(ret, arg1, t0); 367951c6300SRichard Henderson tcg_temp_free_i32(t0); 368951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) { 369951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 370951c6300SRichard Henderson tcg_gen_movi_i32(t0, 0); 371951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2); 372951c6300SRichard Henderson tcg_temp_free_i32(t0); 373951c6300SRichard Henderson } else { 374951c6300SRichard Henderson gen_helper_remu_i32(ret, arg1, arg2); 375951c6300SRichard Henderson } 376951c6300SRichard Henderson } 377951c6300SRichard Henderson 378951c6300SRichard Henderson void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 379951c6300SRichard Henderson { 380951c6300SRichard Henderson if (TCG_TARGET_HAS_andc_i32) { 381951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2); 382951c6300SRichard Henderson } else { 383951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 384951c6300SRichard Henderson tcg_gen_not_i32(t0, arg2); 385951c6300SRichard Henderson tcg_gen_and_i32(ret, arg1, t0); 386951c6300SRichard Henderson tcg_temp_free_i32(t0); 387951c6300SRichard Henderson } 388951c6300SRichard Henderson } 389951c6300SRichard Henderson 390951c6300SRichard Henderson void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 391951c6300SRichard Henderson { 392951c6300SRichard Henderson if (TCG_TARGET_HAS_eqv_i32) { 393951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2); 394951c6300SRichard Henderson } else { 395951c6300SRichard Henderson tcg_gen_xor_i32(ret, arg1, arg2); 396951c6300SRichard Henderson tcg_gen_not_i32(ret, ret); 397951c6300SRichard Henderson } 398951c6300SRichard Henderson } 399951c6300SRichard Henderson 400951c6300SRichard Henderson void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 401951c6300SRichard Henderson { 402951c6300SRichard Henderson if (TCG_TARGET_HAS_nand_i32) { 403951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2); 404951c6300SRichard Henderson } else { 405951c6300SRichard Henderson tcg_gen_and_i32(ret, arg1, arg2); 406951c6300SRichard Henderson tcg_gen_not_i32(ret, ret); 407951c6300SRichard Henderson } 408951c6300SRichard Henderson } 409951c6300SRichard Henderson 410951c6300SRichard Henderson void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 411951c6300SRichard Henderson { 412951c6300SRichard Henderson if (TCG_TARGET_HAS_nor_i32) { 413951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2); 414951c6300SRichard Henderson } else { 415951c6300SRichard Henderson tcg_gen_or_i32(ret, arg1, arg2); 416951c6300SRichard Henderson tcg_gen_not_i32(ret, ret); 417951c6300SRichard Henderson } 418951c6300SRichard Henderson } 419951c6300SRichard Henderson 420951c6300SRichard Henderson void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 421951c6300SRichard Henderson { 422951c6300SRichard Henderson if (TCG_TARGET_HAS_orc_i32) { 423951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2); 424951c6300SRichard Henderson } else { 425951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 426951c6300SRichard Henderson tcg_gen_not_i32(t0, arg2); 427951c6300SRichard Henderson tcg_gen_or_i32(ret, arg1, t0); 428951c6300SRichard Henderson tcg_temp_free_i32(t0); 429951c6300SRichard Henderson } 430951c6300SRichard Henderson } 431951c6300SRichard Henderson 432951c6300SRichard Henderson void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 433951c6300SRichard Henderson { 434951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i32) { 435951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2); 436951c6300SRichard Henderson } else { 437951c6300SRichard Henderson TCGv_i32 t0, t1; 438951c6300SRichard Henderson 439951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 440951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 441951c6300SRichard Henderson tcg_gen_shl_i32(t0, arg1, arg2); 442951c6300SRichard Henderson tcg_gen_subfi_i32(t1, 32, arg2); 443951c6300SRichard Henderson tcg_gen_shr_i32(t1, arg1, t1); 444951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1); 445951c6300SRichard Henderson tcg_temp_free_i32(t0); 446951c6300SRichard Henderson tcg_temp_free_i32(t1); 447951c6300SRichard Henderson } 448951c6300SRichard Henderson } 449951c6300SRichard Henderson 450951c6300SRichard Henderson void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 451951c6300SRichard Henderson { 452951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 453951c6300SRichard Henderson /* some cases can be optimized here */ 454951c6300SRichard Henderson if (arg2 == 0) { 455951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 456951c6300SRichard Henderson } else if (TCG_TARGET_HAS_rot_i32) { 457951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 458951c6300SRichard Henderson tcg_gen_rotl_i32(ret, arg1, t0); 459951c6300SRichard Henderson tcg_temp_free_i32(t0); 460951c6300SRichard Henderson } else { 461951c6300SRichard Henderson TCGv_i32 t0, t1; 462951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 463951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 464951c6300SRichard Henderson tcg_gen_shli_i32(t0, arg1, arg2); 465951c6300SRichard Henderson tcg_gen_shri_i32(t1, arg1, 32 - arg2); 466951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1); 467951c6300SRichard Henderson tcg_temp_free_i32(t0); 468951c6300SRichard Henderson tcg_temp_free_i32(t1); 469951c6300SRichard Henderson } 470951c6300SRichard Henderson } 471951c6300SRichard Henderson 472951c6300SRichard Henderson void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 473951c6300SRichard Henderson { 474951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i32) { 475951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2); 476951c6300SRichard Henderson } else { 477951c6300SRichard Henderson TCGv_i32 t0, t1; 478951c6300SRichard Henderson 479951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 480951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 481951c6300SRichard Henderson tcg_gen_shr_i32(t0, arg1, arg2); 482951c6300SRichard Henderson tcg_gen_subfi_i32(t1, 32, arg2); 483951c6300SRichard Henderson tcg_gen_shl_i32(t1, arg1, t1); 484951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1); 485951c6300SRichard Henderson tcg_temp_free_i32(t0); 486951c6300SRichard Henderson tcg_temp_free_i32(t1); 487951c6300SRichard Henderson } 488951c6300SRichard Henderson } 489951c6300SRichard Henderson 490951c6300SRichard Henderson void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 491951c6300SRichard Henderson { 492951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 493951c6300SRichard Henderson /* some cases can be optimized here */ 494951c6300SRichard Henderson if (arg2 == 0) { 495951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 496951c6300SRichard Henderson } else { 497951c6300SRichard Henderson tcg_gen_rotli_i32(ret, arg1, 32 - arg2); 498951c6300SRichard Henderson } 499951c6300SRichard Henderson } 500951c6300SRichard Henderson 501951c6300SRichard Henderson void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2, 502951c6300SRichard Henderson unsigned int ofs, unsigned int len) 503951c6300SRichard Henderson { 504951c6300SRichard Henderson uint32_t mask; 505951c6300SRichard Henderson TCGv_i32 t1; 506951c6300SRichard Henderson 507951c6300SRichard Henderson tcg_debug_assert(ofs < 32); 508951c6300SRichard Henderson tcg_debug_assert(len <= 32); 509951c6300SRichard Henderson tcg_debug_assert(ofs + len <= 32); 510951c6300SRichard Henderson 511951c6300SRichard Henderson if (ofs == 0 && len == 32) { 512951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg2); 513951c6300SRichard Henderson return; 514951c6300SRichard Henderson } 515951c6300SRichard Henderson if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) { 516951c6300SRichard Henderson tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len); 517951c6300SRichard Henderson return; 518951c6300SRichard Henderson } 519951c6300SRichard Henderson 520951c6300SRichard Henderson mask = (1u << len) - 1; 521951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 522951c6300SRichard Henderson 523951c6300SRichard Henderson if (ofs + len < 32) { 524951c6300SRichard Henderson tcg_gen_andi_i32(t1, arg2, mask); 525951c6300SRichard Henderson tcg_gen_shli_i32(t1, t1, ofs); 526951c6300SRichard Henderson } else { 527951c6300SRichard Henderson tcg_gen_shli_i32(t1, arg2, ofs); 528951c6300SRichard Henderson } 529951c6300SRichard Henderson tcg_gen_andi_i32(ret, arg1, ~(mask << ofs)); 530951c6300SRichard Henderson tcg_gen_or_i32(ret, ret, t1); 531951c6300SRichard Henderson 532951c6300SRichard Henderson tcg_temp_free_i32(t1); 533951c6300SRichard Henderson } 534951c6300SRichard Henderson 535951c6300SRichard Henderson void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1, 536951c6300SRichard Henderson TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2) 537951c6300SRichard Henderson { 538951c6300SRichard Henderson if (TCG_TARGET_HAS_movcond_i32) { 539951c6300SRichard Henderson tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond); 540951c6300SRichard Henderson } else { 541951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 542951c6300SRichard Henderson TCGv_i32 t1 = tcg_temp_new_i32(); 543951c6300SRichard Henderson tcg_gen_setcond_i32(cond, t0, c1, c2); 544951c6300SRichard Henderson tcg_gen_neg_i32(t0, t0); 545951c6300SRichard Henderson tcg_gen_and_i32(t1, v1, t0); 546951c6300SRichard Henderson tcg_gen_andc_i32(ret, v2, t0); 547951c6300SRichard Henderson tcg_gen_or_i32(ret, ret, t1); 548951c6300SRichard Henderson tcg_temp_free_i32(t0); 549951c6300SRichard Henderson tcg_temp_free_i32(t1); 550951c6300SRichard Henderson } 551951c6300SRichard Henderson } 552951c6300SRichard Henderson 553951c6300SRichard Henderson void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al, 554951c6300SRichard Henderson TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh) 555951c6300SRichard Henderson { 556951c6300SRichard Henderson if (TCG_TARGET_HAS_add2_i32) { 557951c6300SRichard Henderson tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh); 558951c6300SRichard Henderson /* Allow the optimizer room to replace add2 with two moves. */ 559951c6300SRichard Henderson tcg_gen_op0(&tcg_ctx, INDEX_op_nop); 560951c6300SRichard Henderson } else { 561951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 562951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 563951c6300SRichard Henderson tcg_gen_concat_i32_i64(t0, al, ah); 564951c6300SRichard Henderson tcg_gen_concat_i32_i64(t1, bl, bh); 565951c6300SRichard Henderson tcg_gen_add_i64(t0, t0, t1); 566951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0); 567951c6300SRichard Henderson tcg_temp_free_i64(t0); 568951c6300SRichard Henderson tcg_temp_free_i64(t1); 569951c6300SRichard Henderson } 570951c6300SRichard Henderson } 571951c6300SRichard Henderson 572951c6300SRichard Henderson void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al, 573951c6300SRichard Henderson TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh) 574951c6300SRichard Henderson { 575951c6300SRichard Henderson if (TCG_TARGET_HAS_sub2_i32) { 576951c6300SRichard Henderson tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh); 577951c6300SRichard Henderson /* Allow the optimizer room to replace sub2 with two moves. */ 578951c6300SRichard Henderson tcg_gen_op0(&tcg_ctx, INDEX_op_nop); 579951c6300SRichard Henderson } else { 580951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 581951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 582951c6300SRichard Henderson tcg_gen_concat_i32_i64(t0, al, ah); 583951c6300SRichard Henderson tcg_gen_concat_i32_i64(t1, bl, bh); 584951c6300SRichard Henderson tcg_gen_sub_i64(t0, t0, t1); 585951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0); 586951c6300SRichard Henderson tcg_temp_free_i64(t0); 587951c6300SRichard Henderson tcg_temp_free_i64(t1); 588951c6300SRichard Henderson } 589951c6300SRichard Henderson } 590951c6300SRichard Henderson 591951c6300SRichard Henderson void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 592951c6300SRichard Henderson { 593951c6300SRichard Henderson if (TCG_TARGET_HAS_mulu2_i32) { 594951c6300SRichard Henderson tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2); 595951c6300SRichard Henderson /* Allow the optimizer room to replace mulu2 with two moves. */ 596951c6300SRichard Henderson tcg_gen_op0(&tcg_ctx, INDEX_op_nop); 597951c6300SRichard Henderson } else if (TCG_TARGET_HAS_muluh_i32) { 598951c6300SRichard Henderson TCGv_i32 t = tcg_temp_new_i32(); 599951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2); 600951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2); 601951c6300SRichard Henderson tcg_gen_mov_i32(rl, t); 602951c6300SRichard Henderson tcg_temp_free_i32(t); 603951c6300SRichard Henderson } else { 604951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 605951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 606951c6300SRichard Henderson tcg_gen_extu_i32_i64(t0, arg1); 607951c6300SRichard Henderson tcg_gen_extu_i32_i64(t1, arg2); 608951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, t1); 609951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0); 610951c6300SRichard Henderson tcg_temp_free_i64(t0); 611951c6300SRichard Henderson tcg_temp_free_i64(t1); 612951c6300SRichard Henderson } 613951c6300SRichard Henderson } 614951c6300SRichard Henderson 615951c6300SRichard Henderson void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 616951c6300SRichard Henderson { 617951c6300SRichard Henderson if (TCG_TARGET_HAS_muls2_i32) { 618951c6300SRichard Henderson tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2); 619951c6300SRichard Henderson /* Allow the optimizer room to replace muls2 with two moves. */ 620951c6300SRichard Henderson tcg_gen_op0(&tcg_ctx, INDEX_op_nop); 621951c6300SRichard Henderson } else if (TCG_TARGET_HAS_mulsh_i32) { 622951c6300SRichard Henderson TCGv_i32 t = tcg_temp_new_i32(); 623951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2); 624951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2); 625951c6300SRichard Henderson tcg_gen_mov_i32(rl, t); 626951c6300SRichard Henderson tcg_temp_free_i32(t); 627951c6300SRichard Henderson } else if (TCG_TARGET_REG_BITS == 32) { 628951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 629951c6300SRichard Henderson TCGv_i32 t1 = tcg_temp_new_i32(); 630951c6300SRichard Henderson TCGv_i32 t2 = tcg_temp_new_i32(); 631951c6300SRichard Henderson TCGv_i32 t3 = tcg_temp_new_i32(); 632951c6300SRichard Henderson tcg_gen_mulu2_i32(t0, t1, arg1, arg2); 633951c6300SRichard Henderson /* Adjust for negative inputs. */ 634951c6300SRichard Henderson tcg_gen_sari_i32(t2, arg1, 31); 635951c6300SRichard Henderson tcg_gen_sari_i32(t3, arg2, 31); 636951c6300SRichard Henderson tcg_gen_and_i32(t2, t2, arg2); 637951c6300SRichard Henderson tcg_gen_and_i32(t3, t3, arg1); 638951c6300SRichard Henderson tcg_gen_sub_i32(rh, t1, t2); 639951c6300SRichard Henderson tcg_gen_sub_i32(rh, rh, t3); 640951c6300SRichard Henderson tcg_gen_mov_i32(rl, t0); 641951c6300SRichard Henderson tcg_temp_free_i32(t0); 642951c6300SRichard Henderson tcg_temp_free_i32(t1); 643951c6300SRichard Henderson tcg_temp_free_i32(t2); 644951c6300SRichard Henderson tcg_temp_free_i32(t3); 645951c6300SRichard Henderson } else { 646951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 647951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 648951c6300SRichard Henderson tcg_gen_ext_i32_i64(t0, arg1); 649951c6300SRichard Henderson tcg_gen_ext_i32_i64(t1, arg2); 650951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, t1); 651951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0); 652951c6300SRichard Henderson tcg_temp_free_i64(t0); 653951c6300SRichard Henderson tcg_temp_free_i64(t1); 654951c6300SRichard Henderson } 655951c6300SRichard Henderson } 656951c6300SRichard Henderson 657951c6300SRichard Henderson void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg) 658951c6300SRichard Henderson { 659951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8s_i32) { 660951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg); 661951c6300SRichard Henderson } else { 662951c6300SRichard Henderson tcg_gen_shli_i32(ret, arg, 24); 663951c6300SRichard Henderson tcg_gen_sari_i32(ret, ret, 24); 664951c6300SRichard Henderson } 665951c6300SRichard Henderson } 666951c6300SRichard Henderson 667951c6300SRichard Henderson void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg) 668951c6300SRichard Henderson { 669951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16s_i32) { 670951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg); 671951c6300SRichard Henderson } else { 672951c6300SRichard Henderson tcg_gen_shli_i32(ret, arg, 16); 673951c6300SRichard Henderson tcg_gen_sari_i32(ret, ret, 16); 674951c6300SRichard Henderson } 675951c6300SRichard Henderson } 676951c6300SRichard Henderson 677951c6300SRichard Henderson void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg) 678951c6300SRichard Henderson { 679951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8u_i32) { 680951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg); 681951c6300SRichard Henderson } else { 682951c6300SRichard Henderson tcg_gen_andi_i32(ret, arg, 0xffu); 683951c6300SRichard Henderson } 684951c6300SRichard Henderson } 685951c6300SRichard Henderson 686951c6300SRichard Henderson void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg) 687951c6300SRichard Henderson { 688951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16u_i32) { 689951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg); 690951c6300SRichard Henderson } else { 691951c6300SRichard Henderson tcg_gen_andi_i32(ret, arg, 0xffffu); 692951c6300SRichard Henderson } 693951c6300SRichard Henderson } 694951c6300SRichard Henderson 695951c6300SRichard Henderson /* Note: we assume the two high bytes are set to zero */ 696951c6300SRichard Henderson void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg) 697951c6300SRichard Henderson { 698951c6300SRichard Henderson if (TCG_TARGET_HAS_bswap16_i32) { 699951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg); 700951c6300SRichard Henderson } else { 701951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 702951c6300SRichard Henderson 703951c6300SRichard Henderson tcg_gen_ext8u_i32(t0, arg); 704951c6300SRichard Henderson tcg_gen_shli_i32(t0, t0, 8); 705951c6300SRichard Henderson tcg_gen_shri_i32(ret, arg, 8); 706951c6300SRichard Henderson tcg_gen_or_i32(ret, ret, t0); 707951c6300SRichard Henderson tcg_temp_free_i32(t0); 708951c6300SRichard Henderson } 709951c6300SRichard Henderson } 710951c6300SRichard Henderson 711951c6300SRichard Henderson void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg) 712951c6300SRichard Henderson { 713951c6300SRichard Henderson if (TCG_TARGET_HAS_bswap32_i32) { 714951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg); 715951c6300SRichard Henderson } else { 716951c6300SRichard Henderson TCGv_i32 t0, t1; 717951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 718951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 719951c6300SRichard Henderson 720951c6300SRichard Henderson tcg_gen_shli_i32(t0, arg, 24); 721951c6300SRichard Henderson 722951c6300SRichard Henderson tcg_gen_andi_i32(t1, arg, 0x0000ff00); 723951c6300SRichard Henderson tcg_gen_shli_i32(t1, t1, 8); 724951c6300SRichard Henderson tcg_gen_or_i32(t0, t0, t1); 725951c6300SRichard Henderson 726951c6300SRichard Henderson tcg_gen_shri_i32(t1, arg, 8); 727951c6300SRichard Henderson tcg_gen_andi_i32(t1, t1, 0x0000ff00); 728951c6300SRichard Henderson tcg_gen_or_i32(t0, t0, t1); 729951c6300SRichard Henderson 730951c6300SRichard Henderson tcg_gen_shri_i32(t1, arg, 24); 731951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1); 732951c6300SRichard Henderson tcg_temp_free_i32(t0); 733951c6300SRichard Henderson tcg_temp_free_i32(t1); 734951c6300SRichard Henderson } 735951c6300SRichard Henderson } 736951c6300SRichard Henderson 737951c6300SRichard Henderson /* 64-bit ops */ 738951c6300SRichard Henderson 739951c6300SRichard Henderson #if TCG_TARGET_REG_BITS == 32 740951c6300SRichard Henderson /* These are all inline for TCG_TARGET_REG_BITS == 64. */ 741951c6300SRichard Henderson 742951c6300SRichard Henderson void tcg_gen_discard_i64(TCGv_i64 arg) 743951c6300SRichard Henderson { 744951c6300SRichard Henderson tcg_gen_discard_i32(TCGV_LOW(arg)); 745951c6300SRichard Henderson tcg_gen_discard_i32(TCGV_HIGH(arg)); 746951c6300SRichard Henderson } 747951c6300SRichard Henderson 748951c6300SRichard Henderson void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg) 749951c6300SRichard Henderson { 750951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 751951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 752951c6300SRichard Henderson } 753951c6300SRichard Henderson 754951c6300SRichard Henderson void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg) 755951c6300SRichard Henderson { 756951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_LOW(ret), arg); 757951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32); 758951c6300SRichard Henderson } 759951c6300SRichard Henderson 760951c6300SRichard Henderson void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 761951c6300SRichard Henderson { 762951c6300SRichard Henderson tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset); 763951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 764951c6300SRichard Henderson } 765951c6300SRichard Henderson 766951c6300SRichard Henderson void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 767951c6300SRichard Henderson { 768951c6300SRichard Henderson tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset); 769951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), 31); 770951c6300SRichard Henderson } 771951c6300SRichard Henderson 772951c6300SRichard Henderson void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 773951c6300SRichard Henderson { 774951c6300SRichard Henderson tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset); 775951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 776951c6300SRichard Henderson } 777951c6300SRichard Henderson 778951c6300SRichard Henderson void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 779951c6300SRichard Henderson { 780951c6300SRichard Henderson tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset); 781951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 782951c6300SRichard Henderson } 783951c6300SRichard Henderson 784951c6300SRichard Henderson void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 785951c6300SRichard Henderson { 786951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 787951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 788951c6300SRichard Henderson } 789951c6300SRichard Henderson 790951c6300SRichard Henderson void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 791951c6300SRichard Henderson { 792951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 793951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 794951c6300SRichard Henderson } 795951c6300SRichard Henderson 796951c6300SRichard Henderson void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 797951c6300SRichard Henderson { 798951c6300SRichard Henderson /* Since arg2 and ret have different types, 799951c6300SRichard Henderson they cannot be the same temporary */ 800951c6300SRichard Henderson #ifdef TCG_TARGET_WORDS_BIGENDIAN 801951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset); 802951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4); 803951c6300SRichard Henderson #else 804951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 805951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4); 806951c6300SRichard Henderson #endif 807951c6300SRichard Henderson } 808951c6300SRichard Henderson 809951c6300SRichard Henderson void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 810951c6300SRichard Henderson { 811951c6300SRichard Henderson #ifdef TCG_TARGET_WORDS_BIGENDIAN 812951c6300SRichard Henderson tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset); 813951c6300SRichard Henderson tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4); 814951c6300SRichard Henderson #else 815951c6300SRichard Henderson tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset); 816951c6300SRichard Henderson tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4); 817951c6300SRichard Henderson #endif 818951c6300SRichard Henderson } 819951c6300SRichard Henderson 820951c6300SRichard Henderson void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 821951c6300SRichard Henderson { 822951c6300SRichard Henderson tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 823951c6300SRichard Henderson tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 824951c6300SRichard Henderson } 825951c6300SRichard Henderson 826951c6300SRichard Henderson void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 827951c6300SRichard Henderson { 828951c6300SRichard Henderson tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 829951c6300SRichard Henderson tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 830951c6300SRichard Henderson } 831951c6300SRichard Henderson 832951c6300SRichard Henderson void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 833951c6300SRichard Henderson { 834951c6300SRichard Henderson tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 835951c6300SRichard Henderson tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 836951c6300SRichard Henderson } 837951c6300SRichard Henderson 838951c6300SRichard Henderson void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 839951c6300SRichard Henderson { 840951c6300SRichard Henderson gen_helper_shl_i64(ret, arg1, arg2); 841951c6300SRichard Henderson } 842951c6300SRichard Henderson 843951c6300SRichard Henderson void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 844951c6300SRichard Henderson { 845951c6300SRichard Henderson gen_helper_shr_i64(ret, arg1, arg2); 846951c6300SRichard Henderson } 847951c6300SRichard Henderson 848951c6300SRichard Henderson void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 849951c6300SRichard Henderson { 850951c6300SRichard Henderson gen_helper_sar_i64(ret, arg1, arg2); 851951c6300SRichard Henderson } 852951c6300SRichard Henderson 853951c6300SRichard Henderson void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 854951c6300SRichard Henderson { 855951c6300SRichard Henderson TCGv_i64 t0; 856951c6300SRichard Henderson TCGv_i32 t1; 857951c6300SRichard Henderson 858951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 859951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 860951c6300SRichard Henderson 861951c6300SRichard Henderson tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0), 862951c6300SRichard Henderson TCGV_LOW(arg1), TCGV_LOW(arg2)); 863951c6300SRichard Henderson 864951c6300SRichard Henderson tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2)); 865951c6300SRichard Henderson tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 866951c6300SRichard Henderson tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2)); 867951c6300SRichard Henderson tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 868951c6300SRichard Henderson 869951c6300SRichard Henderson tcg_gen_mov_i64(ret, t0); 870951c6300SRichard Henderson tcg_temp_free_i64(t0); 871951c6300SRichard Henderson tcg_temp_free_i32(t1); 872951c6300SRichard Henderson } 873951c6300SRichard Henderson #endif /* TCG_TARGET_REG_SIZE == 32 */ 874951c6300SRichard Henderson 875951c6300SRichard Henderson void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 876951c6300SRichard Henderson { 877951c6300SRichard Henderson /* some cases can be optimized here */ 878951c6300SRichard Henderson if (arg2 == 0) { 879951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 880951c6300SRichard Henderson } else { 881951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 882951c6300SRichard Henderson tcg_gen_add_i64(ret, arg1, t0); 883951c6300SRichard Henderson tcg_temp_free_i64(t0); 884951c6300SRichard Henderson } 885951c6300SRichard Henderson } 886951c6300SRichard Henderson 887951c6300SRichard Henderson void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2) 888951c6300SRichard Henderson { 889951c6300SRichard Henderson if (arg1 == 0 && TCG_TARGET_HAS_neg_i64) { 890951c6300SRichard Henderson /* Don't recurse with tcg_gen_neg_i64. */ 891951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg2); 892951c6300SRichard Henderson } else { 893951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg1); 894951c6300SRichard Henderson tcg_gen_sub_i64(ret, t0, arg2); 895951c6300SRichard Henderson tcg_temp_free_i64(t0); 896951c6300SRichard Henderson } 897951c6300SRichard Henderson } 898951c6300SRichard Henderson 899951c6300SRichard Henderson void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 900951c6300SRichard Henderson { 901951c6300SRichard Henderson /* some cases can be optimized here */ 902951c6300SRichard Henderson if (arg2 == 0) { 903951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 904951c6300SRichard Henderson } else { 905951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 906951c6300SRichard Henderson tcg_gen_sub_i64(ret, arg1, t0); 907951c6300SRichard Henderson tcg_temp_free_i64(t0); 908951c6300SRichard Henderson } 909951c6300SRichard Henderson } 910951c6300SRichard Henderson 911951c6300SRichard Henderson void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) 912951c6300SRichard Henderson { 913*3a13c3f3SRichard Henderson TCGv_i64 t0; 914*3a13c3f3SRichard Henderson 915*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 916951c6300SRichard Henderson tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 917951c6300SRichard Henderson tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 918*3a13c3f3SRichard Henderson return; 919*3a13c3f3SRichard Henderson } 920*3a13c3f3SRichard Henderson 921951c6300SRichard Henderson /* Some cases can be optimized here. */ 922951c6300SRichard Henderson switch (arg2) { 923951c6300SRichard Henderson case 0: 924951c6300SRichard Henderson tcg_gen_movi_i64(ret, 0); 925951c6300SRichard Henderson return; 926951c6300SRichard Henderson case 0xffffffffffffffffull: 927951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 928951c6300SRichard Henderson return; 929951c6300SRichard Henderson case 0xffull: 930951c6300SRichard Henderson /* Don't recurse with tcg_gen_ext8u_i64. */ 931951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8u_i64) { 932951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1); 933951c6300SRichard Henderson return; 934951c6300SRichard Henderson } 935951c6300SRichard Henderson break; 936951c6300SRichard Henderson case 0xffffu: 937951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16u_i64) { 938951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1); 939951c6300SRichard Henderson return; 940951c6300SRichard Henderson } 941951c6300SRichard Henderson break; 942951c6300SRichard Henderson case 0xffffffffull: 943951c6300SRichard Henderson if (TCG_TARGET_HAS_ext32u_i64) { 944951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1); 945951c6300SRichard Henderson return; 946951c6300SRichard Henderson } 947951c6300SRichard Henderson break; 948951c6300SRichard Henderson } 949951c6300SRichard Henderson t0 = tcg_const_i64(arg2); 950951c6300SRichard Henderson tcg_gen_and_i64(ret, arg1, t0); 951951c6300SRichard Henderson tcg_temp_free_i64(t0); 952951c6300SRichard Henderson } 953951c6300SRichard Henderson 954951c6300SRichard Henderson void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 955951c6300SRichard Henderson { 956*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 957951c6300SRichard Henderson tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 958951c6300SRichard Henderson tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 959*3a13c3f3SRichard Henderson return; 960*3a13c3f3SRichard Henderson } 961951c6300SRichard Henderson /* Some cases can be optimized here. */ 962951c6300SRichard Henderson if (arg2 == -1) { 963951c6300SRichard Henderson tcg_gen_movi_i64(ret, -1); 964951c6300SRichard Henderson } else if (arg2 == 0) { 965951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 966951c6300SRichard Henderson } else { 967951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 968951c6300SRichard Henderson tcg_gen_or_i64(ret, arg1, t0); 969951c6300SRichard Henderson tcg_temp_free_i64(t0); 970951c6300SRichard Henderson } 971951c6300SRichard Henderson } 972951c6300SRichard Henderson 973951c6300SRichard Henderson void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 974951c6300SRichard Henderson { 975*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 976951c6300SRichard Henderson tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 977951c6300SRichard Henderson tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 978*3a13c3f3SRichard Henderson return; 979*3a13c3f3SRichard Henderson } 980951c6300SRichard Henderson /* Some cases can be optimized here. */ 981951c6300SRichard Henderson if (arg2 == 0) { 982951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 983951c6300SRichard Henderson } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) { 984951c6300SRichard Henderson /* Don't recurse with tcg_gen_not_i64. */ 985951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1); 986951c6300SRichard Henderson } else { 987951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 988951c6300SRichard Henderson tcg_gen_xor_i64(ret, arg1, t0); 989951c6300SRichard Henderson tcg_temp_free_i64(t0); 990951c6300SRichard Henderson } 991951c6300SRichard Henderson } 992951c6300SRichard Henderson 993951c6300SRichard Henderson static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, 994951c6300SRichard Henderson unsigned c, bool right, bool arith) 995951c6300SRichard Henderson { 996951c6300SRichard Henderson tcg_debug_assert(c < 64); 997951c6300SRichard Henderson if (c == 0) { 998951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 999951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 1000951c6300SRichard Henderson } else if (c >= 32) { 1001951c6300SRichard Henderson c -= 32; 1002951c6300SRichard Henderson if (right) { 1003951c6300SRichard Henderson if (arith) { 1004951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1005951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31); 1006951c6300SRichard Henderson } else { 1007951c6300SRichard Henderson tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1008951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1009951c6300SRichard Henderson } 1010951c6300SRichard Henderson } else { 1011951c6300SRichard Henderson tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c); 1012951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_LOW(ret), 0); 1013951c6300SRichard Henderson } 1014951c6300SRichard Henderson } else { 1015951c6300SRichard Henderson TCGv_i32 t0, t1; 1016951c6300SRichard Henderson 1017951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 1018951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 1019951c6300SRichard Henderson if (right) { 1020951c6300SRichard Henderson tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c); 1021951c6300SRichard Henderson if (arith) { 1022951c6300SRichard Henderson tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c); 1023951c6300SRichard Henderson } else { 1024951c6300SRichard Henderson tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c); 1025951c6300SRichard Henderson } 1026951c6300SRichard Henderson tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c); 1027951c6300SRichard Henderson tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0); 1028951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), t1); 1029951c6300SRichard Henderson } else { 1030951c6300SRichard Henderson tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c); 1031951c6300SRichard Henderson /* Note: ret can be the same as arg1, so we use t1 */ 1032951c6300SRichard Henderson tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c); 1033951c6300SRichard Henderson tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c); 1034951c6300SRichard Henderson tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0); 1035951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), t1); 1036951c6300SRichard Henderson } 1037951c6300SRichard Henderson tcg_temp_free_i32(t0); 1038951c6300SRichard Henderson tcg_temp_free_i32(t1); 1039951c6300SRichard Henderson } 1040951c6300SRichard Henderson } 1041951c6300SRichard Henderson 1042951c6300SRichard Henderson void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1043951c6300SRichard Henderson { 1044951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 1045*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1046*3a13c3f3SRichard Henderson tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0); 1047*3a13c3f3SRichard Henderson } else if (arg2 == 0) { 1048951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1049951c6300SRichard Henderson } else { 1050951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1051951c6300SRichard Henderson tcg_gen_shl_i64(ret, arg1, t0); 1052951c6300SRichard Henderson tcg_temp_free_i64(t0); 1053951c6300SRichard Henderson } 1054951c6300SRichard Henderson } 1055951c6300SRichard Henderson 1056951c6300SRichard Henderson void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1057951c6300SRichard Henderson { 1058951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 1059*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1060*3a13c3f3SRichard Henderson tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0); 1061*3a13c3f3SRichard Henderson } else if (arg2 == 0) { 1062951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1063951c6300SRichard Henderson } else { 1064951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1065951c6300SRichard Henderson tcg_gen_shr_i64(ret, arg1, t0); 1066951c6300SRichard Henderson tcg_temp_free_i64(t0); 1067951c6300SRichard Henderson } 1068951c6300SRichard Henderson } 1069951c6300SRichard Henderson 1070951c6300SRichard Henderson void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1071951c6300SRichard Henderson { 1072951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 1073*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1074*3a13c3f3SRichard Henderson tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1); 1075*3a13c3f3SRichard Henderson } else if (arg2 == 0) { 1076951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1077951c6300SRichard Henderson } else { 1078951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1079951c6300SRichard Henderson tcg_gen_sar_i64(ret, arg1, t0); 1080951c6300SRichard Henderson tcg_temp_free_i64(t0); 1081951c6300SRichard Henderson } 1082951c6300SRichard Henderson } 1083951c6300SRichard Henderson 1084951c6300SRichard Henderson void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, int label) 1085951c6300SRichard Henderson { 1086951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 1087951c6300SRichard Henderson tcg_gen_br(label); 1088951c6300SRichard Henderson } else if (cond != TCG_COND_NEVER) { 1089*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1090951c6300SRichard Henderson tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1), 1091951c6300SRichard Henderson TCGV_HIGH(arg1), TCGV_LOW(arg2), 1092951c6300SRichard Henderson TCGV_HIGH(arg2), cond, label); 1093*3a13c3f3SRichard Henderson } else { 1094951c6300SRichard Henderson tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, label); 1095*3a13c3f3SRichard Henderson } 1096951c6300SRichard Henderson } 1097951c6300SRichard Henderson } 1098951c6300SRichard Henderson 1099951c6300SRichard Henderson void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, int label) 1100951c6300SRichard Henderson { 1101951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 1102951c6300SRichard Henderson tcg_gen_br(label); 1103951c6300SRichard Henderson } else if (cond != TCG_COND_NEVER) { 1104951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1105951c6300SRichard Henderson tcg_gen_brcond_i64(cond, arg1, t0, label); 1106951c6300SRichard Henderson tcg_temp_free_i64(t0); 1107951c6300SRichard Henderson } 1108951c6300SRichard Henderson } 1109951c6300SRichard Henderson 1110951c6300SRichard Henderson void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret, 1111951c6300SRichard Henderson TCGv_i64 arg1, TCGv_i64 arg2) 1112951c6300SRichard Henderson { 1113951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 1114951c6300SRichard Henderson tcg_gen_movi_i64(ret, 1); 1115951c6300SRichard Henderson } else if (cond == TCG_COND_NEVER) { 1116951c6300SRichard Henderson tcg_gen_movi_i64(ret, 0); 1117951c6300SRichard Henderson } else { 1118*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1119951c6300SRichard Henderson tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 1120951c6300SRichard Henderson TCGV_LOW(arg1), TCGV_HIGH(arg1), 1121951c6300SRichard Henderson TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); 1122951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1123*3a13c3f3SRichard Henderson } else { 1124951c6300SRichard Henderson tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond); 1125*3a13c3f3SRichard Henderson } 1126951c6300SRichard Henderson } 1127951c6300SRichard Henderson } 1128951c6300SRichard Henderson 1129951c6300SRichard Henderson void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret, 1130951c6300SRichard Henderson TCGv_i64 arg1, int64_t arg2) 1131951c6300SRichard Henderson { 1132951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1133951c6300SRichard Henderson tcg_gen_setcond_i64(cond, ret, arg1, t0); 1134951c6300SRichard Henderson tcg_temp_free_i64(t0); 1135951c6300SRichard Henderson } 1136951c6300SRichard Henderson 1137951c6300SRichard Henderson void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1138951c6300SRichard Henderson { 1139951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1140951c6300SRichard Henderson tcg_gen_mul_i64(ret, arg1, t0); 1141951c6300SRichard Henderson tcg_temp_free_i64(t0); 1142951c6300SRichard Henderson } 1143951c6300SRichard Henderson 1144951c6300SRichard Henderson void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1145951c6300SRichard Henderson { 1146951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i64) { 1147951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2); 1148951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) { 1149951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1150951c6300SRichard Henderson tcg_gen_sari_i64(t0, arg1, 63); 1151951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2); 1152951c6300SRichard Henderson tcg_temp_free_i64(t0); 1153951c6300SRichard Henderson } else { 1154951c6300SRichard Henderson gen_helper_div_i64(ret, arg1, arg2); 1155951c6300SRichard Henderson } 1156951c6300SRichard Henderson } 1157951c6300SRichard Henderson 1158951c6300SRichard Henderson void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1159951c6300SRichard Henderson { 1160951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i64) { 1161951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2); 1162951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i64) { 1163951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1164951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2); 1165951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, arg2); 1166951c6300SRichard Henderson tcg_gen_sub_i64(ret, arg1, t0); 1167951c6300SRichard Henderson tcg_temp_free_i64(t0); 1168951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) { 1169951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1170951c6300SRichard Henderson tcg_gen_sari_i64(t0, arg1, 63); 1171951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2); 1172951c6300SRichard Henderson tcg_temp_free_i64(t0); 1173951c6300SRichard Henderson } else { 1174951c6300SRichard Henderson gen_helper_rem_i64(ret, arg1, arg2); 1175951c6300SRichard Henderson } 1176951c6300SRichard Henderson } 1177951c6300SRichard Henderson 1178951c6300SRichard Henderson void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1179951c6300SRichard Henderson { 1180951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i64) { 1181951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2); 1182951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) { 1183951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1184951c6300SRichard Henderson tcg_gen_movi_i64(t0, 0); 1185951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2); 1186951c6300SRichard Henderson tcg_temp_free_i64(t0); 1187951c6300SRichard Henderson } else { 1188951c6300SRichard Henderson gen_helper_divu_i64(ret, arg1, arg2); 1189951c6300SRichard Henderson } 1190951c6300SRichard Henderson } 1191951c6300SRichard Henderson 1192951c6300SRichard Henderson void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1193951c6300SRichard Henderson { 1194951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i64) { 1195951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2); 1196951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i64) { 1197951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1198951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2); 1199951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, arg2); 1200951c6300SRichard Henderson tcg_gen_sub_i64(ret, arg1, t0); 1201951c6300SRichard Henderson tcg_temp_free_i64(t0); 1202951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) { 1203951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1204951c6300SRichard Henderson tcg_gen_movi_i64(t0, 0); 1205951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2); 1206951c6300SRichard Henderson tcg_temp_free_i64(t0); 1207951c6300SRichard Henderson } else { 1208951c6300SRichard Henderson gen_helper_remu_i64(ret, arg1, arg2); 1209951c6300SRichard Henderson } 1210951c6300SRichard Henderson } 1211951c6300SRichard Henderson 1212951c6300SRichard Henderson void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg) 1213951c6300SRichard Henderson { 1214*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1215951c6300SRichard Henderson tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1216951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1217*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext8s_i64) { 1218951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg); 1219951c6300SRichard Henderson } else { 1220951c6300SRichard Henderson tcg_gen_shli_i64(ret, arg, 56); 1221951c6300SRichard Henderson tcg_gen_sari_i64(ret, ret, 56); 1222951c6300SRichard Henderson } 1223951c6300SRichard Henderson } 1224951c6300SRichard Henderson 1225951c6300SRichard Henderson void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg) 1226951c6300SRichard Henderson { 1227*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1228951c6300SRichard Henderson tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1229951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1230*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext16s_i64) { 1231951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg); 1232951c6300SRichard Henderson } else { 1233951c6300SRichard Henderson tcg_gen_shli_i64(ret, arg, 48); 1234951c6300SRichard Henderson tcg_gen_sari_i64(ret, ret, 48); 1235951c6300SRichard Henderson } 1236951c6300SRichard Henderson } 1237951c6300SRichard Henderson 1238951c6300SRichard Henderson void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg) 1239951c6300SRichard Henderson { 1240*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1241951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1242951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1243*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext32s_i64) { 1244951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg); 1245951c6300SRichard Henderson } else { 1246951c6300SRichard Henderson tcg_gen_shli_i64(ret, arg, 32); 1247951c6300SRichard Henderson tcg_gen_sari_i64(ret, ret, 32); 1248951c6300SRichard Henderson } 1249951c6300SRichard Henderson } 1250951c6300SRichard Henderson 1251951c6300SRichard Henderson void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg) 1252951c6300SRichard Henderson { 1253*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1254951c6300SRichard Henderson tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1255951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1256*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext8u_i64) { 1257951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg); 1258951c6300SRichard Henderson } else { 1259951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg, 0xffu); 1260951c6300SRichard Henderson } 1261951c6300SRichard Henderson } 1262951c6300SRichard Henderson 1263951c6300SRichard Henderson void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg) 1264951c6300SRichard Henderson { 1265*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1266951c6300SRichard Henderson tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1267951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1268*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext16u_i64) { 1269951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg); 1270951c6300SRichard Henderson } else { 1271951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg, 0xffffu); 1272951c6300SRichard Henderson } 1273951c6300SRichard Henderson } 1274951c6300SRichard Henderson 1275951c6300SRichard Henderson void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg) 1276951c6300SRichard Henderson { 1277*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1278951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1279951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1280*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext32u_i64) { 1281951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg); 1282951c6300SRichard Henderson } else { 1283951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg, 0xffffffffu); 1284951c6300SRichard Henderson } 1285951c6300SRichard Henderson } 1286951c6300SRichard Henderson 1287951c6300SRichard Henderson /* Note: we assume the six high bytes are set to zero */ 1288951c6300SRichard Henderson void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg) 1289951c6300SRichard Henderson { 1290*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1291951c6300SRichard Henderson tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1292951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1293*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_bswap16_i64) { 1294951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg); 1295951c6300SRichard Henderson } else { 1296951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1297951c6300SRichard Henderson 1298951c6300SRichard Henderson tcg_gen_ext8u_i64(t0, arg); 1299951c6300SRichard Henderson tcg_gen_shli_i64(t0, t0, 8); 1300951c6300SRichard Henderson tcg_gen_shri_i64(ret, arg, 8); 1301951c6300SRichard Henderson tcg_gen_or_i64(ret, ret, t0); 1302951c6300SRichard Henderson tcg_temp_free_i64(t0); 1303951c6300SRichard Henderson } 1304951c6300SRichard Henderson } 1305951c6300SRichard Henderson 1306951c6300SRichard Henderson /* Note: we assume the four high bytes are set to zero */ 1307951c6300SRichard Henderson void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg) 1308951c6300SRichard Henderson { 1309*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1310951c6300SRichard Henderson tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1311951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1312*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_bswap32_i64) { 1313951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg); 1314951c6300SRichard Henderson } else { 1315951c6300SRichard Henderson TCGv_i64 t0, t1; 1316951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 1317951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1318951c6300SRichard Henderson 1319951c6300SRichard Henderson tcg_gen_shli_i64(t0, arg, 24); 1320951c6300SRichard Henderson tcg_gen_ext32u_i64(t0, t0); 1321951c6300SRichard Henderson 1322951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg, 0x0000ff00); 1323951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, 8); 1324951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1325951c6300SRichard Henderson 1326951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 8); 1327951c6300SRichard Henderson tcg_gen_andi_i64(t1, t1, 0x0000ff00); 1328951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1329951c6300SRichard Henderson 1330951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 24); 1331951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1332951c6300SRichard Henderson tcg_temp_free_i64(t0); 1333951c6300SRichard Henderson tcg_temp_free_i64(t1); 1334951c6300SRichard Henderson } 1335951c6300SRichard Henderson } 1336951c6300SRichard Henderson 1337951c6300SRichard Henderson void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) 1338951c6300SRichard Henderson { 1339*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1340951c6300SRichard Henderson TCGv_i32 t0, t1; 1341951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 1342951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 1343951c6300SRichard Henderson 1344951c6300SRichard Henderson tcg_gen_bswap32_i32(t0, TCGV_LOW(arg)); 1345951c6300SRichard Henderson tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg)); 1346951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), t1); 1347951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), t0); 1348951c6300SRichard Henderson tcg_temp_free_i32(t0); 1349951c6300SRichard Henderson tcg_temp_free_i32(t1); 1350*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_bswap64_i64) { 1351951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg); 1352951c6300SRichard Henderson } else { 1353951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1354951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 1355951c6300SRichard Henderson 1356951c6300SRichard Henderson tcg_gen_shli_i64(t0, arg, 56); 1357951c6300SRichard Henderson 1358951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg, 0x0000ff00); 1359951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, 40); 1360951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1361951c6300SRichard Henderson 1362951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg, 0x00ff0000); 1363951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, 24); 1364951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1365951c6300SRichard Henderson 1366951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg, 0xff000000); 1367951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, 8); 1368951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1369951c6300SRichard Henderson 1370951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 8); 1371951c6300SRichard Henderson tcg_gen_andi_i64(t1, t1, 0xff000000); 1372951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1373951c6300SRichard Henderson 1374951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 24); 1375951c6300SRichard Henderson tcg_gen_andi_i64(t1, t1, 0x00ff0000); 1376951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1377951c6300SRichard Henderson 1378951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 40); 1379951c6300SRichard Henderson tcg_gen_andi_i64(t1, t1, 0x0000ff00); 1380951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1381951c6300SRichard Henderson 1382951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 56); 1383951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1384951c6300SRichard Henderson tcg_temp_free_i64(t0); 1385951c6300SRichard Henderson tcg_temp_free_i64(t1); 1386951c6300SRichard Henderson } 1387951c6300SRichard Henderson } 1388951c6300SRichard Henderson 1389951c6300SRichard Henderson void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg) 1390951c6300SRichard Henderson { 1391*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1392*3a13c3f3SRichard Henderson tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1393*3a13c3f3SRichard Henderson tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 1394*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_not_i64) { 1395951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg); 1396951c6300SRichard Henderson } else { 1397951c6300SRichard Henderson tcg_gen_xori_i64(ret, arg, -1); 1398951c6300SRichard Henderson } 1399951c6300SRichard Henderson } 1400951c6300SRichard Henderson 1401951c6300SRichard Henderson void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1402951c6300SRichard Henderson { 1403*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1404*3a13c3f3SRichard Henderson tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1405*3a13c3f3SRichard Henderson tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1406*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_andc_i64) { 1407951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2); 1408951c6300SRichard Henderson } else { 1409951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1410951c6300SRichard Henderson tcg_gen_not_i64(t0, arg2); 1411951c6300SRichard Henderson tcg_gen_and_i64(ret, arg1, t0); 1412951c6300SRichard Henderson tcg_temp_free_i64(t0); 1413951c6300SRichard Henderson } 1414951c6300SRichard Henderson } 1415951c6300SRichard Henderson 1416951c6300SRichard Henderson void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1417951c6300SRichard Henderson { 1418*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1419*3a13c3f3SRichard Henderson tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1420*3a13c3f3SRichard Henderson tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1421*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_eqv_i64) { 1422951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2); 1423951c6300SRichard Henderson } else { 1424951c6300SRichard Henderson tcg_gen_xor_i64(ret, arg1, arg2); 1425951c6300SRichard Henderson tcg_gen_not_i64(ret, ret); 1426951c6300SRichard Henderson } 1427951c6300SRichard Henderson } 1428951c6300SRichard Henderson 1429951c6300SRichard Henderson void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1430951c6300SRichard Henderson { 1431*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1432*3a13c3f3SRichard Henderson tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1433*3a13c3f3SRichard Henderson tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1434*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_nand_i64) { 1435951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2); 1436951c6300SRichard Henderson } else { 1437951c6300SRichard Henderson tcg_gen_and_i64(ret, arg1, arg2); 1438951c6300SRichard Henderson tcg_gen_not_i64(ret, ret); 1439951c6300SRichard Henderson } 1440951c6300SRichard Henderson } 1441951c6300SRichard Henderson 1442951c6300SRichard Henderson void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1443951c6300SRichard Henderson { 1444*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1445*3a13c3f3SRichard Henderson tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1446*3a13c3f3SRichard Henderson tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1447*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_nor_i64) { 1448951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2); 1449951c6300SRichard Henderson } else { 1450951c6300SRichard Henderson tcg_gen_or_i64(ret, arg1, arg2); 1451951c6300SRichard Henderson tcg_gen_not_i64(ret, ret); 1452951c6300SRichard Henderson } 1453951c6300SRichard Henderson } 1454951c6300SRichard Henderson 1455951c6300SRichard Henderson void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1456951c6300SRichard Henderson { 1457*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1458*3a13c3f3SRichard Henderson tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 1459*3a13c3f3SRichard Henderson tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 1460*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_orc_i64) { 1461951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2); 1462951c6300SRichard Henderson } else { 1463951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1464951c6300SRichard Henderson tcg_gen_not_i64(t0, arg2); 1465951c6300SRichard Henderson tcg_gen_or_i64(ret, arg1, t0); 1466951c6300SRichard Henderson tcg_temp_free_i64(t0); 1467951c6300SRichard Henderson } 1468951c6300SRichard Henderson } 1469951c6300SRichard Henderson 1470951c6300SRichard Henderson void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1471951c6300SRichard Henderson { 1472951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i64) { 1473951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2); 1474951c6300SRichard Henderson } else { 1475951c6300SRichard Henderson TCGv_i64 t0, t1; 1476951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 1477951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1478951c6300SRichard Henderson tcg_gen_shl_i64(t0, arg1, arg2); 1479951c6300SRichard Henderson tcg_gen_subfi_i64(t1, 64, arg2); 1480951c6300SRichard Henderson tcg_gen_shr_i64(t1, arg1, t1); 1481951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1482951c6300SRichard Henderson tcg_temp_free_i64(t0); 1483951c6300SRichard Henderson tcg_temp_free_i64(t1); 1484951c6300SRichard Henderson } 1485951c6300SRichard Henderson } 1486951c6300SRichard Henderson 1487951c6300SRichard Henderson void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1488951c6300SRichard Henderson { 1489951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 1490951c6300SRichard Henderson /* some cases can be optimized here */ 1491951c6300SRichard Henderson if (arg2 == 0) { 1492951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1493951c6300SRichard Henderson } else if (TCG_TARGET_HAS_rot_i64) { 1494951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1495951c6300SRichard Henderson tcg_gen_rotl_i64(ret, arg1, t0); 1496951c6300SRichard Henderson tcg_temp_free_i64(t0); 1497951c6300SRichard Henderson } else { 1498951c6300SRichard Henderson TCGv_i64 t0, t1; 1499951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 1500951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1501951c6300SRichard Henderson tcg_gen_shli_i64(t0, arg1, arg2); 1502951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg1, 64 - arg2); 1503951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1504951c6300SRichard Henderson tcg_temp_free_i64(t0); 1505951c6300SRichard Henderson tcg_temp_free_i64(t1); 1506951c6300SRichard Henderson } 1507951c6300SRichard Henderson } 1508951c6300SRichard Henderson 1509951c6300SRichard Henderson void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1510951c6300SRichard Henderson { 1511951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i64) { 1512951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2); 1513951c6300SRichard Henderson } else { 1514951c6300SRichard Henderson TCGv_i64 t0, t1; 1515951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 1516951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1517951c6300SRichard Henderson tcg_gen_shr_i64(t0, arg1, arg2); 1518951c6300SRichard Henderson tcg_gen_subfi_i64(t1, 64, arg2); 1519951c6300SRichard Henderson tcg_gen_shl_i64(t1, arg1, t1); 1520951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1521951c6300SRichard Henderson tcg_temp_free_i64(t0); 1522951c6300SRichard Henderson tcg_temp_free_i64(t1); 1523951c6300SRichard Henderson } 1524951c6300SRichard Henderson } 1525951c6300SRichard Henderson 1526951c6300SRichard Henderson void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1527951c6300SRichard Henderson { 1528951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 1529951c6300SRichard Henderson /* some cases can be optimized here */ 1530951c6300SRichard Henderson if (arg2 == 0) { 1531951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1532951c6300SRichard Henderson } else { 1533951c6300SRichard Henderson tcg_gen_rotli_i64(ret, arg1, 64 - arg2); 1534951c6300SRichard Henderson } 1535951c6300SRichard Henderson } 1536951c6300SRichard Henderson 1537951c6300SRichard Henderson void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2, 1538951c6300SRichard Henderson unsigned int ofs, unsigned int len) 1539951c6300SRichard Henderson { 1540951c6300SRichard Henderson uint64_t mask; 1541951c6300SRichard Henderson TCGv_i64 t1; 1542951c6300SRichard Henderson 1543951c6300SRichard Henderson tcg_debug_assert(ofs < 64); 1544951c6300SRichard Henderson tcg_debug_assert(len <= 64); 1545951c6300SRichard Henderson tcg_debug_assert(ofs + len <= 64); 1546951c6300SRichard Henderson 1547951c6300SRichard Henderson if (ofs == 0 && len == 64) { 1548951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg2); 1549951c6300SRichard Henderson return; 1550951c6300SRichard Henderson } 1551951c6300SRichard Henderson if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) { 1552951c6300SRichard Henderson tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len); 1553951c6300SRichard Henderson return; 1554951c6300SRichard Henderson } 1555951c6300SRichard Henderson 1556*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1557951c6300SRichard Henderson if (ofs >= 32) { 1558951c6300SRichard Henderson tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 1559951c6300SRichard Henderson TCGV_LOW(arg2), ofs - 32, len); 1560951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 1561951c6300SRichard Henderson return; 1562951c6300SRichard Henderson } 1563951c6300SRichard Henderson if (ofs + len <= 32) { 1564951c6300SRichard Henderson tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1), 1565951c6300SRichard Henderson TCGV_LOW(arg2), ofs, len); 1566951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 1567951c6300SRichard Henderson return; 1568951c6300SRichard Henderson } 1569*3a13c3f3SRichard Henderson } 1570951c6300SRichard Henderson 1571951c6300SRichard Henderson mask = (1ull << len) - 1; 1572951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1573951c6300SRichard Henderson 1574951c6300SRichard Henderson if (ofs + len < 64) { 1575951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg2, mask); 1576951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, ofs); 1577951c6300SRichard Henderson } else { 1578951c6300SRichard Henderson tcg_gen_shli_i64(t1, arg2, ofs); 1579951c6300SRichard Henderson } 1580951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg1, ~(mask << ofs)); 1581951c6300SRichard Henderson tcg_gen_or_i64(ret, ret, t1); 1582951c6300SRichard Henderson 1583951c6300SRichard Henderson tcg_temp_free_i64(t1); 1584951c6300SRichard Henderson } 1585951c6300SRichard Henderson 1586951c6300SRichard Henderson void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1, 1587951c6300SRichard Henderson TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2) 1588951c6300SRichard Henderson { 1589*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1590951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 1591951c6300SRichard Henderson TCGv_i32 t1 = tcg_temp_new_i32(); 1592951c6300SRichard Henderson tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0, 1593951c6300SRichard Henderson TCGV_LOW(c1), TCGV_HIGH(c1), 1594951c6300SRichard Henderson TCGV_LOW(c2), TCGV_HIGH(c2), cond); 1595951c6300SRichard Henderson 1596951c6300SRichard Henderson if (TCG_TARGET_HAS_movcond_i32) { 1597951c6300SRichard Henderson tcg_gen_movi_i32(t1, 0); 1598951c6300SRichard Henderson tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, t1, 1599951c6300SRichard Henderson TCGV_LOW(v1), TCGV_LOW(v2)); 1600951c6300SRichard Henderson tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, t1, 1601951c6300SRichard Henderson TCGV_HIGH(v1), TCGV_HIGH(v2)); 1602951c6300SRichard Henderson } else { 1603951c6300SRichard Henderson tcg_gen_neg_i32(t0, t0); 1604951c6300SRichard Henderson 1605951c6300SRichard Henderson tcg_gen_and_i32(t1, TCGV_LOW(v1), t0); 1606951c6300SRichard Henderson tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0); 1607951c6300SRichard Henderson tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1); 1608951c6300SRichard Henderson 1609951c6300SRichard Henderson tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0); 1610951c6300SRichard Henderson tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0); 1611951c6300SRichard Henderson tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1); 1612951c6300SRichard Henderson } 1613951c6300SRichard Henderson tcg_temp_free_i32(t0); 1614951c6300SRichard Henderson tcg_temp_free_i32(t1); 1615*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_movcond_i64) { 1616951c6300SRichard Henderson tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond); 1617951c6300SRichard Henderson } else { 1618951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1619951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 1620951c6300SRichard Henderson tcg_gen_setcond_i64(cond, t0, c1, c2); 1621951c6300SRichard Henderson tcg_gen_neg_i64(t0, t0); 1622951c6300SRichard Henderson tcg_gen_and_i64(t1, v1, t0); 1623951c6300SRichard Henderson tcg_gen_andc_i64(ret, v2, t0); 1624951c6300SRichard Henderson tcg_gen_or_i64(ret, ret, t1); 1625951c6300SRichard Henderson tcg_temp_free_i64(t0); 1626951c6300SRichard Henderson tcg_temp_free_i64(t1); 1627951c6300SRichard Henderson } 1628951c6300SRichard Henderson } 1629951c6300SRichard Henderson 1630951c6300SRichard Henderson void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 1631951c6300SRichard Henderson TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 1632951c6300SRichard Henderson { 1633951c6300SRichard Henderson if (TCG_TARGET_HAS_add2_i64) { 1634951c6300SRichard Henderson tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh); 1635951c6300SRichard Henderson /* Allow the optimizer room to replace add2 with two moves. */ 1636951c6300SRichard Henderson tcg_gen_op0(&tcg_ctx, INDEX_op_nop); 1637951c6300SRichard Henderson } else { 1638951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1639951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 1640951c6300SRichard Henderson tcg_gen_add_i64(t0, al, bl); 1641951c6300SRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al); 1642951c6300SRichard Henderson tcg_gen_add_i64(rh, ah, bh); 1643951c6300SRichard Henderson tcg_gen_add_i64(rh, rh, t1); 1644951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0); 1645951c6300SRichard Henderson tcg_temp_free_i64(t0); 1646951c6300SRichard Henderson tcg_temp_free_i64(t1); 1647951c6300SRichard Henderson } 1648951c6300SRichard Henderson } 1649951c6300SRichard Henderson 1650951c6300SRichard Henderson void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 1651951c6300SRichard Henderson TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 1652951c6300SRichard Henderson { 1653951c6300SRichard Henderson if (TCG_TARGET_HAS_sub2_i64) { 1654951c6300SRichard Henderson tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh); 1655951c6300SRichard Henderson /* Allow the optimizer room to replace sub2 with two moves. */ 1656951c6300SRichard Henderson tcg_gen_op0(&tcg_ctx, INDEX_op_nop); 1657951c6300SRichard Henderson } else { 1658951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1659951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 1660951c6300SRichard Henderson tcg_gen_sub_i64(t0, al, bl); 1661951c6300SRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl); 1662951c6300SRichard Henderson tcg_gen_sub_i64(rh, ah, bh); 1663951c6300SRichard Henderson tcg_gen_sub_i64(rh, rh, t1); 1664951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0); 1665951c6300SRichard Henderson tcg_temp_free_i64(t0); 1666951c6300SRichard Henderson tcg_temp_free_i64(t1); 1667951c6300SRichard Henderson } 1668951c6300SRichard Henderson } 1669951c6300SRichard Henderson 1670951c6300SRichard Henderson void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 1671951c6300SRichard Henderson { 1672951c6300SRichard Henderson if (TCG_TARGET_HAS_mulu2_i64) { 1673951c6300SRichard Henderson tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2); 1674951c6300SRichard Henderson /* Allow the optimizer room to replace mulu2 with two moves. */ 1675951c6300SRichard Henderson tcg_gen_op0(&tcg_ctx, INDEX_op_nop); 1676951c6300SRichard Henderson } else if (TCG_TARGET_HAS_muluh_i64) { 1677951c6300SRichard Henderson TCGv_i64 t = tcg_temp_new_i64(); 1678951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); 1679951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2); 1680951c6300SRichard Henderson tcg_gen_mov_i64(rl, t); 1681951c6300SRichard Henderson tcg_temp_free_i64(t); 1682951c6300SRichard Henderson } else { 1683951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1684951c6300SRichard Henderson tcg_gen_mul_i64(t0, arg1, arg2); 1685951c6300SRichard Henderson gen_helper_muluh_i64(rh, arg1, arg2); 1686951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0); 1687951c6300SRichard Henderson tcg_temp_free_i64(t0); 1688951c6300SRichard Henderson } 1689951c6300SRichard Henderson } 1690951c6300SRichard Henderson 1691951c6300SRichard Henderson void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 1692951c6300SRichard Henderson { 1693951c6300SRichard Henderson if (TCG_TARGET_HAS_muls2_i64) { 1694951c6300SRichard Henderson tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2); 1695951c6300SRichard Henderson /* Allow the optimizer room to replace muls2 with two moves. */ 1696951c6300SRichard Henderson tcg_gen_op0(&tcg_ctx, INDEX_op_nop); 1697951c6300SRichard Henderson } else if (TCG_TARGET_HAS_mulsh_i64) { 1698951c6300SRichard Henderson TCGv_i64 t = tcg_temp_new_i64(); 1699951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); 1700951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2); 1701951c6300SRichard Henderson tcg_gen_mov_i64(rl, t); 1702951c6300SRichard Henderson tcg_temp_free_i64(t); 1703951c6300SRichard Henderson } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) { 1704951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1705951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 1706951c6300SRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 1707951c6300SRichard Henderson TCGv_i64 t3 = tcg_temp_new_i64(); 1708951c6300SRichard Henderson tcg_gen_mulu2_i64(t0, t1, arg1, arg2); 1709951c6300SRichard Henderson /* Adjust for negative inputs. */ 1710951c6300SRichard Henderson tcg_gen_sari_i64(t2, arg1, 63); 1711951c6300SRichard Henderson tcg_gen_sari_i64(t3, arg2, 63); 1712951c6300SRichard Henderson tcg_gen_and_i64(t2, t2, arg2); 1713951c6300SRichard Henderson tcg_gen_and_i64(t3, t3, arg1); 1714951c6300SRichard Henderson tcg_gen_sub_i64(rh, t1, t2); 1715951c6300SRichard Henderson tcg_gen_sub_i64(rh, rh, t3); 1716951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0); 1717951c6300SRichard Henderson tcg_temp_free_i64(t0); 1718951c6300SRichard Henderson tcg_temp_free_i64(t1); 1719951c6300SRichard Henderson tcg_temp_free_i64(t2); 1720951c6300SRichard Henderson tcg_temp_free_i64(t3); 1721951c6300SRichard Henderson } else { 1722951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1723951c6300SRichard Henderson tcg_gen_mul_i64(t0, arg1, arg2); 1724951c6300SRichard Henderson gen_helper_mulsh_i64(rh, arg1, arg2); 1725951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0); 1726951c6300SRichard Henderson tcg_temp_free_i64(t0); 1727951c6300SRichard Henderson } 1728951c6300SRichard Henderson } 1729951c6300SRichard Henderson 1730951c6300SRichard Henderson /* Size changing operations. */ 1731951c6300SRichard Henderson 1732951c6300SRichard Henderson void tcg_gen_trunc_shr_i64_i32(TCGv_i32 ret, TCGv_i64 arg, unsigned count) 1733951c6300SRichard Henderson { 1734951c6300SRichard Henderson tcg_debug_assert(count < 64); 1735*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1736951c6300SRichard Henderson if (count >= 32) { 1737951c6300SRichard Henderson tcg_gen_shri_i32(ret, TCGV_HIGH(arg), count - 32); 1738951c6300SRichard Henderson } else if (count == 0) { 1739951c6300SRichard Henderson tcg_gen_mov_i32(ret, TCGV_LOW(arg)); 1740951c6300SRichard Henderson } else { 1741951c6300SRichard Henderson TCGv_i64 t = tcg_temp_new_i64(); 1742951c6300SRichard Henderson tcg_gen_shri_i64(t, arg, count); 1743951c6300SRichard Henderson tcg_gen_mov_i32(ret, TCGV_LOW(t)); 1744951c6300SRichard Henderson tcg_temp_free_i64(t); 1745951c6300SRichard Henderson } 1746*3a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_trunc_shr_i32) { 1747951c6300SRichard Henderson tcg_gen_op3i_i32(INDEX_op_trunc_shr_i32, ret, 1748951c6300SRichard Henderson MAKE_TCGV_I32(GET_TCGV_I64(arg)), count); 1749951c6300SRichard Henderson } else if (count == 0) { 1750951c6300SRichard Henderson tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(arg))); 1751951c6300SRichard Henderson } else { 1752951c6300SRichard Henderson TCGv_i64 t = tcg_temp_new_i64(); 1753951c6300SRichard Henderson tcg_gen_shri_i64(t, arg, count); 1754951c6300SRichard Henderson tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(t))); 1755951c6300SRichard Henderson tcg_temp_free_i64(t); 1756951c6300SRichard Henderson } 1757951c6300SRichard Henderson } 1758951c6300SRichard Henderson 1759951c6300SRichard Henderson void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 1760951c6300SRichard Henderson { 1761*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1762951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), arg); 1763951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1764*3a13c3f3SRichard Henderson } else { 1765951c6300SRichard Henderson /* Note: we assume the target supports move between 1766951c6300SRichard Henderson 32 and 64 bit registers. */ 1767951c6300SRichard Henderson tcg_gen_ext32u_i64(ret, MAKE_TCGV_I64(GET_TCGV_I32(arg))); 1768*3a13c3f3SRichard Henderson } 1769951c6300SRichard Henderson } 1770951c6300SRichard Henderson 1771951c6300SRichard Henderson void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 1772951c6300SRichard Henderson { 1773*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1774951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), arg); 1775951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 1776*3a13c3f3SRichard Henderson } else { 1777951c6300SRichard Henderson /* Note: we assume the target supports move between 1778951c6300SRichard Henderson 32 and 64 bit registers. */ 1779951c6300SRichard Henderson tcg_gen_ext32s_i64(ret, MAKE_TCGV_I64(GET_TCGV_I32(arg))); 1780*3a13c3f3SRichard Henderson } 1781951c6300SRichard Henderson } 1782951c6300SRichard Henderson 1783951c6300SRichard Henderson void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high) 1784951c6300SRichard Henderson { 1785*3a13c3f3SRichard Henderson TCGv_i64 tmp; 1786*3a13c3f3SRichard Henderson 1787*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1788951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(dest), low); 1789951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(dest), high); 1790*3a13c3f3SRichard Henderson return; 1791*3a13c3f3SRichard Henderson } 1792*3a13c3f3SRichard Henderson 1793*3a13c3f3SRichard Henderson tmp = tcg_temp_new_i64(); 1794951c6300SRichard Henderson /* These extensions are only needed for type correctness. 1795951c6300SRichard Henderson We may be able to do better given target specific information. */ 1796951c6300SRichard Henderson tcg_gen_extu_i32_i64(tmp, high); 1797951c6300SRichard Henderson tcg_gen_extu_i32_i64(dest, low); 1798951c6300SRichard Henderson /* If deposit is available, use it. Otherwise use the extra 1799951c6300SRichard Henderson knowledge that we have of the zero-extensions above. */ 1800951c6300SRichard Henderson if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) { 1801951c6300SRichard Henderson tcg_gen_deposit_i64(dest, dest, tmp, 32, 32); 1802951c6300SRichard Henderson } else { 1803951c6300SRichard Henderson tcg_gen_shli_i64(tmp, tmp, 32); 1804951c6300SRichard Henderson tcg_gen_or_i64(dest, dest, tmp); 1805951c6300SRichard Henderson } 1806951c6300SRichard Henderson tcg_temp_free_i64(tmp); 1807951c6300SRichard Henderson } 1808951c6300SRichard Henderson 1809951c6300SRichard Henderson void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg) 1810951c6300SRichard Henderson { 1811*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1812951c6300SRichard Henderson tcg_gen_mov_i32(lo, TCGV_LOW(arg)); 1813951c6300SRichard Henderson tcg_gen_mov_i32(hi, TCGV_HIGH(arg)); 1814*3a13c3f3SRichard Henderson } else { 1815951c6300SRichard Henderson tcg_gen_trunc_shr_i64_i32(lo, arg, 0); 1816951c6300SRichard Henderson tcg_gen_trunc_shr_i64_i32(hi, arg, 32); 1817*3a13c3f3SRichard Henderson } 1818951c6300SRichard Henderson } 1819951c6300SRichard Henderson 1820951c6300SRichard Henderson void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg) 1821951c6300SRichard Henderson { 1822951c6300SRichard Henderson tcg_gen_ext32u_i64(lo, arg); 1823951c6300SRichard Henderson tcg_gen_shri_i64(hi, arg, 32); 1824951c6300SRichard Henderson } 1825951c6300SRichard Henderson 1826951c6300SRichard Henderson /* QEMU specific operations. */ 1827951c6300SRichard Henderson 1828951c6300SRichard Henderson void tcg_gen_goto_tb(unsigned idx) 1829951c6300SRichard Henderson { 1830951c6300SRichard Henderson /* We only support two chained exits. */ 1831951c6300SRichard Henderson tcg_debug_assert(idx <= 1); 1832951c6300SRichard Henderson #ifdef CONFIG_DEBUG_TCG 1833951c6300SRichard Henderson /* Verify that we havn't seen this numbered exit before. */ 1834951c6300SRichard Henderson tcg_debug_assert((tcg_ctx.goto_tb_issue_mask & (1 << idx)) == 0); 1835951c6300SRichard Henderson tcg_ctx.goto_tb_issue_mask |= 1 << idx; 1836951c6300SRichard Henderson #endif 1837951c6300SRichard Henderson tcg_gen_op1i(INDEX_op_goto_tb, idx); 1838951c6300SRichard Henderson } 1839951c6300SRichard Henderson 1840951c6300SRichard Henderson static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st) 1841951c6300SRichard Henderson { 1842951c6300SRichard Henderson switch (op & MO_SIZE) { 1843951c6300SRichard Henderson case MO_8: 1844951c6300SRichard Henderson op &= ~MO_BSWAP; 1845951c6300SRichard Henderson break; 1846951c6300SRichard Henderson case MO_16: 1847951c6300SRichard Henderson break; 1848951c6300SRichard Henderson case MO_32: 1849951c6300SRichard Henderson if (!is64) { 1850951c6300SRichard Henderson op &= ~MO_SIGN; 1851951c6300SRichard Henderson } 1852951c6300SRichard Henderson break; 1853951c6300SRichard Henderson case MO_64: 1854951c6300SRichard Henderson if (!is64) { 1855951c6300SRichard Henderson tcg_abort(); 1856951c6300SRichard Henderson } 1857951c6300SRichard Henderson break; 1858951c6300SRichard Henderson } 1859951c6300SRichard Henderson if (st) { 1860951c6300SRichard Henderson op &= ~MO_SIGN; 1861951c6300SRichard Henderson } 1862951c6300SRichard Henderson return op; 1863951c6300SRichard Henderson } 1864951c6300SRichard Henderson 1865951c6300SRichard Henderson static inline void tcg_add_param_i32(TCGv_i32 val) 1866951c6300SRichard Henderson { 1867951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(val); 1868951c6300SRichard Henderson } 1869951c6300SRichard Henderson 1870951c6300SRichard Henderson static inline void tcg_add_param_i64(TCGv_i64 val) 1871951c6300SRichard Henderson { 1872*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1873951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(TCGV_LOW(val)); 1874951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(TCGV_HIGH(val)); 1875*3a13c3f3SRichard Henderson } else { 1876951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(val); 1877*3a13c3f3SRichard Henderson } 1878951c6300SRichard Henderson } 1879951c6300SRichard Henderson 1880951c6300SRichard Henderson #if TARGET_LONG_BITS == 32 1881951c6300SRichard Henderson # define tcg_add_param_tl tcg_add_param_i32 1882951c6300SRichard Henderson #else 1883951c6300SRichard Henderson # define tcg_add_param_tl tcg_add_param_i64 1884951c6300SRichard Henderson #endif 1885951c6300SRichard Henderson 1886951c6300SRichard Henderson void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop) 1887951c6300SRichard Henderson { 1888951c6300SRichard Henderson memop = tcg_canonicalize_memop(memop, 0, 0); 1889951c6300SRichard Henderson 1890951c6300SRichard Henderson *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i32; 1891951c6300SRichard Henderson tcg_add_param_i32(val); 1892951c6300SRichard Henderson tcg_add_param_tl(addr); 1893951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = memop; 1894951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = idx; 1895951c6300SRichard Henderson } 1896951c6300SRichard Henderson 1897951c6300SRichard Henderson void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop) 1898951c6300SRichard Henderson { 1899951c6300SRichard Henderson memop = tcg_canonicalize_memop(memop, 0, 1); 1900951c6300SRichard Henderson 1901951c6300SRichard Henderson *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i32; 1902951c6300SRichard Henderson tcg_add_param_i32(val); 1903951c6300SRichard Henderson tcg_add_param_tl(addr); 1904951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = memop; 1905951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = idx; 1906951c6300SRichard Henderson } 1907951c6300SRichard Henderson 1908951c6300SRichard Henderson void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop) 1909951c6300SRichard Henderson { 1910951c6300SRichard Henderson memop = tcg_canonicalize_memop(memop, 1, 0); 1911951c6300SRichard Henderson 1912*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) { 1913951c6300SRichard Henderson tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop); 1914951c6300SRichard Henderson if (memop & MO_SIGN) { 1915951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31); 1916951c6300SRichard Henderson } else { 1917951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(val), 0); 1918951c6300SRichard Henderson } 1919951c6300SRichard Henderson return; 1920951c6300SRichard Henderson } 1921951c6300SRichard Henderson 1922951c6300SRichard Henderson *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i64; 1923951c6300SRichard Henderson tcg_add_param_i64(val); 1924951c6300SRichard Henderson tcg_add_param_tl(addr); 1925951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = memop; 1926951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = idx; 1927951c6300SRichard Henderson } 1928951c6300SRichard Henderson 1929951c6300SRichard Henderson void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop) 1930951c6300SRichard Henderson { 1931951c6300SRichard Henderson memop = tcg_canonicalize_memop(memop, 1, 1); 1932951c6300SRichard Henderson 1933*3a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) { 1934951c6300SRichard Henderson tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop); 1935951c6300SRichard Henderson return; 1936951c6300SRichard Henderson } 1937951c6300SRichard Henderson 1938951c6300SRichard Henderson *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i64; 1939951c6300SRichard Henderson tcg_add_param_i64(val); 1940951c6300SRichard Henderson tcg_add_param_tl(addr); 1941951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = memop; 1942951c6300SRichard Henderson *tcg_ctx.gen_opparam_ptr++ = idx; 1943951c6300SRichard Henderson } 1944