xref: /openbmc/qemu/tcg/tcg-op.c (revision 33c11879)
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"
26*33c11879SPaolo Bonzini #include "qemu-common.h"
27*33c11879SPaolo Bonzini #include "cpu.h"
28951c6300SRichard Henderson #include "tcg.h"
29951c6300SRichard Henderson #include "tcg-op.h"
30951c6300SRichard Henderson 
313a13c3f3SRichard Henderson /* Reduce the number of ifdefs below.  This assumes that all uses of
323a13c3f3SRichard Henderson    TCGV_HIGH and TCGV_LOW are properly protected by a conditional that
333a13c3f3SRichard Henderson    the compiler can eliminate.  */
343a13c3f3SRichard Henderson #if TCG_TARGET_REG_BITS == 64
353a13c3f3SRichard Henderson extern TCGv_i32 TCGV_LOW_link_error(TCGv_i64);
363a13c3f3SRichard Henderson extern TCGv_i32 TCGV_HIGH_link_error(TCGv_i64);
373a13c3f3SRichard Henderson #define TCGV_LOW  TCGV_LOW_link_error
383a13c3f3SRichard Henderson #define TCGV_HIGH TCGV_HIGH_link_error
393a13c3f3SRichard Henderson #endif
40951c6300SRichard Henderson 
41c45cb8bbSRichard Henderson /* Note that this is optimized for sequential allocation during translate.
42c45cb8bbSRichard Henderson    Up to and including filling in the forward link immediately.  We'll do
43c45cb8bbSRichard Henderson    proper termination of the end of the list after we finish translation.  */
44c45cb8bbSRichard Henderson 
45c45cb8bbSRichard Henderson static void tcg_emit_op(TCGContext *ctx, TCGOpcode opc, int args)
46c45cb8bbSRichard Henderson {
47c45cb8bbSRichard Henderson     int oi = ctx->gen_next_op_idx;
48c45cb8bbSRichard Henderson     int ni = oi + 1;
49c45cb8bbSRichard Henderson     int pi = oi - 1;
50c45cb8bbSRichard Henderson 
51c45cb8bbSRichard Henderson     tcg_debug_assert(oi < OPC_BUF_SIZE);
52c45cb8bbSRichard Henderson     ctx->gen_last_op_idx = oi;
53c45cb8bbSRichard Henderson     ctx->gen_next_op_idx = ni;
54c45cb8bbSRichard Henderson 
55c45cb8bbSRichard Henderson     ctx->gen_op_buf[oi] = (TCGOp){
56c45cb8bbSRichard Henderson         .opc = opc,
57c45cb8bbSRichard Henderson         .args = args,
58c45cb8bbSRichard Henderson         .prev = pi,
59c45cb8bbSRichard Henderson         .next = ni
60c45cb8bbSRichard Henderson     };
61c45cb8bbSRichard Henderson }
62c45cb8bbSRichard Henderson 
63951c6300SRichard Henderson void tcg_gen_op1(TCGContext *ctx, TCGOpcode opc, TCGArg a1)
64951c6300SRichard Henderson {
65c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
66951c6300SRichard Henderson 
67c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 1 <= OPPARAM_BUF_SIZE);
68c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 1;
69c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi] = a1;
70951c6300SRichard Henderson 
71c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
72951c6300SRichard Henderson }
73951c6300SRichard Henderson 
74951c6300SRichard Henderson void tcg_gen_op2(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2)
75951c6300SRichard Henderson {
76c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
77951c6300SRichard Henderson 
78c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 2 <= OPPARAM_BUF_SIZE);
79c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 2;
80c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
81c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
82951c6300SRichard Henderson 
83c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
84951c6300SRichard Henderson }
85951c6300SRichard Henderson 
86951c6300SRichard Henderson void tcg_gen_op3(TCGContext *ctx, TCGOpcode opc, TCGArg a1,
87951c6300SRichard Henderson                  TCGArg a2, TCGArg a3)
88951c6300SRichard Henderson {
89c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
90951c6300SRichard Henderson 
91c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 3 <= OPPARAM_BUF_SIZE);
92c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 3;
93c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
94c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
95c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 2] = a3;
96951c6300SRichard Henderson 
97c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
98951c6300SRichard Henderson }
99951c6300SRichard Henderson 
100951c6300SRichard Henderson void tcg_gen_op4(TCGContext *ctx, TCGOpcode opc, TCGArg a1,
101951c6300SRichard Henderson                  TCGArg a2, TCGArg a3, TCGArg a4)
102951c6300SRichard Henderson {
103c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
104951c6300SRichard Henderson 
105c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 4 <= OPPARAM_BUF_SIZE);
106c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 4;
107c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
108c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
109c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 2] = a3;
110c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 3] = a4;
111951c6300SRichard Henderson 
112c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
113951c6300SRichard Henderson }
114951c6300SRichard Henderson 
115951c6300SRichard Henderson void tcg_gen_op5(TCGContext *ctx, TCGOpcode opc, TCGArg a1,
116951c6300SRichard Henderson                  TCGArg a2, TCGArg a3, TCGArg a4, TCGArg a5)
117951c6300SRichard Henderson {
118c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
119951c6300SRichard Henderson 
120c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 5 <= OPPARAM_BUF_SIZE);
121c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 5;
122c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
123c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
124c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 2] = a3;
125c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 3] = a4;
126c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 4] = a5;
127951c6300SRichard Henderson 
128c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
129951c6300SRichard Henderson }
130951c6300SRichard Henderson 
131951c6300SRichard Henderson void tcg_gen_op6(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2,
132951c6300SRichard Henderson                  TCGArg a3, TCGArg a4, TCGArg a5, TCGArg a6)
133951c6300SRichard Henderson {
134c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
135951c6300SRichard Henderson 
136c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 6 <= OPPARAM_BUF_SIZE);
137c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 6;
138c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
139c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
140c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 2] = a3;
141c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 3] = a4;
142c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 4] = a5;
143c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 5] = a6;
144951c6300SRichard Henderson 
145c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
146951c6300SRichard Henderson }
147951c6300SRichard Henderson 
148951c6300SRichard Henderson /* 32 bit ops */
149951c6300SRichard Henderson 
150951c6300SRichard Henderson void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
151951c6300SRichard Henderson {
152951c6300SRichard Henderson     /* some cases can be optimized here */
153951c6300SRichard Henderson     if (arg2 == 0) {
154951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
155951c6300SRichard Henderson     } else {
156951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
157951c6300SRichard Henderson         tcg_gen_add_i32(ret, arg1, t0);
158951c6300SRichard Henderson         tcg_temp_free_i32(t0);
159951c6300SRichard Henderson     }
160951c6300SRichard Henderson }
161951c6300SRichard Henderson 
162951c6300SRichard Henderson void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2)
163951c6300SRichard Henderson {
164951c6300SRichard Henderson     if (arg1 == 0 && TCG_TARGET_HAS_neg_i32) {
165951c6300SRichard Henderson         /* Don't recurse with tcg_gen_neg_i32.  */
166951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg2);
167951c6300SRichard Henderson     } else {
168951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg1);
169951c6300SRichard Henderson         tcg_gen_sub_i32(ret, t0, arg2);
170951c6300SRichard Henderson         tcg_temp_free_i32(t0);
171951c6300SRichard Henderson     }
172951c6300SRichard Henderson }
173951c6300SRichard Henderson 
174951c6300SRichard Henderson void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
175951c6300SRichard Henderson {
176951c6300SRichard Henderson     /* some cases can be optimized here */
177951c6300SRichard Henderson     if (arg2 == 0) {
178951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
179951c6300SRichard Henderson     } else {
180951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
181951c6300SRichard Henderson         tcg_gen_sub_i32(ret, arg1, t0);
182951c6300SRichard Henderson         tcg_temp_free_i32(t0);
183951c6300SRichard Henderson     }
184951c6300SRichard Henderson }
185951c6300SRichard Henderson 
186951c6300SRichard Henderson void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
187951c6300SRichard Henderson {
188951c6300SRichard Henderson     TCGv_i32 t0;
189951c6300SRichard Henderson     /* Some cases can be optimized here.  */
190951c6300SRichard Henderson     switch (arg2) {
191951c6300SRichard Henderson     case 0:
192951c6300SRichard Henderson         tcg_gen_movi_i32(ret, 0);
193951c6300SRichard Henderson         return;
194951c6300SRichard Henderson     case 0xffffffffu:
195951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
196951c6300SRichard Henderson         return;
197951c6300SRichard Henderson     case 0xffu:
198951c6300SRichard Henderson         /* Don't recurse with tcg_gen_ext8u_i32.  */
199951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext8u_i32) {
200951c6300SRichard Henderson             tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
201951c6300SRichard Henderson             return;
202951c6300SRichard Henderson         }
203951c6300SRichard Henderson         break;
204951c6300SRichard Henderson     case 0xffffu:
205951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext16u_i32) {
206951c6300SRichard Henderson             tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
207951c6300SRichard Henderson             return;
208951c6300SRichard Henderson         }
209951c6300SRichard Henderson         break;
210951c6300SRichard Henderson     }
211951c6300SRichard Henderson     t0 = tcg_const_i32(arg2);
212951c6300SRichard Henderson     tcg_gen_and_i32(ret, arg1, t0);
213951c6300SRichard Henderson     tcg_temp_free_i32(t0);
214951c6300SRichard Henderson }
215951c6300SRichard Henderson 
216951c6300SRichard Henderson void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
217951c6300SRichard Henderson {
218951c6300SRichard Henderson     /* Some cases can be optimized here.  */
219951c6300SRichard Henderson     if (arg2 == -1) {
220951c6300SRichard Henderson         tcg_gen_movi_i32(ret, -1);
221951c6300SRichard Henderson     } else if (arg2 == 0) {
222951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
223951c6300SRichard Henderson     } else {
224951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
225951c6300SRichard Henderson         tcg_gen_or_i32(ret, arg1, t0);
226951c6300SRichard Henderson         tcg_temp_free_i32(t0);
227951c6300SRichard Henderson     }
228951c6300SRichard Henderson }
229951c6300SRichard Henderson 
230951c6300SRichard Henderson void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
231951c6300SRichard Henderson {
232951c6300SRichard Henderson     /* Some cases can be optimized here.  */
233951c6300SRichard Henderson     if (arg2 == 0) {
234951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
235951c6300SRichard Henderson     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) {
236951c6300SRichard Henderson         /* Don't recurse with tcg_gen_not_i32.  */
237951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1);
238951c6300SRichard Henderson     } else {
239951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
240951c6300SRichard Henderson         tcg_gen_xor_i32(ret, arg1, t0);
241951c6300SRichard Henderson         tcg_temp_free_i32(t0);
242951c6300SRichard Henderson     }
243951c6300SRichard Henderson }
244951c6300SRichard Henderson 
245951c6300SRichard Henderson void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
246951c6300SRichard Henderson {
247951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
248951c6300SRichard Henderson     if (arg2 == 0) {
249951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
250951c6300SRichard Henderson     } else {
251951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
252951c6300SRichard Henderson         tcg_gen_shl_i32(ret, arg1, t0);
253951c6300SRichard Henderson         tcg_temp_free_i32(t0);
254951c6300SRichard Henderson     }
255951c6300SRichard Henderson }
256951c6300SRichard Henderson 
257951c6300SRichard Henderson void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
258951c6300SRichard Henderson {
259951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
260951c6300SRichard Henderson     if (arg2 == 0) {
261951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
262951c6300SRichard Henderson     } else {
263951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
264951c6300SRichard Henderson         tcg_gen_shr_i32(ret, arg1, t0);
265951c6300SRichard Henderson         tcg_temp_free_i32(t0);
266951c6300SRichard Henderson     }
267951c6300SRichard Henderson }
268951c6300SRichard Henderson 
269951c6300SRichard Henderson void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
270951c6300SRichard Henderson {
271951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
272951c6300SRichard Henderson     if (arg2 == 0) {
273951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
274951c6300SRichard Henderson     } else {
275951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
276951c6300SRichard Henderson         tcg_gen_sar_i32(ret, arg1, t0);
277951c6300SRichard Henderson         tcg_temp_free_i32(t0);
278951c6300SRichard Henderson     }
279951c6300SRichard Henderson }
280951c6300SRichard Henderson 
28142a268c2SRichard Henderson void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l)
282951c6300SRichard Henderson {
283951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
28442a268c2SRichard Henderson         tcg_gen_br(l);
285951c6300SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
28642a268c2SRichard Henderson         tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l));
287951c6300SRichard Henderson     }
288951c6300SRichard Henderson }
289951c6300SRichard Henderson 
29042a268c2SRichard Henderson void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l)
291951c6300SRichard Henderson {
29237ed3bf1SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
29337ed3bf1SRichard Henderson         tcg_gen_br(l);
29437ed3bf1SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
295951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
29642a268c2SRichard Henderson         tcg_gen_brcond_i32(cond, arg1, t0, l);
297951c6300SRichard Henderson         tcg_temp_free_i32(t0);
298951c6300SRichard Henderson     }
29937ed3bf1SRichard Henderson }
300951c6300SRichard Henderson 
301951c6300SRichard Henderson void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
302951c6300SRichard Henderson                          TCGv_i32 arg1, TCGv_i32 arg2)
303951c6300SRichard Henderson {
304951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
305951c6300SRichard Henderson         tcg_gen_movi_i32(ret, 1);
306951c6300SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
307951c6300SRichard Henderson         tcg_gen_movi_i32(ret, 0);
308951c6300SRichard Henderson     } else {
309951c6300SRichard Henderson         tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
310951c6300SRichard Henderson     }
311951c6300SRichard Henderson }
312951c6300SRichard Henderson 
313951c6300SRichard Henderson void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
314951c6300SRichard Henderson                           TCGv_i32 arg1, int32_t arg2)
315951c6300SRichard Henderson {
316951c6300SRichard Henderson     TCGv_i32 t0 = tcg_const_i32(arg2);
317951c6300SRichard Henderson     tcg_gen_setcond_i32(cond, ret, arg1, t0);
318951c6300SRichard Henderson     tcg_temp_free_i32(t0);
319951c6300SRichard Henderson }
320951c6300SRichard Henderson 
321951c6300SRichard Henderson void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
322951c6300SRichard Henderson {
323951c6300SRichard Henderson     TCGv_i32 t0 = tcg_const_i32(arg2);
324951c6300SRichard Henderson     tcg_gen_mul_i32(ret, arg1, t0);
325951c6300SRichard Henderson     tcg_temp_free_i32(t0);
326951c6300SRichard Henderson }
327951c6300SRichard Henderson 
328951c6300SRichard Henderson void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
329951c6300SRichard Henderson {
330951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i32) {
331951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
332951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
333951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
334951c6300SRichard Henderson         tcg_gen_sari_i32(t0, arg1, 31);
335951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
336951c6300SRichard Henderson         tcg_temp_free_i32(t0);
337951c6300SRichard Henderson     } else {
338951c6300SRichard Henderson         gen_helper_div_i32(ret, arg1, arg2);
339951c6300SRichard Henderson     }
340951c6300SRichard Henderson }
341951c6300SRichard Henderson 
342951c6300SRichard Henderson void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
343951c6300SRichard Henderson {
344951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i32) {
345951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
346951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i32) {
347951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
348951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
349951c6300SRichard Henderson         tcg_gen_mul_i32(t0, t0, arg2);
350951c6300SRichard Henderson         tcg_gen_sub_i32(ret, arg1, t0);
351951c6300SRichard Henderson         tcg_temp_free_i32(t0);
352951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
353951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
354951c6300SRichard Henderson         tcg_gen_sari_i32(t0, arg1, 31);
355951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
356951c6300SRichard Henderson         tcg_temp_free_i32(t0);
357951c6300SRichard Henderson     } else {
358951c6300SRichard Henderson         gen_helper_rem_i32(ret, arg1, arg2);
359951c6300SRichard Henderson     }
360951c6300SRichard Henderson }
361951c6300SRichard Henderson 
362951c6300SRichard Henderson void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
363951c6300SRichard Henderson {
364951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i32) {
365951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
366951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
367951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
368951c6300SRichard Henderson         tcg_gen_movi_i32(t0, 0);
369951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
370951c6300SRichard Henderson         tcg_temp_free_i32(t0);
371951c6300SRichard Henderson     } else {
372951c6300SRichard Henderson         gen_helper_divu_i32(ret, arg1, arg2);
373951c6300SRichard Henderson     }
374951c6300SRichard Henderson }
375951c6300SRichard Henderson 
376951c6300SRichard Henderson void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
377951c6300SRichard Henderson {
378951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i32) {
379951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
380951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i32) {
381951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
382951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
383951c6300SRichard Henderson         tcg_gen_mul_i32(t0, t0, arg2);
384951c6300SRichard Henderson         tcg_gen_sub_i32(ret, arg1, t0);
385951c6300SRichard Henderson         tcg_temp_free_i32(t0);
386951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
387951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
388951c6300SRichard Henderson         tcg_gen_movi_i32(t0, 0);
389951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
390951c6300SRichard Henderson         tcg_temp_free_i32(t0);
391951c6300SRichard Henderson     } else {
392951c6300SRichard Henderson         gen_helper_remu_i32(ret, arg1, arg2);
393951c6300SRichard Henderson     }
394951c6300SRichard Henderson }
395951c6300SRichard Henderson 
396951c6300SRichard Henderson void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
397951c6300SRichard Henderson {
398951c6300SRichard Henderson     if (TCG_TARGET_HAS_andc_i32) {
399951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
400951c6300SRichard Henderson     } else {
401951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
402951c6300SRichard Henderson         tcg_gen_not_i32(t0, arg2);
403951c6300SRichard Henderson         tcg_gen_and_i32(ret, arg1, t0);
404951c6300SRichard Henderson         tcg_temp_free_i32(t0);
405951c6300SRichard Henderson     }
406951c6300SRichard Henderson }
407951c6300SRichard Henderson 
408951c6300SRichard Henderson void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
409951c6300SRichard Henderson {
410951c6300SRichard Henderson     if (TCG_TARGET_HAS_eqv_i32) {
411951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
412951c6300SRichard Henderson     } else {
413951c6300SRichard Henderson         tcg_gen_xor_i32(ret, arg1, arg2);
414951c6300SRichard Henderson         tcg_gen_not_i32(ret, ret);
415951c6300SRichard Henderson     }
416951c6300SRichard Henderson }
417951c6300SRichard Henderson 
418951c6300SRichard Henderson void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
419951c6300SRichard Henderson {
420951c6300SRichard Henderson     if (TCG_TARGET_HAS_nand_i32) {
421951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
422951c6300SRichard Henderson     } else {
423951c6300SRichard Henderson         tcg_gen_and_i32(ret, arg1, arg2);
424951c6300SRichard Henderson         tcg_gen_not_i32(ret, ret);
425951c6300SRichard Henderson     }
426951c6300SRichard Henderson }
427951c6300SRichard Henderson 
428951c6300SRichard Henderson void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
429951c6300SRichard Henderson {
430951c6300SRichard Henderson     if (TCG_TARGET_HAS_nor_i32) {
431951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
432951c6300SRichard Henderson     } else {
433951c6300SRichard Henderson         tcg_gen_or_i32(ret, arg1, arg2);
434951c6300SRichard Henderson         tcg_gen_not_i32(ret, ret);
435951c6300SRichard Henderson     }
436951c6300SRichard Henderson }
437951c6300SRichard Henderson 
438951c6300SRichard Henderson void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
439951c6300SRichard Henderson {
440951c6300SRichard Henderson     if (TCG_TARGET_HAS_orc_i32) {
441951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
442951c6300SRichard Henderson     } else {
443951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
444951c6300SRichard Henderson         tcg_gen_not_i32(t0, arg2);
445951c6300SRichard Henderson         tcg_gen_or_i32(ret, arg1, t0);
446951c6300SRichard Henderson         tcg_temp_free_i32(t0);
447951c6300SRichard Henderson     }
448951c6300SRichard Henderson }
449951c6300SRichard Henderson 
450951c6300SRichard Henderson void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
451951c6300SRichard Henderson {
452951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i32) {
453951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
454951c6300SRichard Henderson     } else {
455951c6300SRichard Henderson         TCGv_i32 t0, t1;
456951c6300SRichard Henderson 
457951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
458951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
459951c6300SRichard Henderson         tcg_gen_shl_i32(t0, arg1, arg2);
460951c6300SRichard Henderson         tcg_gen_subfi_i32(t1, 32, arg2);
461951c6300SRichard Henderson         tcg_gen_shr_i32(t1, arg1, t1);
462951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
463951c6300SRichard Henderson         tcg_temp_free_i32(t0);
464951c6300SRichard Henderson         tcg_temp_free_i32(t1);
465951c6300SRichard Henderson     }
466951c6300SRichard Henderson }
467951c6300SRichard Henderson 
468951c6300SRichard Henderson void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
469951c6300SRichard Henderson {
470951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
471951c6300SRichard Henderson     /* some cases can be optimized here */
472951c6300SRichard Henderson     if (arg2 == 0) {
473951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
474951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_rot_i32) {
475951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
476951c6300SRichard Henderson         tcg_gen_rotl_i32(ret, arg1, t0);
477951c6300SRichard Henderson         tcg_temp_free_i32(t0);
478951c6300SRichard Henderson     } else {
479951c6300SRichard Henderson         TCGv_i32 t0, t1;
480951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
481951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
482951c6300SRichard Henderson         tcg_gen_shli_i32(t0, arg1, arg2);
483951c6300SRichard Henderson         tcg_gen_shri_i32(t1, arg1, 32 - arg2);
484951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
485951c6300SRichard Henderson         tcg_temp_free_i32(t0);
486951c6300SRichard Henderson         tcg_temp_free_i32(t1);
487951c6300SRichard Henderson     }
488951c6300SRichard Henderson }
489951c6300SRichard Henderson 
490951c6300SRichard Henderson void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
491951c6300SRichard Henderson {
492951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i32) {
493951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
494951c6300SRichard Henderson     } else {
495951c6300SRichard Henderson         TCGv_i32 t0, t1;
496951c6300SRichard Henderson 
497951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
498951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
499951c6300SRichard Henderson         tcg_gen_shr_i32(t0, arg1, arg2);
500951c6300SRichard Henderson         tcg_gen_subfi_i32(t1, 32, arg2);
501951c6300SRichard Henderson         tcg_gen_shl_i32(t1, arg1, t1);
502951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
503951c6300SRichard Henderson         tcg_temp_free_i32(t0);
504951c6300SRichard Henderson         tcg_temp_free_i32(t1);
505951c6300SRichard Henderson     }
506951c6300SRichard Henderson }
507951c6300SRichard Henderson 
508951c6300SRichard Henderson void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
509951c6300SRichard Henderson {
510951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
511951c6300SRichard Henderson     /* some cases can be optimized here */
512951c6300SRichard Henderson     if (arg2 == 0) {
513951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
514951c6300SRichard Henderson     } else {
515951c6300SRichard Henderson         tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
516951c6300SRichard Henderson     }
517951c6300SRichard Henderson }
518951c6300SRichard Henderson 
519951c6300SRichard Henderson void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
520951c6300SRichard Henderson                          unsigned int ofs, unsigned int len)
521951c6300SRichard Henderson {
522951c6300SRichard Henderson     uint32_t mask;
523951c6300SRichard Henderson     TCGv_i32 t1;
524951c6300SRichard Henderson 
525951c6300SRichard Henderson     tcg_debug_assert(ofs < 32);
526951c6300SRichard Henderson     tcg_debug_assert(len <= 32);
527951c6300SRichard Henderson     tcg_debug_assert(ofs + len <= 32);
528951c6300SRichard Henderson 
529951c6300SRichard Henderson     if (ofs == 0 && len == 32) {
530951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg2);
531951c6300SRichard Henderson         return;
532951c6300SRichard Henderson     }
533951c6300SRichard Henderson     if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
534951c6300SRichard Henderson         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
535951c6300SRichard Henderson         return;
536951c6300SRichard Henderson     }
537951c6300SRichard Henderson 
538951c6300SRichard Henderson     mask = (1u << len) - 1;
539951c6300SRichard Henderson     t1 = tcg_temp_new_i32();
540951c6300SRichard Henderson 
541951c6300SRichard Henderson     if (ofs + len < 32) {
542951c6300SRichard Henderson         tcg_gen_andi_i32(t1, arg2, mask);
543951c6300SRichard Henderson         tcg_gen_shli_i32(t1, t1, ofs);
544951c6300SRichard Henderson     } else {
545951c6300SRichard Henderson         tcg_gen_shli_i32(t1, arg2, ofs);
546951c6300SRichard Henderson     }
547951c6300SRichard Henderson     tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
548951c6300SRichard Henderson     tcg_gen_or_i32(ret, ret, t1);
549951c6300SRichard Henderson 
550951c6300SRichard Henderson     tcg_temp_free_i32(t1);
551951c6300SRichard Henderson }
552951c6300SRichard Henderson 
553951c6300SRichard Henderson void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
554951c6300SRichard Henderson                          TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2)
555951c6300SRichard Henderson {
55637ed3bf1SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
55737ed3bf1SRichard Henderson         tcg_gen_mov_i32(ret, v1);
55837ed3bf1SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
55937ed3bf1SRichard Henderson         tcg_gen_mov_i32(ret, v2);
56037ed3bf1SRichard Henderson     } else if (TCG_TARGET_HAS_movcond_i32) {
561951c6300SRichard Henderson         tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
562951c6300SRichard Henderson     } else {
563951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
564951c6300SRichard Henderson         TCGv_i32 t1 = tcg_temp_new_i32();
565951c6300SRichard Henderson         tcg_gen_setcond_i32(cond, t0, c1, c2);
566951c6300SRichard Henderson         tcg_gen_neg_i32(t0, t0);
567951c6300SRichard Henderson         tcg_gen_and_i32(t1, v1, t0);
568951c6300SRichard Henderson         tcg_gen_andc_i32(ret, v2, t0);
569951c6300SRichard Henderson         tcg_gen_or_i32(ret, ret, t1);
570951c6300SRichard Henderson         tcg_temp_free_i32(t0);
571951c6300SRichard Henderson         tcg_temp_free_i32(t1);
572951c6300SRichard Henderson     }
573951c6300SRichard Henderson }
574951c6300SRichard Henderson 
575951c6300SRichard Henderson void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
576951c6300SRichard Henderson                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
577951c6300SRichard Henderson {
578951c6300SRichard Henderson     if (TCG_TARGET_HAS_add2_i32) {
579951c6300SRichard Henderson         tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
580951c6300SRichard Henderson     } else {
581951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
582951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
583951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t0, al, ah);
584951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t1, bl, bh);
585951c6300SRichard Henderson         tcg_gen_add_i64(t0, t0, t1);
586951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
587951c6300SRichard Henderson         tcg_temp_free_i64(t0);
588951c6300SRichard Henderson         tcg_temp_free_i64(t1);
589951c6300SRichard Henderson     }
590951c6300SRichard Henderson }
591951c6300SRichard Henderson 
592951c6300SRichard Henderson void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
593951c6300SRichard Henderson                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
594951c6300SRichard Henderson {
595951c6300SRichard Henderson     if (TCG_TARGET_HAS_sub2_i32) {
596951c6300SRichard Henderson         tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
597951c6300SRichard Henderson     } else {
598951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
599951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
600951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t0, al, ah);
601951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t1, bl, bh);
602951c6300SRichard Henderson         tcg_gen_sub_i64(t0, t0, t1);
603951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
604951c6300SRichard Henderson         tcg_temp_free_i64(t0);
605951c6300SRichard Henderson         tcg_temp_free_i64(t1);
606951c6300SRichard Henderson     }
607951c6300SRichard Henderson }
608951c6300SRichard Henderson 
609951c6300SRichard Henderson void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
610951c6300SRichard Henderson {
611951c6300SRichard Henderson     if (TCG_TARGET_HAS_mulu2_i32) {
612951c6300SRichard Henderson         tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
613951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_muluh_i32) {
614951c6300SRichard Henderson         TCGv_i32 t = tcg_temp_new_i32();
615951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
616951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
617951c6300SRichard Henderson         tcg_gen_mov_i32(rl, t);
618951c6300SRichard Henderson         tcg_temp_free_i32(t);
619951c6300SRichard Henderson     } else {
620951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
621951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
622951c6300SRichard Henderson         tcg_gen_extu_i32_i64(t0, arg1);
623951c6300SRichard Henderson         tcg_gen_extu_i32_i64(t1, arg2);
624951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, t1);
625951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
626951c6300SRichard Henderson         tcg_temp_free_i64(t0);
627951c6300SRichard Henderson         tcg_temp_free_i64(t1);
628951c6300SRichard Henderson     }
629951c6300SRichard Henderson }
630951c6300SRichard Henderson 
631951c6300SRichard Henderson void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
632951c6300SRichard Henderson {
633951c6300SRichard Henderson     if (TCG_TARGET_HAS_muls2_i32) {
634951c6300SRichard Henderson         tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
635951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_mulsh_i32) {
636951c6300SRichard Henderson         TCGv_i32 t = tcg_temp_new_i32();
637951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
638951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
639951c6300SRichard Henderson         tcg_gen_mov_i32(rl, t);
640951c6300SRichard Henderson         tcg_temp_free_i32(t);
641951c6300SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 32) {
642951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
643951c6300SRichard Henderson         TCGv_i32 t1 = tcg_temp_new_i32();
644951c6300SRichard Henderson         TCGv_i32 t2 = tcg_temp_new_i32();
645951c6300SRichard Henderson         TCGv_i32 t3 = tcg_temp_new_i32();
646951c6300SRichard Henderson         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
647951c6300SRichard Henderson         /* Adjust for negative inputs.  */
648951c6300SRichard Henderson         tcg_gen_sari_i32(t2, arg1, 31);
649951c6300SRichard Henderson         tcg_gen_sari_i32(t3, arg2, 31);
650951c6300SRichard Henderson         tcg_gen_and_i32(t2, t2, arg2);
651951c6300SRichard Henderson         tcg_gen_and_i32(t3, t3, arg1);
652951c6300SRichard Henderson         tcg_gen_sub_i32(rh, t1, t2);
653951c6300SRichard Henderson         tcg_gen_sub_i32(rh, rh, t3);
654951c6300SRichard Henderson         tcg_gen_mov_i32(rl, t0);
655951c6300SRichard Henderson         tcg_temp_free_i32(t0);
656951c6300SRichard Henderson         tcg_temp_free_i32(t1);
657951c6300SRichard Henderson         tcg_temp_free_i32(t2);
658951c6300SRichard Henderson         tcg_temp_free_i32(t3);
659951c6300SRichard Henderson     } else {
660951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
661951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
662951c6300SRichard Henderson         tcg_gen_ext_i32_i64(t0, arg1);
663951c6300SRichard Henderson         tcg_gen_ext_i32_i64(t1, arg2);
664951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, t1);
665951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
666951c6300SRichard Henderson         tcg_temp_free_i64(t0);
667951c6300SRichard Henderson         tcg_temp_free_i64(t1);
668951c6300SRichard Henderson     }
669951c6300SRichard Henderson }
670951c6300SRichard Henderson 
671951c6300SRichard Henderson void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
672951c6300SRichard Henderson {
673951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext8s_i32) {
674951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
675951c6300SRichard Henderson     } else {
676951c6300SRichard Henderson         tcg_gen_shli_i32(ret, arg, 24);
677951c6300SRichard Henderson         tcg_gen_sari_i32(ret, ret, 24);
678951c6300SRichard Henderson     }
679951c6300SRichard Henderson }
680951c6300SRichard Henderson 
681951c6300SRichard Henderson void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
682951c6300SRichard Henderson {
683951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext16s_i32) {
684951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
685951c6300SRichard Henderson     } else {
686951c6300SRichard Henderson         tcg_gen_shli_i32(ret, arg, 16);
687951c6300SRichard Henderson         tcg_gen_sari_i32(ret, ret, 16);
688951c6300SRichard Henderson     }
689951c6300SRichard Henderson }
690951c6300SRichard Henderson 
691951c6300SRichard Henderson void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
692951c6300SRichard Henderson {
693951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext8u_i32) {
694951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
695951c6300SRichard Henderson     } else {
696951c6300SRichard Henderson         tcg_gen_andi_i32(ret, arg, 0xffu);
697951c6300SRichard Henderson     }
698951c6300SRichard Henderson }
699951c6300SRichard Henderson 
700951c6300SRichard Henderson void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
701951c6300SRichard Henderson {
702951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext16u_i32) {
703951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
704951c6300SRichard Henderson     } else {
705951c6300SRichard Henderson         tcg_gen_andi_i32(ret, arg, 0xffffu);
706951c6300SRichard Henderson     }
707951c6300SRichard Henderson }
708951c6300SRichard Henderson 
709951c6300SRichard Henderson /* Note: we assume the two high bytes are set to zero */
710951c6300SRichard Henderson void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg)
711951c6300SRichard Henderson {
712951c6300SRichard Henderson     if (TCG_TARGET_HAS_bswap16_i32) {
713951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg);
714951c6300SRichard Henderson     } else {
715951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
716951c6300SRichard Henderson 
717951c6300SRichard Henderson         tcg_gen_ext8u_i32(t0, arg);
718951c6300SRichard Henderson         tcg_gen_shli_i32(t0, t0, 8);
719951c6300SRichard Henderson         tcg_gen_shri_i32(ret, arg, 8);
720951c6300SRichard Henderson         tcg_gen_or_i32(ret, ret, t0);
721951c6300SRichard Henderson         tcg_temp_free_i32(t0);
722951c6300SRichard Henderson     }
723951c6300SRichard Henderson }
724951c6300SRichard Henderson 
725951c6300SRichard Henderson void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
726951c6300SRichard Henderson {
727951c6300SRichard Henderson     if (TCG_TARGET_HAS_bswap32_i32) {
728951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg);
729951c6300SRichard Henderson     } else {
730951c6300SRichard Henderson         TCGv_i32 t0, t1;
731951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
732951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
733951c6300SRichard Henderson 
734951c6300SRichard Henderson         tcg_gen_shli_i32(t0, arg, 24);
735951c6300SRichard Henderson 
736951c6300SRichard Henderson         tcg_gen_andi_i32(t1, arg, 0x0000ff00);
737951c6300SRichard Henderson         tcg_gen_shli_i32(t1, t1, 8);
738951c6300SRichard Henderson         tcg_gen_or_i32(t0, t0, t1);
739951c6300SRichard Henderson 
740951c6300SRichard Henderson         tcg_gen_shri_i32(t1, arg, 8);
741951c6300SRichard Henderson         tcg_gen_andi_i32(t1, t1, 0x0000ff00);
742951c6300SRichard Henderson         tcg_gen_or_i32(t0, t0, t1);
743951c6300SRichard Henderson 
744951c6300SRichard Henderson         tcg_gen_shri_i32(t1, arg, 24);
745951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
746951c6300SRichard Henderson         tcg_temp_free_i32(t0);
747951c6300SRichard Henderson         tcg_temp_free_i32(t1);
748951c6300SRichard Henderson     }
749951c6300SRichard Henderson }
750951c6300SRichard Henderson 
751951c6300SRichard Henderson /* 64-bit ops */
752951c6300SRichard Henderson 
753951c6300SRichard Henderson #if TCG_TARGET_REG_BITS == 32
754951c6300SRichard Henderson /* These are all inline for TCG_TARGET_REG_BITS == 64.  */
755951c6300SRichard Henderson 
756951c6300SRichard Henderson void tcg_gen_discard_i64(TCGv_i64 arg)
757951c6300SRichard Henderson {
758951c6300SRichard Henderson     tcg_gen_discard_i32(TCGV_LOW(arg));
759951c6300SRichard Henderson     tcg_gen_discard_i32(TCGV_HIGH(arg));
760951c6300SRichard Henderson }
761951c6300SRichard Henderson 
762951c6300SRichard Henderson void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
763951c6300SRichard Henderson {
764951c6300SRichard Henderson     tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
765951c6300SRichard Henderson     tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
766951c6300SRichard Henderson }
767951c6300SRichard Henderson 
768951c6300SRichard Henderson void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
769951c6300SRichard Henderson {
770951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_LOW(ret), arg);
771951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
772951c6300SRichard Henderson }
773951c6300SRichard Henderson 
774951c6300SRichard Henderson void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
775951c6300SRichard Henderson {
776951c6300SRichard Henderson     tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset);
777951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
778951c6300SRichard Henderson }
779951c6300SRichard Henderson 
780951c6300SRichard Henderson void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
781951c6300SRichard Henderson {
782951c6300SRichard Henderson     tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
783951c6300SRichard Henderson     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), 31);
784951c6300SRichard Henderson }
785951c6300SRichard Henderson 
786951c6300SRichard Henderson void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
787951c6300SRichard Henderson {
788951c6300SRichard Henderson     tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset);
789951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
790951c6300SRichard Henderson }
791951c6300SRichard Henderson 
792951c6300SRichard Henderson void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
793951c6300SRichard Henderson {
794951c6300SRichard Henderson     tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset);
795951c6300SRichard Henderson     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
796951c6300SRichard Henderson }
797951c6300SRichard Henderson 
798951c6300SRichard Henderson void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
799951c6300SRichard Henderson {
800951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
801951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
802951c6300SRichard Henderson }
803951c6300SRichard Henderson 
804951c6300SRichard Henderson void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
805951c6300SRichard Henderson {
806951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
807951c6300SRichard Henderson     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
808951c6300SRichard Henderson }
809951c6300SRichard Henderson 
810951c6300SRichard Henderson void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
811951c6300SRichard Henderson {
812951c6300SRichard Henderson     /* Since arg2 and ret have different types,
813951c6300SRichard Henderson        they cannot be the same temporary */
814cf811fffSPeter Maydell #ifdef HOST_WORDS_BIGENDIAN
815951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
816951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
817951c6300SRichard Henderson #else
818951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
819951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
820951c6300SRichard Henderson #endif
821951c6300SRichard Henderson }
822951c6300SRichard Henderson 
823951c6300SRichard Henderson void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
824951c6300SRichard Henderson {
825cf811fffSPeter Maydell #ifdef HOST_WORDS_BIGENDIAN
826951c6300SRichard Henderson     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
827951c6300SRichard Henderson     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
828951c6300SRichard Henderson #else
829951c6300SRichard Henderson     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
830951c6300SRichard Henderson     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
831951c6300SRichard Henderson #endif
832951c6300SRichard Henderson }
833951c6300SRichard Henderson 
834951c6300SRichard Henderson void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
835951c6300SRichard Henderson {
836951c6300SRichard Henderson     tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
837951c6300SRichard Henderson     tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
838951c6300SRichard Henderson }
839951c6300SRichard Henderson 
840951c6300SRichard Henderson void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
841951c6300SRichard Henderson {
842951c6300SRichard Henderson     tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
843951c6300SRichard Henderson     tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
844951c6300SRichard Henderson }
845951c6300SRichard Henderson 
846951c6300SRichard Henderson void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
847951c6300SRichard Henderson {
848951c6300SRichard Henderson     tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
849951c6300SRichard Henderson     tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
850951c6300SRichard Henderson }
851951c6300SRichard Henderson 
852951c6300SRichard Henderson void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
853951c6300SRichard Henderson {
854951c6300SRichard Henderson     gen_helper_shl_i64(ret, arg1, arg2);
855951c6300SRichard Henderson }
856951c6300SRichard Henderson 
857951c6300SRichard Henderson void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
858951c6300SRichard Henderson {
859951c6300SRichard Henderson     gen_helper_shr_i64(ret, arg1, arg2);
860951c6300SRichard Henderson }
861951c6300SRichard Henderson 
862951c6300SRichard Henderson void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
863951c6300SRichard Henderson {
864951c6300SRichard Henderson     gen_helper_sar_i64(ret, arg1, arg2);
865951c6300SRichard Henderson }
866951c6300SRichard Henderson 
867951c6300SRichard Henderson void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
868951c6300SRichard Henderson {
869951c6300SRichard Henderson     TCGv_i64 t0;
870951c6300SRichard Henderson     TCGv_i32 t1;
871951c6300SRichard Henderson 
872951c6300SRichard Henderson     t0 = tcg_temp_new_i64();
873951c6300SRichard Henderson     t1 = tcg_temp_new_i32();
874951c6300SRichard Henderson 
875951c6300SRichard Henderson     tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
876951c6300SRichard Henderson                       TCGV_LOW(arg1), TCGV_LOW(arg2));
877951c6300SRichard Henderson 
878951c6300SRichard Henderson     tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
879951c6300SRichard Henderson     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
880951c6300SRichard Henderson     tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2));
881951c6300SRichard Henderson     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
882951c6300SRichard Henderson 
883951c6300SRichard Henderson     tcg_gen_mov_i64(ret, t0);
884951c6300SRichard Henderson     tcg_temp_free_i64(t0);
885951c6300SRichard Henderson     tcg_temp_free_i32(t1);
886951c6300SRichard Henderson }
887951c6300SRichard Henderson #endif /* TCG_TARGET_REG_SIZE == 32 */
888951c6300SRichard Henderson 
889951c6300SRichard Henderson void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
890951c6300SRichard Henderson {
891951c6300SRichard Henderson     /* some cases can be optimized here */
892951c6300SRichard Henderson     if (arg2 == 0) {
893951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
894951c6300SRichard Henderson     } else {
895951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
896951c6300SRichard Henderson         tcg_gen_add_i64(ret, arg1, t0);
897951c6300SRichard Henderson         tcg_temp_free_i64(t0);
898951c6300SRichard Henderson     }
899951c6300SRichard Henderson }
900951c6300SRichard Henderson 
901951c6300SRichard Henderson void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2)
902951c6300SRichard Henderson {
903951c6300SRichard Henderson     if (arg1 == 0 && TCG_TARGET_HAS_neg_i64) {
904951c6300SRichard Henderson         /* Don't recurse with tcg_gen_neg_i64.  */
905951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg2);
906951c6300SRichard Henderson     } else {
907951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg1);
908951c6300SRichard Henderson         tcg_gen_sub_i64(ret, t0, arg2);
909951c6300SRichard Henderson         tcg_temp_free_i64(t0);
910951c6300SRichard Henderson     }
911951c6300SRichard Henderson }
912951c6300SRichard Henderson 
913951c6300SRichard Henderson void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
914951c6300SRichard Henderson {
915951c6300SRichard Henderson     /* some cases can be optimized here */
916951c6300SRichard Henderson     if (arg2 == 0) {
917951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
918951c6300SRichard Henderson     } else {
919951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
920951c6300SRichard Henderson         tcg_gen_sub_i64(ret, arg1, t0);
921951c6300SRichard Henderson         tcg_temp_free_i64(t0);
922951c6300SRichard Henderson     }
923951c6300SRichard Henderson }
924951c6300SRichard Henderson 
925951c6300SRichard Henderson void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
926951c6300SRichard Henderson {
9273a13c3f3SRichard Henderson     TCGv_i64 t0;
9283a13c3f3SRichard Henderson 
9293a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
930951c6300SRichard Henderson         tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
931951c6300SRichard Henderson         tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
9323a13c3f3SRichard Henderson         return;
9333a13c3f3SRichard Henderson     }
9343a13c3f3SRichard Henderson 
935951c6300SRichard Henderson     /* Some cases can be optimized here.  */
936951c6300SRichard Henderson     switch (arg2) {
937951c6300SRichard Henderson     case 0:
938951c6300SRichard Henderson         tcg_gen_movi_i64(ret, 0);
939951c6300SRichard Henderson         return;
940951c6300SRichard Henderson     case 0xffffffffffffffffull:
941951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
942951c6300SRichard Henderson         return;
943951c6300SRichard Henderson     case 0xffull:
944951c6300SRichard Henderson         /* Don't recurse with tcg_gen_ext8u_i64.  */
945951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext8u_i64) {
946951c6300SRichard Henderson             tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
947951c6300SRichard Henderson             return;
948951c6300SRichard Henderson         }
949951c6300SRichard Henderson         break;
950951c6300SRichard Henderson     case 0xffffu:
951951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext16u_i64) {
952951c6300SRichard Henderson             tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
953951c6300SRichard Henderson             return;
954951c6300SRichard Henderson         }
955951c6300SRichard Henderson         break;
956951c6300SRichard Henderson     case 0xffffffffull:
957951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext32u_i64) {
958951c6300SRichard Henderson             tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
959951c6300SRichard Henderson             return;
960951c6300SRichard Henderson         }
961951c6300SRichard Henderson         break;
962951c6300SRichard Henderson     }
963951c6300SRichard Henderson     t0 = tcg_const_i64(arg2);
964951c6300SRichard Henderson     tcg_gen_and_i64(ret, arg1, t0);
965951c6300SRichard Henderson     tcg_temp_free_i64(t0);
966951c6300SRichard Henderson }
967951c6300SRichard Henderson 
968951c6300SRichard Henderson void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
969951c6300SRichard Henderson {
9703a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
971951c6300SRichard Henderson         tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
972951c6300SRichard Henderson         tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
9733a13c3f3SRichard Henderson         return;
9743a13c3f3SRichard Henderson     }
975951c6300SRichard Henderson     /* Some cases can be optimized here.  */
976951c6300SRichard Henderson     if (arg2 == -1) {
977951c6300SRichard Henderson         tcg_gen_movi_i64(ret, -1);
978951c6300SRichard Henderson     } else if (arg2 == 0) {
979951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
980951c6300SRichard Henderson     } else {
981951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
982951c6300SRichard Henderson         tcg_gen_or_i64(ret, arg1, t0);
983951c6300SRichard Henderson         tcg_temp_free_i64(t0);
984951c6300SRichard Henderson     }
985951c6300SRichard Henderson }
986951c6300SRichard Henderson 
987951c6300SRichard Henderson void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
988951c6300SRichard Henderson {
9893a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
990951c6300SRichard Henderson         tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
991951c6300SRichard Henderson         tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
9923a13c3f3SRichard Henderson         return;
9933a13c3f3SRichard Henderson     }
994951c6300SRichard Henderson     /* Some cases can be optimized here.  */
995951c6300SRichard Henderson     if (arg2 == 0) {
996951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
997951c6300SRichard Henderson     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) {
998951c6300SRichard Henderson         /* Don't recurse with tcg_gen_not_i64.  */
999951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1);
1000951c6300SRichard Henderson     } else {
1001951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
1002951c6300SRichard Henderson         tcg_gen_xor_i64(ret, arg1, t0);
1003951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1004951c6300SRichard Henderson     }
1005951c6300SRichard Henderson }
1006951c6300SRichard Henderson 
1007951c6300SRichard Henderson static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
1008951c6300SRichard Henderson                                       unsigned c, bool right, bool arith)
1009951c6300SRichard Henderson {
1010951c6300SRichard Henderson     tcg_debug_assert(c < 64);
1011951c6300SRichard Henderson     if (c == 0) {
1012951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1013951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1014951c6300SRichard Henderson     } else if (c >= 32) {
1015951c6300SRichard Henderson         c -= 32;
1016951c6300SRichard Henderson         if (right) {
1017951c6300SRichard Henderson             if (arith) {
1018951c6300SRichard Henderson                 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1019951c6300SRichard Henderson                 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
1020951c6300SRichard Henderson             } else {
1021951c6300SRichard Henderson                 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1022951c6300SRichard Henderson                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1023951c6300SRichard Henderson             }
1024951c6300SRichard Henderson         } else {
1025951c6300SRichard Henderson             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
1026951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_LOW(ret), 0);
1027951c6300SRichard Henderson         }
1028951c6300SRichard Henderson     } else {
1029951c6300SRichard Henderson         TCGv_i32 t0, t1;
1030951c6300SRichard Henderson 
1031951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
1032951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
1033951c6300SRichard Henderson         if (right) {
1034951c6300SRichard Henderson             tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
1035951c6300SRichard Henderson             if (arith) {
1036951c6300SRichard Henderson                 tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
1037951c6300SRichard Henderson             } else {
1038951c6300SRichard Henderson                 tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
1039951c6300SRichard Henderson             }
1040951c6300SRichard Henderson             tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
1041951c6300SRichard Henderson             tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
1042951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
1043951c6300SRichard Henderson         } else {
1044951c6300SRichard Henderson             tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
1045951c6300SRichard Henderson             /* Note: ret can be the same as arg1, so we use t1 */
1046951c6300SRichard Henderson             tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
1047951c6300SRichard Henderson             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
1048951c6300SRichard Henderson             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
1049951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_LOW(ret), t1);
1050951c6300SRichard Henderson         }
1051951c6300SRichard Henderson         tcg_temp_free_i32(t0);
1052951c6300SRichard Henderson         tcg_temp_free_i32(t1);
1053951c6300SRichard Henderson     }
1054951c6300SRichard Henderson }
1055951c6300SRichard Henderson 
1056951c6300SRichard Henderson void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1057951c6300SRichard Henderson {
1058951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
10593a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
10603a13c3f3SRichard Henderson         tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
10613a13c3f3SRichard Henderson     } else if (arg2 == 0) {
1062951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1063951c6300SRichard Henderson     } else {
1064951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
1065951c6300SRichard Henderson         tcg_gen_shl_i64(ret, arg1, t0);
1066951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1067951c6300SRichard Henderson     }
1068951c6300SRichard Henderson }
1069951c6300SRichard Henderson 
1070951c6300SRichard Henderson void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1071951c6300SRichard Henderson {
1072951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
10733a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
10743a13c3f3SRichard Henderson         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
10753a13c3f3SRichard Henderson     } else if (arg2 == 0) {
1076951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1077951c6300SRichard Henderson     } else {
1078951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
1079951c6300SRichard Henderson         tcg_gen_shr_i64(ret, arg1, t0);
1080951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1081951c6300SRichard Henderson     }
1082951c6300SRichard Henderson }
1083951c6300SRichard Henderson 
1084951c6300SRichard Henderson void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1085951c6300SRichard Henderson {
1086951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
10873a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
10883a13c3f3SRichard Henderson         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
10893a13c3f3SRichard Henderson     } else if (arg2 == 0) {
1090951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1091951c6300SRichard Henderson     } else {
1092951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
1093951c6300SRichard Henderson         tcg_gen_sar_i64(ret, arg1, t0);
1094951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1095951c6300SRichard Henderson     }
1096951c6300SRichard Henderson }
1097951c6300SRichard Henderson 
109842a268c2SRichard Henderson void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l)
1099951c6300SRichard Henderson {
1100951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
110142a268c2SRichard Henderson         tcg_gen_br(l);
1102951c6300SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
11033a13c3f3SRichard Henderson         if (TCG_TARGET_REG_BITS == 32) {
1104951c6300SRichard Henderson             tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),
1105951c6300SRichard Henderson                               TCGV_HIGH(arg1), TCGV_LOW(arg2),
110642a268c2SRichard Henderson                               TCGV_HIGH(arg2), cond, label_arg(l));
11073a13c3f3SRichard Henderson         } else {
110842a268c2SRichard Henderson             tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond,
110942a268c2SRichard Henderson                               label_arg(l));
11103a13c3f3SRichard Henderson         }
1111951c6300SRichard Henderson     }
1112951c6300SRichard Henderson }
1113951c6300SRichard Henderson 
111442a268c2SRichard Henderson void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l)
1115951c6300SRichard Henderson {
1116951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
111742a268c2SRichard Henderson         tcg_gen_br(l);
1118951c6300SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
1119951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
112042a268c2SRichard Henderson         tcg_gen_brcond_i64(cond, arg1, t0, l);
1121951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1122951c6300SRichard Henderson     }
1123951c6300SRichard Henderson }
1124951c6300SRichard Henderson 
1125951c6300SRichard Henderson void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
1126951c6300SRichard Henderson                          TCGv_i64 arg1, TCGv_i64 arg2)
1127951c6300SRichard Henderson {
1128951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
1129951c6300SRichard Henderson         tcg_gen_movi_i64(ret, 1);
1130951c6300SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
1131951c6300SRichard Henderson         tcg_gen_movi_i64(ret, 0);
1132951c6300SRichard Henderson     } else {
11333a13c3f3SRichard Henderson         if (TCG_TARGET_REG_BITS == 32) {
1134951c6300SRichard Henderson             tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
1135951c6300SRichard Henderson                              TCGV_LOW(arg1), TCGV_HIGH(arg1),
1136951c6300SRichard Henderson                              TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
1137951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
11383a13c3f3SRichard Henderson         } else {
1139951c6300SRichard Henderson             tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
11403a13c3f3SRichard Henderson         }
1141951c6300SRichard Henderson     }
1142951c6300SRichard Henderson }
1143951c6300SRichard Henderson 
1144951c6300SRichard Henderson void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
1145951c6300SRichard Henderson                           TCGv_i64 arg1, int64_t arg2)
1146951c6300SRichard Henderson {
1147951c6300SRichard Henderson     TCGv_i64 t0 = tcg_const_i64(arg2);
1148951c6300SRichard Henderson     tcg_gen_setcond_i64(cond, ret, arg1, t0);
1149951c6300SRichard Henderson     tcg_temp_free_i64(t0);
1150951c6300SRichard Henderson }
1151951c6300SRichard Henderson 
1152951c6300SRichard Henderson void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1153951c6300SRichard Henderson {
1154951c6300SRichard Henderson     TCGv_i64 t0 = tcg_const_i64(arg2);
1155951c6300SRichard Henderson     tcg_gen_mul_i64(ret, arg1, t0);
1156951c6300SRichard Henderson     tcg_temp_free_i64(t0);
1157951c6300SRichard Henderson }
1158951c6300SRichard Henderson 
1159951c6300SRichard Henderson void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1160951c6300SRichard Henderson {
1161951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i64) {
1162951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
1163951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
1164951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1165951c6300SRichard Henderson         tcg_gen_sari_i64(t0, arg1, 63);
1166951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
1167951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1168951c6300SRichard Henderson     } else {
1169951c6300SRichard Henderson         gen_helper_div_i64(ret, arg1, arg2);
1170951c6300SRichard Henderson     }
1171951c6300SRichard Henderson }
1172951c6300SRichard Henderson 
1173951c6300SRichard Henderson void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1174951c6300SRichard Henderson {
1175951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i64) {
1176951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
1177951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i64) {
1178951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1179951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
1180951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, arg2);
1181951c6300SRichard Henderson         tcg_gen_sub_i64(ret, arg1, t0);
1182951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1183951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
1184951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1185951c6300SRichard Henderson         tcg_gen_sari_i64(t0, arg1, 63);
1186951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
1187951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1188951c6300SRichard Henderson     } else {
1189951c6300SRichard Henderson         gen_helper_rem_i64(ret, arg1, arg2);
1190951c6300SRichard Henderson     }
1191951c6300SRichard Henderson }
1192951c6300SRichard Henderson 
1193951c6300SRichard Henderson void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1194951c6300SRichard Henderson {
1195951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i64) {
1196951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
1197951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
1198951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1199951c6300SRichard Henderson         tcg_gen_movi_i64(t0, 0);
1200951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
1201951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1202951c6300SRichard Henderson     } else {
1203951c6300SRichard Henderson         gen_helper_divu_i64(ret, arg1, arg2);
1204951c6300SRichard Henderson     }
1205951c6300SRichard Henderson }
1206951c6300SRichard Henderson 
1207951c6300SRichard Henderson void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1208951c6300SRichard Henderson {
1209951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i64) {
1210951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
1211951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i64) {
1212951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1213951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
1214951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, arg2);
1215951c6300SRichard Henderson         tcg_gen_sub_i64(ret, arg1, t0);
1216951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1217951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
1218951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1219951c6300SRichard Henderson         tcg_gen_movi_i64(t0, 0);
1220951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
1221951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1222951c6300SRichard Henderson     } else {
1223951c6300SRichard Henderson         gen_helper_remu_i64(ret, arg1, arg2);
1224951c6300SRichard Henderson     }
1225951c6300SRichard Henderson }
1226951c6300SRichard Henderson 
1227951c6300SRichard Henderson void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
1228951c6300SRichard Henderson {
12293a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1230951c6300SRichard Henderson         tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1231951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
12323a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext8s_i64) {
1233951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
1234951c6300SRichard Henderson     } else {
1235951c6300SRichard Henderson         tcg_gen_shli_i64(ret, arg, 56);
1236951c6300SRichard Henderson         tcg_gen_sari_i64(ret, ret, 56);
1237951c6300SRichard Henderson     }
1238951c6300SRichard Henderson }
1239951c6300SRichard Henderson 
1240951c6300SRichard Henderson void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
1241951c6300SRichard Henderson {
12423a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1243951c6300SRichard Henderson         tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1244951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
12453a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext16s_i64) {
1246951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
1247951c6300SRichard Henderson     } else {
1248951c6300SRichard Henderson         tcg_gen_shli_i64(ret, arg, 48);
1249951c6300SRichard Henderson         tcg_gen_sari_i64(ret, ret, 48);
1250951c6300SRichard Henderson     }
1251951c6300SRichard Henderson }
1252951c6300SRichard Henderson 
1253951c6300SRichard Henderson void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
1254951c6300SRichard Henderson {
12553a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1256951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1257951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
12583a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext32s_i64) {
1259951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
1260951c6300SRichard Henderson     } else {
1261951c6300SRichard Henderson         tcg_gen_shli_i64(ret, arg, 32);
1262951c6300SRichard Henderson         tcg_gen_sari_i64(ret, ret, 32);
1263951c6300SRichard Henderson     }
1264951c6300SRichard Henderson }
1265951c6300SRichard Henderson 
1266951c6300SRichard Henderson void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
1267951c6300SRichard Henderson {
12683a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1269951c6300SRichard Henderson         tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1270951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
12713a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext8u_i64) {
1272951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
1273951c6300SRichard Henderson     } else {
1274951c6300SRichard Henderson         tcg_gen_andi_i64(ret, arg, 0xffu);
1275951c6300SRichard Henderson     }
1276951c6300SRichard Henderson }
1277951c6300SRichard Henderson 
1278951c6300SRichard Henderson void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
1279951c6300SRichard Henderson {
12803a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1281951c6300SRichard Henderson         tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1282951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
12833a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext16u_i64) {
1284951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
1285951c6300SRichard Henderson     } else {
1286951c6300SRichard Henderson         tcg_gen_andi_i64(ret, arg, 0xffffu);
1287951c6300SRichard Henderson     }
1288951c6300SRichard Henderson }
1289951c6300SRichard Henderson 
1290951c6300SRichard Henderson void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
1291951c6300SRichard Henderson {
12923a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1293951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1294951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
12953a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext32u_i64) {
1296951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
1297951c6300SRichard Henderson     } else {
1298951c6300SRichard Henderson         tcg_gen_andi_i64(ret, arg, 0xffffffffu);
1299951c6300SRichard Henderson     }
1300951c6300SRichard Henderson }
1301951c6300SRichard Henderson 
1302951c6300SRichard Henderson /* Note: we assume the six high bytes are set to zero */
1303951c6300SRichard Henderson void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg)
1304951c6300SRichard Henderson {
13053a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1306951c6300SRichard Henderson         tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1307951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
13083a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_bswap16_i64) {
1309951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg);
1310951c6300SRichard Henderson     } else {
1311951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1312951c6300SRichard Henderson 
1313951c6300SRichard Henderson         tcg_gen_ext8u_i64(t0, arg);
1314951c6300SRichard Henderson         tcg_gen_shli_i64(t0, t0, 8);
1315951c6300SRichard Henderson         tcg_gen_shri_i64(ret, arg, 8);
1316951c6300SRichard Henderson         tcg_gen_or_i64(ret, ret, t0);
1317951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1318951c6300SRichard Henderson     }
1319951c6300SRichard Henderson }
1320951c6300SRichard Henderson 
1321951c6300SRichard Henderson /* Note: we assume the four high bytes are set to zero */
1322951c6300SRichard Henderson void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg)
1323951c6300SRichard Henderson {
13243a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1325951c6300SRichard Henderson         tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1326951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
13273a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_bswap32_i64) {
1328951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg);
1329951c6300SRichard Henderson     } else {
1330951c6300SRichard Henderson         TCGv_i64 t0, t1;
1331951c6300SRichard Henderson         t0 = tcg_temp_new_i64();
1332951c6300SRichard Henderson         t1 = tcg_temp_new_i64();
1333951c6300SRichard Henderson 
1334951c6300SRichard Henderson         tcg_gen_shli_i64(t0, arg, 24);
1335951c6300SRichard Henderson         tcg_gen_ext32u_i64(t0, t0);
1336951c6300SRichard Henderson 
1337951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg, 0x0000ff00);
1338951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, 8);
1339951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1340951c6300SRichard Henderson 
1341951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 8);
1342951c6300SRichard Henderson         tcg_gen_andi_i64(t1, t1, 0x0000ff00);
1343951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1344951c6300SRichard Henderson 
1345951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 24);
1346951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1347951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1348951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1349951c6300SRichard Henderson     }
1350951c6300SRichard Henderson }
1351951c6300SRichard Henderson 
1352951c6300SRichard Henderson void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
1353951c6300SRichard Henderson {
13543a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1355951c6300SRichard Henderson         TCGv_i32 t0, t1;
1356951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
1357951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
1358951c6300SRichard Henderson 
1359951c6300SRichard Henderson         tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
1360951c6300SRichard Henderson         tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
1361951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), t1);
1362951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
1363951c6300SRichard Henderson         tcg_temp_free_i32(t0);
1364951c6300SRichard Henderson         tcg_temp_free_i32(t1);
13653a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_bswap64_i64) {
1366951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg);
1367951c6300SRichard Henderson     } else {
1368951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1369951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1370951c6300SRichard Henderson 
1371951c6300SRichard Henderson         tcg_gen_shli_i64(t0, arg, 56);
1372951c6300SRichard Henderson 
1373951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg, 0x0000ff00);
1374951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, 40);
1375951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1376951c6300SRichard Henderson 
1377951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg, 0x00ff0000);
1378951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, 24);
1379951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1380951c6300SRichard Henderson 
1381951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg, 0xff000000);
1382951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, 8);
1383951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1384951c6300SRichard Henderson 
1385951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 8);
1386951c6300SRichard Henderson         tcg_gen_andi_i64(t1, t1, 0xff000000);
1387951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1388951c6300SRichard Henderson 
1389951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 24);
1390951c6300SRichard Henderson         tcg_gen_andi_i64(t1, t1, 0x00ff0000);
1391951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1392951c6300SRichard Henderson 
1393951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 40);
1394951c6300SRichard Henderson         tcg_gen_andi_i64(t1, t1, 0x0000ff00);
1395951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1396951c6300SRichard Henderson 
1397951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 56);
1398951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1399951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1400951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1401951c6300SRichard Henderson     }
1402951c6300SRichard Henderson }
1403951c6300SRichard Henderson 
1404951c6300SRichard Henderson void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
1405951c6300SRichard Henderson {
14063a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14073a13c3f3SRichard Henderson         tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
14083a13c3f3SRichard Henderson         tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
14093a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_not_i64) {
1410951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
1411951c6300SRichard Henderson     } else {
1412951c6300SRichard Henderson         tcg_gen_xori_i64(ret, arg, -1);
1413951c6300SRichard Henderson     }
1414951c6300SRichard Henderson }
1415951c6300SRichard Henderson 
1416951c6300SRichard Henderson void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1417951c6300SRichard Henderson {
14183a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14193a13c3f3SRichard Henderson         tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14203a13c3f3SRichard Henderson         tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14213a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_andc_i64) {
1422951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
1423951c6300SRichard Henderson     } else {
1424951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1425951c6300SRichard Henderson         tcg_gen_not_i64(t0, arg2);
1426951c6300SRichard Henderson         tcg_gen_and_i64(ret, arg1, t0);
1427951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1428951c6300SRichard Henderson     }
1429951c6300SRichard Henderson }
1430951c6300SRichard Henderson 
1431951c6300SRichard Henderson void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1432951c6300SRichard Henderson {
14333a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14343a13c3f3SRichard Henderson         tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14353a13c3f3SRichard Henderson         tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14363a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_eqv_i64) {
1437951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
1438951c6300SRichard Henderson     } else {
1439951c6300SRichard Henderson         tcg_gen_xor_i64(ret, arg1, arg2);
1440951c6300SRichard Henderson         tcg_gen_not_i64(ret, ret);
1441951c6300SRichard Henderson     }
1442951c6300SRichard Henderson }
1443951c6300SRichard Henderson 
1444951c6300SRichard Henderson void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1445951c6300SRichard Henderson {
14463a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14473a13c3f3SRichard Henderson         tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14483a13c3f3SRichard Henderson         tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14493a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_nand_i64) {
1450951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
1451951c6300SRichard Henderson     } else {
1452951c6300SRichard Henderson         tcg_gen_and_i64(ret, arg1, arg2);
1453951c6300SRichard Henderson         tcg_gen_not_i64(ret, ret);
1454951c6300SRichard Henderson     }
1455951c6300SRichard Henderson }
1456951c6300SRichard Henderson 
1457951c6300SRichard Henderson void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1458951c6300SRichard Henderson {
14593a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14603a13c3f3SRichard Henderson         tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14613a13c3f3SRichard Henderson         tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14623a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_nor_i64) {
1463951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
1464951c6300SRichard Henderson     } else {
1465951c6300SRichard Henderson         tcg_gen_or_i64(ret, arg1, arg2);
1466951c6300SRichard Henderson         tcg_gen_not_i64(ret, ret);
1467951c6300SRichard Henderson     }
1468951c6300SRichard Henderson }
1469951c6300SRichard Henderson 
1470951c6300SRichard Henderson void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1471951c6300SRichard Henderson {
14723a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14733a13c3f3SRichard Henderson         tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14743a13c3f3SRichard Henderson         tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14753a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_orc_i64) {
1476951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
1477951c6300SRichard Henderson     } else {
1478951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1479951c6300SRichard Henderson         tcg_gen_not_i64(t0, arg2);
1480951c6300SRichard Henderson         tcg_gen_or_i64(ret, arg1, t0);
1481951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1482951c6300SRichard Henderson     }
1483951c6300SRichard Henderson }
1484951c6300SRichard Henderson 
1485951c6300SRichard Henderson void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1486951c6300SRichard Henderson {
1487951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i64) {
1488951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
1489951c6300SRichard Henderson     } else {
1490951c6300SRichard Henderson         TCGv_i64 t0, t1;
1491951c6300SRichard Henderson         t0 = tcg_temp_new_i64();
1492951c6300SRichard Henderson         t1 = tcg_temp_new_i64();
1493951c6300SRichard Henderson         tcg_gen_shl_i64(t0, arg1, arg2);
1494951c6300SRichard Henderson         tcg_gen_subfi_i64(t1, 64, arg2);
1495951c6300SRichard Henderson         tcg_gen_shr_i64(t1, arg1, t1);
1496951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1497951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1498951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1499951c6300SRichard Henderson     }
1500951c6300SRichard Henderson }
1501951c6300SRichard Henderson 
1502951c6300SRichard Henderson void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1503951c6300SRichard Henderson {
1504951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
1505951c6300SRichard Henderson     /* some cases can be optimized here */
1506951c6300SRichard Henderson     if (arg2 == 0) {
1507951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1508951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_rot_i64) {
1509951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
1510951c6300SRichard Henderson         tcg_gen_rotl_i64(ret, arg1, t0);
1511951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1512951c6300SRichard Henderson     } else {
1513951c6300SRichard Henderson         TCGv_i64 t0, t1;
1514951c6300SRichard Henderson         t0 = tcg_temp_new_i64();
1515951c6300SRichard Henderson         t1 = tcg_temp_new_i64();
1516951c6300SRichard Henderson         tcg_gen_shli_i64(t0, arg1, arg2);
1517951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg1, 64 - arg2);
1518951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1519951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1520951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1521951c6300SRichard Henderson     }
1522951c6300SRichard Henderson }
1523951c6300SRichard Henderson 
1524951c6300SRichard Henderson void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1525951c6300SRichard Henderson {
1526951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i64) {
1527951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
1528951c6300SRichard Henderson     } else {
1529951c6300SRichard Henderson         TCGv_i64 t0, t1;
1530951c6300SRichard Henderson         t0 = tcg_temp_new_i64();
1531951c6300SRichard Henderson         t1 = tcg_temp_new_i64();
1532951c6300SRichard Henderson         tcg_gen_shr_i64(t0, arg1, arg2);
1533951c6300SRichard Henderson         tcg_gen_subfi_i64(t1, 64, arg2);
1534951c6300SRichard Henderson         tcg_gen_shl_i64(t1, arg1, t1);
1535951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1536951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1537951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1538951c6300SRichard Henderson     }
1539951c6300SRichard Henderson }
1540951c6300SRichard Henderson 
1541951c6300SRichard Henderson void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1542951c6300SRichard Henderson {
1543951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
1544951c6300SRichard Henderson     /* some cases can be optimized here */
1545951c6300SRichard Henderson     if (arg2 == 0) {
1546951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1547951c6300SRichard Henderson     } else {
1548951c6300SRichard Henderson         tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
1549951c6300SRichard Henderson     }
1550951c6300SRichard Henderson }
1551951c6300SRichard Henderson 
1552951c6300SRichard Henderson void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
1553951c6300SRichard Henderson                          unsigned int ofs, unsigned int len)
1554951c6300SRichard Henderson {
1555951c6300SRichard Henderson     uint64_t mask;
1556951c6300SRichard Henderson     TCGv_i64 t1;
1557951c6300SRichard Henderson 
1558951c6300SRichard Henderson     tcg_debug_assert(ofs < 64);
1559951c6300SRichard Henderson     tcg_debug_assert(len <= 64);
1560951c6300SRichard Henderson     tcg_debug_assert(ofs + len <= 64);
1561951c6300SRichard Henderson 
1562951c6300SRichard Henderson     if (ofs == 0 && len == 64) {
1563951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg2);
1564951c6300SRichard Henderson         return;
1565951c6300SRichard Henderson     }
1566951c6300SRichard Henderson     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
1567951c6300SRichard Henderson         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
1568951c6300SRichard Henderson         return;
1569951c6300SRichard Henderson     }
1570951c6300SRichard Henderson 
15713a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1572951c6300SRichard Henderson         if (ofs >= 32) {
1573951c6300SRichard Henderson             tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1),
1574951c6300SRichard Henderson                                 TCGV_LOW(arg2), ofs - 32, len);
1575951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1576951c6300SRichard Henderson             return;
1577951c6300SRichard Henderson         }
1578951c6300SRichard Henderson         if (ofs + len <= 32) {
1579951c6300SRichard Henderson             tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1),
1580951c6300SRichard Henderson                                 TCGV_LOW(arg2), ofs, len);
1581951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1582951c6300SRichard Henderson             return;
1583951c6300SRichard Henderson         }
15843a13c3f3SRichard Henderson     }
1585951c6300SRichard Henderson 
1586951c6300SRichard Henderson     mask = (1ull << len) - 1;
1587951c6300SRichard Henderson     t1 = tcg_temp_new_i64();
1588951c6300SRichard Henderson 
1589951c6300SRichard Henderson     if (ofs + len < 64) {
1590951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg2, mask);
1591951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, ofs);
1592951c6300SRichard Henderson     } else {
1593951c6300SRichard Henderson         tcg_gen_shli_i64(t1, arg2, ofs);
1594951c6300SRichard Henderson     }
1595951c6300SRichard Henderson     tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
1596951c6300SRichard Henderson     tcg_gen_or_i64(ret, ret, t1);
1597951c6300SRichard Henderson 
1598951c6300SRichard Henderson     tcg_temp_free_i64(t1);
1599951c6300SRichard Henderson }
1600951c6300SRichard Henderson 
1601951c6300SRichard Henderson void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
1602951c6300SRichard Henderson                          TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2)
1603951c6300SRichard Henderson {
160437ed3bf1SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
160537ed3bf1SRichard Henderson         tcg_gen_mov_i64(ret, v1);
160637ed3bf1SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
160737ed3bf1SRichard Henderson         tcg_gen_mov_i64(ret, v2);
160837ed3bf1SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 32) {
1609951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
1610951c6300SRichard Henderson         TCGv_i32 t1 = tcg_temp_new_i32();
1611951c6300SRichard Henderson         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
1612951c6300SRichard Henderson                          TCGV_LOW(c1), TCGV_HIGH(c1),
1613951c6300SRichard Henderson                          TCGV_LOW(c2), TCGV_HIGH(c2), cond);
1614951c6300SRichard Henderson 
1615951c6300SRichard Henderson         if (TCG_TARGET_HAS_movcond_i32) {
1616951c6300SRichard Henderson             tcg_gen_movi_i32(t1, 0);
1617951c6300SRichard Henderson             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, t1,
1618951c6300SRichard Henderson                                 TCGV_LOW(v1), TCGV_LOW(v2));
1619951c6300SRichard Henderson             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, t1,
1620951c6300SRichard Henderson                                 TCGV_HIGH(v1), TCGV_HIGH(v2));
1621951c6300SRichard Henderson         } else {
1622951c6300SRichard Henderson             tcg_gen_neg_i32(t0, t0);
1623951c6300SRichard Henderson 
1624951c6300SRichard Henderson             tcg_gen_and_i32(t1, TCGV_LOW(v1), t0);
1625951c6300SRichard Henderson             tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0);
1626951c6300SRichard Henderson             tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1);
1627951c6300SRichard Henderson 
1628951c6300SRichard Henderson             tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0);
1629951c6300SRichard Henderson             tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0);
1630951c6300SRichard Henderson             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1);
1631951c6300SRichard Henderson         }
1632951c6300SRichard Henderson         tcg_temp_free_i32(t0);
1633951c6300SRichard Henderson         tcg_temp_free_i32(t1);
16343a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_movcond_i64) {
1635951c6300SRichard Henderson         tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
1636951c6300SRichard Henderson     } else {
1637951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1638951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1639951c6300SRichard Henderson         tcg_gen_setcond_i64(cond, t0, c1, c2);
1640951c6300SRichard Henderson         tcg_gen_neg_i64(t0, t0);
1641951c6300SRichard Henderson         tcg_gen_and_i64(t1, v1, t0);
1642951c6300SRichard Henderson         tcg_gen_andc_i64(ret, v2, t0);
1643951c6300SRichard Henderson         tcg_gen_or_i64(ret, ret, t1);
1644951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1645951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1646951c6300SRichard Henderson     }
1647951c6300SRichard Henderson }
1648951c6300SRichard Henderson 
1649951c6300SRichard Henderson void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
1650951c6300SRichard Henderson                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
1651951c6300SRichard Henderson {
1652951c6300SRichard Henderson     if (TCG_TARGET_HAS_add2_i64) {
1653951c6300SRichard Henderson         tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
1654951c6300SRichard Henderson     } else {
1655951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1656951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1657951c6300SRichard Henderson         tcg_gen_add_i64(t0, al, bl);
1658951c6300SRichard Henderson         tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
1659951c6300SRichard Henderson         tcg_gen_add_i64(rh, ah, bh);
1660951c6300SRichard Henderson         tcg_gen_add_i64(rh, rh, t1);
1661951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1662951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1663951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1664951c6300SRichard Henderson     }
1665951c6300SRichard Henderson }
1666951c6300SRichard Henderson 
1667951c6300SRichard Henderson void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
1668951c6300SRichard Henderson                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
1669951c6300SRichard Henderson {
1670951c6300SRichard Henderson     if (TCG_TARGET_HAS_sub2_i64) {
1671951c6300SRichard Henderson         tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
1672951c6300SRichard Henderson     } else {
1673951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1674951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1675951c6300SRichard Henderson         tcg_gen_sub_i64(t0, al, bl);
1676951c6300SRichard Henderson         tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
1677951c6300SRichard Henderson         tcg_gen_sub_i64(rh, ah, bh);
1678951c6300SRichard Henderson         tcg_gen_sub_i64(rh, rh, t1);
1679951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1680951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1681951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1682951c6300SRichard Henderson     }
1683951c6300SRichard Henderson }
1684951c6300SRichard Henderson 
1685951c6300SRichard Henderson void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
1686951c6300SRichard Henderson {
1687951c6300SRichard Henderson     if (TCG_TARGET_HAS_mulu2_i64) {
1688951c6300SRichard Henderson         tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
1689951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_muluh_i64) {
1690951c6300SRichard Henderson         TCGv_i64 t = tcg_temp_new_i64();
1691951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
1692951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
1693951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t);
1694951c6300SRichard Henderson         tcg_temp_free_i64(t);
1695951c6300SRichard Henderson     } else {
1696951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1697951c6300SRichard Henderson         tcg_gen_mul_i64(t0, arg1, arg2);
1698951c6300SRichard Henderson         gen_helper_muluh_i64(rh, arg1, arg2);
1699951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1700951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1701951c6300SRichard Henderson     }
1702951c6300SRichard Henderson }
1703951c6300SRichard Henderson 
1704951c6300SRichard Henderson void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
1705951c6300SRichard Henderson {
1706951c6300SRichard Henderson     if (TCG_TARGET_HAS_muls2_i64) {
1707951c6300SRichard Henderson         tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
1708951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_mulsh_i64) {
1709951c6300SRichard Henderson         TCGv_i64 t = tcg_temp_new_i64();
1710951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
1711951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
1712951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t);
1713951c6300SRichard Henderson         tcg_temp_free_i64(t);
1714951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
1715951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1716951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1717951c6300SRichard Henderson         TCGv_i64 t2 = tcg_temp_new_i64();
1718951c6300SRichard Henderson         TCGv_i64 t3 = tcg_temp_new_i64();
1719951c6300SRichard Henderson         tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
1720951c6300SRichard Henderson         /* Adjust for negative inputs.  */
1721951c6300SRichard Henderson         tcg_gen_sari_i64(t2, arg1, 63);
1722951c6300SRichard Henderson         tcg_gen_sari_i64(t3, arg2, 63);
1723951c6300SRichard Henderson         tcg_gen_and_i64(t2, t2, arg2);
1724951c6300SRichard Henderson         tcg_gen_and_i64(t3, t3, arg1);
1725951c6300SRichard Henderson         tcg_gen_sub_i64(rh, t1, t2);
1726951c6300SRichard Henderson         tcg_gen_sub_i64(rh, rh, t3);
1727951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1728951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1729951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1730951c6300SRichard Henderson         tcg_temp_free_i64(t2);
1731951c6300SRichard Henderson         tcg_temp_free_i64(t3);
1732951c6300SRichard Henderson     } else {
1733951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1734951c6300SRichard Henderson         tcg_gen_mul_i64(t0, arg1, arg2);
1735951c6300SRichard Henderson         gen_helper_mulsh_i64(rh, arg1, arg2);
1736951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1737951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1738951c6300SRichard Henderson     }
1739951c6300SRichard Henderson }
1740951c6300SRichard Henderson 
1741951c6300SRichard Henderson /* Size changing operations.  */
1742951c6300SRichard Henderson 
1743609ad705SRichard Henderson void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
1744951c6300SRichard Henderson {
17453a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1746951c6300SRichard Henderson         tcg_gen_mov_i32(ret, TCGV_LOW(arg));
1747609ad705SRichard Henderson     } else if (TCG_TARGET_HAS_extrl_i64_i32) {
1748609ad705SRichard Henderson         tcg_gen_op2(&tcg_ctx, INDEX_op_extrl_i64_i32,
1749609ad705SRichard Henderson                     GET_TCGV_I32(ret), GET_TCGV_I64(arg));
1750951c6300SRichard Henderson     } else {
1751951c6300SRichard Henderson         tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(arg)));
1752609ad705SRichard Henderson     }
1753609ad705SRichard Henderson }
1754609ad705SRichard Henderson 
1755609ad705SRichard Henderson void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
1756609ad705SRichard Henderson {
1757609ad705SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1758609ad705SRichard Henderson         tcg_gen_mov_i32(ret, TCGV_HIGH(arg));
1759609ad705SRichard Henderson     } else if (TCG_TARGET_HAS_extrh_i64_i32) {
1760609ad705SRichard Henderson         tcg_gen_op2(&tcg_ctx, INDEX_op_extrh_i64_i32,
1761609ad705SRichard Henderson                     GET_TCGV_I32(ret), GET_TCGV_I64(arg));
1762951c6300SRichard Henderson     } else {
1763951c6300SRichard Henderson         TCGv_i64 t = tcg_temp_new_i64();
1764609ad705SRichard Henderson         tcg_gen_shri_i64(t, arg, 32);
1765951c6300SRichard Henderson         tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(t)));
1766951c6300SRichard Henderson         tcg_temp_free_i64(t);
1767951c6300SRichard Henderson     }
1768951c6300SRichard Henderson }
1769951c6300SRichard Henderson 
1770951c6300SRichard Henderson void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
1771951c6300SRichard Henderson {
17723a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1773951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
1774951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
17753a13c3f3SRichard Henderson     } else {
17764f2331e5SAurelien Jarno         tcg_gen_op2(&tcg_ctx, INDEX_op_extu_i32_i64,
17774f2331e5SAurelien Jarno                     GET_TCGV_I64(ret), GET_TCGV_I32(arg));
17783a13c3f3SRichard Henderson     }
1779951c6300SRichard Henderson }
1780951c6300SRichard Henderson 
1781951c6300SRichard Henderson void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
1782951c6300SRichard Henderson {
17833a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1784951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
1785951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
17863a13c3f3SRichard Henderson     } else {
17874f2331e5SAurelien Jarno         tcg_gen_op2(&tcg_ctx, INDEX_op_ext_i32_i64,
17884f2331e5SAurelien Jarno                     GET_TCGV_I64(ret), GET_TCGV_I32(arg));
17893a13c3f3SRichard Henderson     }
1790951c6300SRichard Henderson }
1791951c6300SRichard Henderson 
1792951c6300SRichard Henderson void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
1793951c6300SRichard Henderson {
17943a13c3f3SRichard Henderson     TCGv_i64 tmp;
17953a13c3f3SRichard Henderson 
17963a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1797951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(dest), low);
1798951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(dest), high);
17993a13c3f3SRichard Henderson         return;
18003a13c3f3SRichard Henderson     }
18013a13c3f3SRichard Henderson 
18023a13c3f3SRichard Henderson     tmp = tcg_temp_new_i64();
1803951c6300SRichard Henderson     /* These extensions are only needed for type correctness.
1804951c6300SRichard Henderson        We may be able to do better given target specific information.  */
1805951c6300SRichard Henderson     tcg_gen_extu_i32_i64(tmp, high);
1806951c6300SRichard Henderson     tcg_gen_extu_i32_i64(dest, low);
1807951c6300SRichard Henderson     /* If deposit is available, use it.  Otherwise use the extra
1808951c6300SRichard Henderson        knowledge that we have of the zero-extensions above.  */
1809951c6300SRichard Henderson     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
1810951c6300SRichard Henderson         tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
1811951c6300SRichard Henderson     } else {
1812951c6300SRichard Henderson         tcg_gen_shli_i64(tmp, tmp, 32);
1813951c6300SRichard Henderson         tcg_gen_or_i64(dest, dest, tmp);
1814951c6300SRichard Henderson     }
1815951c6300SRichard Henderson     tcg_temp_free_i64(tmp);
1816951c6300SRichard Henderson }
1817951c6300SRichard Henderson 
1818951c6300SRichard Henderson void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
1819951c6300SRichard Henderson {
18203a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1821951c6300SRichard Henderson         tcg_gen_mov_i32(lo, TCGV_LOW(arg));
1822951c6300SRichard Henderson         tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
18233a13c3f3SRichard Henderson     } else {
1824609ad705SRichard Henderson         tcg_gen_extrl_i64_i32(lo, arg);
1825609ad705SRichard Henderson         tcg_gen_extrh_i64_i32(hi, arg);
18263a13c3f3SRichard Henderson     }
1827951c6300SRichard Henderson }
1828951c6300SRichard Henderson 
1829951c6300SRichard Henderson void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
1830951c6300SRichard Henderson {
1831951c6300SRichard Henderson     tcg_gen_ext32u_i64(lo, arg);
1832951c6300SRichard Henderson     tcg_gen_shri_i64(hi, arg, 32);
1833951c6300SRichard Henderson }
1834951c6300SRichard Henderson 
1835951c6300SRichard Henderson /* QEMU specific operations.  */
1836951c6300SRichard Henderson 
1837951c6300SRichard Henderson void tcg_gen_goto_tb(unsigned idx)
1838951c6300SRichard Henderson {
1839951c6300SRichard Henderson     /* We only support two chained exits.  */
1840951c6300SRichard Henderson     tcg_debug_assert(idx <= 1);
1841951c6300SRichard Henderson #ifdef CONFIG_DEBUG_TCG
1842951c6300SRichard Henderson     /* Verify that we havn't seen this numbered exit before.  */
1843951c6300SRichard Henderson     tcg_debug_assert((tcg_ctx.goto_tb_issue_mask & (1 << idx)) == 0);
1844951c6300SRichard Henderson     tcg_ctx.goto_tb_issue_mask |= 1 << idx;
1845951c6300SRichard Henderson #endif
1846951c6300SRichard Henderson     tcg_gen_op1i(INDEX_op_goto_tb, idx);
1847951c6300SRichard Henderson }
1848951c6300SRichard Henderson 
1849951c6300SRichard Henderson static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st)
1850951c6300SRichard Henderson {
1851951c6300SRichard Henderson     switch (op & MO_SIZE) {
1852951c6300SRichard Henderson     case MO_8:
1853951c6300SRichard Henderson         op &= ~MO_BSWAP;
1854951c6300SRichard Henderson         break;
1855951c6300SRichard Henderson     case MO_16:
1856951c6300SRichard Henderson         break;
1857951c6300SRichard Henderson     case MO_32:
1858951c6300SRichard Henderson         if (!is64) {
1859951c6300SRichard Henderson             op &= ~MO_SIGN;
1860951c6300SRichard Henderson         }
1861951c6300SRichard Henderson         break;
1862951c6300SRichard Henderson     case MO_64:
1863951c6300SRichard Henderson         if (!is64) {
1864951c6300SRichard Henderson             tcg_abort();
1865951c6300SRichard Henderson         }
1866951c6300SRichard Henderson         break;
1867951c6300SRichard Henderson     }
1868951c6300SRichard Henderson     if (st) {
1869951c6300SRichard Henderson         op &= ~MO_SIGN;
1870951c6300SRichard Henderson     }
1871951c6300SRichard Henderson     return op;
1872951c6300SRichard Henderson }
1873951c6300SRichard Henderson 
1874c45cb8bbSRichard Henderson static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv addr,
1875c45cb8bbSRichard Henderson                          TCGMemOp memop, TCGArg idx)
1876951c6300SRichard Henderson {
187759227d5dSRichard Henderson     TCGMemOpIdx oi = make_memop_idx(memop, idx);
1878951c6300SRichard Henderson #if TARGET_LONG_BITS == 32
187959227d5dSRichard Henderson     tcg_gen_op3i_i32(opc, val, addr, oi);
1880951c6300SRichard Henderson #else
1881c45cb8bbSRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
188259227d5dSRichard Henderson         tcg_gen_op4i_i32(opc, val, TCGV_LOW(addr), TCGV_HIGH(addr), oi);
1883c45cb8bbSRichard Henderson     } else {
188459227d5dSRichard Henderson         tcg_gen_op3(&tcg_ctx, opc, GET_TCGV_I32(val), GET_TCGV_I64(addr), oi);
1885c45cb8bbSRichard Henderson     }
1886951c6300SRichard Henderson #endif
1887c45cb8bbSRichard Henderson }
1888c45cb8bbSRichard Henderson 
1889c45cb8bbSRichard Henderson static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 val, TCGv addr,
1890c45cb8bbSRichard Henderson                          TCGMemOp memop, TCGArg idx)
1891c45cb8bbSRichard Henderson {
189259227d5dSRichard Henderson     TCGMemOpIdx oi = make_memop_idx(memop, idx);
1893c45cb8bbSRichard Henderson #if TARGET_LONG_BITS == 32
1894c45cb8bbSRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
189559227d5dSRichard Henderson         tcg_gen_op4i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), addr, oi);
1896c45cb8bbSRichard Henderson     } else {
189759227d5dSRichard Henderson         tcg_gen_op3(&tcg_ctx, opc, GET_TCGV_I64(val), GET_TCGV_I32(addr), oi);
1898c45cb8bbSRichard Henderson     }
1899c45cb8bbSRichard Henderson #else
1900c45cb8bbSRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
190159227d5dSRichard Henderson         tcg_gen_op5i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val),
190259227d5dSRichard Henderson                          TCGV_LOW(addr), TCGV_HIGH(addr), oi);
1903c45cb8bbSRichard Henderson     } else {
190459227d5dSRichard Henderson         tcg_gen_op3i_i64(opc, val, addr, oi);
1905c45cb8bbSRichard Henderson     }
1906c45cb8bbSRichard Henderson #endif
1907c45cb8bbSRichard Henderson }
1908951c6300SRichard Henderson 
1909951c6300SRichard Henderson void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1910951c6300SRichard Henderson {
1911951c6300SRichard Henderson     memop = tcg_canonicalize_memop(memop, 0, 0);
1912c45cb8bbSRichard Henderson     gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx);
1913951c6300SRichard Henderson }
1914951c6300SRichard Henderson 
1915951c6300SRichard Henderson void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1916951c6300SRichard Henderson {
1917951c6300SRichard Henderson     memop = tcg_canonicalize_memop(memop, 0, 1);
1918c45cb8bbSRichard Henderson     gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
1919951c6300SRichard Henderson }
1920951c6300SRichard Henderson 
1921951c6300SRichard Henderson void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1922951c6300SRichard Henderson {
19233a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
1924951c6300SRichard Henderson         tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop);
1925951c6300SRichard Henderson         if (memop & MO_SIGN) {
1926951c6300SRichard Henderson             tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31);
1927951c6300SRichard Henderson         } else {
1928951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_HIGH(val), 0);
1929951c6300SRichard Henderson         }
1930951c6300SRichard Henderson         return;
1931951c6300SRichard Henderson     }
1932951c6300SRichard Henderson 
1933c45cb8bbSRichard Henderson     memop = tcg_canonicalize_memop(memop, 1, 0);
1934c45cb8bbSRichard Henderson     gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx);
1935951c6300SRichard Henderson }
1936951c6300SRichard Henderson 
1937951c6300SRichard Henderson void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1938951c6300SRichard Henderson {
19393a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
1940951c6300SRichard Henderson         tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop);
1941951c6300SRichard Henderson         return;
1942951c6300SRichard Henderson     }
1943951c6300SRichard Henderson 
1944c45cb8bbSRichard Henderson     memop = tcg_canonicalize_memop(memop, 1, 1);
1945c45cb8bbSRichard Henderson     gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx);
1946951c6300SRichard Henderson }
1947