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 25757e725bSPeter Maydell #include "qemu/osdep.h" 2633c11879SPaolo Bonzini #include "qemu-common.h" 2733c11879SPaolo Bonzini #include "cpu.h" 2863c91552SPaolo Bonzini #include "exec/exec-all.h" 29951c6300SRichard Henderson #include "tcg.h" 30951c6300SRichard Henderson #include "tcg-op.h" 31*dcdaadb6SLluís Vilanova #include "trace-tcg.h" 32*dcdaadb6SLluís Vilanova #include "trace/mem.h" 33951c6300SRichard Henderson 343a13c3f3SRichard Henderson /* Reduce the number of ifdefs below. This assumes that all uses of 353a13c3f3SRichard Henderson TCGV_HIGH and TCGV_LOW are properly protected by a conditional that 363a13c3f3SRichard Henderson the compiler can eliminate. */ 373a13c3f3SRichard Henderson #if TCG_TARGET_REG_BITS == 64 383a13c3f3SRichard Henderson extern TCGv_i32 TCGV_LOW_link_error(TCGv_i64); 393a13c3f3SRichard Henderson extern TCGv_i32 TCGV_HIGH_link_error(TCGv_i64); 403a13c3f3SRichard Henderson #define TCGV_LOW TCGV_LOW_link_error 413a13c3f3SRichard Henderson #define TCGV_HIGH TCGV_HIGH_link_error 423a13c3f3SRichard Henderson #endif 43951c6300SRichard Henderson 44c45cb8bbSRichard Henderson /* Note that this is optimized for sequential allocation during translate. 45c45cb8bbSRichard Henderson Up to and including filling in the forward link immediately. We'll do 46c45cb8bbSRichard Henderson proper termination of the end of the list after we finish translation. */ 47c45cb8bbSRichard Henderson 48c45cb8bbSRichard Henderson static void tcg_emit_op(TCGContext *ctx, TCGOpcode opc, int args) 49c45cb8bbSRichard Henderson { 50c45cb8bbSRichard Henderson int oi = ctx->gen_next_op_idx; 51c45cb8bbSRichard Henderson int ni = oi + 1; 52c45cb8bbSRichard Henderson int pi = oi - 1; 53c45cb8bbSRichard Henderson 54c45cb8bbSRichard Henderson tcg_debug_assert(oi < OPC_BUF_SIZE); 55c45cb8bbSRichard Henderson ctx->gen_last_op_idx = oi; 56c45cb8bbSRichard Henderson ctx->gen_next_op_idx = ni; 57c45cb8bbSRichard Henderson 58c45cb8bbSRichard Henderson ctx->gen_op_buf[oi] = (TCGOp){ 59c45cb8bbSRichard Henderson .opc = opc, 60c45cb8bbSRichard Henderson .args = args, 61c45cb8bbSRichard Henderson .prev = pi, 62c45cb8bbSRichard Henderson .next = ni 63c45cb8bbSRichard Henderson }; 64c45cb8bbSRichard Henderson } 65c45cb8bbSRichard Henderson 66951c6300SRichard Henderson void tcg_gen_op1(TCGContext *ctx, TCGOpcode opc, TCGArg a1) 67951c6300SRichard Henderson { 68c45cb8bbSRichard Henderson int pi = ctx->gen_next_parm_idx; 69951c6300SRichard Henderson 70c45cb8bbSRichard Henderson tcg_debug_assert(pi + 1 <= OPPARAM_BUF_SIZE); 71c45cb8bbSRichard Henderson ctx->gen_next_parm_idx = pi + 1; 72c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi] = a1; 73951c6300SRichard Henderson 74c45cb8bbSRichard Henderson tcg_emit_op(ctx, opc, pi); 75951c6300SRichard Henderson } 76951c6300SRichard Henderson 77951c6300SRichard Henderson void tcg_gen_op2(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2) 78951c6300SRichard Henderson { 79c45cb8bbSRichard Henderson int pi = ctx->gen_next_parm_idx; 80951c6300SRichard Henderson 81c45cb8bbSRichard Henderson tcg_debug_assert(pi + 2 <= OPPARAM_BUF_SIZE); 82c45cb8bbSRichard Henderson ctx->gen_next_parm_idx = pi + 2; 83c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 0] = a1; 84c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 1] = a2; 85951c6300SRichard Henderson 86c45cb8bbSRichard Henderson tcg_emit_op(ctx, opc, pi); 87951c6300SRichard Henderson } 88951c6300SRichard Henderson 89951c6300SRichard Henderson void tcg_gen_op3(TCGContext *ctx, TCGOpcode opc, TCGArg a1, 90951c6300SRichard Henderson TCGArg a2, TCGArg a3) 91951c6300SRichard Henderson { 92c45cb8bbSRichard Henderson int pi = ctx->gen_next_parm_idx; 93951c6300SRichard Henderson 94c45cb8bbSRichard Henderson tcg_debug_assert(pi + 3 <= OPPARAM_BUF_SIZE); 95c45cb8bbSRichard Henderson ctx->gen_next_parm_idx = pi + 3; 96c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 0] = a1; 97c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 1] = a2; 98c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 2] = a3; 99951c6300SRichard Henderson 100c45cb8bbSRichard Henderson tcg_emit_op(ctx, opc, pi); 101951c6300SRichard Henderson } 102951c6300SRichard Henderson 103951c6300SRichard Henderson void tcg_gen_op4(TCGContext *ctx, TCGOpcode opc, TCGArg a1, 104951c6300SRichard Henderson TCGArg a2, TCGArg a3, TCGArg a4) 105951c6300SRichard Henderson { 106c45cb8bbSRichard Henderson int pi = ctx->gen_next_parm_idx; 107951c6300SRichard Henderson 108c45cb8bbSRichard Henderson tcg_debug_assert(pi + 4 <= OPPARAM_BUF_SIZE); 109c45cb8bbSRichard Henderson ctx->gen_next_parm_idx = pi + 4; 110c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 0] = a1; 111c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 1] = a2; 112c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 2] = a3; 113c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 3] = a4; 114951c6300SRichard Henderson 115c45cb8bbSRichard Henderson tcg_emit_op(ctx, opc, pi); 116951c6300SRichard Henderson } 117951c6300SRichard Henderson 118951c6300SRichard Henderson void tcg_gen_op5(TCGContext *ctx, TCGOpcode opc, TCGArg a1, 119951c6300SRichard Henderson TCGArg a2, TCGArg a3, TCGArg a4, TCGArg a5) 120951c6300SRichard Henderson { 121c45cb8bbSRichard Henderson int pi = ctx->gen_next_parm_idx; 122951c6300SRichard Henderson 123c45cb8bbSRichard Henderson tcg_debug_assert(pi + 5 <= OPPARAM_BUF_SIZE); 124c45cb8bbSRichard Henderson ctx->gen_next_parm_idx = pi + 5; 125c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 0] = a1; 126c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 1] = a2; 127c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 2] = a3; 128c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 3] = a4; 129c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 4] = a5; 130951c6300SRichard Henderson 131c45cb8bbSRichard Henderson tcg_emit_op(ctx, opc, pi); 132951c6300SRichard Henderson } 133951c6300SRichard Henderson 134951c6300SRichard Henderson void tcg_gen_op6(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2, 135951c6300SRichard Henderson TCGArg a3, TCGArg a4, TCGArg a5, TCGArg a6) 136951c6300SRichard Henderson { 137c45cb8bbSRichard Henderson int pi = ctx->gen_next_parm_idx; 138951c6300SRichard Henderson 139c45cb8bbSRichard Henderson tcg_debug_assert(pi + 6 <= OPPARAM_BUF_SIZE); 140c45cb8bbSRichard Henderson ctx->gen_next_parm_idx = pi + 6; 141c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 0] = a1; 142c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 1] = a2; 143c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 2] = a3; 144c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 3] = a4; 145c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 4] = a5; 146c45cb8bbSRichard Henderson ctx->gen_opparam_buf[pi + 5] = a6; 147951c6300SRichard Henderson 148c45cb8bbSRichard Henderson tcg_emit_op(ctx, opc, pi); 149951c6300SRichard Henderson } 150951c6300SRichard Henderson 151951c6300SRichard Henderson /* 32 bit ops */ 152951c6300SRichard Henderson 153951c6300SRichard Henderson void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 154951c6300SRichard Henderson { 155951c6300SRichard Henderson /* some cases can be optimized here */ 156951c6300SRichard Henderson if (arg2 == 0) { 157951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 158951c6300SRichard Henderson } else { 159951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 160951c6300SRichard Henderson tcg_gen_add_i32(ret, arg1, t0); 161951c6300SRichard Henderson tcg_temp_free_i32(t0); 162951c6300SRichard Henderson } 163951c6300SRichard Henderson } 164951c6300SRichard Henderson 165951c6300SRichard Henderson void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2) 166951c6300SRichard Henderson { 167951c6300SRichard Henderson if (arg1 == 0 && TCG_TARGET_HAS_neg_i32) { 168951c6300SRichard Henderson /* Don't recurse with tcg_gen_neg_i32. */ 169951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg2); 170951c6300SRichard Henderson } else { 171951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg1); 172951c6300SRichard Henderson tcg_gen_sub_i32(ret, t0, arg2); 173951c6300SRichard Henderson tcg_temp_free_i32(t0); 174951c6300SRichard Henderson } 175951c6300SRichard Henderson } 176951c6300SRichard Henderson 177951c6300SRichard Henderson void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 178951c6300SRichard Henderson { 179951c6300SRichard Henderson /* some cases can be optimized here */ 180951c6300SRichard Henderson if (arg2 == 0) { 181951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 182951c6300SRichard Henderson } else { 183951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 184951c6300SRichard Henderson tcg_gen_sub_i32(ret, arg1, t0); 185951c6300SRichard Henderson tcg_temp_free_i32(t0); 186951c6300SRichard Henderson } 187951c6300SRichard Henderson } 188951c6300SRichard Henderson 189951c6300SRichard Henderson void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2) 190951c6300SRichard Henderson { 191951c6300SRichard Henderson TCGv_i32 t0; 192951c6300SRichard Henderson /* Some cases can be optimized here. */ 193951c6300SRichard Henderson switch (arg2) { 194951c6300SRichard Henderson case 0: 195951c6300SRichard Henderson tcg_gen_movi_i32(ret, 0); 196951c6300SRichard Henderson return; 197951c6300SRichard Henderson case 0xffffffffu: 198951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 199951c6300SRichard Henderson return; 200951c6300SRichard Henderson case 0xffu: 201951c6300SRichard Henderson /* Don't recurse with tcg_gen_ext8u_i32. */ 202951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8u_i32) { 203951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1); 204951c6300SRichard Henderson return; 205951c6300SRichard Henderson } 206951c6300SRichard Henderson break; 207951c6300SRichard Henderson case 0xffffu: 208951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16u_i32) { 209951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1); 210951c6300SRichard Henderson return; 211951c6300SRichard Henderson } 212951c6300SRichard Henderson break; 213951c6300SRichard Henderson } 214951c6300SRichard Henderson t0 = tcg_const_i32(arg2); 215951c6300SRichard Henderson tcg_gen_and_i32(ret, arg1, t0); 216951c6300SRichard Henderson tcg_temp_free_i32(t0); 217951c6300SRichard Henderson } 218951c6300SRichard Henderson 219951c6300SRichard Henderson void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 220951c6300SRichard Henderson { 221951c6300SRichard Henderson /* Some cases can be optimized here. */ 222951c6300SRichard Henderson if (arg2 == -1) { 223951c6300SRichard Henderson tcg_gen_movi_i32(ret, -1); 224951c6300SRichard Henderson } else if (arg2 == 0) { 225951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 226951c6300SRichard Henderson } else { 227951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 228951c6300SRichard Henderson tcg_gen_or_i32(ret, arg1, t0); 229951c6300SRichard Henderson tcg_temp_free_i32(t0); 230951c6300SRichard Henderson } 231951c6300SRichard Henderson } 232951c6300SRichard Henderson 233951c6300SRichard Henderson void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 234951c6300SRichard Henderson { 235951c6300SRichard Henderson /* Some cases can be optimized here. */ 236951c6300SRichard Henderson if (arg2 == 0) { 237951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 238951c6300SRichard Henderson } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) { 239951c6300SRichard Henderson /* Don't recurse with tcg_gen_not_i32. */ 240951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1); 241951c6300SRichard Henderson } else { 242951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 243951c6300SRichard Henderson tcg_gen_xor_i32(ret, arg1, t0); 244951c6300SRichard Henderson tcg_temp_free_i32(t0); 245951c6300SRichard Henderson } 246951c6300SRichard Henderson } 247951c6300SRichard Henderson 248951c6300SRichard Henderson void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 249951c6300SRichard Henderson { 250951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 251951c6300SRichard Henderson if (arg2 == 0) { 252951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 253951c6300SRichard Henderson } else { 254951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 255951c6300SRichard Henderson tcg_gen_shl_i32(ret, arg1, t0); 256951c6300SRichard Henderson tcg_temp_free_i32(t0); 257951c6300SRichard Henderson } 258951c6300SRichard Henderson } 259951c6300SRichard Henderson 260951c6300SRichard Henderson void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 261951c6300SRichard Henderson { 262951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 263951c6300SRichard Henderson if (arg2 == 0) { 264951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 265951c6300SRichard Henderson } else { 266951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 267951c6300SRichard Henderson tcg_gen_shr_i32(ret, arg1, t0); 268951c6300SRichard Henderson tcg_temp_free_i32(t0); 269951c6300SRichard Henderson } 270951c6300SRichard Henderson } 271951c6300SRichard Henderson 272951c6300SRichard Henderson void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 273951c6300SRichard Henderson { 274951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 275951c6300SRichard Henderson if (arg2 == 0) { 276951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 277951c6300SRichard Henderson } else { 278951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 279951c6300SRichard Henderson tcg_gen_sar_i32(ret, arg1, t0); 280951c6300SRichard Henderson tcg_temp_free_i32(t0); 281951c6300SRichard Henderson } 282951c6300SRichard Henderson } 283951c6300SRichard Henderson 28442a268c2SRichard Henderson void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l) 285951c6300SRichard Henderson { 286951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 28742a268c2SRichard Henderson tcg_gen_br(l); 288951c6300SRichard Henderson } else if (cond != TCG_COND_NEVER) { 28942a268c2SRichard Henderson tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l)); 290951c6300SRichard Henderson } 291951c6300SRichard Henderson } 292951c6300SRichard Henderson 29342a268c2SRichard Henderson void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l) 294951c6300SRichard Henderson { 29537ed3bf1SRichard Henderson if (cond == TCG_COND_ALWAYS) { 29637ed3bf1SRichard Henderson tcg_gen_br(l); 29737ed3bf1SRichard Henderson } else if (cond != TCG_COND_NEVER) { 298951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 29942a268c2SRichard Henderson tcg_gen_brcond_i32(cond, arg1, t0, l); 300951c6300SRichard Henderson tcg_temp_free_i32(t0); 301951c6300SRichard Henderson } 30237ed3bf1SRichard Henderson } 303951c6300SRichard Henderson 304951c6300SRichard Henderson void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret, 305951c6300SRichard Henderson TCGv_i32 arg1, TCGv_i32 arg2) 306951c6300SRichard Henderson { 307951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 308951c6300SRichard Henderson tcg_gen_movi_i32(ret, 1); 309951c6300SRichard Henderson } else if (cond == TCG_COND_NEVER) { 310951c6300SRichard Henderson tcg_gen_movi_i32(ret, 0); 311951c6300SRichard Henderson } else { 312951c6300SRichard Henderson tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond); 313951c6300SRichard Henderson } 314951c6300SRichard Henderson } 315951c6300SRichard Henderson 316951c6300SRichard Henderson void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret, 317951c6300SRichard Henderson TCGv_i32 arg1, int32_t arg2) 318951c6300SRichard Henderson { 319951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 320951c6300SRichard Henderson tcg_gen_setcond_i32(cond, ret, arg1, t0); 321951c6300SRichard Henderson tcg_temp_free_i32(t0); 322951c6300SRichard Henderson } 323951c6300SRichard Henderson 324951c6300SRichard Henderson void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) 325951c6300SRichard Henderson { 326951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 327951c6300SRichard Henderson tcg_gen_mul_i32(ret, arg1, t0); 328951c6300SRichard Henderson tcg_temp_free_i32(t0); 329951c6300SRichard Henderson } 330951c6300SRichard Henderson 331951c6300SRichard Henderson void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 332951c6300SRichard Henderson { 333951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i32) { 334951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2); 335951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) { 336951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 337951c6300SRichard Henderson tcg_gen_sari_i32(t0, arg1, 31); 338951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2); 339951c6300SRichard Henderson tcg_temp_free_i32(t0); 340951c6300SRichard Henderson } else { 341951c6300SRichard Henderson gen_helper_div_i32(ret, arg1, arg2); 342951c6300SRichard Henderson } 343951c6300SRichard Henderson } 344951c6300SRichard Henderson 345951c6300SRichard Henderson void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 346951c6300SRichard Henderson { 347951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i32) { 348951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2); 349951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i32) { 350951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 351951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2); 352951c6300SRichard Henderson tcg_gen_mul_i32(t0, t0, arg2); 353951c6300SRichard Henderson tcg_gen_sub_i32(ret, arg1, t0); 354951c6300SRichard Henderson tcg_temp_free_i32(t0); 355951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) { 356951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 357951c6300SRichard Henderson tcg_gen_sari_i32(t0, arg1, 31); 358951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2); 359951c6300SRichard Henderson tcg_temp_free_i32(t0); 360951c6300SRichard Henderson } else { 361951c6300SRichard Henderson gen_helper_rem_i32(ret, arg1, arg2); 362951c6300SRichard Henderson } 363951c6300SRichard Henderson } 364951c6300SRichard Henderson 365951c6300SRichard Henderson void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 366951c6300SRichard Henderson { 367951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i32) { 368951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2); 369951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) { 370951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 371951c6300SRichard Henderson tcg_gen_movi_i32(t0, 0); 372951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2); 373951c6300SRichard Henderson tcg_temp_free_i32(t0); 374951c6300SRichard Henderson } else { 375951c6300SRichard Henderson gen_helper_divu_i32(ret, arg1, arg2); 376951c6300SRichard Henderson } 377951c6300SRichard Henderson } 378951c6300SRichard Henderson 379951c6300SRichard Henderson void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 380951c6300SRichard Henderson { 381951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i32) { 382951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2); 383951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i32) { 384951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 385951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2); 386951c6300SRichard Henderson tcg_gen_mul_i32(t0, t0, arg2); 387951c6300SRichard Henderson tcg_gen_sub_i32(ret, arg1, t0); 388951c6300SRichard Henderson tcg_temp_free_i32(t0); 389951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) { 390951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 391951c6300SRichard Henderson tcg_gen_movi_i32(t0, 0); 392951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2); 393951c6300SRichard Henderson tcg_temp_free_i32(t0); 394951c6300SRichard Henderson } else { 395951c6300SRichard Henderson gen_helper_remu_i32(ret, arg1, arg2); 396951c6300SRichard Henderson } 397951c6300SRichard Henderson } 398951c6300SRichard Henderson 399951c6300SRichard Henderson void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 400951c6300SRichard Henderson { 401951c6300SRichard Henderson if (TCG_TARGET_HAS_andc_i32) { 402951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2); 403951c6300SRichard Henderson } else { 404951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 405951c6300SRichard Henderson tcg_gen_not_i32(t0, arg2); 406951c6300SRichard Henderson tcg_gen_and_i32(ret, arg1, t0); 407951c6300SRichard Henderson tcg_temp_free_i32(t0); 408951c6300SRichard Henderson } 409951c6300SRichard Henderson } 410951c6300SRichard Henderson 411951c6300SRichard Henderson void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 412951c6300SRichard Henderson { 413951c6300SRichard Henderson if (TCG_TARGET_HAS_eqv_i32) { 414951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2); 415951c6300SRichard Henderson } else { 416951c6300SRichard Henderson tcg_gen_xor_i32(ret, arg1, arg2); 417951c6300SRichard Henderson tcg_gen_not_i32(ret, ret); 418951c6300SRichard Henderson } 419951c6300SRichard Henderson } 420951c6300SRichard Henderson 421951c6300SRichard Henderson void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 422951c6300SRichard Henderson { 423951c6300SRichard Henderson if (TCG_TARGET_HAS_nand_i32) { 424951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2); 425951c6300SRichard Henderson } else { 426951c6300SRichard Henderson tcg_gen_and_i32(ret, arg1, arg2); 427951c6300SRichard Henderson tcg_gen_not_i32(ret, ret); 428951c6300SRichard Henderson } 429951c6300SRichard Henderson } 430951c6300SRichard Henderson 431951c6300SRichard Henderson void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 432951c6300SRichard Henderson { 433951c6300SRichard Henderson if (TCG_TARGET_HAS_nor_i32) { 434951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2); 435951c6300SRichard Henderson } else { 436951c6300SRichard Henderson tcg_gen_or_i32(ret, arg1, arg2); 437951c6300SRichard Henderson tcg_gen_not_i32(ret, ret); 438951c6300SRichard Henderson } 439951c6300SRichard Henderson } 440951c6300SRichard Henderson 441951c6300SRichard Henderson void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 442951c6300SRichard Henderson { 443951c6300SRichard Henderson if (TCG_TARGET_HAS_orc_i32) { 444951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2); 445951c6300SRichard Henderson } else { 446951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 447951c6300SRichard Henderson tcg_gen_not_i32(t0, arg2); 448951c6300SRichard Henderson tcg_gen_or_i32(ret, arg1, t0); 449951c6300SRichard Henderson tcg_temp_free_i32(t0); 450951c6300SRichard Henderson } 451951c6300SRichard Henderson } 452951c6300SRichard Henderson 453951c6300SRichard Henderson void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 454951c6300SRichard Henderson { 455951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i32) { 456951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2); 457951c6300SRichard Henderson } else { 458951c6300SRichard Henderson TCGv_i32 t0, t1; 459951c6300SRichard Henderson 460951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 461951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 462951c6300SRichard Henderson tcg_gen_shl_i32(t0, arg1, arg2); 463951c6300SRichard Henderson tcg_gen_subfi_i32(t1, 32, arg2); 464951c6300SRichard Henderson tcg_gen_shr_i32(t1, arg1, t1); 465951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1); 466951c6300SRichard Henderson tcg_temp_free_i32(t0); 467951c6300SRichard Henderson tcg_temp_free_i32(t1); 468951c6300SRichard Henderson } 469951c6300SRichard Henderson } 470951c6300SRichard Henderson 471951c6300SRichard Henderson void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 472951c6300SRichard Henderson { 473951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 474951c6300SRichard Henderson /* some cases can be optimized here */ 475951c6300SRichard Henderson if (arg2 == 0) { 476951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 477951c6300SRichard Henderson } else if (TCG_TARGET_HAS_rot_i32) { 478951c6300SRichard Henderson TCGv_i32 t0 = tcg_const_i32(arg2); 479951c6300SRichard Henderson tcg_gen_rotl_i32(ret, arg1, t0); 480951c6300SRichard Henderson tcg_temp_free_i32(t0); 481951c6300SRichard Henderson } else { 482951c6300SRichard Henderson TCGv_i32 t0, t1; 483951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 484951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 485951c6300SRichard Henderson tcg_gen_shli_i32(t0, arg1, arg2); 486951c6300SRichard Henderson tcg_gen_shri_i32(t1, arg1, 32 - arg2); 487951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1); 488951c6300SRichard Henderson tcg_temp_free_i32(t0); 489951c6300SRichard Henderson tcg_temp_free_i32(t1); 490951c6300SRichard Henderson } 491951c6300SRichard Henderson } 492951c6300SRichard Henderson 493951c6300SRichard Henderson void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) 494951c6300SRichard Henderson { 495951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i32) { 496951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2); 497951c6300SRichard Henderson } else { 498951c6300SRichard Henderson TCGv_i32 t0, t1; 499951c6300SRichard Henderson 500951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 501951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 502951c6300SRichard Henderson tcg_gen_shr_i32(t0, arg1, arg2); 503951c6300SRichard Henderson tcg_gen_subfi_i32(t1, 32, arg2); 504951c6300SRichard Henderson tcg_gen_shl_i32(t1, arg1, t1); 505951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1); 506951c6300SRichard Henderson tcg_temp_free_i32(t0); 507951c6300SRichard Henderson tcg_temp_free_i32(t1); 508951c6300SRichard Henderson } 509951c6300SRichard Henderson } 510951c6300SRichard Henderson 511951c6300SRichard Henderson void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2) 512951c6300SRichard Henderson { 513951c6300SRichard Henderson tcg_debug_assert(arg2 < 32); 514951c6300SRichard Henderson /* some cases can be optimized here */ 515951c6300SRichard Henderson if (arg2 == 0) { 516951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1); 517951c6300SRichard Henderson } else { 518951c6300SRichard Henderson tcg_gen_rotli_i32(ret, arg1, 32 - arg2); 519951c6300SRichard Henderson } 520951c6300SRichard Henderson } 521951c6300SRichard Henderson 522951c6300SRichard Henderson void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2, 523951c6300SRichard Henderson unsigned int ofs, unsigned int len) 524951c6300SRichard Henderson { 525951c6300SRichard Henderson uint32_t mask; 526951c6300SRichard Henderson TCGv_i32 t1; 527951c6300SRichard Henderson 528951c6300SRichard Henderson tcg_debug_assert(ofs < 32); 529951c6300SRichard Henderson tcg_debug_assert(len <= 32); 530951c6300SRichard Henderson tcg_debug_assert(ofs + len <= 32); 531951c6300SRichard Henderson 532951c6300SRichard Henderson if (ofs == 0 && len == 32) { 533951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg2); 534951c6300SRichard Henderson return; 535951c6300SRichard Henderson } 536951c6300SRichard Henderson if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) { 537951c6300SRichard Henderson tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len); 538951c6300SRichard Henderson return; 539951c6300SRichard Henderson } 540951c6300SRichard Henderson 541951c6300SRichard Henderson mask = (1u << len) - 1; 542951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 543951c6300SRichard Henderson 544951c6300SRichard Henderson if (ofs + len < 32) { 545951c6300SRichard Henderson tcg_gen_andi_i32(t1, arg2, mask); 546951c6300SRichard Henderson tcg_gen_shli_i32(t1, t1, ofs); 547951c6300SRichard Henderson } else { 548951c6300SRichard Henderson tcg_gen_shli_i32(t1, arg2, ofs); 549951c6300SRichard Henderson } 550951c6300SRichard Henderson tcg_gen_andi_i32(ret, arg1, ~(mask << ofs)); 551951c6300SRichard Henderson tcg_gen_or_i32(ret, ret, t1); 552951c6300SRichard Henderson 553951c6300SRichard Henderson tcg_temp_free_i32(t1); 554951c6300SRichard Henderson } 555951c6300SRichard Henderson 556951c6300SRichard Henderson void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1, 557951c6300SRichard Henderson TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2) 558951c6300SRichard Henderson { 55937ed3bf1SRichard Henderson if (cond == TCG_COND_ALWAYS) { 56037ed3bf1SRichard Henderson tcg_gen_mov_i32(ret, v1); 56137ed3bf1SRichard Henderson } else if (cond == TCG_COND_NEVER) { 56237ed3bf1SRichard Henderson tcg_gen_mov_i32(ret, v2); 56337ed3bf1SRichard Henderson } else if (TCG_TARGET_HAS_movcond_i32) { 564951c6300SRichard Henderson tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond); 565951c6300SRichard Henderson } else { 566951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 567951c6300SRichard Henderson TCGv_i32 t1 = tcg_temp_new_i32(); 568951c6300SRichard Henderson tcg_gen_setcond_i32(cond, t0, c1, c2); 569951c6300SRichard Henderson tcg_gen_neg_i32(t0, t0); 570951c6300SRichard Henderson tcg_gen_and_i32(t1, v1, t0); 571951c6300SRichard Henderson tcg_gen_andc_i32(ret, v2, t0); 572951c6300SRichard Henderson tcg_gen_or_i32(ret, ret, t1); 573951c6300SRichard Henderson tcg_temp_free_i32(t0); 574951c6300SRichard Henderson tcg_temp_free_i32(t1); 575951c6300SRichard Henderson } 576951c6300SRichard Henderson } 577951c6300SRichard Henderson 578951c6300SRichard Henderson void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al, 579951c6300SRichard Henderson TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh) 580951c6300SRichard Henderson { 581951c6300SRichard Henderson if (TCG_TARGET_HAS_add2_i32) { 582951c6300SRichard Henderson tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh); 583951c6300SRichard Henderson } else { 584951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 585951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 586951c6300SRichard Henderson tcg_gen_concat_i32_i64(t0, al, ah); 587951c6300SRichard Henderson tcg_gen_concat_i32_i64(t1, bl, bh); 588951c6300SRichard Henderson tcg_gen_add_i64(t0, t0, t1); 589951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0); 590951c6300SRichard Henderson tcg_temp_free_i64(t0); 591951c6300SRichard Henderson tcg_temp_free_i64(t1); 592951c6300SRichard Henderson } 593951c6300SRichard Henderson } 594951c6300SRichard Henderson 595951c6300SRichard Henderson void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al, 596951c6300SRichard Henderson TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh) 597951c6300SRichard Henderson { 598951c6300SRichard Henderson if (TCG_TARGET_HAS_sub2_i32) { 599951c6300SRichard Henderson tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh); 600951c6300SRichard Henderson } else { 601951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 602951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 603951c6300SRichard Henderson tcg_gen_concat_i32_i64(t0, al, ah); 604951c6300SRichard Henderson tcg_gen_concat_i32_i64(t1, bl, bh); 605951c6300SRichard Henderson tcg_gen_sub_i64(t0, t0, t1); 606951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0); 607951c6300SRichard Henderson tcg_temp_free_i64(t0); 608951c6300SRichard Henderson tcg_temp_free_i64(t1); 609951c6300SRichard Henderson } 610951c6300SRichard Henderson } 611951c6300SRichard Henderson 612951c6300SRichard Henderson void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 613951c6300SRichard Henderson { 614951c6300SRichard Henderson if (TCG_TARGET_HAS_mulu2_i32) { 615951c6300SRichard Henderson tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2); 616951c6300SRichard Henderson } else if (TCG_TARGET_HAS_muluh_i32) { 617951c6300SRichard Henderson TCGv_i32 t = tcg_temp_new_i32(); 618951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2); 619951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2); 620951c6300SRichard Henderson tcg_gen_mov_i32(rl, t); 621951c6300SRichard Henderson tcg_temp_free_i32(t); 622951c6300SRichard Henderson } else { 623951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 624951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 625951c6300SRichard Henderson tcg_gen_extu_i32_i64(t0, arg1); 626951c6300SRichard Henderson tcg_gen_extu_i32_i64(t1, arg2); 627951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, t1); 628951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0); 629951c6300SRichard Henderson tcg_temp_free_i64(t0); 630951c6300SRichard Henderson tcg_temp_free_i64(t1); 631951c6300SRichard Henderson } 632951c6300SRichard Henderson } 633951c6300SRichard Henderson 634951c6300SRichard Henderson void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) 635951c6300SRichard Henderson { 636951c6300SRichard Henderson if (TCG_TARGET_HAS_muls2_i32) { 637951c6300SRichard Henderson tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2); 638951c6300SRichard Henderson } else if (TCG_TARGET_HAS_mulsh_i32) { 639951c6300SRichard Henderson TCGv_i32 t = tcg_temp_new_i32(); 640951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2); 641951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2); 642951c6300SRichard Henderson tcg_gen_mov_i32(rl, t); 643951c6300SRichard Henderson tcg_temp_free_i32(t); 644951c6300SRichard Henderson } else if (TCG_TARGET_REG_BITS == 32) { 645951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 646951c6300SRichard Henderson TCGv_i32 t1 = tcg_temp_new_i32(); 647951c6300SRichard Henderson TCGv_i32 t2 = tcg_temp_new_i32(); 648951c6300SRichard Henderson TCGv_i32 t3 = tcg_temp_new_i32(); 649951c6300SRichard Henderson tcg_gen_mulu2_i32(t0, t1, arg1, arg2); 650951c6300SRichard Henderson /* Adjust for negative inputs. */ 651951c6300SRichard Henderson tcg_gen_sari_i32(t2, arg1, 31); 652951c6300SRichard Henderson tcg_gen_sari_i32(t3, arg2, 31); 653951c6300SRichard Henderson tcg_gen_and_i32(t2, t2, arg2); 654951c6300SRichard Henderson tcg_gen_and_i32(t3, t3, arg1); 655951c6300SRichard Henderson tcg_gen_sub_i32(rh, t1, t2); 656951c6300SRichard Henderson tcg_gen_sub_i32(rh, rh, t3); 657951c6300SRichard Henderson tcg_gen_mov_i32(rl, t0); 658951c6300SRichard Henderson tcg_temp_free_i32(t0); 659951c6300SRichard Henderson tcg_temp_free_i32(t1); 660951c6300SRichard Henderson tcg_temp_free_i32(t2); 661951c6300SRichard Henderson tcg_temp_free_i32(t3); 662951c6300SRichard Henderson } else { 663951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 664951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 665951c6300SRichard Henderson tcg_gen_ext_i32_i64(t0, arg1); 666951c6300SRichard Henderson tcg_gen_ext_i32_i64(t1, arg2); 667951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, t1); 668951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0); 669951c6300SRichard Henderson tcg_temp_free_i64(t0); 670951c6300SRichard Henderson tcg_temp_free_i64(t1); 671951c6300SRichard Henderson } 672951c6300SRichard Henderson } 673951c6300SRichard Henderson 674951c6300SRichard Henderson void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg) 675951c6300SRichard Henderson { 676951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8s_i32) { 677951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg); 678951c6300SRichard Henderson } else { 679951c6300SRichard Henderson tcg_gen_shli_i32(ret, arg, 24); 680951c6300SRichard Henderson tcg_gen_sari_i32(ret, ret, 24); 681951c6300SRichard Henderson } 682951c6300SRichard Henderson } 683951c6300SRichard Henderson 684951c6300SRichard Henderson void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg) 685951c6300SRichard Henderson { 686951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16s_i32) { 687951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg); 688951c6300SRichard Henderson } else { 689951c6300SRichard Henderson tcg_gen_shli_i32(ret, arg, 16); 690951c6300SRichard Henderson tcg_gen_sari_i32(ret, ret, 16); 691951c6300SRichard Henderson } 692951c6300SRichard Henderson } 693951c6300SRichard Henderson 694951c6300SRichard Henderson void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg) 695951c6300SRichard Henderson { 696951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8u_i32) { 697951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg); 698951c6300SRichard Henderson } else { 699951c6300SRichard Henderson tcg_gen_andi_i32(ret, arg, 0xffu); 700951c6300SRichard Henderson } 701951c6300SRichard Henderson } 702951c6300SRichard Henderson 703951c6300SRichard Henderson void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg) 704951c6300SRichard Henderson { 705951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16u_i32) { 706951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg); 707951c6300SRichard Henderson } else { 708951c6300SRichard Henderson tcg_gen_andi_i32(ret, arg, 0xffffu); 709951c6300SRichard Henderson } 710951c6300SRichard Henderson } 711951c6300SRichard Henderson 712951c6300SRichard Henderson /* Note: we assume the two high bytes are set to zero */ 713951c6300SRichard Henderson void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg) 714951c6300SRichard Henderson { 715951c6300SRichard Henderson if (TCG_TARGET_HAS_bswap16_i32) { 716951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg); 717951c6300SRichard Henderson } else { 718951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 719951c6300SRichard Henderson 720951c6300SRichard Henderson tcg_gen_ext8u_i32(t0, arg); 721951c6300SRichard Henderson tcg_gen_shli_i32(t0, t0, 8); 722951c6300SRichard Henderson tcg_gen_shri_i32(ret, arg, 8); 723951c6300SRichard Henderson tcg_gen_or_i32(ret, ret, t0); 724951c6300SRichard Henderson tcg_temp_free_i32(t0); 725951c6300SRichard Henderson } 726951c6300SRichard Henderson } 727951c6300SRichard Henderson 728951c6300SRichard Henderson void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg) 729951c6300SRichard Henderson { 730951c6300SRichard Henderson if (TCG_TARGET_HAS_bswap32_i32) { 731951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg); 732951c6300SRichard Henderson } else { 733951c6300SRichard Henderson TCGv_i32 t0, t1; 734951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 735951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 736951c6300SRichard Henderson 737951c6300SRichard Henderson tcg_gen_shli_i32(t0, arg, 24); 738951c6300SRichard Henderson 739951c6300SRichard Henderson tcg_gen_andi_i32(t1, arg, 0x0000ff00); 740951c6300SRichard Henderson tcg_gen_shli_i32(t1, t1, 8); 741951c6300SRichard Henderson tcg_gen_or_i32(t0, t0, t1); 742951c6300SRichard Henderson 743951c6300SRichard Henderson tcg_gen_shri_i32(t1, arg, 8); 744951c6300SRichard Henderson tcg_gen_andi_i32(t1, t1, 0x0000ff00); 745951c6300SRichard Henderson tcg_gen_or_i32(t0, t0, t1); 746951c6300SRichard Henderson 747951c6300SRichard Henderson tcg_gen_shri_i32(t1, arg, 24); 748951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1); 749951c6300SRichard Henderson tcg_temp_free_i32(t0); 750951c6300SRichard Henderson tcg_temp_free_i32(t1); 751951c6300SRichard Henderson } 752951c6300SRichard Henderson } 753951c6300SRichard Henderson 754951c6300SRichard Henderson /* 64-bit ops */ 755951c6300SRichard Henderson 756951c6300SRichard Henderson #if TCG_TARGET_REG_BITS == 32 757951c6300SRichard Henderson /* These are all inline for TCG_TARGET_REG_BITS == 64. */ 758951c6300SRichard Henderson 759951c6300SRichard Henderson void tcg_gen_discard_i64(TCGv_i64 arg) 760951c6300SRichard Henderson { 761951c6300SRichard Henderson tcg_gen_discard_i32(TCGV_LOW(arg)); 762951c6300SRichard Henderson tcg_gen_discard_i32(TCGV_HIGH(arg)); 763951c6300SRichard Henderson } 764951c6300SRichard Henderson 765951c6300SRichard Henderson void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg) 766951c6300SRichard Henderson { 767951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 768951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 769951c6300SRichard Henderson } 770951c6300SRichard Henderson 771951c6300SRichard Henderson void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg) 772951c6300SRichard Henderson { 773951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_LOW(ret), arg); 774951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32); 775951c6300SRichard Henderson } 776951c6300SRichard Henderson 777951c6300SRichard Henderson void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 778951c6300SRichard Henderson { 779951c6300SRichard Henderson tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset); 780951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 781951c6300SRichard Henderson } 782951c6300SRichard Henderson 783951c6300SRichard Henderson void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 784951c6300SRichard Henderson { 785951c6300SRichard Henderson tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset); 786951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), 31); 787951c6300SRichard Henderson } 788951c6300SRichard Henderson 789951c6300SRichard Henderson void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 790951c6300SRichard Henderson { 791951c6300SRichard Henderson tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset); 792951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 793951c6300SRichard Henderson } 794951c6300SRichard Henderson 795951c6300SRichard Henderson void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 796951c6300SRichard Henderson { 797951c6300SRichard Henderson tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset); 798951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 799951c6300SRichard Henderson } 800951c6300SRichard Henderson 801951c6300SRichard Henderson void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 802951c6300SRichard Henderson { 803951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 804951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 805951c6300SRichard Henderson } 806951c6300SRichard Henderson 807951c6300SRichard Henderson void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 808951c6300SRichard Henderson { 809951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 810951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 811951c6300SRichard Henderson } 812951c6300SRichard Henderson 813951c6300SRichard Henderson void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) 814951c6300SRichard Henderson { 815951c6300SRichard Henderson /* Since arg2 and ret have different types, 816951c6300SRichard Henderson they cannot be the same temporary */ 817cf811fffSPeter Maydell #ifdef HOST_WORDS_BIGENDIAN 818951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset); 819951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4); 820951c6300SRichard Henderson #else 821951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset); 822951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4); 823951c6300SRichard Henderson #endif 824951c6300SRichard Henderson } 825951c6300SRichard Henderson 826951c6300SRichard Henderson void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) 827951c6300SRichard Henderson { 828cf811fffSPeter Maydell #ifdef HOST_WORDS_BIGENDIAN 829951c6300SRichard Henderson tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset); 830951c6300SRichard Henderson tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4); 831951c6300SRichard Henderson #else 832951c6300SRichard Henderson tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset); 833951c6300SRichard Henderson tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4); 834951c6300SRichard Henderson #endif 835951c6300SRichard Henderson } 836951c6300SRichard Henderson 837951c6300SRichard Henderson void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 838951c6300SRichard Henderson { 839951c6300SRichard Henderson tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 840951c6300SRichard Henderson tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 841951c6300SRichard Henderson } 842951c6300SRichard Henderson 843951c6300SRichard Henderson void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 844951c6300SRichard Henderson { 845951c6300SRichard Henderson tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 846951c6300SRichard Henderson tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 847951c6300SRichard Henderson } 848951c6300SRichard Henderson 849951c6300SRichard Henderson void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 850951c6300SRichard Henderson { 851951c6300SRichard Henderson tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 852951c6300SRichard Henderson tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 853951c6300SRichard Henderson } 854951c6300SRichard Henderson 855951c6300SRichard Henderson void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 856951c6300SRichard Henderson { 857951c6300SRichard Henderson gen_helper_shl_i64(ret, arg1, arg2); 858951c6300SRichard Henderson } 859951c6300SRichard Henderson 860951c6300SRichard Henderson void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 861951c6300SRichard Henderson { 862951c6300SRichard Henderson gen_helper_shr_i64(ret, arg1, arg2); 863951c6300SRichard Henderson } 864951c6300SRichard Henderson 865951c6300SRichard Henderson void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 866951c6300SRichard Henderson { 867951c6300SRichard Henderson gen_helper_sar_i64(ret, arg1, arg2); 868951c6300SRichard Henderson } 869951c6300SRichard Henderson 870951c6300SRichard Henderson void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 871951c6300SRichard Henderson { 872951c6300SRichard Henderson TCGv_i64 t0; 873951c6300SRichard Henderson TCGv_i32 t1; 874951c6300SRichard Henderson 875951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 876951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 877951c6300SRichard Henderson 878951c6300SRichard Henderson tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0), 879951c6300SRichard Henderson TCGV_LOW(arg1), TCGV_LOW(arg2)); 880951c6300SRichard Henderson 881951c6300SRichard Henderson tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2)); 882951c6300SRichard Henderson tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 883951c6300SRichard Henderson tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2)); 884951c6300SRichard Henderson tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); 885951c6300SRichard Henderson 886951c6300SRichard Henderson tcg_gen_mov_i64(ret, t0); 887951c6300SRichard Henderson tcg_temp_free_i64(t0); 888951c6300SRichard Henderson tcg_temp_free_i32(t1); 889951c6300SRichard Henderson } 890951c6300SRichard Henderson #endif /* TCG_TARGET_REG_SIZE == 32 */ 891951c6300SRichard Henderson 892951c6300SRichard Henderson void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 893951c6300SRichard Henderson { 894951c6300SRichard Henderson /* some cases can be optimized here */ 895951c6300SRichard Henderson if (arg2 == 0) { 896951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 897951c6300SRichard Henderson } else { 898951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 899951c6300SRichard Henderson tcg_gen_add_i64(ret, arg1, t0); 900951c6300SRichard Henderson tcg_temp_free_i64(t0); 901951c6300SRichard Henderson } 902951c6300SRichard Henderson } 903951c6300SRichard Henderson 904951c6300SRichard Henderson void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2) 905951c6300SRichard Henderson { 906951c6300SRichard Henderson if (arg1 == 0 && TCG_TARGET_HAS_neg_i64) { 907951c6300SRichard Henderson /* Don't recurse with tcg_gen_neg_i64. */ 908951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg2); 909951c6300SRichard Henderson } else { 910951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg1); 911951c6300SRichard Henderson tcg_gen_sub_i64(ret, t0, arg2); 912951c6300SRichard Henderson tcg_temp_free_i64(t0); 913951c6300SRichard Henderson } 914951c6300SRichard Henderson } 915951c6300SRichard Henderson 916951c6300SRichard Henderson void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 917951c6300SRichard Henderson { 918951c6300SRichard Henderson /* some cases can be optimized here */ 919951c6300SRichard Henderson if (arg2 == 0) { 920951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 921951c6300SRichard Henderson } else { 922951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 923951c6300SRichard Henderson tcg_gen_sub_i64(ret, arg1, t0); 924951c6300SRichard Henderson tcg_temp_free_i64(t0); 925951c6300SRichard Henderson } 926951c6300SRichard Henderson } 927951c6300SRichard Henderson 928951c6300SRichard Henderson void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2) 929951c6300SRichard Henderson { 9303a13c3f3SRichard Henderson TCGv_i64 t0; 9313a13c3f3SRichard Henderson 9323a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 933951c6300SRichard Henderson tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 934951c6300SRichard Henderson tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 9353a13c3f3SRichard Henderson return; 9363a13c3f3SRichard Henderson } 9373a13c3f3SRichard Henderson 938951c6300SRichard Henderson /* Some cases can be optimized here. */ 939951c6300SRichard Henderson switch (arg2) { 940951c6300SRichard Henderson case 0: 941951c6300SRichard Henderson tcg_gen_movi_i64(ret, 0); 942951c6300SRichard Henderson return; 943951c6300SRichard Henderson case 0xffffffffffffffffull: 944951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 945951c6300SRichard Henderson return; 946951c6300SRichard Henderson case 0xffull: 947951c6300SRichard Henderson /* Don't recurse with tcg_gen_ext8u_i64. */ 948951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8u_i64) { 949951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1); 950951c6300SRichard Henderson return; 951951c6300SRichard Henderson } 952951c6300SRichard Henderson break; 953951c6300SRichard Henderson case 0xffffu: 954951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16u_i64) { 955951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1); 956951c6300SRichard Henderson return; 957951c6300SRichard Henderson } 958951c6300SRichard Henderson break; 959951c6300SRichard Henderson case 0xffffffffull: 960951c6300SRichard Henderson if (TCG_TARGET_HAS_ext32u_i64) { 961951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1); 962951c6300SRichard Henderson return; 963951c6300SRichard Henderson } 964951c6300SRichard Henderson break; 965951c6300SRichard Henderson } 966951c6300SRichard Henderson t0 = tcg_const_i64(arg2); 967951c6300SRichard Henderson tcg_gen_and_i64(ret, arg1, t0); 968951c6300SRichard Henderson tcg_temp_free_i64(t0); 969951c6300SRichard Henderson } 970951c6300SRichard Henderson 971951c6300SRichard Henderson void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 972951c6300SRichard Henderson { 9733a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 974951c6300SRichard Henderson tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 975951c6300SRichard Henderson tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 9763a13c3f3SRichard Henderson return; 9773a13c3f3SRichard Henderson } 978951c6300SRichard Henderson /* Some cases can be optimized here. */ 979951c6300SRichard Henderson if (arg2 == -1) { 980951c6300SRichard Henderson tcg_gen_movi_i64(ret, -1); 981951c6300SRichard Henderson } else if (arg2 == 0) { 982951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 983951c6300SRichard Henderson } else { 984951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 985951c6300SRichard Henderson tcg_gen_or_i64(ret, arg1, t0); 986951c6300SRichard Henderson tcg_temp_free_i64(t0); 987951c6300SRichard Henderson } 988951c6300SRichard Henderson } 989951c6300SRichard Henderson 990951c6300SRichard Henderson void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 991951c6300SRichard Henderson { 9923a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 993951c6300SRichard Henderson tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); 994951c6300SRichard Henderson tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); 9953a13c3f3SRichard Henderson return; 9963a13c3f3SRichard Henderson } 997951c6300SRichard Henderson /* Some cases can be optimized here. */ 998951c6300SRichard Henderson if (arg2 == 0) { 999951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1000951c6300SRichard Henderson } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) { 1001951c6300SRichard Henderson /* Don't recurse with tcg_gen_not_i64. */ 1002951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1); 1003951c6300SRichard Henderson } else { 1004951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1005951c6300SRichard Henderson tcg_gen_xor_i64(ret, arg1, t0); 1006951c6300SRichard Henderson tcg_temp_free_i64(t0); 1007951c6300SRichard Henderson } 1008951c6300SRichard Henderson } 1009951c6300SRichard Henderson 1010951c6300SRichard Henderson static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, 1011951c6300SRichard Henderson unsigned c, bool right, bool arith) 1012951c6300SRichard Henderson { 1013951c6300SRichard Henderson tcg_debug_assert(c < 64); 1014951c6300SRichard Henderson if (c == 0) { 1015951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 1016951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 1017951c6300SRichard Henderson } else if (c >= 32) { 1018951c6300SRichard Henderson c -= 32; 1019951c6300SRichard Henderson if (right) { 1020951c6300SRichard Henderson if (arith) { 1021951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1022951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31); 1023951c6300SRichard Henderson } else { 1024951c6300SRichard Henderson tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 1025951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 1026951c6300SRichard Henderson } 1027951c6300SRichard Henderson } else { 1028951c6300SRichard Henderson tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c); 1029951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_LOW(ret), 0); 1030951c6300SRichard Henderson } 1031951c6300SRichard Henderson } else { 1032951c6300SRichard Henderson TCGv_i32 t0, t1; 1033951c6300SRichard Henderson 1034951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 1035951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 1036951c6300SRichard Henderson if (right) { 1037951c6300SRichard Henderson tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c); 1038951c6300SRichard Henderson if (arith) { 1039951c6300SRichard Henderson tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c); 1040951c6300SRichard Henderson } else { 1041951c6300SRichard Henderson tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c); 1042951c6300SRichard Henderson } 1043951c6300SRichard Henderson tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c); 1044951c6300SRichard Henderson tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0); 1045951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), t1); 1046951c6300SRichard Henderson } else { 1047951c6300SRichard Henderson tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c); 1048951c6300SRichard Henderson /* Note: ret can be the same as arg1, so we use t1 */ 1049951c6300SRichard Henderson tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c); 1050951c6300SRichard Henderson tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c); 1051951c6300SRichard Henderson tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0); 1052951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), t1); 1053951c6300SRichard Henderson } 1054951c6300SRichard Henderson tcg_temp_free_i32(t0); 1055951c6300SRichard Henderson tcg_temp_free_i32(t1); 1056951c6300SRichard Henderson } 1057951c6300SRichard Henderson } 1058951c6300SRichard Henderson 1059951c6300SRichard Henderson void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1060951c6300SRichard Henderson { 1061951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 10623a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 10633a13c3f3SRichard Henderson tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0); 10643a13c3f3SRichard Henderson } else if (arg2 == 0) { 1065951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1066951c6300SRichard Henderson } else { 1067951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1068951c6300SRichard Henderson tcg_gen_shl_i64(ret, arg1, t0); 1069951c6300SRichard Henderson tcg_temp_free_i64(t0); 1070951c6300SRichard Henderson } 1071951c6300SRichard Henderson } 1072951c6300SRichard Henderson 1073951c6300SRichard Henderson void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1074951c6300SRichard Henderson { 1075951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 10763a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 10773a13c3f3SRichard Henderson tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0); 10783a13c3f3SRichard Henderson } else if (arg2 == 0) { 1079951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1080951c6300SRichard Henderson } else { 1081951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1082951c6300SRichard Henderson tcg_gen_shr_i64(ret, arg1, t0); 1083951c6300SRichard Henderson tcg_temp_free_i64(t0); 1084951c6300SRichard Henderson } 1085951c6300SRichard Henderson } 1086951c6300SRichard Henderson 1087951c6300SRichard Henderson void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1088951c6300SRichard Henderson { 1089951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 10903a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 10913a13c3f3SRichard Henderson tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1); 10923a13c3f3SRichard Henderson } else if (arg2 == 0) { 1093951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1094951c6300SRichard Henderson } else { 1095951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1096951c6300SRichard Henderson tcg_gen_sar_i64(ret, arg1, t0); 1097951c6300SRichard Henderson tcg_temp_free_i64(t0); 1098951c6300SRichard Henderson } 1099951c6300SRichard Henderson } 1100951c6300SRichard Henderson 110142a268c2SRichard Henderson void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l) 1102951c6300SRichard Henderson { 1103951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 110442a268c2SRichard Henderson tcg_gen_br(l); 1105951c6300SRichard Henderson } else if (cond != TCG_COND_NEVER) { 11063a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1107951c6300SRichard Henderson tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1), 1108951c6300SRichard Henderson TCGV_HIGH(arg1), TCGV_LOW(arg2), 110942a268c2SRichard Henderson TCGV_HIGH(arg2), cond, label_arg(l)); 11103a13c3f3SRichard Henderson } else { 111142a268c2SRichard Henderson tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, 111242a268c2SRichard Henderson label_arg(l)); 11133a13c3f3SRichard Henderson } 1114951c6300SRichard Henderson } 1115951c6300SRichard Henderson } 1116951c6300SRichard Henderson 111742a268c2SRichard Henderson void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l) 1118951c6300SRichard Henderson { 1119951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 112042a268c2SRichard Henderson tcg_gen_br(l); 1121951c6300SRichard Henderson } else if (cond != TCG_COND_NEVER) { 1122951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 112342a268c2SRichard Henderson tcg_gen_brcond_i64(cond, arg1, t0, l); 1124951c6300SRichard Henderson tcg_temp_free_i64(t0); 1125951c6300SRichard Henderson } 1126951c6300SRichard Henderson } 1127951c6300SRichard Henderson 1128951c6300SRichard Henderson void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret, 1129951c6300SRichard Henderson TCGv_i64 arg1, TCGv_i64 arg2) 1130951c6300SRichard Henderson { 1131951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) { 1132951c6300SRichard Henderson tcg_gen_movi_i64(ret, 1); 1133951c6300SRichard Henderson } else if (cond == TCG_COND_NEVER) { 1134951c6300SRichard Henderson tcg_gen_movi_i64(ret, 0); 1135951c6300SRichard Henderson } else { 11363a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1137951c6300SRichard Henderson tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), 1138951c6300SRichard Henderson TCGV_LOW(arg1), TCGV_HIGH(arg1), 1139951c6300SRichard Henderson TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); 1140951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 11413a13c3f3SRichard Henderson } else { 1142951c6300SRichard Henderson tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond); 11433a13c3f3SRichard Henderson } 1144951c6300SRichard Henderson } 1145951c6300SRichard Henderson } 1146951c6300SRichard Henderson 1147951c6300SRichard Henderson void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret, 1148951c6300SRichard Henderson TCGv_i64 arg1, int64_t arg2) 1149951c6300SRichard Henderson { 1150951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1151951c6300SRichard Henderson tcg_gen_setcond_i64(cond, ret, arg1, t0); 1152951c6300SRichard Henderson tcg_temp_free_i64(t0); 1153951c6300SRichard Henderson } 1154951c6300SRichard Henderson 1155951c6300SRichard Henderson void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) 1156951c6300SRichard Henderson { 1157951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1158951c6300SRichard Henderson tcg_gen_mul_i64(ret, arg1, t0); 1159951c6300SRichard Henderson tcg_temp_free_i64(t0); 1160951c6300SRichard Henderson } 1161951c6300SRichard Henderson 1162951c6300SRichard Henderson void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1163951c6300SRichard Henderson { 1164951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i64) { 1165951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2); 1166951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) { 1167951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1168951c6300SRichard Henderson tcg_gen_sari_i64(t0, arg1, 63); 1169951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2); 1170951c6300SRichard Henderson tcg_temp_free_i64(t0); 1171951c6300SRichard Henderson } else { 1172951c6300SRichard Henderson gen_helper_div_i64(ret, arg1, arg2); 1173951c6300SRichard Henderson } 1174951c6300SRichard Henderson } 1175951c6300SRichard Henderson 1176951c6300SRichard Henderson void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1177951c6300SRichard Henderson { 1178951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i64) { 1179951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2); 1180951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i64) { 1181951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1182951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2); 1183951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, arg2); 1184951c6300SRichard Henderson tcg_gen_sub_i64(ret, arg1, t0); 1185951c6300SRichard Henderson tcg_temp_free_i64(t0); 1186951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) { 1187951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1188951c6300SRichard Henderson tcg_gen_sari_i64(t0, arg1, 63); 1189951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2); 1190951c6300SRichard Henderson tcg_temp_free_i64(t0); 1191951c6300SRichard Henderson } else { 1192951c6300SRichard Henderson gen_helper_rem_i64(ret, arg1, arg2); 1193951c6300SRichard Henderson } 1194951c6300SRichard Henderson } 1195951c6300SRichard Henderson 1196951c6300SRichard Henderson void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1197951c6300SRichard Henderson { 1198951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i64) { 1199951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2); 1200951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) { 1201951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1202951c6300SRichard Henderson tcg_gen_movi_i64(t0, 0); 1203951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2); 1204951c6300SRichard Henderson tcg_temp_free_i64(t0); 1205951c6300SRichard Henderson } else { 1206951c6300SRichard Henderson gen_helper_divu_i64(ret, arg1, arg2); 1207951c6300SRichard Henderson } 1208951c6300SRichard Henderson } 1209951c6300SRichard Henderson 1210951c6300SRichard Henderson void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1211951c6300SRichard Henderson { 1212951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i64) { 1213951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2); 1214951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i64) { 1215951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1216951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2); 1217951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, arg2); 1218951c6300SRichard Henderson tcg_gen_sub_i64(ret, arg1, t0); 1219951c6300SRichard Henderson tcg_temp_free_i64(t0); 1220951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) { 1221951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1222951c6300SRichard Henderson tcg_gen_movi_i64(t0, 0); 1223951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2); 1224951c6300SRichard Henderson tcg_temp_free_i64(t0); 1225951c6300SRichard Henderson } else { 1226951c6300SRichard Henderson gen_helper_remu_i64(ret, arg1, arg2); 1227951c6300SRichard Henderson } 1228951c6300SRichard Henderson } 1229951c6300SRichard Henderson 1230951c6300SRichard Henderson void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg) 1231951c6300SRichard Henderson { 12323a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1233951c6300SRichard Henderson tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1234951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 12353a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext8s_i64) { 1236951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg); 1237951c6300SRichard Henderson } else { 1238951c6300SRichard Henderson tcg_gen_shli_i64(ret, arg, 56); 1239951c6300SRichard Henderson tcg_gen_sari_i64(ret, ret, 56); 1240951c6300SRichard Henderson } 1241951c6300SRichard Henderson } 1242951c6300SRichard Henderson 1243951c6300SRichard Henderson void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg) 1244951c6300SRichard Henderson { 12453a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1246951c6300SRichard Henderson tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1247951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 12483a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext16s_i64) { 1249951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg); 1250951c6300SRichard Henderson } else { 1251951c6300SRichard Henderson tcg_gen_shli_i64(ret, arg, 48); 1252951c6300SRichard Henderson tcg_gen_sari_i64(ret, ret, 48); 1253951c6300SRichard Henderson } 1254951c6300SRichard Henderson } 1255951c6300SRichard Henderson 1256951c6300SRichard Henderson void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg) 1257951c6300SRichard Henderson { 12583a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1259951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1260951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 12613a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext32s_i64) { 1262951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg); 1263951c6300SRichard Henderson } else { 1264951c6300SRichard Henderson tcg_gen_shli_i64(ret, arg, 32); 1265951c6300SRichard Henderson tcg_gen_sari_i64(ret, ret, 32); 1266951c6300SRichard Henderson } 1267951c6300SRichard Henderson } 1268951c6300SRichard Henderson 1269951c6300SRichard Henderson void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg) 1270951c6300SRichard Henderson { 12713a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1272951c6300SRichard Henderson tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1273951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 12743a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext8u_i64) { 1275951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg); 1276951c6300SRichard Henderson } else { 1277951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg, 0xffu); 1278951c6300SRichard Henderson } 1279951c6300SRichard Henderson } 1280951c6300SRichard Henderson 1281951c6300SRichard Henderson void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg) 1282951c6300SRichard Henderson { 12833a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1284951c6300SRichard Henderson tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1285951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 12863a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext16u_i64) { 1287951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg); 1288951c6300SRichard Henderson } else { 1289951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg, 0xffffu); 1290951c6300SRichard Henderson } 1291951c6300SRichard Henderson } 1292951c6300SRichard Henderson 1293951c6300SRichard Henderson void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg) 1294951c6300SRichard Henderson { 12953a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1296951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1297951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 12983a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext32u_i64) { 1299951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg); 1300951c6300SRichard Henderson } else { 1301951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg, 0xffffffffu); 1302951c6300SRichard Henderson } 1303951c6300SRichard Henderson } 1304951c6300SRichard Henderson 1305951c6300SRichard Henderson /* Note: we assume the six high bytes are set to zero */ 1306951c6300SRichard Henderson void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg) 1307951c6300SRichard Henderson { 13083a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1309951c6300SRichard Henderson tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1310951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 13113a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_bswap16_i64) { 1312951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg); 1313951c6300SRichard Henderson } else { 1314951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1315951c6300SRichard Henderson 1316951c6300SRichard Henderson tcg_gen_ext8u_i64(t0, arg); 1317951c6300SRichard Henderson tcg_gen_shli_i64(t0, t0, 8); 1318951c6300SRichard Henderson tcg_gen_shri_i64(ret, arg, 8); 1319951c6300SRichard Henderson tcg_gen_or_i64(ret, ret, t0); 1320951c6300SRichard Henderson tcg_temp_free_i64(t0); 1321951c6300SRichard Henderson } 1322951c6300SRichard Henderson } 1323951c6300SRichard Henderson 1324951c6300SRichard Henderson /* Note: we assume the four high bytes are set to zero */ 1325951c6300SRichard Henderson void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg) 1326951c6300SRichard Henderson { 13273a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1328951c6300SRichard Henderson tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 1329951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 13303a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_bswap32_i64) { 1331951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg); 1332951c6300SRichard Henderson } else { 1333951c6300SRichard Henderson TCGv_i64 t0, t1; 1334951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 1335951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1336951c6300SRichard Henderson 1337951c6300SRichard Henderson tcg_gen_shli_i64(t0, arg, 24); 1338951c6300SRichard Henderson tcg_gen_ext32u_i64(t0, t0); 1339951c6300SRichard Henderson 1340951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg, 0x0000ff00); 1341951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, 8); 1342951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1343951c6300SRichard Henderson 1344951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 8); 1345951c6300SRichard Henderson tcg_gen_andi_i64(t1, t1, 0x0000ff00); 1346951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1347951c6300SRichard Henderson 1348951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 24); 1349951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1350951c6300SRichard Henderson tcg_temp_free_i64(t0); 1351951c6300SRichard Henderson tcg_temp_free_i64(t1); 1352951c6300SRichard Henderson } 1353951c6300SRichard Henderson } 1354951c6300SRichard Henderson 1355951c6300SRichard Henderson void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) 1356951c6300SRichard Henderson { 13573a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1358951c6300SRichard Henderson TCGv_i32 t0, t1; 1359951c6300SRichard Henderson t0 = tcg_temp_new_i32(); 1360951c6300SRichard Henderson t1 = tcg_temp_new_i32(); 1361951c6300SRichard Henderson 1362951c6300SRichard Henderson tcg_gen_bswap32_i32(t0, TCGV_LOW(arg)); 1363951c6300SRichard Henderson tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg)); 1364951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), t1); 1365951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), t0); 1366951c6300SRichard Henderson tcg_temp_free_i32(t0); 1367951c6300SRichard Henderson tcg_temp_free_i32(t1); 13683a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_bswap64_i64) { 1369951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg); 1370951c6300SRichard Henderson } else { 1371951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1372951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 1373951c6300SRichard Henderson 1374951c6300SRichard Henderson tcg_gen_shli_i64(t0, arg, 56); 1375951c6300SRichard Henderson 1376951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg, 0x0000ff00); 1377951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, 40); 1378951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1379951c6300SRichard Henderson 1380951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg, 0x00ff0000); 1381951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, 24); 1382951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1383951c6300SRichard Henderson 1384951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg, 0xff000000); 1385951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, 8); 1386951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1387951c6300SRichard Henderson 1388951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 8); 1389951c6300SRichard Henderson tcg_gen_andi_i64(t1, t1, 0xff000000); 1390951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1391951c6300SRichard Henderson 1392951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 24); 1393951c6300SRichard Henderson tcg_gen_andi_i64(t1, t1, 0x00ff0000); 1394951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1395951c6300SRichard Henderson 1396951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 40); 1397951c6300SRichard Henderson tcg_gen_andi_i64(t1, t1, 0x0000ff00); 1398951c6300SRichard Henderson tcg_gen_or_i64(t0, t0, t1); 1399951c6300SRichard Henderson 1400951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg, 56); 1401951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1402951c6300SRichard Henderson tcg_temp_free_i64(t0); 1403951c6300SRichard Henderson tcg_temp_free_i64(t1); 1404951c6300SRichard Henderson } 1405951c6300SRichard Henderson } 1406951c6300SRichard Henderson 1407951c6300SRichard Henderson void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg) 1408951c6300SRichard Henderson { 14093a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 14103a13c3f3SRichard Henderson tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg)); 14113a13c3f3SRichard Henderson tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); 14123a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_not_i64) { 1413951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg); 1414951c6300SRichard Henderson } else { 1415951c6300SRichard Henderson tcg_gen_xori_i64(ret, arg, -1); 1416951c6300SRichard Henderson } 1417951c6300SRichard Henderson } 1418951c6300SRichard Henderson 1419951c6300SRichard Henderson void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1420951c6300SRichard Henderson { 14213a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 14223a13c3f3SRichard Henderson tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 14233a13c3f3SRichard Henderson tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 14243a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_andc_i64) { 1425951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2); 1426951c6300SRichard Henderson } else { 1427951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1428951c6300SRichard Henderson tcg_gen_not_i64(t0, arg2); 1429951c6300SRichard Henderson tcg_gen_and_i64(ret, arg1, t0); 1430951c6300SRichard Henderson tcg_temp_free_i64(t0); 1431951c6300SRichard Henderson } 1432951c6300SRichard Henderson } 1433951c6300SRichard Henderson 1434951c6300SRichard Henderson void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1435951c6300SRichard Henderson { 14363a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 14373a13c3f3SRichard Henderson tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 14383a13c3f3SRichard Henderson tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 14393a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_eqv_i64) { 1440951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2); 1441951c6300SRichard Henderson } else { 1442951c6300SRichard Henderson tcg_gen_xor_i64(ret, arg1, arg2); 1443951c6300SRichard Henderson tcg_gen_not_i64(ret, ret); 1444951c6300SRichard Henderson } 1445951c6300SRichard Henderson } 1446951c6300SRichard Henderson 1447951c6300SRichard Henderson void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1448951c6300SRichard Henderson { 14493a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 14503a13c3f3SRichard Henderson tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 14513a13c3f3SRichard Henderson tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 14523a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_nand_i64) { 1453951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2); 1454951c6300SRichard Henderson } else { 1455951c6300SRichard Henderson tcg_gen_and_i64(ret, arg1, arg2); 1456951c6300SRichard Henderson tcg_gen_not_i64(ret, ret); 1457951c6300SRichard Henderson } 1458951c6300SRichard Henderson } 1459951c6300SRichard Henderson 1460951c6300SRichard Henderson void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1461951c6300SRichard Henderson { 14623a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 14633a13c3f3SRichard Henderson tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 14643a13c3f3SRichard Henderson tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 14653a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_nor_i64) { 1466951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2); 1467951c6300SRichard Henderson } else { 1468951c6300SRichard Henderson tcg_gen_or_i64(ret, arg1, arg2); 1469951c6300SRichard Henderson tcg_gen_not_i64(ret, ret); 1470951c6300SRichard Henderson } 1471951c6300SRichard Henderson } 1472951c6300SRichard Henderson 1473951c6300SRichard Henderson void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1474951c6300SRichard Henderson { 14753a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 14763a13c3f3SRichard Henderson tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); 14773a13c3f3SRichard Henderson tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); 14783a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_orc_i64) { 1479951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2); 1480951c6300SRichard Henderson } else { 1481951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1482951c6300SRichard Henderson tcg_gen_not_i64(t0, arg2); 1483951c6300SRichard Henderson tcg_gen_or_i64(ret, arg1, t0); 1484951c6300SRichard Henderson tcg_temp_free_i64(t0); 1485951c6300SRichard Henderson } 1486951c6300SRichard Henderson } 1487951c6300SRichard Henderson 1488951c6300SRichard Henderson void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1489951c6300SRichard Henderson { 1490951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i64) { 1491951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2); 1492951c6300SRichard Henderson } else { 1493951c6300SRichard Henderson TCGv_i64 t0, t1; 1494951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 1495951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1496951c6300SRichard Henderson tcg_gen_shl_i64(t0, arg1, arg2); 1497951c6300SRichard Henderson tcg_gen_subfi_i64(t1, 64, arg2); 1498951c6300SRichard Henderson tcg_gen_shr_i64(t1, arg1, t1); 1499951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1500951c6300SRichard Henderson tcg_temp_free_i64(t0); 1501951c6300SRichard Henderson tcg_temp_free_i64(t1); 1502951c6300SRichard Henderson } 1503951c6300SRichard Henderson } 1504951c6300SRichard Henderson 1505951c6300SRichard Henderson void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1506951c6300SRichard Henderson { 1507951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 1508951c6300SRichard Henderson /* some cases can be optimized here */ 1509951c6300SRichard Henderson if (arg2 == 0) { 1510951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1511951c6300SRichard Henderson } else if (TCG_TARGET_HAS_rot_i64) { 1512951c6300SRichard Henderson TCGv_i64 t0 = tcg_const_i64(arg2); 1513951c6300SRichard Henderson tcg_gen_rotl_i64(ret, arg1, t0); 1514951c6300SRichard Henderson tcg_temp_free_i64(t0); 1515951c6300SRichard Henderson } else { 1516951c6300SRichard Henderson TCGv_i64 t0, t1; 1517951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 1518951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1519951c6300SRichard Henderson tcg_gen_shli_i64(t0, arg1, arg2); 1520951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg1, 64 - arg2); 1521951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1522951c6300SRichard Henderson tcg_temp_free_i64(t0); 1523951c6300SRichard Henderson tcg_temp_free_i64(t1); 1524951c6300SRichard Henderson } 1525951c6300SRichard Henderson } 1526951c6300SRichard Henderson 1527951c6300SRichard Henderson void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) 1528951c6300SRichard Henderson { 1529951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i64) { 1530951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2); 1531951c6300SRichard Henderson } else { 1532951c6300SRichard Henderson TCGv_i64 t0, t1; 1533951c6300SRichard Henderson t0 = tcg_temp_new_i64(); 1534951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1535951c6300SRichard Henderson tcg_gen_shr_i64(t0, arg1, arg2); 1536951c6300SRichard Henderson tcg_gen_subfi_i64(t1, 64, arg2); 1537951c6300SRichard Henderson tcg_gen_shl_i64(t1, arg1, t1); 1538951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1); 1539951c6300SRichard Henderson tcg_temp_free_i64(t0); 1540951c6300SRichard Henderson tcg_temp_free_i64(t1); 1541951c6300SRichard Henderson } 1542951c6300SRichard Henderson } 1543951c6300SRichard Henderson 1544951c6300SRichard Henderson void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2) 1545951c6300SRichard Henderson { 1546951c6300SRichard Henderson tcg_debug_assert(arg2 < 64); 1547951c6300SRichard Henderson /* some cases can be optimized here */ 1548951c6300SRichard Henderson if (arg2 == 0) { 1549951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1); 1550951c6300SRichard Henderson } else { 1551951c6300SRichard Henderson tcg_gen_rotli_i64(ret, arg1, 64 - arg2); 1552951c6300SRichard Henderson } 1553951c6300SRichard Henderson } 1554951c6300SRichard Henderson 1555951c6300SRichard Henderson void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2, 1556951c6300SRichard Henderson unsigned int ofs, unsigned int len) 1557951c6300SRichard Henderson { 1558951c6300SRichard Henderson uint64_t mask; 1559951c6300SRichard Henderson TCGv_i64 t1; 1560951c6300SRichard Henderson 1561951c6300SRichard Henderson tcg_debug_assert(ofs < 64); 1562951c6300SRichard Henderson tcg_debug_assert(len <= 64); 1563951c6300SRichard Henderson tcg_debug_assert(ofs + len <= 64); 1564951c6300SRichard Henderson 1565951c6300SRichard Henderson if (ofs == 0 && len == 64) { 1566951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg2); 1567951c6300SRichard Henderson return; 1568951c6300SRichard Henderson } 1569951c6300SRichard Henderson if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) { 1570951c6300SRichard Henderson tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len); 1571951c6300SRichard Henderson return; 1572951c6300SRichard Henderson } 1573951c6300SRichard Henderson 15743a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1575951c6300SRichard Henderson if (ofs >= 32) { 1576951c6300SRichard Henderson tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 1577951c6300SRichard Henderson TCGV_LOW(arg2), ofs - 32, len); 1578951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 1579951c6300SRichard Henderson return; 1580951c6300SRichard Henderson } 1581951c6300SRichard Henderson if (ofs + len <= 32) { 1582951c6300SRichard Henderson tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1), 1583951c6300SRichard Henderson TCGV_LOW(arg2), ofs, len); 1584951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 1585951c6300SRichard Henderson return; 1586951c6300SRichard Henderson } 15873a13c3f3SRichard Henderson } 1588951c6300SRichard Henderson 1589951c6300SRichard Henderson mask = (1ull << len) - 1; 1590951c6300SRichard Henderson t1 = tcg_temp_new_i64(); 1591951c6300SRichard Henderson 1592951c6300SRichard Henderson if (ofs + len < 64) { 1593951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg2, mask); 1594951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, ofs); 1595951c6300SRichard Henderson } else { 1596951c6300SRichard Henderson tcg_gen_shli_i64(t1, arg2, ofs); 1597951c6300SRichard Henderson } 1598951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg1, ~(mask << ofs)); 1599951c6300SRichard Henderson tcg_gen_or_i64(ret, ret, t1); 1600951c6300SRichard Henderson 1601951c6300SRichard Henderson tcg_temp_free_i64(t1); 1602951c6300SRichard Henderson } 1603951c6300SRichard Henderson 1604951c6300SRichard Henderson void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1, 1605951c6300SRichard Henderson TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2) 1606951c6300SRichard Henderson { 160737ed3bf1SRichard Henderson if (cond == TCG_COND_ALWAYS) { 160837ed3bf1SRichard Henderson tcg_gen_mov_i64(ret, v1); 160937ed3bf1SRichard Henderson } else if (cond == TCG_COND_NEVER) { 161037ed3bf1SRichard Henderson tcg_gen_mov_i64(ret, v2); 161137ed3bf1SRichard Henderson } else if (TCG_TARGET_REG_BITS == 32) { 1612951c6300SRichard Henderson TCGv_i32 t0 = tcg_temp_new_i32(); 1613951c6300SRichard Henderson TCGv_i32 t1 = tcg_temp_new_i32(); 1614951c6300SRichard Henderson tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0, 1615951c6300SRichard Henderson TCGV_LOW(c1), TCGV_HIGH(c1), 1616951c6300SRichard Henderson TCGV_LOW(c2), TCGV_HIGH(c2), cond); 1617951c6300SRichard Henderson 1618951c6300SRichard Henderson if (TCG_TARGET_HAS_movcond_i32) { 1619951c6300SRichard Henderson tcg_gen_movi_i32(t1, 0); 1620951c6300SRichard Henderson tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, t1, 1621951c6300SRichard Henderson TCGV_LOW(v1), TCGV_LOW(v2)); 1622951c6300SRichard Henderson tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, t1, 1623951c6300SRichard Henderson TCGV_HIGH(v1), TCGV_HIGH(v2)); 1624951c6300SRichard Henderson } else { 1625951c6300SRichard Henderson tcg_gen_neg_i32(t0, t0); 1626951c6300SRichard Henderson 1627951c6300SRichard Henderson tcg_gen_and_i32(t1, TCGV_LOW(v1), t0); 1628951c6300SRichard Henderson tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0); 1629951c6300SRichard Henderson tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1); 1630951c6300SRichard Henderson 1631951c6300SRichard Henderson tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0); 1632951c6300SRichard Henderson tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0); 1633951c6300SRichard Henderson tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1); 1634951c6300SRichard Henderson } 1635951c6300SRichard Henderson tcg_temp_free_i32(t0); 1636951c6300SRichard Henderson tcg_temp_free_i32(t1); 16373a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_movcond_i64) { 1638951c6300SRichard Henderson tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond); 1639951c6300SRichard Henderson } else { 1640951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1641951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 1642951c6300SRichard Henderson tcg_gen_setcond_i64(cond, t0, c1, c2); 1643951c6300SRichard Henderson tcg_gen_neg_i64(t0, t0); 1644951c6300SRichard Henderson tcg_gen_and_i64(t1, v1, t0); 1645951c6300SRichard Henderson tcg_gen_andc_i64(ret, v2, t0); 1646951c6300SRichard Henderson tcg_gen_or_i64(ret, ret, t1); 1647951c6300SRichard Henderson tcg_temp_free_i64(t0); 1648951c6300SRichard Henderson tcg_temp_free_i64(t1); 1649951c6300SRichard Henderson } 1650951c6300SRichard Henderson } 1651951c6300SRichard Henderson 1652951c6300SRichard Henderson void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 1653951c6300SRichard Henderson TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 1654951c6300SRichard Henderson { 1655951c6300SRichard Henderson if (TCG_TARGET_HAS_add2_i64) { 1656951c6300SRichard Henderson tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh); 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_add_i64(t0, al, bl); 1661951c6300SRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al); 1662951c6300SRichard Henderson tcg_gen_add_i64(rh, ah, bh); 1663951c6300SRichard Henderson tcg_gen_add_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_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, 1671951c6300SRichard Henderson TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh) 1672951c6300SRichard Henderson { 1673951c6300SRichard Henderson if (TCG_TARGET_HAS_sub2_i64) { 1674951c6300SRichard Henderson tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh); 1675951c6300SRichard Henderson } else { 1676951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1677951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 1678951c6300SRichard Henderson tcg_gen_sub_i64(t0, al, bl); 1679951c6300SRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl); 1680951c6300SRichard Henderson tcg_gen_sub_i64(rh, ah, bh); 1681951c6300SRichard Henderson tcg_gen_sub_i64(rh, rh, t1); 1682951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0); 1683951c6300SRichard Henderson tcg_temp_free_i64(t0); 1684951c6300SRichard Henderson tcg_temp_free_i64(t1); 1685951c6300SRichard Henderson } 1686951c6300SRichard Henderson } 1687951c6300SRichard Henderson 1688951c6300SRichard Henderson void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 1689951c6300SRichard Henderson { 1690951c6300SRichard Henderson if (TCG_TARGET_HAS_mulu2_i64) { 1691951c6300SRichard Henderson tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2); 1692951c6300SRichard Henderson } else if (TCG_TARGET_HAS_muluh_i64) { 1693951c6300SRichard Henderson TCGv_i64 t = tcg_temp_new_i64(); 1694951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); 1695951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2); 1696951c6300SRichard Henderson tcg_gen_mov_i64(rl, t); 1697951c6300SRichard Henderson tcg_temp_free_i64(t); 1698951c6300SRichard Henderson } else { 1699951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1700951c6300SRichard Henderson tcg_gen_mul_i64(t0, arg1, arg2); 1701951c6300SRichard Henderson gen_helper_muluh_i64(rh, arg1, arg2); 1702951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0); 1703951c6300SRichard Henderson tcg_temp_free_i64(t0); 1704951c6300SRichard Henderson } 1705951c6300SRichard Henderson } 1706951c6300SRichard Henderson 1707951c6300SRichard Henderson void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) 1708951c6300SRichard Henderson { 1709951c6300SRichard Henderson if (TCG_TARGET_HAS_muls2_i64) { 1710951c6300SRichard Henderson tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2); 1711951c6300SRichard Henderson } else if (TCG_TARGET_HAS_mulsh_i64) { 1712951c6300SRichard Henderson TCGv_i64 t = tcg_temp_new_i64(); 1713951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2); 1714951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2); 1715951c6300SRichard Henderson tcg_gen_mov_i64(rl, t); 1716951c6300SRichard Henderson tcg_temp_free_i64(t); 1717951c6300SRichard Henderson } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) { 1718951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1719951c6300SRichard Henderson TCGv_i64 t1 = tcg_temp_new_i64(); 1720951c6300SRichard Henderson TCGv_i64 t2 = tcg_temp_new_i64(); 1721951c6300SRichard Henderson TCGv_i64 t3 = tcg_temp_new_i64(); 1722951c6300SRichard Henderson tcg_gen_mulu2_i64(t0, t1, arg1, arg2); 1723951c6300SRichard Henderson /* Adjust for negative inputs. */ 1724951c6300SRichard Henderson tcg_gen_sari_i64(t2, arg1, 63); 1725951c6300SRichard Henderson tcg_gen_sari_i64(t3, arg2, 63); 1726951c6300SRichard Henderson tcg_gen_and_i64(t2, t2, arg2); 1727951c6300SRichard Henderson tcg_gen_and_i64(t3, t3, arg1); 1728951c6300SRichard Henderson tcg_gen_sub_i64(rh, t1, t2); 1729951c6300SRichard Henderson tcg_gen_sub_i64(rh, rh, t3); 1730951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0); 1731951c6300SRichard Henderson tcg_temp_free_i64(t0); 1732951c6300SRichard Henderson tcg_temp_free_i64(t1); 1733951c6300SRichard Henderson tcg_temp_free_i64(t2); 1734951c6300SRichard Henderson tcg_temp_free_i64(t3); 1735951c6300SRichard Henderson } else { 1736951c6300SRichard Henderson TCGv_i64 t0 = tcg_temp_new_i64(); 1737951c6300SRichard Henderson tcg_gen_mul_i64(t0, arg1, arg2); 1738951c6300SRichard Henderson gen_helper_mulsh_i64(rh, arg1, arg2); 1739951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0); 1740951c6300SRichard Henderson tcg_temp_free_i64(t0); 1741951c6300SRichard Henderson } 1742951c6300SRichard Henderson } 1743951c6300SRichard Henderson 1744951c6300SRichard Henderson /* Size changing operations. */ 1745951c6300SRichard Henderson 1746609ad705SRichard Henderson void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg) 1747951c6300SRichard Henderson { 17483a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1749951c6300SRichard Henderson tcg_gen_mov_i32(ret, TCGV_LOW(arg)); 1750609ad705SRichard Henderson } else if (TCG_TARGET_HAS_extrl_i64_i32) { 1751609ad705SRichard Henderson tcg_gen_op2(&tcg_ctx, INDEX_op_extrl_i64_i32, 1752609ad705SRichard Henderson GET_TCGV_I32(ret), GET_TCGV_I64(arg)); 1753951c6300SRichard Henderson } else { 1754951c6300SRichard Henderson tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(arg))); 1755609ad705SRichard Henderson } 1756609ad705SRichard Henderson } 1757609ad705SRichard Henderson 1758609ad705SRichard Henderson void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg) 1759609ad705SRichard Henderson { 1760609ad705SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1761609ad705SRichard Henderson tcg_gen_mov_i32(ret, TCGV_HIGH(arg)); 1762609ad705SRichard Henderson } else if (TCG_TARGET_HAS_extrh_i64_i32) { 1763609ad705SRichard Henderson tcg_gen_op2(&tcg_ctx, INDEX_op_extrh_i64_i32, 1764609ad705SRichard Henderson GET_TCGV_I32(ret), GET_TCGV_I64(arg)); 1765951c6300SRichard Henderson } else { 1766951c6300SRichard Henderson TCGv_i64 t = tcg_temp_new_i64(); 1767609ad705SRichard Henderson tcg_gen_shri_i64(t, arg, 32); 1768951c6300SRichard Henderson tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(t))); 1769951c6300SRichard Henderson tcg_temp_free_i64(t); 1770951c6300SRichard Henderson } 1771951c6300SRichard Henderson } 1772951c6300SRichard Henderson 1773951c6300SRichard Henderson void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 1774951c6300SRichard Henderson { 17753a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1776951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), arg); 1777951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 17783a13c3f3SRichard Henderson } else { 17794f2331e5SAurelien Jarno tcg_gen_op2(&tcg_ctx, INDEX_op_extu_i32_i64, 17804f2331e5SAurelien Jarno GET_TCGV_I64(ret), GET_TCGV_I32(arg)); 17813a13c3f3SRichard Henderson } 1782951c6300SRichard Henderson } 1783951c6300SRichard Henderson 1784951c6300SRichard Henderson void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg) 1785951c6300SRichard Henderson { 17863a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1787951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), arg); 1788951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); 17893a13c3f3SRichard Henderson } else { 17904f2331e5SAurelien Jarno tcg_gen_op2(&tcg_ctx, INDEX_op_ext_i32_i64, 17914f2331e5SAurelien Jarno GET_TCGV_I64(ret), GET_TCGV_I32(arg)); 17923a13c3f3SRichard Henderson } 1793951c6300SRichard Henderson } 1794951c6300SRichard Henderson 1795951c6300SRichard Henderson void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high) 1796951c6300SRichard Henderson { 17973a13c3f3SRichard Henderson TCGv_i64 tmp; 17983a13c3f3SRichard Henderson 17993a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1800951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(dest), low); 1801951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(dest), high); 18023a13c3f3SRichard Henderson return; 18033a13c3f3SRichard Henderson } 18043a13c3f3SRichard Henderson 18053a13c3f3SRichard Henderson tmp = tcg_temp_new_i64(); 1806951c6300SRichard Henderson /* These extensions are only needed for type correctness. 1807951c6300SRichard Henderson We may be able to do better given target specific information. */ 1808951c6300SRichard Henderson tcg_gen_extu_i32_i64(tmp, high); 1809951c6300SRichard Henderson tcg_gen_extu_i32_i64(dest, low); 1810951c6300SRichard Henderson /* If deposit is available, use it. Otherwise use the extra 1811951c6300SRichard Henderson knowledge that we have of the zero-extensions above. */ 1812951c6300SRichard Henderson if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) { 1813951c6300SRichard Henderson tcg_gen_deposit_i64(dest, dest, tmp, 32, 32); 1814951c6300SRichard Henderson } else { 1815951c6300SRichard Henderson tcg_gen_shli_i64(tmp, tmp, 32); 1816951c6300SRichard Henderson tcg_gen_or_i64(dest, dest, tmp); 1817951c6300SRichard Henderson } 1818951c6300SRichard Henderson tcg_temp_free_i64(tmp); 1819951c6300SRichard Henderson } 1820951c6300SRichard Henderson 1821951c6300SRichard Henderson void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg) 1822951c6300SRichard Henderson { 18233a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 1824951c6300SRichard Henderson tcg_gen_mov_i32(lo, TCGV_LOW(arg)); 1825951c6300SRichard Henderson tcg_gen_mov_i32(hi, TCGV_HIGH(arg)); 18263a13c3f3SRichard Henderson } else { 1827609ad705SRichard Henderson tcg_gen_extrl_i64_i32(lo, arg); 1828609ad705SRichard Henderson tcg_gen_extrh_i64_i32(hi, arg); 18293a13c3f3SRichard Henderson } 1830951c6300SRichard Henderson } 1831951c6300SRichard Henderson 1832951c6300SRichard Henderson void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg) 1833951c6300SRichard Henderson { 1834951c6300SRichard Henderson tcg_gen_ext32u_i64(lo, arg); 1835951c6300SRichard Henderson tcg_gen_shri_i64(hi, arg, 32); 1836951c6300SRichard Henderson } 1837951c6300SRichard Henderson 1838951c6300SRichard Henderson /* QEMU specific operations. */ 1839951c6300SRichard Henderson 1840951c6300SRichard Henderson void tcg_gen_goto_tb(unsigned idx) 1841951c6300SRichard Henderson { 1842951c6300SRichard Henderson /* We only support two chained exits. */ 1843951c6300SRichard Henderson tcg_debug_assert(idx <= 1); 1844951c6300SRichard Henderson #ifdef CONFIG_DEBUG_TCG 1845951c6300SRichard Henderson /* Verify that we havn't seen this numbered exit before. */ 1846951c6300SRichard Henderson tcg_debug_assert((tcg_ctx.goto_tb_issue_mask & (1 << idx)) == 0); 1847951c6300SRichard Henderson tcg_ctx.goto_tb_issue_mask |= 1 << idx; 1848951c6300SRichard Henderson #endif 1849951c6300SRichard Henderson tcg_gen_op1i(INDEX_op_goto_tb, idx); 1850951c6300SRichard Henderson } 1851951c6300SRichard Henderson 1852951c6300SRichard Henderson static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st) 1853951c6300SRichard Henderson { 1854951c6300SRichard Henderson switch (op & MO_SIZE) { 1855951c6300SRichard Henderson case MO_8: 1856951c6300SRichard Henderson op &= ~MO_BSWAP; 1857951c6300SRichard Henderson break; 1858951c6300SRichard Henderson case MO_16: 1859951c6300SRichard Henderson break; 1860951c6300SRichard Henderson case MO_32: 1861951c6300SRichard Henderson if (!is64) { 1862951c6300SRichard Henderson op &= ~MO_SIGN; 1863951c6300SRichard Henderson } 1864951c6300SRichard Henderson break; 1865951c6300SRichard Henderson case MO_64: 1866951c6300SRichard Henderson if (!is64) { 1867951c6300SRichard Henderson tcg_abort(); 1868951c6300SRichard Henderson } 1869951c6300SRichard Henderson break; 1870951c6300SRichard Henderson } 1871951c6300SRichard Henderson if (st) { 1872951c6300SRichard Henderson op &= ~MO_SIGN; 1873951c6300SRichard Henderson } 1874951c6300SRichard Henderson return op; 1875951c6300SRichard Henderson } 1876951c6300SRichard Henderson 1877c45cb8bbSRichard Henderson static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv addr, 1878c45cb8bbSRichard Henderson TCGMemOp memop, TCGArg idx) 1879951c6300SRichard Henderson { 188059227d5dSRichard Henderson TCGMemOpIdx oi = make_memop_idx(memop, idx); 1881951c6300SRichard Henderson #if TARGET_LONG_BITS == 32 188259227d5dSRichard Henderson tcg_gen_op3i_i32(opc, val, addr, oi); 1883951c6300SRichard Henderson #else 1884c45cb8bbSRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 188559227d5dSRichard Henderson tcg_gen_op4i_i32(opc, val, TCGV_LOW(addr), TCGV_HIGH(addr), oi); 1886c45cb8bbSRichard Henderson } else { 188759227d5dSRichard Henderson tcg_gen_op3(&tcg_ctx, opc, GET_TCGV_I32(val), GET_TCGV_I64(addr), oi); 1888c45cb8bbSRichard Henderson } 1889951c6300SRichard Henderson #endif 1890c45cb8bbSRichard Henderson } 1891c45cb8bbSRichard Henderson 1892c45cb8bbSRichard Henderson static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 val, TCGv addr, 1893c45cb8bbSRichard Henderson TCGMemOp memop, TCGArg idx) 1894c45cb8bbSRichard Henderson { 189559227d5dSRichard Henderson TCGMemOpIdx oi = make_memop_idx(memop, idx); 1896c45cb8bbSRichard Henderson #if TARGET_LONG_BITS == 32 1897c45cb8bbSRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 189859227d5dSRichard Henderson tcg_gen_op4i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), addr, oi); 1899c45cb8bbSRichard Henderson } else { 190059227d5dSRichard Henderson tcg_gen_op3(&tcg_ctx, opc, GET_TCGV_I64(val), GET_TCGV_I32(addr), oi); 1901c45cb8bbSRichard Henderson } 1902c45cb8bbSRichard Henderson #else 1903c45cb8bbSRichard Henderson if (TCG_TARGET_REG_BITS == 32) { 190459227d5dSRichard Henderson tcg_gen_op5i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), 190559227d5dSRichard Henderson TCGV_LOW(addr), TCGV_HIGH(addr), oi); 1906c45cb8bbSRichard Henderson } else { 190759227d5dSRichard Henderson tcg_gen_op3i_i64(opc, val, addr, oi); 1908c45cb8bbSRichard Henderson } 1909c45cb8bbSRichard Henderson #endif 1910c45cb8bbSRichard Henderson } 1911951c6300SRichard Henderson 1912951c6300SRichard Henderson void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop) 1913951c6300SRichard Henderson { 1914951c6300SRichard Henderson memop = tcg_canonicalize_memop(memop, 0, 0); 1915*dcdaadb6SLluís Vilanova trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, 1916*dcdaadb6SLluís Vilanova addr, trace_mem_get_info(memop, 0)); 1917c45cb8bbSRichard Henderson gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx); 1918951c6300SRichard Henderson } 1919951c6300SRichard Henderson 1920951c6300SRichard Henderson void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop) 1921951c6300SRichard Henderson { 1922951c6300SRichard Henderson memop = tcg_canonicalize_memop(memop, 0, 1); 1923*dcdaadb6SLluís Vilanova trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, 1924*dcdaadb6SLluís Vilanova addr, trace_mem_get_info(memop, 1)); 1925c45cb8bbSRichard Henderson gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx); 1926951c6300SRichard Henderson } 1927951c6300SRichard Henderson 1928951c6300SRichard Henderson void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop) 1929951c6300SRichard Henderson { 19303a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) { 1931951c6300SRichard Henderson tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop); 1932951c6300SRichard Henderson if (memop & MO_SIGN) { 1933951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31); 1934951c6300SRichard Henderson } else { 1935951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(val), 0); 1936951c6300SRichard Henderson } 1937951c6300SRichard Henderson return; 1938951c6300SRichard Henderson } 1939951c6300SRichard Henderson 1940c45cb8bbSRichard Henderson memop = tcg_canonicalize_memop(memop, 1, 0); 1941*dcdaadb6SLluís Vilanova trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, 1942*dcdaadb6SLluís Vilanova addr, trace_mem_get_info(memop, 0)); 1943c45cb8bbSRichard Henderson gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx); 1944951c6300SRichard Henderson } 1945951c6300SRichard Henderson 1946951c6300SRichard Henderson void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop) 1947951c6300SRichard Henderson { 19483a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) { 1949951c6300SRichard Henderson tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop); 1950951c6300SRichard Henderson return; 1951951c6300SRichard Henderson } 1952951c6300SRichard Henderson 1953c45cb8bbSRichard Henderson memop = tcg_canonicalize_memop(memop, 1, 1); 1954*dcdaadb6SLluís Vilanova trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, 1955*dcdaadb6SLluís Vilanova addr, trace_mem_get_info(memop, 1)); 1956c45cb8bbSRichard Henderson gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx); 1957951c6300SRichard Henderson } 1958