xref: /openbmc/qemu/tcg/tcg-op.c (revision 37ed3bf1)
1951c6300SRichard Henderson /*
2951c6300SRichard Henderson  * Tiny Code Generator for QEMU
3951c6300SRichard Henderson  *
4951c6300SRichard Henderson  * Copyright (c) 2008 Fabrice Bellard
5951c6300SRichard Henderson  *
6951c6300SRichard Henderson  * Permission is hereby granted, free of charge, to any person obtaining a copy
7951c6300SRichard Henderson  * of this software and associated documentation files (the "Software"), to deal
8951c6300SRichard Henderson  * in the Software without restriction, including without limitation the rights
9951c6300SRichard Henderson  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10951c6300SRichard Henderson  * copies of the Software, and to permit persons to whom the Software is
11951c6300SRichard Henderson  * furnished to do so, subject to the following conditions:
12951c6300SRichard Henderson  *
13951c6300SRichard Henderson  * The above copyright notice and this permission notice shall be included in
14951c6300SRichard Henderson  * all copies or substantial portions of the Software.
15951c6300SRichard Henderson  *
16951c6300SRichard Henderson  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17951c6300SRichard Henderson  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18951c6300SRichard Henderson  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19951c6300SRichard Henderson  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20951c6300SRichard Henderson  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21951c6300SRichard Henderson  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22951c6300SRichard Henderson  * THE SOFTWARE.
23951c6300SRichard Henderson  */
24951c6300SRichard Henderson 
25951c6300SRichard Henderson #include "tcg.h"
26951c6300SRichard Henderson #include "tcg-op.h"
27951c6300SRichard Henderson 
283a13c3f3SRichard Henderson /* Reduce the number of ifdefs below.  This assumes that all uses of
293a13c3f3SRichard Henderson    TCGV_HIGH and TCGV_LOW are properly protected by a conditional that
303a13c3f3SRichard Henderson    the compiler can eliminate.  */
313a13c3f3SRichard Henderson #if TCG_TARGET_REG_BITS == 64
323a13c3f3SRichard Henderson extern TCGv_i32 TCGV_LOW_link_error(TCGv_i64);
333a13c3f3SRichard Henderson extern TCGv_i32 TCGV_HIGH_link_error(TCGv_i64);
343a13c3f3SRichard Henderson #define TCGV_LOW  TCGV_LOW_link_error
353a13c3f3SRichard Henderson #define TCGV_HIGH TCGV_HIGH_link_error
363a13c3f3SRichard Henderson #endif
37951c6300SRichard Henderson 
38c45cb8bbSRichard Henderson /* Note that this is optimized for sequential allocation during translate.
39c45cb8bbSRichard Henderson    Up to and including filling in the forward link immediately.  We'll do
40c45cb8bbSRichard Henderson    proper termination of the end of the list after we finish translation.  */
41c45cb8bbSRichard Henderson 
42c45cb8bbSRichard Henderson static void tcg_emit_op(TCGContext *ctx, TCGOpcode opc, int args)
43c45cb8bbSRichard Henderson {
44c45cb8bbSRichard Henderson     int oi = ctx->gen_next_op_idx;
45c45cb8bbSRichard Henderson     int ni = oi + 1;
46c45cb8bbSRichard Henderson     int pi = oi - 1;
47c45cb8bbSRichard Henderson 
48c45cb8bbSRichard Henderson     tcg_debug_assert(oi < OPC_BUF_SIZE);
49c45cb8bbSRichard Henderson     ctx->gen_last_op_idx = oi;
50c45cb8bbSRichard Henderson     ctx->gen_next_op_idx = ni;
51c45cb8bbSRichard Henderson 
52c45cb8bbSRichard Henderson     ctx->gen_op_buf[oi] = (TCGOp){
53c45cb8bbSRichard Henderson         .opc = opc,
54c45cb8bbSRichard Henderson         .args = args,
55c45cb8bbSRichard Henderson         .prev = pi,
56c45cb8bbSRichard Henderson         .next = ni
57c45cb8bbSRichard Henderson     };
58c45cb8bbSRichard Henderson }
59c45cb8bbSRichard Henderson 
60951c6300SRichard Henderson void tcg_gen_op1(TCGContext *ctx, TCGOpcode opc, TCGArg a1)
61951c6300SRichard Henderson {
62c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
63951c6300SRichard Henderson 
64c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 1 <= OPPARAM_BUF_SIZE);
65c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 1;
66c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi] = a1;
67951c6300SRichard Henderson 
68c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
69951c6300SRichard Henderson }
70951c6300SRichard Henderson 
71951c6300SRichard Henderson void tcg_gen_op2(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2)
72951c6300SRichard Henderson {
73c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
74951c6300SRichard Henderson 
75c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 2 <= OPPARAM_BUF_SIZE);
76c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 2;
77c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
78c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
79951c6300SRichard Henderson 
80c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
81951c6300SRichard Henderson }
82951c6300SRichard Henderson 
83951c6300SRichard Henderson void tcg_gen_op3(TCGContext *ctx, TCGOpcode opc, TCGArg a1,
84951c6300SRichard Henderson                  TCGArg a2, TCGArg a3)
85951c6300SRichard Henderson {
86c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
87951c6300SRichard Henderson 
88c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 3 <= OPPARAM_BUF_SIZE);
89c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 3;
90c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
91c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
92c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 2] = a3;
93951c6300SRichard Henderson 
94c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
95951c6300SRichard Henderson }
96951c6300SRichard Henderson 
97951c6300SRichard Henderson void tcg_gen_op4(TCGContext *ctx, TCGOpcode opc, TCGArg a1,
98951c6300SRichard Henderson                  TCGArg a2, TCGArg a3, TCGArg a4)
99951c6300SRichard Henderson {
100c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
101951c6300SRichard Henderson 
102c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 4 <= OPPARAM_BUF_SIZE);
103c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 4;
104c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
105c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
106c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 2] = a3;
107c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 3] = a4;
108951c6300SRichard Henderson 
109c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
110951c6300SRichard Henderson }
111951c6300SRichard Henderson 
112951c6300SRichard Henderson void tcg_gen_op5(TCGContext *ctx, TCGOpcode opc, TCGArg a1,
113951c6300SRichard Henderson                  TCGArg a2, TCGArg a3, TCGArg a4, TCGArg a5)
114951c6300SRichard Henderson {
115c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
116951c6300SRichard Henderson 
117c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 5 <= OPPARAM_BUF_SIZE);
118c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 5;
119c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
120c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
121c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 2] = a3;
122c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 3] = a4;
123c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 4] = a5;
124951c6300SRichard Henderson 
125c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
126951c6300SRichard Henderson }
127951c6300SRichard Henderson 
128951c6300SRichard Henderson void tcg_gen_op6(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2,
129951c6300SRichard Henderson                  TCGArg a3, TCGArg a4, TCGArg a5, TCGArg a6)
130951c6300SRichard Henderson {
131c45cb8bbSRichard Henderson     int pi = ctx->gen_next_parm_idx;
132951c6300SRichard Henderson 
133c45cb8bbSRichard Henderson     tcg_debug_assert(pi + 6 <= OPPARAM_BUF_SIZE);
134c45cb8bbSRichard Henderson     ctx->gen_next_parm_idx = pi + 6;
135c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 0] = a1;
136c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 1] = a2;
137c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 2] = a3;
138c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 3] = a4;
139c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 4] = a5;
140c45cb8bbSRichard Henderson     ctx->gen_opparam_buf[pi + 5] = a6;
141951c6300SRichard Henderson 
142c45cb8bbSRichard Henderson     tcg_emit_op(ctx, opc, pi);
143951c6300SRichard Henderson }
144951c6300SRichard Henderson 
145951c6300SRichard Henderson /* 32 bit ops */
146951c6300SRichard Henderson 
147951c6300SRichard Henderson void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
148951c6300SRichard Henderson {
149951c6300SRichard Henderson     /* some cases can be optimized here */
150951c6300SRichard Henderson     if (arg2 == 0) {
151951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
152951c6300SRichard Henderson     } else {
153951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
154951c6300SRichard Henderson         tcg_gen_add_i32(ret, arg1, t0);
155951c6300SRichard Henderson         tcg_temp_free_i32(t0);
156951c6300SRichard Henderson     }
157951c6300SRichard Henderson }
158951c6300SRichard Henderson 
159951c6300SRichard Henderson void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2)
160951c6300SRichard Henderson {
161951c6300SRichard Henderson     if (arg1 == 0 && TCG_TARGET_HAS_neg_i32) {
162951c6300SRichard Henderson         /* Don't recurse with tcg_gen_neg_i32.  */
163951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg2);
164951c6300SRichard Henderson     } else {
165951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg1);
166951c6300SRichard Henderson         tcg_gen_sub_i32(ret, t0, arg2);
167951c6300SRichard Henderson         tcg_temp_free_i32(t0);
168951c6300SRichard Henderson     }
169951c6300SRichard Henderson }
170951c6300SRichard Henderson 
171951c6300SRichard Henderson void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
172951c6300SRichard Henderson {
173951c6300SRichard Henderson     /* some cases can be optimized here */
174951c6300SRichard Henderson     if (arg2 == 0) {
175951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
176951c6300SRichard Henderson     } else {
177951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
178951c6300SRichard Henderson         tcg_gen_sub_i32(ret, arg1, t0);
179951c6300SRichard Henderson         tcg_temp_free_i32(t0);
180951c6300SRichard Henderson     }
181951c6300SRichard Henderson }
182951c6300SRichard Henderson 
183951c6300SRichard Henderson void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
184951c6300SRichard Henderson {
185951c6300SRichard Henderson     TCGv_i32 t0;
186951c6300SRichard Henderson     /* Some cases can be optimized here.  */
187951c6300SRichard Henderson     switch (arg2) {
188951c6300SRichard Henderson     case 0:
189951c6300SRichard Henderson         tcg_gen_movi_i32(ret, 0);
190951c6300SRichard Henderson         return;
191951c6300SRichard Henderson     case 0xffffffffu:
192951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
193951c6300SRichard Henderson         return;
194951c6300SRichard Henderson     case 0xffu:
195951c6300SRichard Henderson         /* Don't recurse with tcg_gen_ext8u_i32.  */
196951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext8u_i32) {
197951c6300SRichard Henderson             tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
198951c6300SRichard Henderson             return;
199951c6300SRichard Henderson         }
200951c6300SRichard Henderson         break;
201951c6300SRichard Henderson     case 0xffffu:
202951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext16u_i32) {
203951c6300SRichard Henderson             tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
204951c6300SRichard Henderson             return;
205951c6300SRichard Henderson         }
206951c6300SRichard Henderson         break;
207951c6300SRichard Henderson     }
208951c6300SRichard Henderson     t0 = tcg_const_i32(arg2);
209951c6300SRichard Henderson     tcg_gen_and_i32(ret, arg1, t0);
210951c6300SRichard Henderson     tcg_temp_free_i32(t0);
211951c6300SRichard Henderson }
212951c6300SRichard Henderson 
213951c6300SRichard Henderson void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
214951c6300SRichard Henderson {
215951c6300SRichard Henderson     /* Some cases can be optimized here.  */
216951c6300SRichard Henderson     if (arg2 == -1) {
217951c6300SRichard Henderson         tcg_gen_movi_i32(ret, -1);
218951c6300SRichard Henderson     } else if (arg2 == 0) {
219951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
220951c6300SRichard Henderson     } else {
221951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
222951c6300SRichard Henderson         tcg_gen_or_i32(ret, arg1, t0);
223951c6300SRichard Henderson         tcg_temp_free_i32(t0);
224951c6300SRichard Henderson     }
225951c6300SRichard Henderson }
226951c6300SRichard Henderson 
227951c6300SRichard Henderson void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
228951c6300SRichard Henderson {
229951c6300SRichard Henderson     /* Some cases can be optimized here.  */
230951c6300SRichard Henderson     if (arg2 == 0) {
231951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
232951c6300SRichard Henderson     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) {
233951c6300SRichard Henderson         /* Don't recurse with tcg_gen_not_i32.  */
234951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1);
235951c6300SRichard Henderson     } else {
236951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
237951c6300SRichard Henderson         tcg_gen_xor_i32(ret, arg1, t0);
238951c6300SRichard Henderson         tcg_temp_free_i32(t0);
239951c6300SRichard Henderson     }
240951c6300SRichard Henderson }
241951c6300SRichard Henderson 
242951c6300SRichard Henderson void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
243951c6300SRichard Henderson {
244951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
245951c6300SRichard Henderson     if (arg2 == 0) {
246951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
247951c6300SRichard Henderson     } else {
248951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
249951c6300SRichard Henderson         tcg_gen_shl_i32(ret, arg1, t0);
250951c6300SRichard Henderson         tcg_temp_free_i32(t0);
251951c6300SRichard Henderson     }
252951c6300SRichard Henderson }
253951c6300SRichard Henderson 
254951c6300SRichard Henderson void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
255951c6300SRichard Henderson {
256951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
257951c6300SRichard Henderson     if (arg2 == 0) {
258951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
259951c6300SRichard Henderson     } else {
260951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
261951c6300SRichard Henderson         tcg_gen_shr_i32(ret, arg1, t0);
262951c6300SRichard Henderson         tcg_temp_free_i32(t0);
263951c6300SRichard Henderson     }
264951c6300SRichard Henderson }
265951c6300SRichard Henderson 
266951c6300SRichard Henderson void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
267951c6300SRichard Henderson {
268951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
269951c6300SRichard Henderson     if (arg2 == 0) {
270951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
271951c6300SRichard Henderson     } else {
272951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
273951c6300SRichard Henderson         tcg_gen_sar_i32(ret, arg1, t0);
274951c6300SRichard Henderson         tcg_temp_free_i32(t0);
275951c6300SRichard Henderson     }
276951c6300SRichard Henderson }
277951c6300SRichard Henderson 
27842a268c2SRichard Henderson void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l)
279951c6300SRichard Henderson {
280951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
28142a268c2SRichard Henderson         tcg_gen_br(l);
282951c6300SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
28342a268c2SRichard Henderson         tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l));
284951c6300SRichard Henderson     }
285951c6300SRichard Henderson }
286951c6300SRichard Henderson 
28742a268c2SRichard Henderson void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l)
288951c6300SRichard Henderson {
289*37ed3bf1SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
290*37ed3bf1SRichard Henderson         tcg_gen_br(l);
291*37ed3bf1SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
292951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
29342a268c2SRichard Henderson         tcg_gen_brcond_i32(cond, arg1, t0, l);
294951c6300SRichard Henderson         tcg_temp_free_i32(t0);
295951c6300SRichard Henderson     }
296*37ed3bf1SRichard Henderson }
297951c6300SRichard Henderson 
298951c6300SRichard Henderson void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
299951c6300SRichard Henderson                          TCGv_i32 arg1, TCGv_i32 arg2)
300951c6300SRichard Henderson {
301951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
302951c6300SRichard Henderson         tcg_gen_movi_i32(ret, 1);
303951c6300SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
304951c6300SRichard Henderson         tcg_gen_movi_i32(ret, 0);
305951c6300SRichard Henderson     } else {
306951c6300SRichard Henderson         tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
307951c6300SRichard Henderson     }
308951c6300SRichard Henderson }
309951c6300SRichard Henderson 
310951c6300SRichard Henderson void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
311951c6300SRichard Henderson                           TCGv_i32 arg1, int32_t arg2)
312951c6300SRichard Henderson {
313951c6300SRichard Henderson     TCGv_i32 t0 = tcg_const_i32(arg2);
314951c6300SRichard Henderson     tcg_gen_setcond_i32(cond, ret, arg1, t0);
315951c6300SRichard Henderson     tcg_temp_free_i32(t0);
316951c6300SRichard Henderson }
317951c6300SRichard Henderson 
318951c6300SRichard Henderson void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
319951c6300SRichard Henderson {
320951c6300SRichard Henderson     TCGv_i32 t0 = tcg_const_i32(arg2);
321951c6300SRichard Henderson     tcg_gen_mul_i32(ret, arg1, t0);
322951c6300SRichard Henderson     tcg_temp_free_i32(t0);
323951c6300SRichard Henderson }
324951c6300SRichard Henderson 
325951c6300SRichard Henderson void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
326951c6300SRichard Henderson {
327951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i32) {
328951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
329951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
330951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
331951c6300SRichard Henderson         tcg_gen_sari_i32(t0, arg1, 31);
332951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
333951c6300SRichard Henderson         tcg_temp_free_i32(t0);
334951c6300SRichard Henderson     } else {
335951c6300SRichard Henderson         gen_helper_div_i32(ret, arg1, arg2);
336951c6300SRichard Henderson     }
337951c6300SRichard Henderson }
338951c6300SRichard Henderson 
339951c6300SRichard Henderson void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
340951c6300SRichard Henderson {
341951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i32) {
342951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
343951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i32) {
344951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
345951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
346951c6300SRichard Henderson         tcg_gen_mul_i32(t0, t0, arg2);
347951c6300SRichard Henderson         tcg_gen_sub_i32(ret, arg1, t0);
348951c6300SRichard Henderson         tcg_temp_free_i32(t0);
349951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
350951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
351951c6300SRichard Henderson         tcg_gen_sari_i32(t0, arg1, 31);
352951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
353951c6300SRichard Henderson         tcg_temp_free_i32(t0);
354951c6300SRichard Henderson     } else {
355951c6300SRichard Henderson         gen_helper_rem_i32(ret, arg1, arg2);
356951c6300SRichard Henderson     }
357951c6300SRichard Henderson }
358951c6300SRichard Henderson 
359951c6300SRichard Henderson void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
360951c6300SRichard Henderson {
361951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i32) {
362951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
363951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
364951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
365951c6300SRichard Henderson         tcg_gen_movi_i32(t0, 0);
366951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
367951c6300SRichard Henderson         tcg_temp_free_i32(t0);
368951c6300SRichard Henderson     } else {
369951c6300SRichard Henderson         gen_helper_divu_i32(ret, arg1, arg2);
370951c6300SRichard Henderson     }
371951c6300SRichard Henderson }
372951c6300SRichard Henderson 
373951c6300SRichard Henderson void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
374951c6300SRichard Henderson {
375951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i32) {
376951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
377951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i32) {
378951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
379951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
380951c6300SRichard Henderson         tcg_gen_mul_i32(t0, t0, arg2);
381951c6300SRichard Henderson         tcg_gen_sub_i32(ret, arg1, t0);
382951c6300SRichard Henderson         tcg_temp_free_i32(t0);
383951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
384951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
385951c6300SRichard Henderson         tcg_gen_movi_i32(t0, 0);
386951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
387951c6300SRichard Henderson         tcg_temp_free_i32(t0);
388951c6300SRichard Henderson     } else {
389951c6300SRichard Henderson         gen_helper_remu_i32(ret, arg1, arg2);
390951c6300SRichard Henderson     }
391951c6300SRichard Henderson }
392951c6300SRichard Henderson 
393951c6300SRichard Henderson void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
394951c6300SRichard Henderson {
395951c6300SRichard Henderson     if (TCG_TARGET_HAS_andc_i32) {
396951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
397951c6300SRichard Henderson     } else {
398951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
399951c6300SRichard Henderson         tcg_gen_not_i32(t0, arg2);
400951c6300SRichard Henderson         tcg_gen_and_i32(ret, arg1, t0);
401951c6300SRichard Henderson         tcg_temp_free_i32(t0);
402951c6300SRichard Henderson     }
403951c6300SRichard Henderson }
404951c6300SRichard Henderson 
405951c6300SRichard Henderson void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
406951c6300SRichard Henderson {
407951c6300SRichard Henderson     if (TCG_TARGET_HAS_eqv_i32) {
408951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
409951c6300SRichard Henderson     } else {
410951c6300SRichard Henderson         tcg_gen_xor_i32(ret, arg1, arg2);
411951c6300SRichard Henderson         tcg_gen_not_i32(ret, ret);
412951c6300SRichard Henderson     }
413951c6300SRichard Henderson }
414951c6300SRichard Henderson 
415951c6300SRichard Henderson void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
416951c6300SRichard Henderson {
417951c6300SRichard Henderson     if (TCG_TARGET_HAS_nand_i32) {
418951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
419951c6300SRichard Henderson     } else {
420951c6300SRichard Henderson         tcg_gen_and_i32(ret, arg1, arg2);
421951c6300SRichard Henderson         tcg_gen_not_i32(ret, ret);
422951c6300SRichard Henderson     }
423951c6300SRichard Henderson }
424951c6300SRichard Henderson 
425951c6300SRichard Henderson void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
426951c6300SRichard Henderson {
427951c6300SRichard Henderson     if (TCG_TARGET_HAS_nor_i32) {
428951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
429951c6300SRichard Henderson     } else {
430951c6300SRichard Henderson         tcg_gen_or_i32(ret, arg1, arg2);
431951c6300SRichard Henderson         tcg_gen_not_i32(ret, ret);
432951c6300SRichard Henderson     }
433951c6300SRichard Henderson }
434951c6300SRichard Henderson 
435951c6300SRichard Henderson void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
436951c6300SRichard Henderson {
437951c6300SRichard Henderson     if (TCG_TARGET_HAS_orc_i32) {
438951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
439951c6300SRichard Henderson     } else {
440951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
441951c6300SRichard Henderson         tcg_gen_not_i32(t0, arg2);
442951c6300SRichard Henderson         tcg_gen_or_i32(ret, arg1, t0);
443951c6300SRichard Henderson         tcg_temp_free_i32(t0);
444951c6300SRichard Henderson     }
445951c6300SRichard Henderson }
446951c6300SRichard Henderson 
447951c6300SRichard Henderson void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
448951c6300SRichard Henderson {
449951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i32) {
450951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
451951c6300SRichard Henderson     } else {
452951c6300SRichard Henderson         TCGv_i32 t0, t1;
453951c6300SRichard Henderson 
454951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
455951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
456951c6300SRichard Henderson         tcg_gen_shl_i32(t0, arg1, arg2);
457951c6300SRichard Henderson         tcg_gen_subfi_i32(t1, 32, arg2);
458951c6300SRichard Henderson         tcg_gen_shr_i32(t1, arg1, t1);
459951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
460951c6300SRichard Henderson         tcg_temp_free_i32(t0);
461951c6300SRichard Henderson         tcg_temp_free_i32(t1);
462951c6300SRichard Henderson     }
463951c6300SRichard Henderson }
464951c6300SRichard Henderson 
465951c6300SRichard Henderson void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
466951c6300SRichard Henderson {
467951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
468951c6300SRichard Henderson     /* some cases can be optimized here */
469951c6300SRichard Henderson     if (arg2 == 0) {
470951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
471951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_rot_i32) {
472951c6300SRichard Henderson         TCGv_i32 t0 = tcg_const_i32(arg2);
473951c6300SRichard Henderson         tcg_gen_rotl_i32(ret, arg1, t0);
474951c6300SRichard Henderson         tcg_temp_free_i32(t0);
475951c6300SRichard Henderson     } else {
476951c6300SRichard Henderson         TCGv_i32 t0, t1;
477951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
478951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
479951c6300SRichard Henderson         tcg_gen_shli_i32(t0, arg1, arg2);
480951c6300SRichard Henderson         tcg_gen_shri_i32(t1, arg1, 32 - arg2);
481951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
482951c6300SRichard Henderson         tcg_temp_free_i32(t0);
483951c6300SRichard Henderson         tcg_temp_free_i32(t1);
484951c6300SRichard Henderson     }
485951c6300SRichard Henderson }
486951c6300SRichard Henderson 
487951c6300SRichard Henderson void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
488951c6300SRichard Henderson {
489951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i32) {
490951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
491951c6300SRichard Henderson     } else {
492951c6300SRichard Henderson         TCGv_i32 t0, t1;
493951c6300SRichard Henderson 
494951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
495951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
496951c6300SRichard Henderson         tcg_gen_shr_i32(t0, arg1, arg2);
497951c6300SRichard Henderson         tcg_gen_subfi_i32(t1, 32, arg2);
498951c6300SRichard Henderson         tcg_gen_shl_i32(t1, arg1, t1);
499951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
500951c6300SRichard Henderson         tcg_temp_free_i32(t0);
501951c6300SRichard Henderson         tcg_temp_free_i32(t1);
502951c6300SRichard Henderson     }
503951c6300SRichard Henderson }
504951c6300SRichard Henderson 
505951c6300SRichard Henderson void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
506951c6300SRichard Henderson {
507951c6300SRichard Henderson     tcg_debug_assert(arg2 < 32);
508951c6300SRichard Henderson     /* some cases can be optimized here */
509951c6300SRichard Henderson     if (arg2 == 0) {
510951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
511951c6300SRichard Henderson     } else {
512951c6300SRichard Henderson         tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
513951c6300SRichard Henderson     }
514951c6300SRichard Henderson }
515951c6300SRichard Henderson 
516951c6300SRichard Henderson void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
517951c6300SRichard Henderson                          unsigned int ofs, unsigned int len)
518951c6300SRichard Henderson {
519951c6300SRichard Henderson     uint32_t mask;
520951c6300SRichard Henderson     TCGv_i32 t1;
521951c6300SRichard Henderson 
522951c6300SRichard Henderson     tcg_debug_assert(ofs < 32);
523951c6300SRichard Henderson     tcg_debug_assert(len <= 32);
524951c6300SRichard Henderson     tcg_debug_assert(ofs + len <= 32);
525951c6300SRichard Henderson 
526951c6300SRichard Henderson     if (ofs == 0 && len == 32) {
527951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg2);
528951c6300SRichard Henderson         return;
529951c6300SRichard Henderson     }
530951c6300SRichard Henderson     if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
531951c6300SRichard Henderson         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
532951c6300SRichard Henderson         return;
533951c6300SRichard Henderson     }
534951c6300SRichard Henderson 
535951c6300SRichard Henderson     mask = (1u << len) - 1;
536951c6300SRichard Henderson     t1 = tcg_temp_new_i32();
537951c6300SRichard Henderson 
538951c6300SRichard Henderson     if (ofs + len < 32) {
539951c6300SRichard Henderson         tcg_gen_andi_i32(t1, arg2, mask);
540951c6300SRichard Henderson         tcg_gen_shli_i32(t1, t1, ofs);
541951c6300SRichard Henderson     } else {
542951c6300SRichard Henderson         tcg_gen_shli_i32(t1, arg2, ofs);
543951c6300SRichard Henderson     }
544951c6300SRichard Henderson     tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
545951c6300SRichard Henderson     tcg_gen_or_i32(ret, ret, t1);
546951c6300SRichard Henderson 
547951c6300SRichard Henderson     tcg_temp_free_i32(t1);
548951c6300SRichard Henderson }
549951c6300SRichard Henderson 
550951c6300SRichard Henderson void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
551951c6300SRichard Henderson                          TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2)
552951c6300SRichard Henderson {
553*37ed3bf1SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
554*37ed3bf1SRichard Henderson         tcg_gen_mov_i32(ret, v1);
555*37ed3bf1SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
556*37ed3bf1SRichard Henderson         tcg_gen_mov_i32(ret, v2);
557*37ed3bf1SRichard Henderson     } else if (TCG_TARGET_HAS_movcond_i32) {
558951c6300SRichard Henderson         tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
559951c6300SRichard Henderson     } else {
560951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
561951c6300SRichard Henderson         TCGv_i32 t1 = tcg_temp_new_i32();
562951c6300SRichard Henderson         tcg_gen_setcond_i32(cond, t0, c1, c2);
563951c6300SRichard Henderson         tcg_gen_neg_i32(t0, t0);
564951c6300SRichard Henderson         tcg_gen_and_i32(t1, v1, t0);
565951c6300SRichard Henderson         tcg_gen_andc_i32(ret, v2, t0);
566951c6300SRichard Henderson         tcg_gen_or_i32(ret, ret, t1);
567951c6300SRichard Henderson         tcg_temp_free_i32(t0);
568951c6300SRichard Henderson         tcg_temp_free_i32(t1);
569951c6300SRichard Henderson     }
570951c6300SRichard Henderson }
571951c6300SRichard Henderson 
572951c6300SRichard Henderson void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
573951c6300SRichard Henderson                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
574951c6300SRichard Henderson {
575951c6300SRichard Henderson     if (TCG_TARGET_HAS_add2_i32) {
576951c6300SRichard Henderson         tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
577951c6300SRichard Henderson     } else {
578951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
579951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
580951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t0, al, ah);
581951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t1, bl, bh);
582951c6300SRichard Henderson         tcg_gen_add_i64(t0, t0, t1);
583951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
584951c6300SRichard Henderson         tcg_temp_free_i64(t0);
585951c6300SRichard Henderson         tcg_temp_free_i64(t1);
586951c6300SRichard Henderson     }
587951c6300SRichard Henderson }
588951c6300SRichard Henderson 
589951c6300SRichard Henderson void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
590951c6300SRichard Henderson                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
591951c6300SRichard Henderson {
592951c6300SRichard Henderson     if (TCG_TARGET_HAS_sub2_i32) {
593951c6300SRichard Henderson         tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
594951c6300SRichard Henderson     } else {
595951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
596951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
597951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t0, al, ah);
598951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t1, bl, bh);
599951c6300SRichard Henderson         tcg_gen_sub_i64(t0, t0, t1);
600951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
601951c6300SRichard Henderson         tcg_temp_free_i64(t0);
602951c6300SRichard Henderson         tcg_temp_free_i64(t1);
603951c6300SRichard Henderson     }
604951c6300SRichard Henderson }
605951c6300SRichard Henderson 
606951c6300SRichard Henderson void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
607951c6300SRichard Henderson {
608951c6300SRichard Henderson     if (TCG_TARGET_HAS_mulu2_i32) {
609951c6300SRichard Henderson         tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
610951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_muluh_i32) {
611951c6300SRichard Henderson         TCGv_i32 t = tcg_temp_new_i32();
612951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
613951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
614951c6300SRichard Henderson         tcg_gen_mov_i32(rl, t);
615951c6300SRichard Henderson         tcg_temp_free_i32(t);
616951c6300SRichard Henderson     } else {
617951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
618951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
619951c6300SRichard Henderson         tcg_gen_extu_i32_i64(t0, arg1);
620951c6300SRichard Henderson         tcg_gen_extu_i32_i64(t1, arg2);
621951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, t1);
622951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
623951c6300SRichard Henderson         tcg_temp_free_i64(t0);
624951c6300SRichard Henderson         tcg_temp_free_i64(t1);
625951c6300SRichard Henderson     }
626951c6300SRichard Henderson }
627951c6300SRichard Henderson 
628951c6300SRichard Henderson void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
629951c6300SRichard Henderson {
630951c6300SRichard Henderson     if (TCG_TARGET_HAS_muls2_i32) {
631951c6300SRichard Henderson         tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
632951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_mulsh_i32) {
633951c6300SRichard Henderson         TCGv_i32 t = tcg_temp_new_i32();
634951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
635951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
636951c6300SRichard Henderson         tcg_gen_mov_i32(rl, t);
637951c6300SRichard Henderson         tcg_temp_free_i32(t);
638951c6300SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 32) {
639951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
640951c6300SRichard Henderson         TCGv_i32 t1 = tcg_temp_new_i32();
641951c6300SRichard Henderson         TCGv_i32 t2 = tcg_temp_new_i32();
642951c6300SRichard Henderson         TCGv_i32 t3 = tcg_temp_new_i32();
643951c6300SRichard Henderson         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
644951c6300SRichard Henderson         /* Adjust for negative inputs.  */
645951c6300SRichard Henderson         tcg_gen_sari_i32(t2, arg1, 31);
646951c6300SRichard Henderson         tcg_gen_sari_i32(t3, arg2, 31);
647951c6300SRichard Henderson         tcg_gen_and_i32(t2, t2, arg2);
648951c6300SRichard Henderson         tcg_gen_and_i32(t3, t3, arg1);
649951c6300SRichard Henderson         tcg_gen_sub_i32(rh, t1, t2);
650951c6300SRichard Henderson         tcg_gen_sub_i32(rh, rh, t3);
651951c6300SRichard Henderson         tcg_gen_mov_i32(rl, t0);
652951c6300SRichard Henderson         tcg_temp_free_i32(t0);
653951c6300SRichard Henderson         tcg_temp_free_i32(t1);
654951c6300SRichard Henderson         tcg_temp_free_i32(t2);
655951c6300SRichard Henderson         tcg_temp_free_i32(t3);
656951c6300SRichard Henderson     } else {
657951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
658951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
659951c6300SRichard Henderson         tcg_gen_ext_i32_i64(t0, arg1);
660951c6300SRichard Henderson         tcg_gen_ext_i32_i64(t1, arg2);
661951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, t1);
662951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
663951c6300SRichard Henderson         tcg_temp_free_i64(t0);
664951c6300SRichard Henderson         tcg_temp_free_i64(t1);
665951c6300SRichard Henderson     }
666951c6300SRichard Henderson }
667951c6300SRichard Henderson 
668951c6300SRichard Henderson void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
669951c6300SRichard Henderson {
670951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext8s_i32) {
671951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
672951c6300SRichard Henderson     } else {
673951c6300SRichard Henderson         tcg_gen_shli_i32(ret, arg, 24);
674951c6300SRichard Henderson         tcg_gen_sari_i32(ret, ret, 24);
675951c6300SRichard Henderson     }
676951c6300SRichard Henderson }
677951c6300SRichard Henderson 
678951c6300SRichard Henderson void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
679951c6300SRichard Henderson {
680951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext16s_i32) {
681951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
682951c6300SRichard Henderson     } else {
683951c6300SRichard Henderson         tcg_gen_shli_i32(ret, arg, 16);
684951c6300SRichard Henderson         tcg_gen_sari_i32(ret, ret, 16);
685951c6300SRichard Henderson     }
686951c6300SRichard Henderson }
687951c6300SRichard Henderson 
688951c6300SRichard Henderson void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
689951c6300SRichard Henderson {
690951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext8u_i32) {
691951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
692951c6300SRichard Henderson     } else {
693951c6300SRichard Henderson         tcg_gen_andi_i32(ret, arg, 0xffu);
694951c6300SRichard Henderson     }
695951c6300SRichard Henderson }
696951c6300SRichard Henderson 
697951c6300SRichard Henderson void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
698951c6300SRichard Henderson {
699951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext16u_i32) {
700951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
701951c6300SRichard Henderson     } else {
702951c6300SRichard Henderson         tcg_gen_andi_i32(ret, arg, 0xffffu);
703951c6300SRichard Henderson     }
704951c6300SRichard Henderson }
705951c6300SRichard Henderson 
706951c6300SRichard Henderson /* Note: we assume the two high bytes are set to zero */
707951c6300SRichard Henderson void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg)
708951c6300SRichard Henderson {
709951c6300SRichard Henderson     if (TCG_TARGET_HAS_bswap16_i32) {
710951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg);
711951c6300SRichard Henderson     } else {
712951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
713951c6300SRichard Henderson 
714951c6300SRichard Henderson         tcg_gen_ext8u_i32(t0, arg);
715951c6300SRichard Henderson         tcg_gen_shli_i32(t0, t0, 8);
716951c6300SRichard Henderson         tcg_gen_shri_i32(ret, arg, 8);
717951c6300SRichard Henderson         tcg_gen_or_i32(ret, ret, t0);
718951c6300SRichard Henderson         tcg_temp_free_i32(t0);
719951c6300SRichard Henderson     }
720951c6300SRichard Henderson }
721951c6300SRichard Henderson 
722951c6300SRichard Henderson void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
723951c6300SRichard Henderson {
724951c6300SRichard Henderson     if (TCG_TARGET_HAS_bswap32_i32) {
725951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg);
726951c6300SRichard Henderson     } else {
727951c6300SRichard Henderson         TCGv_i32 t0, t1;
728951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
729951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
730951c6300SRichard Henderson 
731951c6300SRichard Henderson         tcg_gen_shli_i32(t0, arg, 24);
732951c6300SRichard Henderson 
733951c6300SRichard Henderson         tcg_gen_andi_i32(t1, arg, 0x0000ff00);
734951c6300SRichard Henderson         tcg_gen_shli_i32(t1, t1, 8);
735951c6300SRichard Henderson         tcg_gen_or_i32(t0, t0, t1);
736951c6300SRichard Henderson 
737951c6300SRichard Henderson         tcg_gen_shri_i32(t1, arg, 8);
738951c6300SRichard Henderson         tcg_gen_andi_i32(t1, t1, 0x0000ff00);
739951c6300SRichard Henderson         tcg_gen_or_i32(t0, t0, t1);
740951c6300SRichard Henderson 
741951c6300SRichard Henderson         tcg_gen_shri_i32(t1, arg, 24);
742951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
743951c6300SRichard Henderson         tcg_temp_free_i32(t0);
744951c6300SRichard Henderson         tcg_temp_free_i32(t1);
745951c6300SRichard Henderson     }
746951c6300SRichard Henderson }
747951c6300SRichard Henderson 
748951c6300SRichard Henderson /* 64-bit ops */
749951c6300SRichard Henderson 
750951c6300SRichard Henderson #if TCG_TARGET_REG_BITS == 32
751951c6300SRichard Henderson /* These are all inline for TCG_TARGET_REG_BITS == 64.  */
752951c6300SRichard Henderson 
753951c6300SRichard Henderson void tcg_gen_discard_i64(TCGv_i64 arg)
754951c6300SRichard Henderson {
755951c6300SRichard Henderson     tcg_gen_discard_i32(TCGV_LOW(arg));
756951c6300SRichard Henderson     tcg_gen_discard_i32(TCGV_HIGH(arg));
757951c6300SRichard Henderson }
758951c6300SRichard Henderson 
759951c6300SRichard Henderson void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
760951c6300SRichard Henderson {
761951c6300SRichard Henderson     tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
762951c6300SRichard Henderson     tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
763951c6300SRichard Henderson }
764951c6300SRichard Henderson 
765951c6300SRichard Henderson void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
766951c6300SRichard Henderson {
767951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_LOW(ret), arg);
768951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
769951c6300SRichard Henderson }
770951c6300SRichard Henderson 
771951c6300SRichard Henderson void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
772951c6300SRichard Henderson {
773951c6300SRichard Henderson     tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset);
774951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
775951c6300SRichard Henderson }
776951c6300SRichard Henderson 
777951c6300SRichard Henderson void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
778951c6300SRichard Henderson {
779951c6300SRichard Henderson     tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
780951c6300SRichard Henderson     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), 31);
781951c6300SRichard Henderson }
782951c6300SRichard Henderson 
783951c6300SRichard Henderson void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
784951c6300SRichard Henderson {
785951c6300SRichard Henderson     tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset);
786951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
787951c6300SRichard Henderson }
788951c6300SRichard Henderson 
789951c6300SRichard Henderson void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
790951c6300SRichard Henderson {
791951c6300SRichard Henderson     tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset);
792951c6300SRichard Henderson     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
793951c6300SRichard Henderson }
794951c6300SRichard Henderson 
795951c6300SRichard Henderson void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
796951c6300SRichard Henderson {
797951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
798951c6300SRichard Henderson     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
799951c6300SRichard Henderson }
800951c6300SRichard Henderson 
801951c6300SRichard Henderson void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
802951c6300SRichard Henderson {
803951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
804951c6300SRichard Henderson     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
805951c6300SRichard Henderson }
806951c6300SRichard Henderson 
807951c6300SRichard Henderson void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
808951c6300SRichard Henderson {
809951c6300SRichard Henderson     /* Since arg2 and ret have different types,
810951c6300SRichard Henderson        they cannot be the same temporary */
811951c6300SRichard Henderson #ifdef TCG_TARGET_WORDS_BIGENDIAN
812951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
813951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
814951c6300SRichard Henderson #else
815951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
816951c6300SRichard Henderson     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
817951c6300SRichard Henderson #endif
818951c6300SRichard Henderson }
819951c6300SRichard Henderson 
820951c6300SRichard Henderson void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
821951c6300SRichard Henderson {
822951c6300SRichard Henderson #ifdef TCG_TARGET_WORDS_BIGENDIAN
823951c6300SRichard Henderson     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
824951c6300SRichard Henderson     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
825951c6300SRichard Henderson #else
826951c6300SRichard Henderson     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
827951c6300SRichard Henderson     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
828951c6300SRichard Henderson #endif
829951c6300SRichard Henderson }
830951c6300SRichard Henderson 
831951c6300SRichard Henderson void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
832951c6300SRichard Henderson {
833951c6300SRichard Henderson     tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
834951c6300SRichard Henderson     tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
835951c6300SRichard Henderson }
836951c6300SRichard Henderson 
837951c6300SRichard Henderson void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
838951c6300SRichard Henderson {
839951c6300SRichard Henderson     tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
840951c6300SRichard Henderson     tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
841951c6300SRichard Henderson }
842951c6300SRichard Henderson 
843951c6300SRichard Henderson void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
844951c6300SRichard Henderson {
845951c6300SRichard Henderson     tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
846951c6300SRichard Henderson     tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
847951c6300SRichard Henderson }
848951c6300SRichard Henderson 
849951c6300SRichard Henderson void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
850951c6300SRichard Henderson {
851951c6300SRichard Henderson     gen_helper_shl_i64(ret, arg1, arg2);
852951c6300SRichard Henderson }
853951c6300SRichard Henderson 
854951c6300SRichard Henderson void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
855951c6300SRichard Henderson {
856951c6300SRichard Henderson     gen_helper_shr_i64(ret, arg1, arg2);
857951c6300SRichard Henderson }
858951c6300SRichard Henderson 
859951c6300SRichard Henderson void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
860951c6300SRichard Henderson {
861951c6300SRichard Henderson     gen_helper_sar_i64(ret, arg1, arg2);
862951c6300SRichard Henderson }
863951c6300SRichard Henderson 
864951c6300SRichard Henderson void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
865951c6300SRichard Henderson {
866951c6300SRichard Henderson     TCGv_i64 t0;
867951c6300SRichard Henderson     TCGv_i32 t1;
868951c6300SRichard Henderson 
869951c6300SRichard Henderson     t0 = tcg_temp_new_i64();
870951c6300SRichard Henderson     t1 = tcg_temp_new_i32();
871951c6300SRichard Henderson 
872951c6300SRichard Henderson     tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
873951c6300SRichard Henderson                       TCGV_LOW(arg1), TCGV_LOW(arg2));
874951c6300SRichard Henderson 
875951c6300SRichard Henderson     tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
876951c6300SRichard Henderson     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
877951c6300SRichard Henderson     tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2));
878951c6300SRichard Henderson     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
879951c6300SRichard Henderson 
880951c6300SRichard Henderson     tcg_gen_mov_i64(ret, t0);
881951c6300SRichard Henderson     tcg_temp_free_i64(t0);
882951c6300SRichard Henderson     tcg_temp_free_i32(t1);
883951c6300SRichard Henderson }
884951c6300SRichard Henderson #endif /* TCG_TARGET_REG_SIZE == 32 */
885951c6300SRichard Henderson 
886951c6300SRichard Henderson void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
887951c6300SRichard Henderson {
888951c6300SRichard Henderson     /* some cases can be optimized here */
889951c6300SRichard Henderson     if (arg2 == 0) {
890951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
891951c6300SRichard Henderson     } else {
892951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
893951c6300SRichard Henderson         tcg_gen_add_i64(ret, arg1, t0);
894951c6300SRichard Henderson         tcg_temp_free_i64(t0);
895951c6300SRichard Henderson     }
896951c6300SRichard Henderson }
897951c6300SRichard Henderson 
898951c6300SRichard Henderson void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2)
899951c6300SRichard Henderson {
900951c6300SRichard Henderson     if (arg1 == 0 && TCG_TARGET_HAS_neg_i64) {
901951c6300SRichard Henderson         /* Don't recurse with tcg_gen_neg_i64.  */
902951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg2);
903951c6300SRichard Henderson     } else {
904951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg1);
905951c6300SRichard Henderson         tcg_gen_sub_i64(ret, t0, arg2);
906951c6300SRichard Henderson         tcg_temp_free_i64(t0);
907951c6300SRichard Henderson     }
908951c6300SRichard Henderson }
909951c6300SRichard Henderson 
910951c6300SRichard Henderson void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
911951c6300SRichard Henderson {
912951c6300SRichard Henderson     /* some cases can be optimized here */
913951c6300SRichard Henderson     if (arg2 == 0) {
914951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
915951c6300SRichard Henderson     } else {
916951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
917951c6300SRichard Henderson         tcg_gen_sub_i64(ret, arg1, t0);
918951c6300SRichard Henderson         tcg_temp_free_i64(t0);
919951c6300SRichard Henderson     }
920951c6300SRichard Henderson }
921951c6300SRichard Henderson 
922951c6300SRichard Henderson void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
923951c6300SRichard Henderson {
9243a13c3f3SRichard Henderson     TCGv_i64 t0;
9253a13c3f3SRichard Henderson 
9263a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
927951c6300SRichard Henderson         tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
928951c6300SRichard Henderson         tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
9293a13c3f3SRichard Henderson         return;
9303a13c3f3SRichard Henderson     }
9313a13c3f3SRichard Henderson 
932951c6300SRichard Henderson     /* Some cases can be optimized here.  */
933951c6300SRichard Henderson     switch (arg2) {
934951c6300SRichard Henderson     case 0:
935951c6300SRichard Henderson         tcg_gen_movi_i64(ret, 0);
936951c6300SRichard Henderson         return;
937951c6300SRichard Henderson     case 0xffffffffffffffffull:
938951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
939951c6300SRichard Henderson         return;
940951c6300SRichard Henderson     case 0xffull:
941951c6300SRichard Henderson         /* Don't recurse with tcg_gen_ext8u_i64.  */
942951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext8u_i64) {
943951c6300SRichard Henderson             tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
944951c6300SRichard Henderson             return;
945951c6300SRichard Henderson         }
946951c6300SRichard Henderson         break;
947951c6300SRichard Henderson     case 0xffffu:
948951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext16u_i64) {
949951c6300SRichard Henderson             tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
950951c6300SRichard Henderson             return;
951951c6300SRichard Henderson         }
952951c6300SRichard Henderson         break;
953951c6300SRichard Henderson     case 0xffffffffull:
954951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext32u_i64) {
955951c6300SRichard Henderson             tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
956951c6300SRichard Henderson             return;
957951c6300SRichard Henderson         }
958951c6300SRichard Henderson         break;
959951c6300SRichard Henderson     }
960951c6300SRichard Henderson     t0 = tcg_const_i64(arg2);
961951c6300SRichard Henderson     tcg_gen_and_i64(ret, arg1, t0);
962951c6300SRichard Henderson     tcg_temp_free_i64(t0);
963951c6300SRichard Henderson }
964951c6300SRichard Henderson 
965951c6300SRichard Henderson void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
966951c6300SRichard Henderson {
9673a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
968951c6300SRichard Henderson         tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
969951c6300SRichard Henderson         tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
9703a13c3f3SRichard Henderson         return;
9713a13c3f3SRichard Henderson     }
972951c6300SRichard Henderson     /* Some cases can be optimized here.  */
973951c6300SRichard Henderson     if (arg2 == -1) {
974951c6300SRichard Henderson         tcg_gen_movi_i64(ret, -1);
975951c6300SRichard Henderson     } else if (arg2 == 0) {
976951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
977951c6300SRichard Henderson     } else {
978951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
979951c6300SRichard Henderson         tcg_gen_or_i64(ret, arg1, t0);
980951c6300SRichard Henderson         tcg_temp_free_i64(t0);
981951c6300SRichard Henderson     }
982951c6300SRichard Henderson }
983951c6300SRichard Henderson 
984951c6300SRichard Henderson void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
985951c6300SRichard Henderson {
9863a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
987951c6300SRichard Henderson         tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
988951c6300SRichard Henderson         tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
9893a13c3f3SRichard Henderson         return;
9903a13c3f3SRichard Henderson     }
991951c6300SRichard Henderson     /* Some cases can be optimized here.  */
992951c6300SRichard Henderson     if (arg2 == 0) {
993951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
994951c6300SRichard Henderson     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) {
995951c6300SRichard Henderson         /* Don't recurse with tcg_gen_not_i64.  */
996951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1);
997951c6300SRichard Henderson     } else {
998951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
999951c6300SRichard Henderson         tcg_gen_xor_i64(ret, arg1, t0);
1000951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1001951c6300SRichard Henderson     }
1002951c6300SRichard Henderson }
1003951c6300SRichard Henderson 
1004951c6300SRichard Henderson static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
1005951c6300SRichard Henderson                                       unsigned c, bool right, bool arith)
1006951c6300SRichard Henderson {
1007951c6300SRichard Henderson     tcg_debug_assert(c < 64);
1008951c6300SRichard Henderson     if (c == 0) {
1009951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1010951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1011951c6300SRichard Henderson     } else if (c >= 32) {
1012951c6300SRichard Henderson         c -= 32;
1013951c6300SRichard Henderson         if (right) {
1014951c6300SRichard Henderson             if (arith) {
1015951c6300SRichard Henderson                 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1016951c6300SRichard Henderson                 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
1017951c6300SRichard Henderson             } else {
1018951c6300SRichard Henderson                 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1019951c6300SRichard Henderson                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1020951c6300SRichard Henderson             }
1021951c6300SRichard Henderson         } else {
1022951c6300SRichard Henderson             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
1023951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_LOW(ret), 0);
1024951c6300SRichard Henderson         }
1025951c6300SRichard Henderson     } else {
1026951c6300SRichard Henderson         TCGv_i32 t0, t1;
1027951c6300SRichard Henderson 
1028951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
1029951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
1030951c6300SRichard Henderson         if (right) {
1031951c6300SRichard Henderson             tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
1032951c6300SRichard Henderson             if (arith) {
1033951c6300SRichard Henderson                 tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
1034951c6300SRichard Henderson             } else {
1035951c6300SRichard Henderson                 tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
1036951c6300SRichard Henderson             }
1037951c6300SRichard Henderson             tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
1038951c6300SRichard Henderson             tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
1039951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
1040951c6300SRichard Henderson         } else {
1041951c6300SRichard Henderson             tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
1042951c6300SRichard Henderson             /* Note: ret can be the same as arg1, so we use t1 */
1043951c6300SRichard Henderson             tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
1044951c6300SRichard Henderson             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
1045951c6300SRichard Henderson             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
1046951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_LOW(ret), t1);
1047951c6300SRichard Henderson         }
1048951c6300SRichard Henderson         tcg_temp_free_i32(t0);
1049951c6300SRichard Henderson         tcg_temp_free_i32(t1);
1050951c6300SRichard Henderson     }
1051951c6300SRichard Henderson }
1052951c6300SRichard Henderson 
1053951c6300SRichard Henderson void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1054951c6300SRichard Henderson {
1055951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
10563a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
10573a13c3f3SRichard Henderson         tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
10583a13c3f3SRichard Henderson     } else if (arg2 == 0) {
1059951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1060951c6300SRichard Henderson     } else {
1061951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
1062951c6300SRichard Henderson         tcg_gen_shl_i64(ret, arg1, t0);
1063951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1064951c6300SRichard Henderson     }
1065951c6300SRichard Henderson }
1066951c6300SRichard Henderson 
1067951c6300SRichard Henderson void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1068951c6300SRichard Henderson {
1069951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
10703a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
10713a13c3f3SRichard Henderson         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
10723a13c3f3SRichard Henderson     } else if (arg2 == 0) {
1073951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1074951c6300SRichard Henderson     } else {
1075951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
1076951c6300SRichard Henderson         tcg_gen_shr_i64(ret, arg1, t0);
1077951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1078951c6300SRichard Henderson     }
1079951c6300SRichard Henderson }
1080951c6300SRichard Henderson 
1081951c6300SRichard Henderson void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1082951c6300SRichard Henderson {
1083951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
10843a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
10853a13c3f3SRichard Henderson         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
10863a13c3f3SRichard Henderson     } else if (arg2 == 0) {
1087951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1088951c6300SRichard Henderson     } else {
1089951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
1090951c6300SRichard Henderson         tcg_gen_sar_i64(ret, arg1, t0);
1091951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1092951c6300SRichard Henderson     }
1093951c6300SRichard Henderson }
1094951c6300SRichard Henderson 
109542a268c2SRichard Henderson void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l)
1096951c6300SRichard Henderson {
1097951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
109842a268c2SRichard Henderson         tcg_gen_br(l);
1099951c6300SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
11003a13c3f3SRichard Henderson         if (TCG_TARGET_REG_BITS == 32) {
1101951c6300SRichard Henderson             tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),
1102951c6300SRichard Henderson                               TCGV_HIGH(arg1), TCGV_LOW(arg2),
110342a268c2SRichard Henderson                               TCGV_HIGH(arg2), cond, label_arg(l));
11043a13c3f3SRichard Henderson         } else {
110542a268c2SRichard Henderson             tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond,
110642a268c2SRichard Henderson                               label_arg(l));
11073a13c3f3SRichard Henderson         }
1108951c6300SRichard Henderson     }
1109951c6300SRichard Henderson }
1110951c6300SRichard Henderson 
111142a268c2SRichard Henderson void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l)
1112951c6300SRichard Henderson {
1113951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
111442a268c2SRichard Henderson         tcg_gen_br(l);
1115951c6300SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
1116951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
111742a268c2SRichard Henderson         tcg_gen_brcond_i64(cond, arg1, t0, l);
1118951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1119951c6300SRichard Henderson     }
1120951c6300SRichard Henderson }
1121951c6300SRichard Henderson 
1122951c6300SRichard Henderson void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
1123951c6300SRichard Henderson                          TCGv_i64 arg1, TCGv_i64 arg2)
1124951c6300SRichard Henderson {
1125951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
1126951c6300SRichard Henderson         tcg_gen_movi_i64(ret, 1);
1127951c6300SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
1128951c6300SRichard Henderson         tcg_gen_movi_i64(ret, 0);
1129951c6300SRichard Henderson     } else {
11303a13c3f3SRichard Henderson         if (TCG_TARGET_REG_BITS == 32) {
1131951c6300SRichard Henderson             tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
1132951c6300SRichard Henderson                              TCGV_LOW(arg1), TCGV_HIGH(arg1),
1133951c6300SRichard Henderson                              TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
1134951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
11353a13c3f3SRichard Henderson         } else {
1136951c6300SRichard Henderson             tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
11373a13c3f3SRichard Henderson         }
1138951c6300SRichard Henderson     }
1139951c6300SRichard Henderson }
1140951c6300SRichard Henderson 
1141951c6300SRichard Henderson void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
1142951c6300SRichard Henderson                           TCGv_i64 arg1, int64_t arg2)
1143951c6300SRichard Henderson {
1144951c6300SRichard Henderson     TCGv_i64 t0 = tcg_const_i64(arg2);
1145951c6300SRichard Henderson     tcg_gen_setcond_i64(cond, ret, arg1, t0);
1146951c6300SRichard Henderson     tcg_temp_free_i64(t0);
1147951c6300SRichard Henderson }
1148951c6300SRichard Henderson 
1149951c6300SRichard Henderson void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1150951c6300SRichard Henderson {
1151951c6300SRichard Henderson     TCGv_i64 t0 = tcg_const_i64(arg2);
1152951c6300SRichard Henderson     tcg_gen_mul_i64(ret, arg1, t0);
1153951c6300SRichard Henderson     tcg_temp_free_i64(t0);
1154951c6300SRichard Henderson }
1155951c6300SRichard Henderson 
1156951c6300SRichard Henderson void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1157951c6300SRichard Henderson {
1158951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i64) {
1159951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
1160951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
1161951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1162951c6300SRichard Henderson         tcg_gen_sari_i64(t0, arg1, 63);
1163951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
1164951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1165951c6300SRichard Henderson     } else {
1166951c6300SRichard Henderson         gen_helper_div_i64(ret, arg1, arg2);
1167951c6300SRichard Henderson     }
1168951c6300SRichard Henderson }
1169951c6300SRichard Henderson 
1170951c6300SRichard Henderson void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1171951c6300SRichard Henderson {
1172951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i64) {
1173951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
1174951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i64) {
1175951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1176951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
1177951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, arg2);
1178951c6300SRichard Henderson         tcg_gen_sub_i64(ret, arg1, t0);
1179951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1180951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
1181951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1182951c6300SRichard Henderson         tcg_gen_sari_i64(t0, arg1, 63);
1183951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
1184951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1185951c6300SRichard Henderson     } else {
1186951c6300SRichard Henderson         gen_helper_rem_i64(ret, arg1, arg2);
1187951c6300SRichard Henderson     }
1188951c6300SRichard Henderson }
1189951c6300SRichard Henderson 
1190951c6300SRichard Henderson void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1191951c6300SRichard Henderson {
1192951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i64) {
1193951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
1194951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
1195951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1196951c6300SRichard Henderson         tcg_gen_movi_i64(t0, 0);
1197951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
1198951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1199951c6300SRichard Henderson     } else {
1200951c6300SRichard Henderson         gen_helper_divu_i64(ret, arg1, arg2);
1201951c6300SRichard Henderson     }
1202951c6300SRichard Henderson }
1203951c6300SRichard Henderson 
1204951c6300SRichard Henderson void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1205951c6300SRichard Henderson {
1206951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i64) {
1207951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
1208951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i64) {
1209951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1210951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
1211951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, arg2);
1212951c6300SRichard Henderson         tcg_gen_sub_i64(ret, arg1, t0);
1213951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1214951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
1215951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1216951c6300SRichard Henderson         tcg_gen_movi_i64(t0, 0);
1217951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
1218951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1219951c6300SRichard Henderson     } else {
1220951c6300SRichard Henderson         gen_helper_remu_i64(ret, arg1, arg2);
1221951c6300SRichard Henderson     }
1222951c6300SRichard Henderson }
1223951c6300SRichard Henderson 
1224951c6300SRichard Henderson void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
1225951c6300SRichard Henderson {
12263a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1227951c6300SRichard Henderson         tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1228951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
12293a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext8s_i64) {
1230951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
1231951c6300SRichard Henderson     } else {
1232951c6300SRichard Henderson         tcg_gen_shli_i64(ret, arg, 56);
1233951c6300SRichard Henderson         tcg_gen_sari_i64(ret, ret, 56);
1234951c6300SRichard Henderson     }
1235951c6300SRichard Henderson }
1236951c6300SRichard Henderson 
1237951c6300SRichard Henderson void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
1238951c6300SRichard Henderson {
12393a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1240951c6300SRichard Henderson         tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1241951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
12423a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext16s_i64) {
1243951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
1244951c6300SRichard Henderson     } else {
1245951c6300SRichard Henderson         tcg_gen_shli_i64(ret, arg, 48);
1246951c6300SRichard Henderson         tcg_gen_sari_i64(ret, ret, 48);
1247951c6300SRichard Henderson     }
1248951c6300SRichard Henderson }
1249951c6300SRichard Henderson 
1250951c6300SRichard Henderson void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
1251951c6300SRichard Henderson {
12523a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1253951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1254951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
12553a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext32s_i64) {
1256951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
1257951c6300SRichard Henderson     } else {
1258951c6300SRichard Henderson         tcg_gen_shli_i64(ret, arg, 32);
1259951c6300SRichard Henderson         tcg_gen_sari_i64(ret, ret, 32);
1260951c6300SRichard Henderson     }
1261951c6300SRichard Henderson }
1262951c6300SRichard Henderson 
1263951c6300SRichard Henderson void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
1264951c6300SRichard Henderson {
12653a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1266951c6300SRichard Henderson         tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1267951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
12683a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext8u_i64) {
1269951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
1270951c6300SRichard Henderson     } else {
1271951c6300SRichard Henderson         tcg_gen_andi_i64(ret, arg, 0xffu);
1272951c6300SRichard Henderson     }
1273951c6300SRichard Henderson }
1274951c6300SRichard Henderson 
1275951c6300SRichard Henderson void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
1276951c6300SRichard Henderson {
12773a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1278951c6300SRichard Henderson         tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1279951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
12803a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext16u_i64) {
1281951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
1282951c6300SRichard Henderson     } else {
1283951c6300SRichard Henderson         tcg_gen_andi_i64(ret, arg, 0xffffu);
1284951c6300SRichard Henderson     }
1285951c6300SRichard Henderson }
1286951c6300SRichard Henderson 
1287951c6300SRichard Henderson void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
1288951c6300SRichard Henderson {
12893a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1290951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1291951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
12923a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext32u_i64) {
1293951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
1294951c6300SRichard Henderson     } else {
1295951c6300SRichard Henderson         tcg_gen_andi_i64(ret, arg, 0xffffffffu);
1296951c6300SRichard Henderson     }
1297951c6300SRichard Henderson }
1298951c6300SRichard Henderson 
1299951c6300SRichard Henderson /* Note: we assume the six high bytes are set to zero */
1300951c6300SRichard Henderson void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg)
1301951c6300SRichard Henderson {
13023a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1303951c6300SRichard Henderson         tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1304951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
13053a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_bswap16_i64) {
1306951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg);
1307951c6300SRichard Henderson     } else {
1308951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1309951c6300SRichard Henderson 
1310951c6300SRichard Henderson         tcg_gen_ext8u_i64(t0, arg);
1311951c6300SRichard Henderson         tcg_gen_shli_i64(t0, t0, 8);
1312951c6300SRichard Henderson         tcg_gen_shri_i64(ret, arg, 8);
1313951c6300SRichard Henderson         tcg_gen_or_i64(ret, ret, t0);
1314951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1315951c6300SRichard Henderson     }
1316951c6300SRichard Henderson }
1317951c6300SRichard Henderson 
1318951c6300SRichard Henderson /* Note: we assume the four high bytes are set to zero */
1319951c6300SRichard Henderson void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg)
1320951c6300SRichard Henderson {
13213a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1322951c6300SRichard Henderson         tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1323951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
13243a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_bswap32_i64) {
1325951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg);
1326951c6300SRichard Henderson     } else {
1327951c6300SRichard Henderson         TCGv_i64 t0, t1;
1328951c6300SRichard Henderson         t0 = tcg_temp_new_i64();
1329951c6300SRichard Henderson         t1 = tcg_temp_new_i64();
1330951c6300SRichard Henderson 
1331951c6300SRichard Henderson         tcg_gen_shli_i64(t0, arg, 24);
1332951c6300SRichard Henderson         tcg_gen_ext32u_i64(t0, t0);
1333951c6300SRichard Henderson 
1334951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg, 0x0000ff00);
1335951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, 8);
1336951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1337951c6300SRichard Henderson 
1338951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 8);
1339951c6300SRichard Henderson         tcg_gen_andi_i64(t1, t1, 0x0000ff00);
1340951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1341951c6300SRichard Henderson 
1342951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 24);
1343951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1344951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1345951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1346951c6300SRichard Henderson     }
1347951c6300SRichard Henderson }
1348951c6300SRichard Henderson 
1349951c6300SRichard Henderson void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
1350951c6300SRichard Henderson {
13513a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1352951c6300SRichard Henderson         TCGv_i32 t0, t1;
1353951c6300SRichard Henderson         t0 = tcg_temp_new_i32();
1354951c6300SRichard Henderson         t1 = tcg_temp_new_i32();
1355951c6300SRichard Henderson 
1356951c6300SRichard Henderson         tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
1357951c6300SRichard Henderson         tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
1358951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), t1);
1359951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
1360951c6300SRichard Henderson         tcg_temp_free_i32(t0);
1361951c6300SRichard Henderson         tcg_temp_free_i32(t1);
13623a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_bswap64_i64) {
1363951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg);
1364951c6300SRichard Henderson     } else {
1365951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1366951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1367951c6300SRichard Henderson 
1368951c6300SRichard Henderson         tcg_gen_shli_i64(t0, arg, 56);
1369951c6300SRichard Henderson 
1370951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg, 0x0000ff00);
1371951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, 40);
1372951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1373951c6300SRichard Henderson 
1374951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg, 0x00ff0000);
1375951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, 24);
1376951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1377951c6300SRichard Henderson 
1378951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg, 0xff000000);
1379951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, 8);
1380951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1381951c6300SRichard Henderson 
1382951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 8);
1383951c6300SRichard Henderson         tcg_gen_andi_i64(t1, t1, 0xff000000);
1384951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1385951c6300SRichard Henderson 
1386951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 24);
1387951c6300SRichard Henderson         tcg_gen_andi_i64(t1, t1, 0x00ff0000);
1388951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1389951c6300SRichard Henderson 
1390951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 40);
1391951c6300SRichard Henderson         tcg_gen_andi_i64(t1, t1, 0x0000ff00);
1392951c6300SRichard Henderson         tcg_gen_or_i64(t0, t0, t1);
1393951c6300SRichard Henderson 
1394951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg, 56);
1395951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1396951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1397951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1398951c6300SRichard Henderson     }
1399951c6300SRichard Henderson }
1400951c6300SRichard Henderson 
1401951c6300SRichard Henderson void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
1402951c6300SRichard Henderson {
14033a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14043a13c3f3SRichard Henderson         tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
14053a13c3f3SRichard Henderson         tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
14063a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_not_i64) {
1407951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
1408951c6300SRichard Henderson     } else {
1409951c6300SRichard Henderson         tcg_gen_xori_i64(ret, arg, -1);
1410951c6300SRichard Henderson     }
1411951c6300SRichard Henderson }
1412951c6300SRichard Henderson 
1413951c6300SRichard Henderson void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1414951c6300SRichard Henderson {
14153a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14163a13c3f3SRichard Henderson         tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14173a13c3f3SRichard Henderson         tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14183a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_andc_i64) {
1419951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
1420951c6300SRichard Henderson     } else {
1421951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1422951c6300SRichard Henderson         tcg_gen_not_i64(t0, arg2);
1423951c6300SRichard Henderson         tcg_gen_and_i64(ret, arg1, t0);
1424951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1425951c6300SRichard Henderson     }
1426951c6300SRichard Henderson }
1427951c6300SRichard Henderson 
1428951c6300SRichard Henderson void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1429951c6300SRichard Henderson {
14303a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14313a13c3f3SRichard Henderson         tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14323a13c3f3SRichard Henderson         tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14333a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_eqv_i64) {
1434951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
1435951c6300SRichard Henderson     } else {
1436951c6300SRichard Henderson         tcg_gen_xor_i64(ret, arg1, arg2);
1437951c6300SRichard Henderson         tcg_gen_not_i64(ret, ret);
1438951c6300SRichard Henderson     }
1439951c6300SRichard Henderson }
1440951c6300SRichard Henderson 
1441951c6300SRichard Henderson void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1442951c6300SRichard Henderson {
14433a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14443a13c3f3SRichard Henderson         tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14453a13c3f3SRichard Henderson         tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14463a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_nand_i64) {
1447951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
1448951c6300SRichard Henderson     } else {
1449951c6300SRichard Henderson         tcg_gen_and_i64(ret, arg1, arg2);
1450951c6300SRichard Henderson         tcg_gen_not_i64(ret, ret);
1451951c6300SRichard Henderson     }
1452951c6300SRichard Henderson }
1453951c6300SRichard Henderson 
1454951c6300SRichard Henderson void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1455951c6300SRichard Henderson {
14563a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14573a13c3f3SRichard Henderson         tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14583a13c3f3SRichard Henderson         tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14593a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_nor_i64) {
1460951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
1461951c6300SRichard Henderson     } else {
1462951c6300SRichard Henderson         tcg_gen_or_i64(ret, arg1, arg2);
1463951c6300SRichard Henderson         tcg_gen_not_i64(ret, ret);
1464951c6300SRichard Henderson     }
1465951c6300SRichard Henderson }
1466951c6300SRichard Henderson 
1467951c6300SRichard Henderson void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1468951c6300SRichard Henderson {
14693a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
14703a13c3f3SRichard Henderson         tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
14713a13c3f3SRichard Henderson         tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
14723a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_orc_i64) {
1473951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
1474951c6300SRichard Henderson     } else {
1475951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1476951c6300SRichard Henderson         tcg_gen_not_i64(t0, arg2);
1477951c6300SRichard Henderson         tcg_gen_or_i64(ret, arg1, t0);
1478951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1479951c6300SRichard Henderson     }
1480951c6300SRichard Henderson }
1481951c6300SRichard Henderson 
1482951c6300SRichard Henderson void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1483951c6300SRichard Henderson {
1484951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i64) {
1485951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
1486951c6300SRichard Henderson     } else {
1487951c6300SRichard Henderson         TCGv_i64 t0, t1;
1488951c6300SRichard Henderson         t0 = tcg_temp_new_i64();
1489951c6300SRichard Henderson         t1 = tcg_temp_new_i64();
1490951c6300SRichard Henderson         tcg_gen_shl_i64(t0, arg1, arg2);
1491951c6300SRichard Henderson         tcg_gen_subfi_i64(t1, 64, arg2);
1492951c6300SRichard Henderson         tcg_gen_shr_i64(t1, arg1, t1);
1493951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1494951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1495951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1496951c6300SRichard Henderson     }
1497951c6300SRichard Henderson }
1498951c6300SRichard Henderson 
1499951c6300SRichard Henderson void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1500951c6300SRichard Henderson {
1501951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
1502951c6300SRichard Henderson     /* some cases can be optimized here */
1503951c6300SRichard Henderson     if (arg2 == 0) {
1504951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1505951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_rot_i64) {
1506951c6300SRichard Henderson         TCGv_i64 t0 = tcg_const_i64(arg2);
1507951c6300SRichard Henderson         tcg_gen_rotl_i64(ret, arg1, t0);
1508951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1509951c6300SRichard Henderson     } else {
1510951c6300SRichard Henderson         TCGv_i64 t0, t1;
1511951c6300SRichard Henderson         t0 = tcg_temp_new_i64();
1512951c6300SRichard Henderson         t1 = tcg_temp_new_i64();
1513951c6300SRichard Henderson         tcg_gen_shli_i64(t0, arg1, arg2);
1514951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg1, 64 - arg2);
1515951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1516951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1517951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1518951c6300SRichard Henderson     }
1519951c6300SRichard Henderson }
1520951c6300SRichard Henderson 
1521951c6300SRichard Henderson void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1522951c6300SRichard Henderson {
1523951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i64) {
1524951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
1525951c6300SRichard Henderson     } else {
1526951c6300SRichard Henderson         TCGv_i64 t0, t1;
1527951c6300SRichard Henderson         t0 = tcg_temp_new_i64();
1528951c6300SRichard Henderson         t1 = tcg_temp_new_i64();
1529951c6300SRichard Henderson         tcg_gen_shr_i64(t0, arg1, arg2);
1530951c6300SRichard Henderson         tcg_gen_subfi_i64(t1, 64, arg2);
1531951c6300SRichard Henderson         tcg_gen_shl_i64(t1, arg1, t1);
1532951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
1533951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1534951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1535951c6300SRichard Henderson     }
1536951c6300SRichard Henderson }
1537951c6300SRichard Henderson 
1538951c6300SRichard Henderson void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1539951c6300SRichard Henderson {
1540951c6300SRichard Henderson     tcg_debug_assert(arg2 < 64);
1541951c6300SRichard Henderson     /* some cases can be optimized here */
1542951c6300SRichard Henderson     if (arg2 == 0) {
1543951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1544951c6300SRichard Henderson     } else {
1545951c6300SRichard Henderson         tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
1546951c6300SRichard Henderson     }
1547951c6300SRichard Henderson }
1548951c6300SRichard Henderson 
1549951c6300SRichard Henderson void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
1550951c6300SRichard Henderson                          unsigned int ofs, unsigned int len)
1551951c6300SRichard Henderson {
1552951c6300SRichard Henderson     uint64_t mask;
1553951c6300SRichard Henderson     TCGv_i64 t1;
1554951c6300SRichard Henderson 
1555951c6300SRichard Henderson     tcg_debug_assert(ofs < 64);
1556951c6300SRichard Henderson     tcg_debug_assert(len <= 64);
1557951c6300SRichard Henderson     tcg_debug_assert(ofs + len <= 64);
1558951c6300SRichard Henderson 
1559951c6300SRichard Henderson     if (ofs == 0 && len == 64) {
1560951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg2);
1561951c6300SRichard Henderson         return;
1562951c6300SRichard Henderson     }
1563951c6300SRichard Henderson     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
1564951c6300SRichard Henderson         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
1565951c6300SRichard Henderson         return;
1566951c6300SRichard Henderson     }
1567951c6300SRichard Henderson 
15683a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1569951c6300SRichard Henderson         if (ofs >= 32) {
1570951c6300SRichard Henderson             tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1),
1571951c6300SRichard Henderson                                 TCGV_LOW(arg2), ofs - 32, len);
1572951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1573951c6300SRichard Henderson             return;
1574951c6300SRichard Henderson         }
1575951c6300SRichard Henderson         if (ofs + len <= 32) {
1576951c6300SRichard Henderson             tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1),
1577951c6300SRichard Henderson                                 TCGV_LOW(arg2), ofs, len);
1578951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1579951c6300SRichard Henderson             return;
1580951c6300SRichard Henderson         }
15813a13c3f3SRichard Henderson     }
1582951c6300SRichard Henderson 
1583951c6300SRichard Henderson     mask = (1ull << len) - 1;
1584951c6300SRichard Henderson     t1 = tcg_temp_new_i64();
1585951c6300SRichard Henderson 
1586951c6300SRichard Henderson     if (ofs + len < 64) {
1587951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg2, mask);
1588951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, ofs);
1589951c6300SRichard Henderson     } else {
1590951c6300SRichard Henderson         tcg_gen_shli_i64(t1, arg2, ofs);
1591951c6300SRichard Henderson     }
1592951c6300SRichard Henderson     tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
1593951c6300SRichard Henderson     tcg_gen_or_i64(ret, ret, t1);
1594951c6300SRichard Henderson 
1595951c6300SRichard Henderson     tcg_temp_free_i64(t1);
1596951c6300SRichard Henderson }
1597951c6300SRichard Henderson 
1598951c6300SRichard Henderson void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
1599951c6300SRichard Henderson                          TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2)
1600951c6300SRichard Henderson {
1601*37ed3bf1SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
1602*37ed3bf1SRichard Henderson         tcg_gen_mov_i64(ret, v1);
1603*37ed3bf1SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
1604*37ed3bf1SRichard Henderson         tcg_gen_mov_i64(ret, v2);
1605*37ed3bf1SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 32) {
1606951c6300SRichard Henderson         TCGv_i32 t0 = tcg_temp_new_i32();
1607951c6300SRichard Henderson         TCGv_i32 t1 = tcg_temp_new_i32();
1608951c6300SRichard Henderson         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
1609951c6300SRichard Henderson                          TCGV_LOW(c1), TCGV_HIGH(c1),
1610951c6300SRichard Henderson                          TCGV_LOW(c2), TCGV_HIGH(c2), cond);
1611951c6300SRichard Henderson 
1612951c6300SRichard Henderson         if (TCG_TARGET_HAS_movcond_i32) {
1613951c6300SRichard Henderson             tcg_gen_movi_i32(t1, 0);
1614951c6300SRichard Henderson             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, t1,
1615951c6300SRichard Henderson                                 TCGV_LOW(v1), TCGV_LOW(v2));
1616951c6300SRichard Henderson             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, t1,
1617951c6300SRichard Henderson                                 TCGV_HIGH(v1), TCGV_HIGH(v2));
1618951c6300SRichard Henderson         } else {
1619951c6300SRichard Henderson             tcg_gen_neg_i32(t0, t0);
1620951c6300SRichard Henderson 
1621951c6300SRichard Henderson             tcg_gen_and_i32(t1, TCGV_LOW(v1), t0);
1622951c6300SRichard Henderson             tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0);
1623951c6300SRichard Henderson             tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1);
1624951c6300SRichard Henderson 
1625951c6300SRichard Henderson             tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0);
1626951c6300SRichard Henderson             tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0);
1627951c6300SRichard Henderson             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1);
1628951c6300SRichard Henderson         }
1629951c6300SRichard Henderson         tcg_temp_free_i32(t0);
1630951c6300SRichard Henderson         tcg_temp_free_i32(t1);
16313a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_movcond_i64) {
1632951c6300SRichard Henderson         tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
1633951c6300SRichard Henderson     } else {
1634951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1635951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1636951c6300SRichard Henderson         tcg_gen_setcond_i64(cond, t0, c1, c2);
1637951c6300SRichard Henderson         tcg_gen_neg_i64(t0, t0);
1638951c6300SRichard Henderson         tcg_gen_and_i64(t1, v1, t0);
1639951c6300SRichard Henderson         tcg_gen_andc_i64(ret, v2, t0);
1640951c6300SRichard Henderson         tcg_gen_or_i64(ret, ret, t1);
1641951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1642951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1643951c6300SRichard Henderson     }
1644951c6300SRichard Henderson }
1645951c6300SRichard Henderson 
1646951c6300SRichard Henderson void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
1647951c6300SRichard Henderson                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
1648951c6300SRichard Henderson {
1649951c6300SRichard Henderson     if (TCG_TARGET_HAS_add2_i64) {
1650951c6300SRichard Henderson         tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
1651951c6300SRichard Henderson     } else {
1652951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1653951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1654951c6300SRichard Henderson         tcg_gen_add_i64(t0, al, bl);
1655951c6300SRichard Henderson         tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
1656951c6300SRichard Henderson         tcg_gen_add_i64(rh, ah, bh);
1657951c6300SRichard Henderson         tcg_gen_add_i64(rh, rh, t1);
1658951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1659951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1660951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1661951c6300SRichard Henderson     }
1662951c6300SRichard Henderson }
1663951c6300SRichard Henderson 
1664951c6300SRichard Henderson void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
1665951c6300SRichard Henderson                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
1666951c6300SRichard Henderson {
1667951c6300SRichard Henderson     if (TCG_TARGET_HAS_sub2_i64) {
1668951c6300SRichard Henderson         tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
1669951c6300SRichard Henderson     } else {
1670951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1671951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1672951c6300SRichard Henderson         tcg_gen_sub_i64(t0, al, bl);
1673951c6300SRichard Henderson         tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
1674951c6300SRichard Henderson         tcg_gen_sub_i64(rh, ah, bh);
1675951c6300SRichard Henderson         tcg_gen_sub_i64(rh, rh, t1);
1676951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1677951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1678951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1679951c6300SRichard Henderson     }
1680951c6300SRichard Henderson }
1681951c6300SRichard Henderson 
1682951c6300SRichard Henderson void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
1683951c6300SRichard Henderson {
1684951c6300SRichard Henderson     if (TCG_TARGET_HAS_mulu2_i64) {
1685951c6300SRichard Henderson         tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
1686951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_muluh_i64) {
1687951c6300SRichard Henderson         TCGv_i64 t = tcg_temp_new_i64();
1688951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
1689951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
1690951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t);
1691951c6300SRichard Henderson         tcg_temp_free_i64(t);
1692951c6300SRichard Henderson     } else {
1693951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1694951c6300SRichard Henderson         tcg_gen_mul_i64(t0, arg1, arg2);
1695951c6300SRichard Henderson         gen_helper_muluh_i64(rh, arg1, arg2);
1696951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1697951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1698951c6300SRichard Henderson     }
1699951c6300SRichard Henderson }
1700951c6300SRichard Henderson 
1701951c6300SRichard Henderson void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
1702951c6300SRichard Henderson {
1703951c6300SRichard Henderson     if (TCG_TARGET_HAS_muls2_i64) {
1704951c6300SRichard Henderson         tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
1705951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_mulsh_i64) {
1706951c6300SRichard Henderson         TCGv_i64 t = tcg_temp_new_i64();
1707951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
1708951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
1709951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t);
1710951c6300SRichard Henderson         tcg_temp_free_i64(t);
1711951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
1712951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1713951c6300SRichard Henderson         TCGv_i64 t1 = tcg_temp_new_i64();
1714951c6300SRichard Henderson         TCGv_i64 t2 = tcg_temp_new_i64();
1715951c6300SRichard Henderson         TCGv_i64 t3 = tcg_temp_new_i64();
1716951c6300SRichard Henderson         tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
1717951c6300SRichard Henderson         /* Adjust for negative inputs.  */
1718951c6300SRichard Henderson         tcg_gen_sari_i64(t2, arg1, 63);
1719951c6300SRichard Henderson         tcg_gen_sari_i64(t3, arg2, 63);
1720951c6300SRichard Henderson         tcg_gen_and_i64(t2, t2, arg2);
1721951c6300SRichard Henderson         tcg_gen_and_i64(t3, t3, arg1);
1722951c6300SRichard Henderson         tcg_gen_sub_i64(rh, t1, t2);
1723951c6300SRichard Henderson         tcg_gen_sub_i64(rh, rh, t3);
1724951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1725951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1726951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1727951c6300SRichard Henderson         tcg_temp_free_i64(t2);
1728951c6300SRichard Henderson         tcg_temp_free_i64(t3);
1729951c6300SRichard Henderson     } else {
1730951c6300SRichard Henderson         TCGv_i64 t0 = tcg_temp_new_i64();
1731951c6300SRichard Henderson         tcg_gen_mul_i64(t0, arg1, arg2);
1732951c6300SRichard Henderson         gen_helper_mulsh_i64(rh, arg1, arg2);
1733951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
1734951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1735951c6300SRichard Henderson     }
1736951c6300SRichard Henderson }
1737951c6300SRichard Henderson 
1738951c6300SRichard Henderson /* Size changing operations.  */
1739951c6300SRichard Henderson 
1740951c6300SRichard Henderson void tcg_gen_trunc_shr_i64_i32(TCGv_i32 ret, TCGv_i64 arg, unsigned count)
1741951c6300SRichard Henderson {
1742951c6300SRichard Henderson     tcg_debug_assert(count < 64);
17433a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1744951c6300SRichard Henderson         if (count >= 32) {
1745951c6300SRichard Henderson             tcg_gen_shri_i32(ret, TCGV_HIGH(arg), count - 32);
1746951c6300SRichard Henderson         } else if (count == 0) {
1747951c6300SRichard Henderson             tcg_gen_mov_i32(ret, TCGV_LOW(arg));
1748951c6300SRichard Henderson         } else {
1749951c6300SRichard Henderson             TCGv_i64 t = tcg_temp_new_i64();
1750951c6300SRichard Henderson             tcg_gen_shri_i64(t, arg, count);
1751951c6300SRichard Henderson             tcg_gen_mov_i32(ret, TCGV_LOW(t));
1752951c6300SRichard Henderson             tcg_temp_free_i64(t);
1753951c6300SRichard Henderson         }
17543a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_trunc_shr_i32) {
1755951c6300SRichard Henderson         tcg_gen_op3i_i32(INDEX_op_trunc_shr_i32, ret,
1756951c6300SRichard Henderson                          MAKE_TCGV_I32(GET_TCGV_I64(arg)), count);
1757951c6300SRichard Henderson     } else if (count == 0) {
1758951c6300SRichard Henderson         tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(arg)));
1759951c6300SRichard Henderson     } else {
1760951c6300SRichard Henderson         TCGv_i64 t = tcg_temp_new_i64();
1761951c6300SRichard Henderson         tcg_gen_shri_i64(t, arg, count);
1762951c6300SRichard Henderson         tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(t)));
1763951c6300SRichard Henderson         tcg_temp_free_i64(t);
1764951c6300SRichard Henderson     }
1765951c6300SRichard Henderson }
1766951c6300SRichard Henderson 
1767951c6300SRichard Henderson void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
1768951c6300SRichard Henderson {
17693a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1770951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
1771951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
17723a13c3f3SRichard Henderson     } else {
1773951c6300SRichard Henderson         /* Note: we assume the target supports move between
1774951c6300SRichard Henderson            32 and 64 bit registers.  */
1775951c6300SRichard Henderson         tcg_gen_ext32u_i64(ret, MAKE_TCGV_I64(GET_TCGV_I32(arg)));
17763a13c3f3SRichard Henderson     }
1777951c6300SRichard Henderson }
1778951c6300SRichard Henderson 
1779951c6300SRichard Henderson void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
1780951c6300SRichard Henderson {
17813a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1782951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
1783951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
17843a13c3f3SRichard Henderson     } else {
1785951c6300SRichard Henderson         /* Note: we assume the target supports move between
1786951c6300SRichard Henderson            32 and 64 bit registers.  */
1787951c6300SRichard Henderson         tcg_gen_ext32s_i64(ret, MAKE_TCGV_I64(GET_TCGV_I32(arg)));
17883a13c3f3SRichard Henderson     }
1789951c6300SRichard Henderson }
1790951c6300SRichard Henderson 
1791951c6300SRichard Henderson void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
1792951c6300SRichard Henderson {
17933a13c3f3SRichard Henderson     TCGv_i64 tmp;
17943a13c3f3SRichard Henderson 
17953a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1796951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(dest), low);
1797951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(dest), high);
17983a13c3f3SRichard Henderson         return;
17993a13c3f3SRichard Henderson     }
18003a13c3f3SRichard Henderson 
18013a13c3f3SRichard Henderson     tmp = tcg_temp_new_i64();
1802951c6300SRichard Henderson     /* These extensions are only needed for type correctness.
1803951c6300SRichard Henderson        We may be able to do better given target specific information.  */
1804951c6300SRichard Henderson     tcg_gen_extu_i32_i64(tmp, high);
1805951c6300SRichard Henderson     tcg_gen_extu_i32_i64(dest, low);
1806951c6300SRichard Henderson     /* If deposit is available, use it.  Otherwise use the extra
1807951c6300SRichard Henderson        knowledge that we have of the zero-extensions above.  */
1808951c6300SRichard Henderson     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
1809951c6300SRichard Henderson         tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
1810951c6300SRichard Henderson     } else {
1811951c6300SRichard Henderson         tcg_gen_shli_i64(tmp, tmp, 32);
1812951c6300SRichard Henderson         tcg_gen_or_i64(dest, dest, tmp);
1813951c6300SRichard Henderson     }
1814951c6300SRichard Henderson     tcg_temp_free_i64(tmp);
1815951c6300SRichard Henderson }
1816951c6300SRichard Henderson 
1817951c6300SRichard Henderson void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
1818951c6300SRichard Henderson {
18193a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1820951c6300SRichard Henderson         tcg_gen_mov_i32(lo, TCGV_LOW(arg));
1821951c6300SRichard Henderson         tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
18223a13c3f3SRichard Henderson     } else {
1823951c6300SRichard Henderson         tcg_gen_trunc_shr_i64_i32(lo, arg, 0);
1824951c6300SRichard Henderson         tcg_gen_trunc_shr_i64_i32(hi, arg, 32);
18253a13c3f3SRichard Henderson     }
1826951c6300SRichard Henderson }
1827951c6300SRichard Henderson 
1828951c6300SRichard Henderson void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
1829951c6300SRichard Henderson {
1830951c6300SRichard Henderson     tcg_gen_ext32u_i64(lo, arg);
1831951c6300SRichard Henderson     tcg_gen_shri_i64(hi, arg, 32);
1832951c6300SRichard Henderson }
1833951c6300SRichard Henderson 
1834951c6300SRichard Henderson /* QEMU specific operations.  */
1835951c6300SRichard Henderson 
1836951c6300SRichard Henderson void tcg_gen_goto_tb(unsigned idx)
1837951c6300SRichard Henderson {
1838951c6300SRichard Henderson     /* We only support two chained exits.  */
1839951c6300SRichard Henderson     tcg_debug_assert(idx <= 1);
1840951c6300SRichard Henderson #ifdef CONFIG_DEBUG_TCG
1841951c6300SRichard Henderson     /* Verify that we havn't seen this numbered exit before.  */
1842951c6300SRichard Henderson     tcg_debug_assert((tcg_ctx.goto_tb_issue_mask & (1 << idx)) == 0);
1843951c6300SRichard Henderson     tcg_ctx.goto_tb_issue_mask |= 1 << idx;
1844951c6300SRichard Henderson #endif
1845951c6300SRichard Henderson     tcg_gen_op1i(INDEX_op_goto_tb, idx);
1846951c6300SRichard Henderson }
1847951c6300SRichard Henderson 
1848951c6300SRichard Henderson static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st)
1849951c6300SRichard Henderson {
1850951c6300SRichard Henderson     switch (op & MO_SIZE) {
1851951c6300SRichard Henderson     case MO_8:
1852951c6300SRichard Henderson         op &= ~MO_BSWAP;
1853951c6300SRichard Henderson         break;
1854951c6300SRichard Henderson     case MO_16:
1855951c6300SRichard Henderson         break;
1856951c6300SRichard Henderson     case MO_32:
1857951c6300SRichard Henderson         if (!is64) {
1858951c6300SRichard Henderson             op &= ~MO_SIGN;
1859951c6300SRichard Henderson         }
1860951c6300SRichard Henderson         break;
1861951c6300SRichard Henderson     case MO_64:
1862951c6300SRichard Henderson         if (!is64) {
1863951c6300SRichard Henderson             tcg_abort();
1864951c6300SRichard Henderson         }
1865951c6300SRichard Henderson         break;
1866951c6300SRichard Henderson     }
1867951c6300SRichard Henderson     if (st) {
1868951c6300SRichard Henderson         op &= ~MO_SIGN;
1869951c6300SRichard Henderson     }
1870951c6300SRichard Henderson     return op;
1871951c6300SRichard Henderson }
1872951c6300SRichard Henderson 
1873c45cb8bbSRichard Henderson static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv addr,
1874c45cb8bbSRichard Henderson                          TCGMemOp memop, TCGArg idx)
1875951c6300SRichard Henderson {
1876951c6300SRichard Henderson #if TARGET_LONG_BITS == 32
1877c45cb8bbSRichard Henderson     tcg_gen_op4ii_i32(opc, val, addr, memop, idx);
1878951c6300SRichard Henderson #else
1879c45cb8bbSRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1880c45cb8bbSRichard Henderson         tcg_gen_op5ii_i32(opc, val, TCGV_LOW(addr), TCGV_HIGH(addr),
1881c45cb8bbSRichard Henderson                           memop, idx);
1882c45cb8bbSRichard Henderson     } else {
1883c45cb8bbSRichard Henderson         tcg_gen_op4(&tcg_ctx, opc, GET_TCGV_I32(val), GET_TCGV_I64(addr),
1884c45cb8bbSRichard Henderson                     memop, idx);
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 {
1892c45cb8bbSRichard Henderson #if TARGET_LONG_BITS == 32
1893c45cb8bbSRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1894c45cb8bbSRichard Henderson         tcg_gen_op5ii_i32(opc, TCGV_LOW(val), TCGV_HIGH(val),
1895c45cb8bbSRichard Henderson                           addr, memop, idx);
1896c45cb8bbSRichard Henderson     } else {
1897c45cb8bbSRichard Henderson         tcg_gen_op4(&tcg_ctx, opc, GET_TCGV_I64(val), GET_TCGV_I32(addr),
1898c45cb8bbSRichard Henderson                     memop, idx);
1899c45cb8bbSRichard Henderson     }
1900c45cb8bbSRichard Henderson #else
1901c45cb8bbSRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1902c45cb8bbSRichard Henderson         tcg_gen_op6ii_i32(opc, TCGV_LOW(val), TCGV_HIGH(val),
1903c45cb8bbSRichard Henderson                           TCGV_LOW(addr), TCGV_HIGH(addr), memop, idx);
1904c45cb8bbSRichard Henderson     } else {
1905c45cb8bbSRichard Henderson         tcg_gen_op4ii_i64(opc, val, addr, memop, idx);
1906c45cb8bbSRichard Henderson     }
1907c45cb8bbSRichard Henderson #endif
1908c45cb8bbSRichard Henderson }
1909951c6300SRichard Henderson 
1910951c6300SRichard Henderson void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1911951c6300SRichard Henderson {
1912951c6300SRichard Henderson     memop = tcg_canonicalize_memop(memop, 0, 0);
1913c45cb8bbSRichard Henderson     gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx);
1914951c6300SRichard Henderson }
1915951c6300SRichard Henderson 
1916951c6300SRichard Henderson void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1917951c6300SRichard Henderson {
1918951c6300SRichard Henderson     memop = tcg_canonicalize_memop(memop, 0, 1);
1919c45cb8bbSRichard Henderson     gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
1920951c6300SRichard Henderson }
1921951c6300SRichard Henderson 
1922951c6300SRichard Henderson void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1923951c6300SRichard Henderson {
19243a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
1925951c6300SRichard Henderson         tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop);
1926951c6300SRichard Henderson         if (memop & MO_SIGN) {
1927951c6300SRichard Henderson             tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31);
1928951c6300SRichard Henderson         } else {
1929951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_HIGH(val), 0);
1930951c6300SRichard Henderson         }
1931951c6300SRichard Henderson         return;
1932951c6300SRichard Henderson     }
1933951c6300SRichard Henderson 
1934c45cb8bbSRichard Henderson     memop = tcg_canonicalize_memop(memop, 1, 0);
1935c45cb8bbSRichard Henderson     gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx);
1936951c6300SRichard Henderson }
1937951c6300SRichard Henderson 
1938951c6300SRichard Henderson void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
1939951c6300SRichard Henderson {
19403a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
1941951c6300SRichard Henderson         tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop);
1942951c6300SRichard Henderson         return;
1943951c6300SRichard Henderson     }
1944951c6300SRichard Henderson 
1945c45cb8bbSRichard Henderson     memop = tcg_canonicalize_memop(memop, 1, 1);
1946c45cb8bbSRichard Henderson     gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx);
1947951c6300SRichard Henderson }
1948