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