xref: /qemu/tcg/tcg-op.c (revision f99b38fc)
1 /*
2  * Tiny Code Generator for QEMU
3  *
4  * Copyright (c) 2008 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 #include "qemu/osdep.h"
26 #include "qemu-common.h"
27 #include "cpu.h"
28 #include "exec/exec-all.h"
29 #include "tcg.h"
30 #include "tcg-op.h"
31 #include "tcg-mo.h"
32 #include "trace-tcg.h"
33 #include "trace/mem.h"
34 
35 /* Reduce the number of ifdefs below.  This assumes that all uses of
36    TCGV_HIGH and TCGV_LOW are properly protected by a conditional that
37    the compiler can eliminate.  */
38 #if TCG_TARGET_REG_BITS == 64
39 extern TCGv_i32 TCGV_LOW_link_error(TCGv_i64);
40 extern TCGv_i32 TCGV_HIGH_link_error(TCGv_i64);
41 #define TCGV_LOW  TCGV_LOW_link_error
42 #define TCGV_HIGH TCGV_HIGH_link_error
43 #endif
44 
45 /* Note that this is optimized for sequential allocation during translate.
46    Up to and including filling in the forward link immediately.  We'll do
47    proper termination of the end of the list after we finish translation.  */
48 
49 static void tcg_emit_op(TCGContext *ctx, TCGOpcode opc, int args)
50 {
51     int oi = ctx->gen_next_op_idx;
52     int ni = oi + 1;
53     int pi = oi - 1;
54 
55     tcg_debug_assert(oi < OPC_BUF_SIZE);
56     ctx->gen_op_buf[0].prev = oi;
57     ctx->gen_next_op_idx = ni;
58 
59     ctx->gen_op_buf[oi] = (TCGOp){
60         .opc = opc,
61         .args = args,
62         .prev = pi,
63         .next = ni
64     };
65 }
66 
67 void tcg_gen_op1(TCGContext *ctx, TCGOpcode opc, TCGArg a1)
68 {
69     int pi = ctx->gen_next_parm_idx;
70 
71     tcg_debug_assert(pi + 1 <= OPPARAM_BUF_SIZE);
72     ctx->gen_next_parm_idx = pi + 1;
73     ctx->gen_opparam_buf[pi] = a1;
74 
75     tcg_emit_op(ctx, opc, pi);
76 }
77 
78 void tcg_gen_op2(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2)
79 {
80     int pi = ctx->gen_next_parm_idx;
81 
82     tcg_debug_assert(pi + 2 <= OPPARAM_BUF_SIZE);
83     ctx->gen_next_parm_idx = pi + 2;
84     ctx->gen_opparam_buf[pi + 0] = a1;
85     ctx->gen_opparam_buf[pi + 1] = a2;
86 
87     tcg_emit_op(ctx, opc, pi);
88 }
89 
90 void tcg_gen_op3(TCGContext *ctx, TCGOpcode opc, TCGArg a1,
91                  TCGArg a2, TCGArg a3)
92 {
93     int pi = ctx->gen_next_parm_idx;
94 
95     tcg_debug_assert(pi + 3 <= OPPARAM_BUF_SIZE);
96     ctx->gen_next_parm_idx = pi + 3;
97     ctx->gen_opparam_buf[pi + 0] = a1;
98     ctx->gen_opparam_buf[pi + 1] = a2;
99     ctx->gen_opparam_buf[pi + 2] = a3;
100 
101     tcg_emit_op(ctx, opc, pi);
102 }
103 
104 void tcg_gen_op4(TCGContext *ctx, TCGOpcode opc, TCGArg a1,
105                  TCGArg a2, TCGArg a3, TCGArg a4)
106 {
107     int pi = ctx->gen_next_parm_idx;
108 
109     tcg_debug_assert(pi + 4 <= OPPARAM_BUF_SIZE);
110     ctx->gen_next_parm_idx = pi + 4;
111     ctx->gen_opparam_buf[pi + 0] = a1;
112     ctx->gen_opparam_buf[pi + 1] = a2;
113     ctx->gen_opparam_buf[pi + 2] = a3;
114     ctx->gen_opparam_buf[pi + 3] = a4;
115 
116     tcg_emit_op(ctx, opc, pi);
117 }
118 
119 void tcg_gen_op5(TCGContext *ctx, TCGOpcode opc, TCGArg a1,
120                  TCGArg a2, TCGArg a3, TCGArg a4, TCGArg a5)
121 {
122     int pi = ctx->gen_next_parm_idx;
123 
124     tcg_debug_assert(pi + 5 <= OPPARAM_BUF_SIZE);
125     ctx->gen_next_parm_idx = pi + 5;
126     ctx->gen_opparam_buf[pi + 0] = a1;
127     ctx->gen_opparam_buf[pi + 1] = a2;
128     ctx->gen_opparam_buf[pi + 2] = a3;
129     ctx->gen_opparam_buf[pi + 3] = a4;
130     ctx->gen_opparam_buf[pi + 4] = a5;
131 
132     tcg_emit_op(ctx, opc, pi);
133 }
134 
135 void tcg_gen_op6(TCGContext *ctx, TCGOpcode opc, TCGArg a1, TCGArg a2,
136                  TCGArg a3, TCGArg a4, TCGArg a5, TCGArg a6)
137 {
138     int pi = ctx->gen_next_parm_idx;
139 
140     tcg_debug_assert(pi + 6 <= OPPARAM_BUF_SIZE);
141     ctx->gen_next_parm_idx = pi + 6;
142     ctx->gen_opparam_buf[pi + 0] = a1;
143     ctx->gen_opparam_buf[pi + 1] = a2;
144     ctx->gen_opparam_buf[pi + 2] = a3;
145     ctx->gen_opparam_buf[pi + 3] = a4;
146     ctx->gen_opparam_buf[pi + 4] = a5;
147     ctx->gen_opparam_buf[pi + 5] = a6;
148 
149     tcg_emit_op(ctx, opc, pi);
150 }
151 
152 void tcg_gen_mb(TCGBar mb_type)
153 {
154     if (parallel_cpus) {
155         tcg_gen_op1(&tcg_ctx, INDEX_op_mb, mb_type);
156     }
157 }
158 
159 /* 32 bit ops */
160 
161 void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
162 {
163     /* some cases can be optimized here */
164     if (arg2 == 0) {
165         tcg_gen_mov_i32(ret, arg1);
166     } else {
167         TCGv_i32 t0 = tcg_const_i32(arg2);
168         tcg_gen_add_i32(ret, arg1, t0);
169         tcg_temp_free_i32(t0);
170     }
171 }
172 
173 void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2)
174 {
175     if (arg1 == 0 && TCG_TARGET_HAS_neg_i32) {
176         /* Don't recurse with tcg_gen_neg_i32.  */
177         tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg2);
178     } else {
179         TCGv_i32 t0 = tcg_const_i32(arg1);
180         tcg_gen_sub_i32(ret, t0, arg2);
181         tcg_temp_free_i32(t0);
182     }
183 }
184 
185 void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
186 {
187     /* some cases can be optimized here */
188     if (arg2 == 0) {
189         tcg_gen_mov_i32(ret, arg1);
190     } else {
191         TCGv_i32 t0 = tcg_const_i32(arg2);
192         tcg_gen_sub_i32(ret, arg1, t0);
193         tcg_temp_free_i32(t0);
194     }
195 }
196 
197 void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
198 {
199     TCGv_i32 t0;
200     /* Some cases can be optimized here.  */
201     switch (arg2) {
202     case 0:
203         tcg_gen_movi_i32(ret, 0);
204         return;
205     case 0xffffffffu:
206         tcg_gen_mov_i32(ret, arg1);
207         return;
208     case 0xffu:
209         /* Don't recurse with tcg_gen_ext8u_i32.  */
210         if (TCG_TARGET_HAS_ext8u_i32) {
211             tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
212             return;
213         }
214         break;
215     case 0xffffu:
216         if (TCG_TARGET_HAS_ext16u_i32) {
217             tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
218             return;
219         }
220         break;
221     }
222     t0 = tcg_const_i32(arg2);
223     tcg_gen_and_i32(ret, arg1, t0);
224     tcg_temp_free_i32(t0);
225 }
226 
227 void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
228 {
229     /* Some cases can be optimized here.  */
230     if (arg2 == -1) {
231         tcg_gen_movi_i32(ret, -1);
232     } else if (arg2 == 0) {
233         tcg_gen_mov_i32(ret, arg1);
234     } else {
235         TCGv_i32 t0 = tcg_const_i32(arg2);
236         tcg_gen_or_i32(ret, arg1, t0);
237         tcg_temp_free_i32(t0);
238     }
239 }
240 
241 void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
242 {
243     /* Some cases can be optimized here.  */
244     if (arg2 == 0) {
245         tcg_gen_mov_i32(ret, arg1);
246     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) {
247         /* Don't recurse with tcg_gen_not_i32.  */
248         tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1);
249     } else {
250         TCGv_i32 t0 = tcg_const_i32(arg2);
251         tcg_gen_xor_i32(ret, arg1, t0);
252         tcg_temp_free_i32(t0);
253     }
254 }
255 
256 void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
257 {
258     tcg_debug_assert(arg2 < 32);
259     if (arg2 == 0) {
260         tcg_gen_mov_i32(ret, arg1);
261     } else {
262         TCGv_i32 t0 = tcg_const_i32(arg2);
263         tcg_gen_shl_i32(ret, arg1, t0);
264         tcg_temp_free_i32(t0);
265     }
266 }
267 
268 void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
269 {
270     tcg_debug_assert(arg2 < 32);
271     if (arg2 == 0) {
272         tcg_gen_mov_i32(ret, arg1);
273     } else {
274         TCGv_i32 t0 = tcg_const_i32(arg2);
275         tcg_gen_shr_i32(ret, arg1, t0);
276         tcg_temp_free_i32(t0);
277     }
278 }
279 
280 void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
281 {
282     tcg_debug_assert(arg2 < 32);
283     if (arg2 == 0) {
284         tcg_gen_mov_i32(ret, arg1);
285     } else {
286         TCGv_i32 t0 = tcg_const_i32(arg2);
287         tcg_gen_sar_i32(ret, arg1, t0);
288         tcg_temp_free_i32(t0);
289     }
290 }
291 
292 void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l)
293 {
294     if (cond == TCG_COND_ALWAYS) {
295         tcg_gen_br(l);
296     } else if (cond != TCG_COND_NEVER) {
297         tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l));
298     }
299 }
300 
301 void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l)
302 {
303     if (cond == TCG_COND_ALWAYS) {
304         tcg_gen_br(l);
305     } else if (cond != TCG_COND_NEVER) {
306         TCGv_i32 t0 = tcg_const_i32(arg2);
307         tcg_gen_brcond_i32(cond, arg1, t0, l);
308         tcg_temp_free_i32(t0);
309     }
310 }
311 
312 void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
313                          TCGv_i32 arg1, TCGv_i32 arg2)
314 {
315     if (cond == TCG_COND_ALWAYS) {
316         tcg_gen_movi_i32(ret, 1);
317     } else if (cond == TCG_COND_NEVER) {
318         tcg_gen_movi_i32(ret, 0);
319     } else {
320         tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
321     }
322 }
323 
324 void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
325                           TCGv_i32 arg1, int32_t arg2)
326 {
327     TCGv_i32 t0 = tcg_const_i32(arg2);
328     tcg_gen_setcond_i32(cond, ret, arg1, t0);
329     tcg_temp_free_i32(t0);
330 }
331 
332 void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
333 {
334     TCGv_i32 t0 = tcg_const_i32(arg2);
335     tcg_gen_mul_i32(ret, arg1, t0);
336     tcg_temp_free_i32(t0);
337 }
338 
339 void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
340 {
341     if (TCG_TARGET_HAS_div_i32) {
342         tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
343     } else if (TCG_TARGET_HAS_div2_i32) {
344         TCGv_i32 t0 = tcg_temp_new_i32();
345         tcg_gen_sari_i32(t0, arg1, 31);
346         tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
347         tcg_temp_free_i32(t0);
348     } else {
349         gen_helper_div_i32(ret, arg1, arg2);
350     }
351 }
352 
353 void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
354 {
355     if (TCG_TARGET_HAS_rem_i32) {
356         tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
357     } else if (TCG_TARGET_HAS_div_i32) {
358         TCGv_i32 t0 = tcg_temp_new_i32();
359         tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
360         tcg_gen_mul_i32(t0, t0, arg2);
361         tcg_gen_sub_i32(ret, arg1, t0);
362         tcg_temp_free_i32(t0);
363     } else if (TCG_TARGET_HAS_div2_i32) {
364         TCGv_i32 t0 = tcg_temp_new_i32();
365         tcg_gen_sari_i32(t0, arg1, 31);
366         tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
367         tcg_temp_free_i32(t0);
368     } else {
369         gen_helper_rem_i32(ret, arg1, arg2);
370     }
371 }
372 
373 void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
374 {
375     if (TCG_TARGET_HAS_div_i32) {
376         tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
377     } else if (TCG_TARGET_HAS_div2_i32) {
378         TCGv_i32 t0 = tcg_temp_new_i32();
379         tcg_gen_movi_i32(t0, 0);
380         tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
381         tcg_temp_free_i32(t0);
382     } else {
383         gen_helper_divu_i32(ret, arg1, arg2);
384     }
385 }
386 
387 void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
388 {
389     if (TCG_TARGET_HAS_rem_i32) {
390         tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
391     } else if (TCG_TARGET_HAS_div_i32) {
392         TCGv_i32 t0 = tcg_temp_new_i32();
393         tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
394         tcg_gen_mul_i32(t0, t0, arg2);
395         tcg_gen_sub_i32(ret, arg1, t0);
396         tcg_temp_free_i32(t0);
397     } else if (TCG_TARGET_HAS_div2_i32) {
398         TCGv_i32 t0 = tcg_temp_new_i32();
399         tcg_gen_movi_i32(t0, 0);
400         tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
401         tcg_temp_free_i32(t0);
402     } else {
403         gen_helper_remu_i32(ret, arg1, arg2);
404     }
405 }
406 
407 void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
408 {
409     if (TCG_TARGET_HAS_andc_i32) {
410         tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
411     } else {
412         TCGv_i32 t0 = tcg_temp_new_i32();
413         tcg_gen_not_i32(t0, arg2);
414         tcg_gen_and_i32(ret, arg1, t0);
415         tcg_temp_free_i32(t0);
416     }
417 }
418 
419 void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
420 {
421     if (TCG_TARGET_HAS_eqv_i32) {
422         tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
423     } else {
424         tcg_gen_xor_i32(ret, arg1, arg2);
425         tcg_gen_not_i32(ret, ret);
426     }
427 }
428 
429 void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
430 {
431     if (TCG_TARGET_HAS_nand_i32) {
432         tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
433     } else {
434         tcg_gen_and_i32(ret, arg1, arg2);
435         tcg_gen_not_i32(ret, ret);
436     }
437 }
438 
439 void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
440 {
441     if (TCG_TARGET_HAS_nor_i32) {
442         tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
443     } else {
444         tcg_gen_or_i32(ret, arg1, arg2);
445         tcg_gen_not_i32(ret, ret);
446     }
447 }
448 
449 void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
450 {
451     if (TCG_TARGET_HAS_orc_i32) {
452         tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
453     } else {
454         TCGv_i32 t0 = tcg_temp_new_i32();
455         tcg_gen_not_i32(t0, arg2);
456         tcg_gen_or_i32(ret, arg1, t0);
457         tcg_temp_free_i32(t0);
458     }
459 }
460 
461 void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
462 {
463     if (TCG_TARGET_HAS_clz_i32) {
464         tcg_gen_op3_i32(INDEX_op_clz_i32, ret, arg1, arg2);
465     } else if (TCG_TARGET_HAS_clz_i64) {
466         TCGv_i64 t1 = tcg_temp_new_i64();
467         TCGv_i64 t2 = tcg_temp_new_i64();
468         tcg_gen_extu_i32_i64(t1, arg1);
469         tcg_gen_extu_i32_i64(t2, arg2);
470         tcg_gen_addi_i64(t2, t2, 32);
471         tcg_gen_clz_i64(t1, t1, t2);
472         tcg_gen_extrl_i64_i32(ret, t1);
473         tcg_temp_free_i64(t1);
474         tcg_temp_free_i64(t2);
475         tcg_gen_subi_i32(ret, ret, 32);
476     } else {
477         gen_helper_clz_i32(ret, arg1, arg2);
478     }
479 }
480 
481 void tcg_gen_clzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
482 {
483     TCGv_i32 t = tcg_const_i32(arg2);
484     tcg_gen_clz_i32(ret, arg1, t);
485     tcg_temp_free_i32(t);
486 }
487 
488 void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
489 {
490     if (TCG_TARGET_HAS_ctz_i32) {
491         tcg_gen_op3_i32(INDEX_op_ctz_i32, ret, arg1, arg2);
492     } else if (TCG_TARGET_HAS_ctz_i64) {
493         TCGv_i64 t1 = tcg_temp_new_i64();
494         TCGv_i64 t2 = tcg_temp_new_i64();
495         tcg_gen_extu_i32_i64(t1, arg1);
496         tcg_gen_extu_i32_i64(t2, arg2);
497         tcg_gen_ctz_i64(t1, t1, t2);
498         tcg_gen_extrl_i64_i32(ret, t1);
499         tcg_temp_free_i64(t1);
500         tcg_temp_free_i64(t2);
501     } else if (TCG_TARGET_HAS_ctpop_i32
502                || TCG_TARGET_HAS_ctpop_i64
503                || TCG_TARGET_HAS_clz_i32
504                || TCG_TARGET_HAS_clz_i64) {
505         TCGv_i32 z, t = tcg_temp_new_i32();
506 
507         if (TCG_TARGET_HAS_ctpop_i32 || TCG_TARGET_HAS_ctpop_i64) {
508             tcg_gen_subi_i32(t, arg1, 1);
509             tcg_gen_andc_i32(t, t, arg1);
510             tcg_gen_ctpop_i32(t, t);
511         } else {
512             /* Since all non-x86 hosts have clz(0) == 32, don't fight it.  */
513             tcg_gen_neg_i32(t, arg1);
514             tcg_gen_and_i32(t, t, arg1);
515             tcg_gen_clzi_i32(t, t, 32);
516             tcg_gen_xori_i32(t, t, 31);
517         }
518         z = tcg_const_i32(0);
519         tcg_gen_movcond_i32(TCG_COND_EQ, ret, arg1, z, arg2, t);
520         tcg_temp_free_i32(t);
521         tcg_temp_free_i32(z);
522     } else {
523         gen_helper_ctz_i32(ret, arg1, arg2);
524     }
525 }
526 
527 void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
528 {
529     if (!TCG_TARGET_HAS_ctz_i32 && TCG_TARGET_HAS_ctpop_i32 && arg2 == 32) {
530         /* This equivalence has the advantage of not requiring a fixup.  */
531         TCGv_i32 t = tcg_temp_new_i32();
532         tcg_gen_subi_i32(t, arg1, 1);
533         tcg_gen_andc_i32(t, t, arg1);
534         tcg_gen_ctpop_i32(ret, t);
535         tcg_temp_free_i32(t);
536     } else {
537         TCGv_i32 t = tcg_const_i32(arg2);
538         tcg_gen_ctz_i32(ret, arg1, t);
539         tcg_temp_free_i32(t);
540     }
541 }
542 
543 void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg)
544 {
545     if (TCG_TARGET_HAS_clz_i32) {
546         TCGv_i32 t = tcg_temp_new_i32();
547         tcg_gen_sari_i32(t, arg, 31);
548         tcg_gen_xor_i32(t, t, arg);
549         tcg_gen_clzi_i32(t, t, 32);
550         tcg_gen_subi_i32(ret, t, 1);
551         tcg_temp_free_i32(t);
552     } else {
553         gen_helper_clrsb_i32(ret, arg);
554     }
555 }
556 
557 void tcg_gen_ctpop_i32(TCGv_i32 ret, TCGv_i32 arg1)
558 {
559     if (TCG_TARGET_HAS_ctpop_i32) {
560         tcg_gen_op2_i32(INDEX_op_ctpop_i32, ret, arg1);
561     } else if (TCG_TARGET_HAS_ctpop_i64) {
562         TCGv_i64 t = tcg_temp_new_i64();
563         tcg_gen_extu_i32_i64(t, arg1);
564         tcg_gen_ctpop_i64(t, t);
565         tcg_gen_extrl_i64_i32(ret, t);
566         tcg_temp_free_i64(t);
567     } else {
568         gen_helper_ctpop_i32(ret, arg1);
569     }
570 }
571 
572 void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
573 {
574     if (TCG_TARGET_HAS_rot_i32) {
575         tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
576     } else {
577         TCGv_i32 t0, t1;
578 
579         t0 = tcg_temp_new_i32();
580         t1 = tcg_temp_new_i32();
581         tcg_gen_shl_i32(t0, arg1, arg2);
582         tcg_gen_subfi_i32(t1, 32, arg2);
583         tcg_gen_shr_i32(t1, arg1, t1);
584         tcg_gen_or_i32(ret, t0, t1);
585         tcg_temp_free_i32(t0);
586         tcg_temp_free_i32(t1);
587     }
588 }
589 
590 void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
591 {
592     tcg_debug_assert(arg2 < 32);
593     /* some cases can be optimized here */
594     if (arg2 == 0) {
595         tcg_gen_mov_i32(ret, arg1);
596     } else if (TCG_TARGET_HAS_rot_i32) {
597         TCGv_i32 t0 = tcg_const_i32(arg2);
598         tcg_gen_rotl_i32(ret, arg1, t0);
599         tcg_temp_free_i32(t0);
600     } else {
601         TCGv_i32 t0, t1;
602         t0 = tcg_temp_new_i32();
603         t1 = tcg_temp_new_i32();
604         tcg_gen_shli_i32(t0, arg1, arg2);
605         tcg_gen_shri_i32(t1, arg1, 32 - arg2);
606         tcg_gen_or_i32(ret, t0, t1);
607         tcg_temp_free_i32(t0);
608         tcg_temp_free_i32(t1);
609     }
610 }
611 
612 void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
613 {
614     if (TCG_TARGET_HAS_rot_i32) {
615         tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
616     } else {
617         TCGv_i32 t0, t1;
618 
619         t0 = tcg_temp_new_i32();
620         t1 = tcg_temp_new_i32();
621         tcg_gen_shr_i32(t0, arg1, arg2);
622         tcg_gen_subfi_i32(t1, 32, arg2);
623         tcg_gen_shl_i32(t1, arg1, t1);
624         tcg_gen_or_i32(ret, t0, t1);
625         tcg_temp_free_i32(t0);
626         tcg_temp_free_i32(t1);
627     }
628 }
629 
630 void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2)
631 {
632     tcg_debug_assert(arg2 < 32);
633     /* some cases can be optimized here */
634     if (arg2 == 0) {
635         tcg_gen_mov_i32(ret, arg1);
636     } else {
637         tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
638     }
639 }
640 
641 void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
642                          unsigned int ofs, unsigned int len)
643 {
644     uint32_t mask;
645     TCGv_i32 t1;
646 
647     tcg_debug_assert(ofs < 32);
648     tcg_debug_assert(len > 0);
649     tcg_debug_assert(len <= 32);
650     tcg_debug_assert(ofs + len <= 32);
651 
652     if (len == 32) {
653         tcg_gen_mov_i32(ret, arg2);
654         return;
655     }
656     if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
657         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
658         return;
659     }
660 
661     mask = (1u << len) - 1;
662     t1 = tcg_temp_new_i32();
663 
664     if (ofs + len < 32) {
665         tcg_gen_andi_i32(t1, arg2, mask);
666         tcg_gen_shli_i32(t1, t1, ofs);
667     } else {
668         tcg_gen_shli_i32(t1, arg2, ofs);
669     }
670     tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
671     tcg_gen_or_i32(ret, ret, t1);
672 
673     tcg_temp_free_i32(t1);
674 }
675 
676 void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
677                            unsigned int ofs, unsigned int len)
678 {
679     tcg_debug_assert(ofs < 32);
680     tcg_debug_assert(len > 0);
681     tcg_debug_assert(len <= 32);
682     tcg_debug_assert(ofs + len <= 32);
683 
684     if (ofs + len == 32) {
685         tcg_gen_shli_i32(ret, arg, ofs);
686     } else if (ofs == 0) {
687         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
688     } else if (TCG_TARGET_HAS_deposit_i32
689                && TCG_TARGET_deposit_i32_valid(ofs, len)) {
690         TCGv_i32 zero = tcg_const_i32(0);
691         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len);
692         tcg_temp_free_i32(zero);
693     } else {
694         /* To help two-operand hosts we prefer to zero-extend first,
695            which allows ARG to stay live.  */
696         switch (len) {
697         case 16:
698             if (TCG_TARGET_HAS_ext16u_i32) {
699                 tcg_gen_ext16u_i32(ret, arg);
700                 tcg_gen_shli_i32(ret, ret, ofs);
701                 return;
702             }
703             break;
704         case 8:
705             if (TCG_TARGET_HAS_ext8u_i32) {
706                 tcg_gen_ext8u_i32(ret, arg);
707                 tcg_gen_shli_i32(ret, ret, ofs);
708                 return;
709             }
710             break;
711         }
712         /* Otherwise prefer zero-extension over AND for code size.  */
713         switch (ofs + len) {
714         case 16:
715             if (TCG_TARGET_HAS_ext16u_i32) {
716                 tcg_gen_shli_i32(ret, arg, ofs);
717                 tcg_gen_ext16u_i32(ret, ret);
718                 return;
719             }
720             break;
721         case 8:
722             if (TCG_TARGET_HAS_ext8u_i32) {
723                 tcg_gen_shli_i32(ret, arg, ofs);
724                 tcg_gen_ext8u_i32(ret, ret);
725                 return;
726             }
727             break;
728         }
729         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
730         tcg_gen_shli_i32(ret, ret, ofs);
731     }
732 }
733 
734 void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
735                          unsigned int ofs, unsigned int len)
736 {
737     tcg_debug_assert(ofs < 32);
738     tcg_debug_assert(len > 0);
739     tcg_debug_assert(len <= 32);
740     tcg_debug_assert(ofs + len <= 32);
741 
742     /* Canonicalize certain special cases, even if extract is supported.  */
743     if (ofs + len == 32) {
744         tcg_gen_shri_i32(ret, arg, 32 - len);
745         return;
746     }
747     if (ofs == 0) {
748         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
749         return;
750     }
751 
752     if (TCG_TARGET_HAS_extract_i32
753         && TCG_TARGET_extract_i32_valid(ofs, len)) {
754         tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, ofs, len);
755         return;
756     }
757 
758     /* Assume that zero-extension, if available, is cheaper than a shift.  */
759     switch (ofs + len) {
760     case 16:
761         if (TCG_TARGET_HAS_ext16u_i32) {
762             tcg_gen_ext16u_i32(ret, arg);
763             tcg_gen_shri_i32(ret, ret, ofs);
764             return;
765         }
766         break;
767     case 8:
768         if (TCG_TARGET_HAS_ext8u_i32) {
769             tcg_gen_ext8u_i32(ret, arg);
770             tcg_gen_shri_i32(ret, ret, ofs);
771             return;
772         }
773         break;
774     }
775 
776     /* ??? Ideally we'd know what values are available for immediate AND.
777        Assume that 8 bits are available, plus the special case of 16,
778        so that we get ext8u, ext16u.  */
779     switch (len) {
780     case 1 ... 8: case 16:
781         tcg_gen_shri_i32(ret, arg, ofs);
782         tcg_gen_andi_i32(ret, ret, (1u << len) - 1);
783         break;
784     default:
785         tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
786         tcg_gen_shri_i32(ret, ret, 32 - len);
787         break;
788     }
789 }
790 
791 void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
792                           unsigned int ofs, unsigned int len)
793 {
794     tcg_debug_assert(ofs < 32);
795     tcg_debug_assert(len > 0);
796     tcg_debug_assert(len <= 32);
797     tcg_debug_assert(ofs + len <= 32);
798 
799     /* Canonicalize certain special cases, even if extract is supported.  */
800     if (ofs + len == 32) {
801         tcg_gen_sari_i32(ret, arg, 32 - len);
802         return;
803     }
804     if (ofs == 0) {
805         switch (len) {
806         case 16:
807             tcg_gen_ext16s_i32(ret, arg);
808             return;
809         case 8:
810             tcg_gen_ext8s_i32(ret, arg);
811             return;
812         }
813     }
814 
815     if (TCG_TARGET_HAS_sextract_i32
816         && TCG_TARGET_extract_i32_valid(ofs, len)) {
817         tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len);
818         return;
819     }
820 
821     /* Assume that sign-extension, if available, is cheaper than a shift.  */
822     switch (ofs + len) {
823     case 16:
824         if (TCG_TARGET_HAS_ext16s_i32) {
825             tcg_gen_ext16s_i32(ret, arg);
826             tcg_gen_sari_i32(ret, ret, ofs);
827             return;
828         }
829         break;
830     case 8:
831         if (TCG_TARGET_HAS_ext8s_i32) {
832             tcg_gen_ext8s_i32(ret, arg);
833             tcg_gen_sari_i32(ret, ret, ofs);
834             return;
835         }
836         break;
837     }
838     switch (len) {
839     case 16:
840         if (TCG_TARGET_HAS_ext16s_i32) {
841             tcg_gen_shri_i32(ret, arg, ofs);
842             tcg_gen_ext16s_i32(ret, ret);
843             return;
844         }
845         break;
846     case 8:
847         if (TCG_TARGET_HAS_ext8s_i32) {
848             tcg_gen_shri_i32(ret, arg, ofs);
849             tcg_gen_ext8s_i32(ret, ret);
850             return;
851         }
852         break;
853     }
854 
855     tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
856     tcg_gen_sari_i32(ret, ret, 32 - len);
857 }
858 
859 void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
860                          TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2)
861 {
862     if (cond == TCG_COND_ALWAYS) {
863         tcg_gen_mov_i32(ret, v1);
864     } else if (cond == TCG_COND_NEVER) {
865         tcg_gen_mov_i32(ret, v2);
866     } else if (TCG_TARGET_HAS_movcond_i32) {
867         tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
868     } else {
869         TCGv_i32 t0 = tcg_temp_new_i32();
870         TCGv_i32 t1 = tcg_temp_new_i32();
871         tcg_gen_setcond_i32(cond, t0, c1, c2);
872         tcg_gen_neg_i32(t0, t0);
873         tcg_gen_and_i32(t1, v1, t0);
874         tcg_gen_andc_i32(ret, v2, t0);
875         tcg_gen_or_i32(ret, ret, t1);
876         tcg_temp_free_i32(t0);
877         tcg_temp_free_i32(t1);
878     }
879 }
880 
881 void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
882                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
883 {
884     if (TCG_TARGET_HAS_add2_i32) {
885         tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
886     } else {
887         TCGv_i64 t0 = tcg_temp_new_i64();
888         TCGv_i64 t1 = tcg_temp_new_i64();
889         tcg_gen_concat_i32_i64(t0, al, ah);
890         tcg_gen_concat_i32_i64(t1, bl, bh);
891         tcg_gen_add_i64(t0, t0, t1);
892         tcg_gen_extr_i64_i32(rl, rh, t0);
893         tcg_temp_free_i64(t0);
894         tcg_temp_free_i64(t1);
895     }
896 }
897 
898 void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
899                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
900 {
901     if (TCG_TARGET_HAS_sub2_i32) {
902         tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
903     } else {
904         TCGv_i64 t0 = tcg_temp_new_i64();
905         TCGv_i64 t1 = tcg_temp_new_i64();
906         tcg_gen_concat_i32_i64(t0, al, ah);
907         tcg_gen_concat_i32_i64(t1, bl, bh);
908         tcg_gen_sub_i64(t0, t0, t1);
909         tcg_gen_extr_i64_i32(rl, rh, t0);
910         tcg_temp_free_i64(t0);
911         tcg_temp_free_i64(t1);
912     }
913 }
914 
915 void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
916 {
917     if (TCG_TARGET_HAS_mulu2_i32) {
918         tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
919     } else if (TCG_TARGET_HAS_muluh_i32) {
920         TCGv_i32 t = tcg_temp_new_i32();
921         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
922         tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
923         tcg_gen_mov_i32(rl, t);
924         tcg_temp_free_i32(t);
925     } else {
926         TCGv_i64 t0 = tcg_temp_new_i64();
927         TCGv_i64 t1 = tcg_temp_new_i64();
928         tcg_gen_extu_i32_i64(t0, arg1);
929         tcg_gen_extu_i32_i64(t1, arg2);
930         tcg_gen_mul_i64(t0, t0, t1);
931         tcg_gen_extr_i64_i32(rl, rh, t0);
932         tcg_temp_free_i64(t0);
933         tcg_temp_free_i64(t1);
934     }
935 }
936 
937 void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
938 {
939     if (TCG_TARGET_HAS_muls2_i32) {
940         tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
941     } else if (TCG_TARGET_HAS_mulsh_i32) {
942         TCGv_i32 t = tcg_temp_new_i32();
943         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
944         tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
945         tcg_gen_mov_i32(rl, t);
946         tcg_temp_free_i32(t);
947     } else if (TCG_TARGET_REG_BITS == 32) {
948         TCGv_i32 t0 = tcg_temp_new_i32();
949         TCGv_i32 t1 = tcg_temp_new_i32();
950         TCGv_i32 t2 = tcg_temp_new_i32();
951         TCGv_i32 t3 = tcg_temp_new_i32();
952         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
953         /* Adjust for negative inputs.  */
954         tcg_gen_sari_i32(t2, arg1, 31);
955         tcg_gen_sari_i32(t3, arg2, 31);
956         tcg_gen_and_i32(t2, t2, arg2);
957         tcg_gen_and_i32(t3, t3, arg1);
958         tcg_gen_sub_i32(rh, t1, t2);
959         tcg_gen_sub_i32(rh, rh, t3);
960         tcg_gen_mov_i32(rl, t0);
961         tcg_temp_free_i32(t0);
962         tcg_temp_free_i32(t1);
963         tcg_temp_free_i32(t2);
964         tcg_temp_free_i32(t3);
965     } else {
966         TCGv_i64 t0 = tcg_temp_new_i64();
967         TCGv_i64 t1 = tcg_temp_new_i64();
968         tcg_gen_ext_i32_i64(t0, arg1);
969         tcg_gen_ext_i32_i64(t1, arg2);
970         tcg_gen_mul_i64(t0, t0, t1);
971         tcg_gen_extr_i64_i32(rl, rh, t0);
972         tcg_temp_free_i64(t0);
973         tcg_temp_free_i64(t1);
974     }
975 }
976 
977 void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
978 {
979     if (TCG_TARGET_REG_BITS == 32) {
980         TCGv_i32 t0 = tcg_temp_new_i32();
981         TCGv_i32 t1 = tcg_temp_new_i32();
982         TCGv_i32 t2 = tcg_temp_new_i32();
983         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
984         /* Adjust for negative input for the signed arg1.  */
985         tcg_gen_sari_i32(t2, arg1, 31);
986         tcg_gen_and_i32(t2, t2, arg2);
987         tcg_gen_sub_i32(rh, t1, t2);
988         tcg_gen_mov_i32(rl, t0);
989         tcg_temp_free_i32(t0);
990         tcg_temp_free_i32(t1);
991         tcg_temp_free_i32(t2);
992     } else {
993         TCGv_i64 t0 = tcg_temp_new_i64();
994         TCGv_i64 t1 = tcg_temp_new_i64();
995         tcg_gen_ext_i32_i64(t0, arg1);
996         tcg_gen_extu_i32_i64(t1, arg2);
997         tcg_gen_mul_i64(t0, t0, t1);
998         tcg_gen_extr_i64_i32(rl, rh, t0);
999         tcg_temp_free_i64(t0);
1000         tcg_temp_free_i64(t1);
1001     }
1002 }
1003 
1004 void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
1005 {
1006     if (TCG_TARGET_HAS_ext8s_i32) {
1007         tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
1008     } else {
1009         tcg_gen_shli_i32(ret, arg, 24);
1010         tcg_gen_sari_i32(ret, ret, 24);
1011     }
1012 }
1013 
1014 void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
1015 {
1016     if (TCG_TARGET_HAS_ext16s_i32) {
1017         tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
1018     } else {
1019         tcg_gen_shli_i32(ret, arg, 16);
1020         tcg_gen_sari_i32(ret, ret, 16);
1021     }
1022 }
1023 
1024 void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
1025 {
1026     if (TCG_TARGET_HAS_ext8u_i32) {
1027         tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
1028     } else {
1029         tcg_gen_andi_i32(ret, arg, 0xffu);
1030     }
1031 }
1032 
1033 void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
1034 {
1035     if (TCG_TARGET_HAS_ext16u_i32) {
1036         tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
1037     } else {
1038         tcg_gen_andi_i32(ret, arg, 0xffffu);
1039     }
1040 }
1041 
1042 /* Note: we assume the two high bytes are set to zero */
1043 void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg)
1044 {
1045     if (TCG_TARGET_HAS_bswap16_i32) {
1046         tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg);
1047     } else {
1048         TCGv_i32 t0 = tcg_temp_new_i32();
1049 
1050         tcg_gen_ext8u_i32(t0, arg);
1051         tcg_gen_shli_i32(t0, t0, 8);
1052         tcg_gen_shri_i32(ret, arg, 8);
1053         tcg_gen_or_i32(ret, ret, t0);
1054         tcg_temp_free_i32(t0);
1055     }
1056 }
1057 
1058 void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
1059 {
1060     if (TCG_TARGET_HAS_bswap32_i32) {
1061         tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg);
1062     } else {
1063         TCGv_i32 t0, t1;
1064         t0 = tcg_temp_new_i32();
1065         t1 = tcg_temp_new_i32();
1066 
1067         tcg_gen_shli_i32(t0, arg, 24);
1068 
1069         tcg_gen_andi_i32(t1, arg, 0x0000ff00);
1070         tcg_gen_shli_i32(t1, t1, 8);
1071         tcg_gen_or_i32(t0, t0, t1);
1072 
1073         tcg_gen_shri_i32(t1, arg, 8);
1074         tcg_gen_andi_i32(t1, t1, 0x0000ff00);
1075         tcg_gen_or_i32(t0, t0, t1);
1076 
1077         tcg_gen_shri_i32(t1, arg, 24);
1078         tcg_gen_or_i32(ret, t0, t1);
1079         tcg_temp_free_i32(t0);
1080         tcg_temp_free_i32(t1);
1081     }
1082 }
1083 
1084 /* 64-bit ops */
1085 
1086 #if TCG_TARGET_REG_BITS == 32
1087 /* These are all inline for TCG_TARGET_REG_BITS == 64.  */
1088 
1089 void tcg_gen_discard_i64(TCGv_i64 arg)
1090 {
1091     tcg_gen_discard_i32(TCGV_LOW(arg));
1092     tcg_gen_discard_i32(TCGV_HIGH(arg));
1093 }
1094 
1095 void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
1096 {
1097     tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1098     tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
1099 }
1100 
1101 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
1102 {
1103     tcg_gen_movi_i32(TCGV_LOW(ret), arg);
1104     tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
1105 }
1106 
1107 void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1108 {
1109     tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset);
1110     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1111 }
1112 
1113 void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1114 {
1115     tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
1116     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1117 }
1118 
1119 void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1120 {
1121     tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset);
1122     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1123 }
1124 
1125 void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1126 {
1127     tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset);
1128     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1129 }
1130 
1131 void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1132 {
1133     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1134     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1135 }
1136 
1137 void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1138 {
1139     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1140     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1141 }
1142 
1143 void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1144 {
1145     /* Since arg2 and ret have different types,
1146        they cannot be the same temporary */
1147 #ifdef HOST_WORDS_BIGENDIAN
1148     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
1149     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
1150 #else
1151     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1152     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
1153 #endif
1154 }
1155 
1156 void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1157 {
1158 #ifdef HOST_WORDS_BIGENDIAN
1159     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
1160     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
1161 #else
1162     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
1163     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
1164 #endif
1165 }
1166 
1167 void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1168 {
1169     tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1170     tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1171 }
1172 
1173 void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1174 {
1175     tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1176     tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1177 }
1178 
1179 void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1180 {
1181     tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1182     tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1183 }
1184 
1185 void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1186 {
1187     gen_helper_shl_i64(ret, arg1, arg2);
1188 }
1189 
1190 void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1191 {
1192     gen_helper_shr_i64(ret, arg1, arg2);
1193 }
1194 
1195 void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1196 {
1197     gen_helper_sar_i64(ret, arg1, arg2);
1198 }
1199 
1200 void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1201 {
1202     TCGv_i64 t0;
1203     TCGv_i32 t1;
1204 
1205     t0 = tcg_temp_new_i64();
1206     t1 = tcg_temp_new_i32();
1207 
1208     tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
1209                       TCGV_LOW(arg1), TCGV_LOW(arg2));
1210 
1211     tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
1212     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1213     tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2));
1214     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1215 
1216     tcg_gen_mov_i64(ret, t0);
1217     tcg_temp_free_i64(t0);
1218     tcg_temp_free_i32(t1);
1219 }
1220 #endif /* TCG_TARGET_REG_SIZE == 32 */
1221 
1222 void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1223 {
1224     /* some cases can be optimized here */
1225     if (arg2 == 0) {
1226         tcg_gen_mov_i64(ret, arg1);
1227     } else {
1228         TCGv_i64 t0 = tcg_const_i64(arg2);
1229         tcg_gen_add_i64(ret, arg1, t0);
1230         tcg_temp_free_i64(t0);
1231     }
1232 }
1233 
1234 void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2)
1235 {
1236     if (arg1 == 0 && TCG_TARGET_HAS_neg_i64) {
1237         /* Don't recurse with tcg_gen_neg_i64.  */
1238         tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg2);
1239     } else {
1240         TCGv_i64 t0 = tcg_const_i64(arg1);
1241         tcg_gen_sub_i64(ret, t0, arg2);
1242         tcg_temp_free_i64(t0);
1243     }
1244 }
1245 
1246 void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1247 {
1248     /* some cases can be optimized here */
1249     if (arg2 == 0) {
1250         tcg_gen_mov_i64(ret, arg1);
1251     } else {
1252         TCGv_i64 t0 = tcg_const_i64(arg2);
1253         tcg_gen_sub_i64(ret, arg1, t0);
1254         tcg_temp_free_i64(t0);
1255     }
1256 }
1257 
1258 void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
1259 {
1260     TCGv_i64 t0;
1261 
1262     if (TCG_TARGET_REG_BITS == 32) {
1263         tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1264         tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
1265         return;
1266     }
1267 
1268     /* Some cases can be optimized here.  */
1269     switch (arg2) {
1270     case 0:
1271         tcg_gen_movi_i64(ret, 0);
1272         return;
1273     case 0xffffffffffffffffull:
1274         tcg_gen_mov_i64(ret, arg1);
1275         return;
1276     case 0xffull:
1277         /* Don't recurse with tcg_gen_ext8u_i64.  */
1278         if (TCG_TARGET_HAS_ext8u_i64) {
1279             tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
1280             return;
1281         }
1282         break;
1283     case 0xffffu:
1284         if (TCG_TARGET_HAS_ext16u_i64) {
1285             tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
1286             return;
1287         }
1288         break;
1289     case 0xffffffffull:
1290         if (TCG_TARGET_HAS_ext32u_i64) {
1291             tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
1292             return;
1293         }
1294         break;
1295     }
1296     t0 = tcg_const_i64(arg2);
1297     tcg_gen_and_i64(ret, arg1, t0);
1298     tcg_temp_free_i64(t0);
1299 }
1300 
1301 void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1302 {
1303     if (TCG_TARGET_REG_BITS == 32) {
1304         tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1305         tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
1306         return;
1307     }
1308     /* Some cases can be optimized here.  */
1309     if (arg2 == -1) {
1310         tcg_gen_movi_i64(ret, -1);
1311     } else if (arg2 == 0) {
1312         tcg_gen_mov_i64(ret, arg1);
1313     } else {
1314         TCGv_i64 t0 = tcg_const_i64(arg2);
1315         tcg_gen_or_i64(ret, arg1, t0);
1316         tcg_temp_free_i64(t0);
1317     }
1318 }
1319 
1320 void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1321 {
1322     if (TCG_TARGET_REG_BITS == 32) {
1323         tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1324         tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
1325         return;
1326     }
1327     /* Some cases can be optimized here.  */
1328     if (arg2 == 0) {
1329         tcg_gen_mov_i64(ret, arg1);
1330     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) {
1331         /* Don't recurse with tcg_gen_not_i64.  */
1332         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1);
1333     } else {
1334         TCGv_i64 t0 = tcg_const_i64(arg2);
1335         tcg_gen_xor_i64(ret, arg1, t0);
1336         tcg_temp_free_i64(t0);
1337     }
1338 }
1339 
1340 static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
1341                                       unsigned c, bool right, bool arith)
1342 {
1343     tcg_debug_assert(c < 64);
1344     if (c == 0) {
1345         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1346         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1347     } else if (c >= 32) {
1348         c -= 32;
1349         if (right) {
1350             if (arith) {
1351                 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1352                 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
1353             } else {
1354                 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1355                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1356             }
1357         } else {
1358             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
1359             tcg_gen_movi_i32(TCGV_LOW(ret), 0);
1360         }
1361     } else {
1362         TCGv_i32 t0, t1;
1363 
1364         t0 = tcg_temp_new_i32();
1365         t1 = tcg_temp_new_i32();
1366         if (right) {
1367             tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
1368             if (arith) {
1369                 tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
1370             } else {
1371                 tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
1372             }
1373             tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
1374             tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
1375             tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
1376         } else {
1377             tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
1378             /* Note: ret can be the same as arg1, so we use t1 */
1379             tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
1380             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
1381             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
1382             tcg_gen_mov_i32(TCGV_LOW(ret), t1);
1383         }
1384         tcg_temp_free_i32(t0);
1385         tcg_temp_free_i32(t1);
1386     }
1387 }
1388 
1389 void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1390 {
1391     tcg_debug_assert(arg2 < 64);
1392     if (TCG_TARGET_REG_BITS == 32) {
1393         tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
1394     } else if (arg2 == 0) {
1395         tcg_gen_mov_i64(ret, arg1);
1396     } else {
1397         TCGv_i64 t0 = tcg_const_i64(arg2);
1398         tcg_gen_shl_i64(ret, arg1, t0);
1399         tcg_temp_free_i64(t0);
1400     }
1401 }
1402 
1403 void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1404 {
1405     tcg_debug_assert(arg2 < 64);
1406     if (TCG_TARGET_REG_BITS == 32) {
1407         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
1408     } else if (arg2 == 0) {
1409         tcg_gen_mov_i64(ret, arg1);
1410     } else {
1411         TCGv_i64 t0 = tcg_const_i64(arg2);
1412         tcg_gen_shr_i64(ret, arg1, t0);
1413         tcg_temp_free_i64(t0);
1414     }
1415 }
1416 
1417 void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1418 {
1419     tcg_debug_assert(arg2 < 64);
1420     if (TCG_TARGET_REG_BITS == 32) {
1421         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
1422     } else if (arg2 == 0) {
1423         tcg_gen_mov_i64(ret, arg1);
1424     } else {
1425         TCGv_i64 t0 = tcg_const_i64(arg2);
1426         tcg_gen_sar_i64(ret, arg1, t0);
1427         tcg_temp_free_i64(t0);
1428     }
1429 }
1430 
1431 void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l)
1432 {
1433     if (cond == TCG_COND_ALWAYS) {
1434         tcg_gen_br(l);
1435     } else if (cond != TCG_COND_NEVER) {
1436         if (TCG_TARGET_REG_BITS == 32) {
1437             tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),
1438                               TCGV_HIGH(arg1), TCGV_LOW(arg2),
1439                               TCGV_HIGH(arg2), cond, label_arg(l));
1440         } else {
1441             tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond,
1442                               label_arg(l));
1443         }
1444     }
1445 }
1446 
1447 void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l)
1448 {
1449     if (cond == TCG_COND_ALWAYS) {
1450         tcg_gen_br(l);
1451     } else if (cond != TCG_COND_NEVER) {
1452         TCGv_i64 t0 = tcg_const_i64(arg2);
1453         tcg_gen_brcond_i64(cond, arg1, t0, l);
1454         tcg_temp_free_i64(t0);
1455     }
1456 }
1457 
1458 void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
1459                          TCGv_i64 arg1, TCGv_i64 arg2)
1460 {
1461     if (cond == TCG_COND_ALWAYS) {
1462         tcg_gen_movi_i64(ret, 1);
1463     } else if (cond == TCG_COND_NEVER) {
1464         tcg_gen_movi_i64(ret, 0);
1465     } else {
1466         if (TCG_TARGET_REG_BITS == 32) {
1467             tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
1468                              TCGV_LOW(arg1), TCGV_HIGH(arg1),
1469                              TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
1470             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1471         } else {
1472             tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
1473         }
1474     }
1475 }
1476 
1477 void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
1478                           TCGv_i64 arg1, int64_t arg2)
1479 {
1480     TCGv_i64 t0 = tcg_const_i64(arg2);
1481     tcg_gen_setcond_i64(cond, ret, arg1, t0);
1482     tcg_temp_free_i64(t0);
1483 }
1484 
1485 void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1486 {
1487     TCGv_i64 t0 = tcg_const_i64(arg2);
1488     tcg_gen_mul_i64(ret, arg1, t0);
1489     tcg_temp_free_i64(t0);
1490 }
1491 
1492 void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1493 {
1494     if (TCG_TARGET_HAS_div_i64) {
1495         tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
1496     } else if (TCG_TARGET_HAS_div2_i64) {
1497         TCGv_i64 t0 = tcg_temp_new_i64();
1498         tcg_gen_sari_i64(t0, arg1, 63);
1499         tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
1500         tcg_temp_free_i64(t0);
1501     } else {
1502         gen_helper_div_i64(ret, arg1, arg2);
1503     }
1504 }
1505 
1506 void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1507 {
1508     if (TCG_TARGET_HAS_rem_i64) {
1509         tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
1510     } else if (TCG_TARGET_HAS_div_i64) {
1511         TCGv_i64 t0 = tcg_temp_new_i64();
1512         tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
1513         tcg_gen_mul_i64(t0, t0, arg2);
1514         tcg_gen_sub_i64(ret, arg1, t0);
1515         tcg_temp_free_i64(t0);
1516     } else if (TCG_TARGET_HAS_div2_i64) {
1517         TCGv_i64 t0 = tcg_temp_new_i64();
1518         tcg_gen_sari_i64(t0, arg1, 63);
1519         tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
1520         tcg_temp_free_i64(t0);
1521     } else {
1522         gen_helper_rem_i64(ret, arg1, arg2);
1523     }
1524 }
1525 
1526 void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1527 {
1528     if (TCG_TARGET_HAS_div_i64) {
1529         tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
1530     } else if (TCG_TARGET_HAS_div2_i64) {
1531         TCGv_i64 t0 = tcg_temp_new_i64();
1532         tcg_gen_movi_i64(t0, 0);
1533         tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
1534         tcg_temp_free_i64(t0);
1535     } else {
1536         gen_helper_divu_i64(ret, arg1, arg2);
1537     }
1538 }
1539 
1540 void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1541 {
1542     if (TCG_TARGET_HAS_rem_i64) {
1543         tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
1544     } else if (TCG_TARGET_HAS_div_i64) {
1545         TCGv_i64 t0 = tcg_temp_new_i64();
1546         tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
1547         tcg_gen_mul_i64(t0, t0, arg2);
1548         tcg_gen_sub_i64(ret, arg1, t0);
1549         tcg_temp_free_i64(t0);
1550     } else if (TCG_TARGET_HAS_div2_i64) {
1551         TCGv_i64 t0 = tcg_temp_new_i64();
1552         tcg_gen_movi_i64(t0, 0);
1553         tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
1554         tcg_temp_free_i64(t0);
1555     } else {
1556         gen_helper_remu_i64(ret, arg1, arg2);
1557     }
1558 }
1559 
1560 void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
1561 {
1562     if (TCG_TARGET_REG_BITS == 32) {
1563         tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1564         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1565     } else if (TCG_TARGET_HAS_ext8s_i64) {
1566         tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
1567     } else {
1568         tcg_gen_shli_i64(ret, arg, 56);
1569         tcg_gen_sari_i64(ret, ret, 56);
1570     }
1571 }
1572 
1573 void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
1574 {
1575     if (TCG_TARGET_REG_BITS == 32) {
1576         tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1577         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1578     } else if (TCG_TARGET_HAS_ext16s_i64) {
1579         tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
1580     } else {
1581         tcg_gen_shli_i64(ret, arg, 48);
1582         tcg_gen_sari_i64(ret, ret, 48);
1583     }
1584 }
1585 
1586 void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
1587 {
1588     if (TCG_TARGET_REG_BITS == 32) {
1589         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1590         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1591     } else if (TCG_TARGET_HAS_ext32s_i64) {
1592         tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
1593     } else {
1594         tcg_gen_shli_i64(ret, arg, 32);
1595         tcg_gen_sari_i64(ret, ret, 32);
1596     }
1597 }
1598 
1599 void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
1600 {
1601     if (TCG_TARGET_REG_BITS == 32) {
1602         tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1603         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1604     } else if (TCG_TARGET_HAS_ext8u_i64) {
1605         tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
1606     } else {
1607         tcg_gen_andi_i64(ret, arg, 0xffu);
1608     }
1609 }
1610 
1611 void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
1612 {
1613     if (TCG_TARGET_REG_BITS == 32) {
1614         tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1615         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1616     } else if (TCG_TARGET_HAS_ext16u_i64) {
1617         tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
1618     } else {
1619         tcg_gen_andi_i64(ret, arg, 0xffffu);
1620     }
1621 }
1622 
1623 void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
1624 {
1625     if (TCG_TARGET_REG_BITS == 32) {
1626         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1627         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1628     } else if (TCG_TARGET_HAS_ext32u_i64) {
1629         tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
1630     } else {
1631         tcg_gen_andi_i64(ret, arg, 0xffffffffu);
1632     }
1633 }
1634 
1635 /* Note: we assume the six high bytes are set to zero */
1636 void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg)
1637 {
1638     if (TCG_TARGET_REG_BITS == 32) {
1639         tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1640         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1641     } else if (TCG_TARGET_HAS_bswap16_i64) {
1642         tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg);
1643     } else {
1644         TCGv_i64 t0 = tcg_temp_new_i64();
1645 
1646         tcg_gen_ext8u_i64(t0, arg);
1647         tcg_gen_shli_i64(t0, t0, 8);
1648         tcg_gen_shri_i64(ret, arg, 8);
1649         tcg_gen_or_i64(ret, ret, t0);
1650         tcg_temp_free_i64(t0);
1651     }
1652 }
1653 
1654 /* Note: we assume the four high bytes are set to zero */
1655 void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg)
1656 {
1657     if (TCG_TARGET_REG_BITS == 32) {
1658         tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1659         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1660     } else if (TCG_TARGET_HAS_bswap32_i64) {
1661         tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg);
1662     } else {
1663         TCGv_i64 t0, t1;
1664         t0 = tcg_temp_new_i64();
1665         t1 = tcg_temp_new_i64();
1666 
1667         tcg_gen_shli_i64(t0, arg, 24);
1668         tcg_gen_ext32u_i64(t0, t0);
1669 
1670         tcg_gen_andi_i64(t1, arg, 0x0000ff00);
1671         tcg_gen_shli_i64(t1, t1, 8);
1672         tcg_gen_or_i64(t0, t0, t1);
1673 
1674         tcg_gen_shri_i64(t1, arg, 8);
1675         tcg_gen_andi_i64(t1, t1, 0x0000ff00);
1676         tcg_gen_or_i64(t0, t0, t1);
1677 
1678         tcg_gen_shri_i64(t1, arg, 24);
1679         tcg_gen_or_i64(ret, t0, t1);
1680         tcg_temp_free_i64(t0);
1681         tcg_temp_free_i64(t1);
1682     }
1683 }
1684 
1685 void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
1686 {
1687     if (TCG_TARGET_REG_BITS == 32) {
1688         TCGv_i32 t0, t1;
1689         t0 = tcg_temp_new_i32();
1690         t1 = tcg_temp_new_i32();
1691 
1692         tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
1693         tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
1694         tcg_gen_mov_i32(TCGV_LOW(ret), t1);
1695         tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
1696         tcg_temp_free_i32(t0);
1697         tcg_temp_free_i32(t1);
1698     } else if (TCG_TARGET_HAS_bswap64_i64) {
1699         tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg);
1700     } else {
1701         TCGv_i64 t0 = tcg_temp_new_i64();
1702         TCGv_i64 t1 = tcg_temp_new_i64();
1703 
1704         tcg_gen_shli_i64(t0, arg, 56);
1705 
1706         tcg_gen_andi_i64(t1, arg, 0x0000ff00);
1707         tcg_gen_shli_i64(t1, t1, 40);
1708         tcg_gen_or_i64(t0, t0, t1);
1709 
1710         tcg_gen_andi_i64(t1, arg, 0x00ff0000);
1711         tcg_gen_shli_i64(t1, t1, 24);
1712         tcg_gen_or_i64(t0, t0, t1);
1713 
1714         tcg_gen_andi_i64(t1, arg, 0xff000000);
1715         tcg_gen_shli_i64(t1, t1, 8);
1716         tcg_gen_or_i64(t0, t0, t1);
1717 
1718         tcg_gen_shri_i64(t1, arg, 8);
1719         tcg_gen_andi_i64(t1, t1, 0xff000000);
1720         tcg_gen_or_i64(t0, t0, t1);
1721 
1722         tcg_gen_shri_i64(t1, arg, 24);
1723         tcg_gen_andi_i64(t1, t1, 0x00ff0000);
1724         tcg_gen_or_i64(t0, t0, t1);
1725 
1726         tcg_gen_shri_i64(t1, arg, 40);
1727         tcg_gen_andi_i64(t1, t1, 0x0000ff00);
1728         tcg_gen_or_i64(t0, t0, t1);
1729 
1730         tcg_gen_shri_i64(t1, arg, 56);
1731         tcg_gen_or_i64(ret, t0, t1);
1732         tcg_temp_free_i64(t0);
1733         tcg_temp_free_i64(t1);
1734     }
1735 }
1736 
1737 void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
1738 {
1739     if (TCG_TARGET_REG_BITS == 32) {
1740         tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1741         tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
1742     } else if (TCG_TARGET_HAS_not_i64) {
1743         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
1744     } else {
1745         tcg_gen_xori_i64(ret, arg, -1);
1746     }
1747 }
1748 
1749 void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1750 {
1751     if (TCG_TARGET_REG_BITS == 32) {
1752         tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1753         tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1754     } else if (TCG_TARGET_HAS_andc_i64) {
1755         tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
1756     } else {
1757         TCGv_i64 t0 = tcg_temp_new_i64();
1758         tcg_gen_not_i64(t0, arg2);
1759         tcg_gen_and_i64(ret, arg1, t0);
1760         tcg_temp_free_i64(t0);
1761     }
1762 }
1763 
1764 void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1765 {
1766     if (TCG_TARGET_REG_BITS == 32) {
1767         tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1768         tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1769     } else if (TCG_TARGET_HAS_eqv_i64) {
1770         tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
1771     } else {
1772         tcg_gen_xor_i64(ret, arg1, arg2);
1773         tcg_gen_not_i64(ret, ret);
1774     }
1775 }
1776 
1777 void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1778 {
1779     if (TCG_TARGET_REG_BITS == 32) {
1780         tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1781         tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1782     } else if (TCG_TARGET_HAS_nand_i64) {
1783         tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
1784     } else {
1785         tcg_gen_and_i64(ret, arg1, arg2);
1786         tcg_gen_not_i64(ret, ret);
1787     }
1788 }
1789 
1790 void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1791 {
1792     if (TCG_TARGET_REG_BITS == 32) {
1793         tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1794         tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1795     } else if (TCG_TARGET_HAS_nor_i64) {
1796         tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
1797     } else {
1798         tcg_gen_or_i64(ret, arg1, arg2);
1799         tcg_gen_not_i64(ret, ret);
1800     }
1801 }
1802 
1803 void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1804 {
1805     if (TCG_TARGET_REG_BITS == 32) {
1806         tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1807         tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1808     } else if (TCG_TARGET_HAS_orc_i64) {
1809         tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
1810     } else {
1811         TCGv_i64 t0 = tcg_temp_new_i64();
1812         tcg_gen_not_i64(t0, arg2);
1813         tcg_gen_or_i64(ret, arg1, t0);
1814         tcg_temp_free_i64(t0);
1815     }
1816 }
1817 
1818 void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1819 {
1820     if (TCG_TARGET_HAS_clz_i64) {
1821         tcg_gen_op3_i64(INDEX_op_clz_i64, ret, arg1, arg2);
1822     } else {
1823         gen_helper_clz_i64(ret, arg1, arg2);
1824     }
1825 }
1826 
1827 void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
1828 {
1829     if (TCG_TARGET_REG_BITS == 32
1830         && TCG_TARGET_HAS_clz_i32
1831         && arg2 <= 0xffffffffu) {
1832         TCGv_i32 t = tcg_const_i32((uint32_t)arg2 - 32);
1833         tcg_gen_clz_i32(t, TCGV_LOW(arg1), t);
1834         tcg_gen_addi_i32(t, t, 32);
1835         tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t);
1836         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1837         tcg_temp_free_i32(t);
1838     } else {
1839         TCGv_i64 t = tcg_const_i64(arg2);
1840         tcg_gen_clz_i64(ret, arg1, t);
1841         tcg_temp_free_i64(t);
1842     }
1843 }
1844 
1845 void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1846 {
1847     if (TCG_TARGET_HAS_ctz_i64) {
1848         tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2);
1849     } else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) {
1850         TCGv_i64 z, t = tcg_temp_new_i64();
1851 
1852         if (TCG_TARGET_HAS_ctpop_i64) {
1853             tcg_gen_subi_i64(t, arg1, 1);
1854             tcg_gen_andc_i64(t, t, arg1);
1855             tcg_gen_ctpop_i64(t, t);
1856         } else {
1857             /* Since all non-x86 hosts have clz(0) == 64, don't fight it.  */
1858             tcg_gen_neg_i64(t, arg1);
1859             tcg_gen_and_i64(t, t, arg1);
1860             tcg_gen_clzi_i64(t, t, 64);
1861             tcg_gen_xori_i64(t, t, 63);
1862         }
1863         z = tcg_const_i64(0);
1864         tcg_gen_movcond_i64(TCG_COND_EQ, ret, arg1, z, arg2, t);
1865         tcg_temp_free_i64(t);
1866         tcg_temp_free_i64(z);
1867     } else {
1868         gen_helper_ctz_i64(ret, arg1, arg2);
1869     }
1870 }
1871 
1872 void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
1873 {
1874     if (TCG_TARGET_REG_BITS == 32
1875         && TCG_TARGET_HAS_ctz_i32
1876         && arg2 <= 0xffffffffu) {
1877         TCGv_i32 t32 = tcg_const_i32((uint32_t)arg2 - 32);
1878         tcg_gen_ctz_i32(t32, TCGV_HIGH(arg1), t32);
1879         tcg_gen_addi_i32(t32, t32, 32);
1880         tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32);
1881         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1882         tcg_temp_free_i32(t32);
1883     } else if (!TCG_TARGET_HAS_ctz_i64
1884                && TCG_TARGET_HAS_ctpop_i64
1885                && arg2 == 64) {
1886         /* This equivalence has the advantage of not requiring a fixup.  */
1887         TCGv_i64 t = tcg_temp_new_i64();
1888         tcg_gen_subi_i64(t, arg1, 1);
1889         tcg_gen_andc_i64(t, t, arg1);
1890         tcg_gen_ctpop_i64(ret, t);
1891         tcg_temp_free_i64(t);
1892     } else {
1893         TCGv_i64 t64 = tcg_const_i64(arg2);
1894         tcg_gen_ctz_i64(ret, arg1, t64);
1895         tcg_temp_free_i64(t64);
1896     }
1897 }
1898 
1899 void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg)
1900 {
1901     if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) {
1902         TCGv_i64 t = tcg_temp_new_i64();
1903         tcg_gen_sari_i64(t, arg, 63);
1904         tcg_gen_xor_i64(t, t, arg);
1905         tcg_gen_clzi_i64(t, t, 64);
1906         tcg_gen_subi_i64(ret, t, 1);
1907         tcg_temp_free_i64(t);
1908     } else {
1909         gen_helper_clrsb_i64(ret, arg);
1910     }
1911 }
1912 
1913 void tcg_gen_ctpop_i64(TCGv_i64 ret, TCGv_i64 arg1)
1914 {
1915     if (TCG_TARGET_HAS_ctpop_i64) {
1916         tcg_gen_op2_i64(INDEX_op_ctpop_i64, ret, arg1);
1917     } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_ctpop_i32) {
1918         tcg_gen_ctpop_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1919         tcg_gen_ctpop_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1920         tcg_gen_add_i32(TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret));
1921         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1922     } else {
1923         gen_helper_ctpop_i64(ret, arg1);
1924     }
1925 }
1926 
1927 void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1928 {
1929     if (TCG_TARGET_HAS_rot_i64) {
1930         tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
1931     } else {
1932         TCGv_i64 t0, t1;
1933         t0 = tcg_temp_new_i64();
1934         t1 = tcg_temp_new_i64();
1935         tcg_gen_shl_i64(t0, arg1, arg2);
1936         tcg_gen_subfi_i64(t1, 64, arg2);
1937         tcg_gen_shr_i64(t1, arg1, t1);
1938         tcg_gen_or_i64(ret, t0, t1);
1939         tcg_temp_free_i64(t0);
1940         tcg_temp_free_i64(t1);
1941     }
1942 }
1943 
1944 void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1945 {
1946     tcg_debug_assert(arg2 < 64);
1947     /* some cases can be optimized here */
1948     if (arg2 == 0) {
1949         tcg_gen_mov_i64(ret, arg1);
1950     } else if (TCG_TARGET_HAS_rot_i64) {
1951         TCGv_i64 t0 = tcg_const_i64(arg2);
1952         tcg_gen_rotl_i64(ret, arg1, t0);
1953         tcg_temp_free_i64(t0);
1954     } else {
1955         TCGv_i64 t0, t1;
1956         t0 = tcg_temp_new_i64();
1957         t1 = tcg_temp_new_i64();
1958         tcg_gen_shli_i64(t0, arg1, arg2);
1959         tcg_gen_shri_i64(t1, arg1, 64 - arg2);
1960         tcg_gen_or_i64(ret, t0, t1);
1961         tcg_temp_free_i64(t0);
1962         tcg_temp_free_i64(t1);
1963     }
1964 }
1965 
1966 void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1967 {
1968     if (TCG_TARGET_HAS_rot_i64) {
1969         tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
1970     } else {
1971         TCGv_i64 t0, t1;
1972         t0 = tcg_temp_new_i64();
1973         t1 = tcg_temp_new_i64();
1974         tcg_gen_shr_i64(t0, arg1, arg2);
1975         tcg_gen_subfi_i64(t1, 64, arg2);
1976         tcg_gen_shl_i64(t1, arg1, t1);
1977         tcg_gen_or_i64(ret, t0, t1);
1978         tcg_temp_free_i64(t0);
1979         tcg_temp_free_i64(t1);
1980     }
1981 }
1982 
1983 void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2)
1984 {
1985     tcg_debug_assert(arg2 < 64);
1986     /* some cases can be optimized here */
1987     if (arg2 == 0) {
1988         tcg_gen_mov_i64(ret, arg1);
1989     } else {
1990         tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
1991     }
1992 }
1993 
1994 void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
1995                          unsigned int ofs, unsigned int len)
1996 {
1997     uint64_t mask;
1998     TCGv_i64 t1;
1999 
2000     tcg_debug_assert(ofs < 64);
2001     tcg_debug_assert(len > 0);
2002     tcg_debug_assert(len <= 64);
2003     tcg_debug_assert(ofs + len <= 64);
2004 
2005     if (len == 64) {
2006         tcg_gen_mov_i64(ret, arg2);
2007         return;
2008     }
2009     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
2010         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
2011         return;
2012     }
2013 
2014     if (TCG_TARGET_REG_BITS == 32) {
2015         if (ofs >= 32) {
2016             tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1),
2017                                 TCGV_LOW(arg2), ofs - 32, len);
2018             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
2019             return;
2020         }
2021         if (ofs + len <= 32) {
2022             tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1),
2023                                 TCGV_LOW(arg2), ofs, len);
2024             tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
2025             return;
2026         }
2027     }
2028 
2029     mask = (1ull << len) - 1;
2030     t1 = tcg_temp_new_i64();
2031 
2032     if (ofs + len < 64) {
2033         tcg_gen_andi_i64(t1, arg2, mask);
2034         tcg_gen_shli_i64(t1, t1, ofs);
2035     } else {
2036         tcg_gen_shli_i64(t1, arg2, ofs);
2037     }
2038     tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
2039     tcg_gen_or_i64(ret, ret, t1);
2040 
2041     tcg_temp_free_i64(t1);
2042 }
2043 
2044 void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
2045                            unsigned int ofs, unsigned int len)
2046 {
2047     tcg_debug_assert(ofs < 64);
2048     tcg_debug_assert(len > 0);
2049     tcg_debug_assert(len <= 64);
2050     tcg_debug_assert(ofs + len <= 64);
2051 
2052     if (ofs + len == 64) {
2053         tcg_gen_shli_i64(ret, arg, ofs);
2054     } else if (ofs == 0) {
2055         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
2056     } else if (TCG_TARGET_HAS_deposit_i64
2057                && TCG_TARGET_deposit_i64_valid(ofs, len)) {
2058         TCGv_i64 zero = tcg_const_i64(0);
2059         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len);
2060         tcg_temp_free_i64(zero);
2061     } else {
2062         if (TCG_TARGET_REG_BITS == 32) {
2063             if (ofs >= 32) {
2064                 tcg_gen_deposit_z_i32(TCGV_HIGH(ret), TCGV_LOW(arg),
2065                                       ofs - 32, len);
2066                 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
2067                 return;
2068             }
2069             if (ofs + len <= 32) {
2070                 tcg_gen_deposit_z_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
2071                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2072                 return;
2073             }
2074         }
2075         /* To help two-operand hosts we prefer to zero-extend first,
2076            which allows ARG to stay live.  */
2077         switch (len) {
2078         case 32:
2079             if (TCG_TARGET_HAS_ext32u_i64) {
2080                 tcg_gen_ext32u_i64(ret, arg);
2081                 tcg_gen_shli_i64(ret, ret, ofs);
2082                 return;
2083             }
2084             break;
2085         case 16:
2086             if (TCG_TARGET_HAS_ext16u_i64) {
2087                 tcg_gen_ext16u_i64(ret, arg);
2088                 tcg_gen_shli_i64(ret, ret, ofs);
2089                 return;
2090             }
2091             break;
2092         case 8:
2093             if (TCG_TARGET_HAS_ext8u_i64) {
2094                 tcg_gen_ext8u_i64(ret, arg);
2095                 tcg_gen_shli_i64(ret, ret, ofs);
2096                 return;
2097             }
2098             break;
2099         }
2100         /* Otherwise prefer zero-extension over AND for code size.  */
2101         switch (ofs + len) {
2102         case 32:
2103             if (TCG_TARGET_HAS_ext32u_i64) {
2104                 tcg_gen_shli_i64(ret, arg, ofs);
2105                 tcg_gen_ext32u_i64(ret, ret);
2106                 return;
2107             }
2108             break;
2109         case 16:
2110             if (TCG_TARGET_HAS_ext16u_i64) {
2111                 tcg_gen_shli_i64(ret, arg, ofs);
2112                 tcg_gen_ext16u_i64(ret, ret);
2113                 return;
2114             }
2115             break;
2116         case 8:
2117             if (TCG_TARGET_HAS_ext8u_i64) {
2118                 tcg_gen_shli_i64(ret, arg, ofs);
2119                 tcg_gen_ext8u_i64(ret, ret);
2120                 return;
2121             }
2122             break;
2123         }
2124         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
2125         tcg_gen_shli_i64(ret, ret, ofs);
2126     }
2127 }
2128 
2129 void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
2130                          unsigned int ofs, unsigned int len)
2131 {
2132     tcg_debug_assert(ofs < 64);
2133     tcg_debug_assert(len > 0);
2134     tcg_debug_assert(len <= 64);
2135     tcg_debug_assert(ofs + len <= 64);
2136 
2137     /* Canonicalize certain special cases, even if extract is supported.  */
2138     if (ofs + len == 64) {
2139         tcg_gen_shri_i64(ret, arg, 64 - len);
2140         return;
2141     }
2142     if (ofs == 0) {
2143         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
2144         return;
2145     }
2146 
2147     if (TCG_TARGET_REG_BITS == 32) {
2148         /* Look for a 32-bit extract within one of the two words.  */
2149         if (ofs >= 32) {
2150             tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
2151             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2152             return;
2153         }
2154         if (ofs + len <= 32) {
2155             tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
2156             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2157             return;
2158         }
2159         /* The field is split across two words.  One double-word
2160            shift is better than two double-word shifts.  */
2161         goto do_shift_and;
2162     }
2163 
2164     if (TCG_TARGET_HAS_extract_i64
2165         && TCG_TARGET_extract_i64_valid(ofs, len)) {
2166         tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len);
2167         return;
2168     }
2169 
2170     /* Assume that zero-extension, if available, is cheaper than a shift.  */
2171     switch (ofs + len) {
2172     case 32:
2173         if (TCG_TARGET_HAS_ext32u_i64) {
2174             tcg_gen_ext32u_i64(ret, arg);
2175             tcg_gen_shri_i64(ret, ret, ofs);
2176             return;
2177         }
2178         break;
2179     case 16:
2180         if (TCG_TARGET_HAS_ext16u_i64) {
2181             tcg_gen_ext16u_i64(ret, arg);
2182             tcg_gen_shri_i64(ret, ret, ofs);
2183             return;
2184         }
2185         break;
2186     case 8:
2187         if (TCG_TARGET_HAS_ext8u_i64) {
2188             tcg_gen_ext8u_i64(ret, arg);
2189             tcg_gen_shri_i64(ret, ret, ofs);
2190             return;
2191         }
2192         break;
2193     }
2194 
2195     /* ??? Ideally we'd know what values are available for immediate AND.
2196        Assume that 8 bits are available, plus the special cases of 16 and 32,
2197        so that we get ext8u, ext16u, and ext32u.  */
2198     switch (len) {
2199     case 1 ... 8: case 16: case 32:
2200     do_shift_and:
2201         tcg_gen_shri_i64(ret, arg, ofs);
2202         tcg_gen_andi_i64(ret, ret, (1ull << len) - 1);
2203         break;
2204     default:
2205         tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
2206         tcg_gen_shri_i64(ret, ret, 64 - len);
2207         break;
2208     }
2209 }
2210 
2211 void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
2212                           unsigned int ofs, unsigned int len)
2213 {
2214     tcg_debug_assert(ofs < 64);
2215     tcg_debug_assert(len > 0);
2216     tcg_debug_assert(len <= 64);
2217     tcg_debug_assert(ofs + len <= 64);
2218 
2219     /* Canonicalize certain special cases, even if sextract is supported.  */
2220     if (ofs + len == 64) {
2221         tcg_gen_sari_i64(ret, arg, 64 - len);
2222         return;
2223     }
2224     if (ofs == 0) {
2225         switch (len) {
2226         case 32:
2227             tcg_gen_ext32s_i64(ret, arg);
2228             return;
2229         case 16:
2230             tcg_gen_ext16s_i64(ret, arg);
2231             return;
2232         case 8:
2233             tcg_gen_ext8s_i64(ret, arg);
2234             return;
2235         }
2236     }
2237 
2238     if (TCG_TARGET_REG_BITS == 32) {
2239         /* Look for a 32-bit extract within one of the two words.  */
2240         if (ofs >= 32) {
2241             tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
2242         } else if (ofs + len <= 32) {
2243             tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
2244         } else if (ofs == 0) {
2245             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2246             tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32);
2247             return;
2248         } else if (len > 32) {
2249             TCGv_i32 t = tcg_temp_new_i32();
2250             /* Extract the bits for the high word normally.  */
2251             tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32);
2252             /* Shift the field down for the low part.  */
2253             tcg_gen_shri_i64(ret, arg, ofs);
2254             /* Overwrite the shift into the high part.  */
2255             tcg_gen_mov_i32(TCGV_HIGH(ret), t);
2256             tcg_temp_free_i32(t);
2257             return;
2258         } else {
2259             /* Shift the field down for the low part, such that the
2260                field sits at the MSB.  */
2261             tcg_gen_shri_i64(ret, arg, ofs + len - 32);
2262             /* Shift the field down from the MSB, sign extending.  */
2263             tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_LOW(ret), 32 - len);
2264         }
2265         /* Sign-extend the field from 32 bits.  */
2266         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2267         return;
2268     }
2269 
2270     if (TCG_TARGET_HAS_sextract_i64
2271         && TCG_TARGET_extract_i64_valid(ofs, len)) {
2272         tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len);
2273         return;
2274     }
2275 
2276     /* Assume that sign-extension, if available, is cheaper than a shift.  */
2277     switch (ofs + len) {
2278     case 32:
2279         if (TCG_TARGET_HAS_ext32s_i64) {
2280             tcg_gen_ext32s_i64(ret, arg);
2281             tcg_gen_sari_i64(ret, ret, ofs);
2282             return;
2283         }
2284         break;
2285     case 16:
2286         if (TCG_TARGET_HAS_ext16s_i64) {
2287             tcg_gen_ext16s_i64(ret, arg);
2288             tcg_gen_sari_i64(ret, ret, ofs);
2289             return;
2290         }
2291         break;
2292     case 8:
2293         if (TCG_TARGET_HAS_ext8s_i64) {
2294             tcg_gen_ext8s_i64(ret, arg);
2295             tcg_gen_sari_i64(ret, ret, ofs);
2296             return;
2297         }
2298         break;
2299     }
2300     switch (len) {
2301     case 32:
2302         if (TCG_TARGET_HAS_ext32s_i64) {
2303             tcg_gen_shri_i64(ret, arg, ofs);
2304             tcg_gen_ext32s_i64(ret, ret);
2305             return;
2306         }
2307         break;
2308     case 16:
2309         if (TCG_TARGET_HAS_ext16s_i64) {
2310             tcg_gen_shri_i64(ret, arg, ofs);
2311             tcg_gen_ext16s_i64(ret, ret);
2312             return;
2313         }
2314         break;
2315     case 8:
2316         if (TCG_TARGET_HAS_ext8s_i64) {
2317             tcg_gen_shri_i64(ret, arg, ofs);
2318             tcg_gen_ext8s_i64(ret, ret);
2319             return;
2320         }
2321         break;
2322     }
2323     tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
2324     tcg_gen_sari_i64(ret, ret, 64 - len);
2325 }
2326 
2327 void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
2328                          TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2)
2329 {
2330     if (cond == TCG_COND_ALWAYS) {
2331         tcg_gen_mov_i64(ret, v1);
2332     } else if (cond == TCG_COND_NEVER) {
2333         tcg_gen_mov_i64(ret, v2);
2334     } else if (TCG_TARGET_REG_BITS == 32) {
2335         TCGv_i32 t0 = tcg_temp_new_i32();
2336         TCGv_i32 t1 = tcg_temp_new_i32();
2337         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
2338                          TCGV_LOW(c1), TCGV_HIGH(c1),
2339                          TCGV_LOW(c2), TCGV_HIGH(c2), cond);
2340 
2341         if (TCG_TARGET_HAS_movcond_i32) {
2342             tcg_gen_movi_i32(t1, 0);
2343             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, t1,
2344                                 TCGV_LOW(v1), TCGV_LOW(v2));
2345             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, t1,
2346                                 TCGV_HIGH(v1), TCGV_HIGH(v2));
2347         } else {
2348             tcg_gen_neg_i32(t0, t0);
2349 
2350             tcg_gen_and_i32(t1, TCGV_LOW(v1), t0);
2351             tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0);
2352             tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1);
2353 
2354             tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0);
2355             tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0);
2356             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1);
2357         }
2358         tcg_temp_free_i32(t0);
2359         tcg_temp_free_i32(t1);
2360     } else if (TCG_TARGET_HAS_movcond_i64) {
2361         tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
2362     } else {
2363         TCGv_i64 t0 = tcg_temp_new_i64();
2364         TCGv_i64 t1 = tcg_temp_new_i64();
2365         tcg_gen_setcond_i64(cond, t0, c1, c2);
2366         tcg_gen_neg_i64(t0, t0);
2367         tcg_gen_and_i64(t1, v1, t0);
2368         tcg_gen_andc_i64(ret, v2, t0);
2369         tcg_gen_or_i64(ret, ret, t1);
2370         tcg_temp_free_i64(t0);
2371         tcg_temp_free_i64(t1);
2372     }
2373 }
2374 
2375 void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
2376                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
2377 {
2378     if (TCG_TARGET_HAS_add2_i64) {
2379         tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
2380     } else {
2381         TCGv_i64 t0 = tcg_temp_new_i64();
2382         TCGv_i64 t1 = tcg_temp_new_i64();
2383         tcg_gen_add_i64(t0, al, bl);
2384         tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
2385         tcg_gen_add_i64(rh, ah, bh);
2386         tcg_gen_add_i64(rh, rh, t1);
2387         tcg_gen_mov_i64(rl, t0);
2388         tcg_temp_free_i64(t0);
2389         tcg_temp_free_i64(t1);
2390     }
2391 }
2392 
2393 void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
2394                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
2395 {
2396     if (TCG_TARGET_HAS_sub2_i64) {
2397         tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
2398     } else {
2399         TCGv_i64 t0 = tcg_temp_new_i64();
2400         TCGv_i64 t1 = tcg_temp_new_i64();
2401         tcg_gen_sub_i64(t0, al, bl);
2402         tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
2403         tcg_gen_sub_i64(rh, ah, bh);
2404         tcg_gen_sub_i64(rh, rh, t1);
2405         tcg_gen_mov_i64(rl, t0);
2406         tcg_temp_free_i64(t0);
2407         tcg_temp_free_i64(t1);
2408     }
2409 }
2410 
2411 void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
2412 {
2413     if (TCG_TARGET_HAS_mulu2_i64) {
2414         tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
2415     } else if (TCG_TARGET_HAS_muluh_i64) {
2416         TCGv_i64 t = tcg_temp_new_i64();
2417         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
2418         tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
2419         tcg_gen_mov_i64(rl, t);
2420         tcg_temp_free_i64(t);
2421     } else {
2422         TCGv_i64 t0 = tcg_temp_new_i64();
2423         tcg_gen_mul_i64(t0, arg1, arg2);
2424         gen_helper_muluh_i64(rh, arg1, arg2);
2425         tcg_gen_mov_i64(rl, t0);
2426         tcg_temp_free_i64(t0);
2427     }
2428 }
2429 
2430 void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
2431 {
2432     if (TCG_TARGET_HAS_muls2_i64) {
2433         tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
2434     } else if (TCG_TARGET_HAS_mulsh_i64) {
2435         TCGv_i64 t = tcg_temp_new_i64();
2436         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
2437         tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
2438         tcg_gen_mov_i64(rl, t);
2439         tcg_temp_free_i64(t);
2440     } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
2441         TCGv_i64 t0 = tcg_temp_new_i64();
2442         TCGv_i64 t1 = tcg_temp_new_i64();
2443         TCGv_i64 t2 = tcg_temp_new_i64();
2444         TCGv_i64 t3 = tcg_temp_new_i64();
2445         tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
2446         /* Adjust for negative inputs.  */
2447         tcg_gen_sari_i64(t2, arg1, 63);
2448         tcg_gen_sari_i64(t3, arg2, 63);
2449         tcg_gen_and_i64(t2, t2, arg2);
2450         tcg_gen_and_i64(t3, t3, arg1);
2451         tcg_gen_sub_i64(rh, t1, t2);
2452         tcg_gen_sub_i64(rh, rh, t3);
2453         tcg_gen_mov_i64(rl, t0);
2454         tcg_temp_free_i64(t0);
2455         tcg_temp_free_i64(t1);
2456         tcg_temp_free_i64(t2);
2457         tcg_temp_free_i64(t3);
2458     } else {
2459         TCGv_i64 t0 = tcg_temp_new_i64();
2460         tcg_gen_mul_i64(t0, arg1, arg2);
2461         gen_helper_mulsh_i64(rh, arg1, arg2);
2462         tcg_gen_mov_i64(rl, t0);
2463         tcg_temp_free_i64(t0);
2464     }
2465 }
2466 
2467 void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
2468 {
2469     TCGv_i64 t0 = tcg_temp_new_i64();
2470     TCGv_i64 t1 = tcg_temp_new_i64();
2471     TCGv_i64 t2 = tcg_temp_new_i64();
2472     tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
2473     /* Adjust for negative input for the signed arg1.  */
2474     tcg_gen_sari_i64(t2, arg1, 63);
2475     tcg_gen_and_i64(t2, t2, arg2);
2476     tcg_gen_sub_i64(rh, t1, t2);
2477     tcg_gen_mov_i64(rl, t0);
2478     tcg_temp_free_i64(t0);
2479     tcg_temp_free_i64(t1);
2480     tcg_temp_free_i64(t2);
2481 }
2482 
2483 /* Size changing operations.  */
2484 
2485 void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
2486 {
2487     if (TCG_TARGET_REG_BITS == 32) {
2488         tcg_gen_mov_i32(ret, TCGV_LOW(arg));
2489     } else if (TCG_TARGET_HAS_extrl_i64_i32) {
2490         tcg_gen_op2(&tcg_ctx, INDEX_op_extrl_i64_i32,
2491                     GET_TCGV_I32(ret), GET_TCGV_I64(arg));
2492     } else {
2493         tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(arg)));
2494     }
2495 }
2496 
2497 void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
2498 {
2499     if (TCG_TARGET_REG_BITS == 32) {
2500         tcg_gen_mov_i32(ret, TCGV_HIGH(arg));
2501     } else if (TCG_TARGET_HAS_extrh_i64_i32) {
2502         tcg_gen_op2(&tcg_ctx, INDEX_op_extrh_i64_i32,
2503                     GET_TCGV_I32(ret), GET_TCGV_I64(arg));
2504     } else {
2505         TCGv_i64 t = tcg_temp_new_i64();
2506         tcg_gen_shri_i64(t, arg, 32);
2507         tcg_gen_mov_i32(ret, MAKE_TCGV_I32(GET_TCGV_I64(t)));
2508         tcg_temp_free_i64(t);
2509     }
2510 }
2511 
2512 void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
2513 {
2514     if (TCG_TARGET_REG_BITS == 32) {
2515         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
2516         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2517     } else {
2518         tcg_gen_op2(&tcg_ctx, INDEX_op_extu_i32_i64,
2519                     GET_TCGV_I64(ret), GET_TCGV_I32(arg));
2520     }
2521 }
2522 
2523 void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
2524 {
2525     if (TCG_TARGET_REG_BITS == 32) {
2526         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
2527         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2528     } else {
2529         tcg_gen_op2(&tcg_ctx, INDEX_op_ext_i32_i64,
2530                     GET_TCGV_I64(ret), GET_TCGV_I32(arg));
2531     }
2532 }
2533 
2534 void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
2535 {
2536     TCGv_i64 tmp;
2537 
2538     if (TCG_TARGET_REG_BITS == 32) {
2539         tcg_gen_mov_i32(TCGV_LOW(dest), low);
2540         tcg_gen_mov_i32(TCGV_HIGH(dest), high);
2541         return;
2542     }
2543 
2544     tmp = tcg_temp_new_i64();
2545     /* These extensions are only needed for type correctness.
2546        We may be able to do better given target specific information.  */
2547     tcg_gen_extu_i32_i64(tmp, high);
2548     tcg_gen_extu_i32_i64(dest, low);
2549     /* If deposit is available, use it.  Otherwise use the extra
2550        knowledge that we have of the zero-extensions above.  */
2551     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
2552         tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
2553     } else {
2554         tcg_gen_shli_i64(tmp, tmp, 32);
2555         tcg_gen_or_i64(dest, dest, tmp);
2556     }
2557     tcg_temp_free_i64(tmp);
2558 }
2559 
2560 void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
2561 {
2562     if (TCG_TARGET_REG_BITS == 32) {
2563         tcg_gen_mov_i32(lo, TCGV_LOW(arg));
2564         tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
2565     } else {
2566         tcg_gen_extrl_i64_i32(lo, arg);
2567         tcg_gen_extrh_i64_i32(hi, arg);
2568     }
2569 }
2570 
2571 void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
2572 {
2573     tcg_gen_ext32u_i64(lo, arg);
2574     tcg_gen_shri_i64(hi, arg, 32);
2575 }
2576 
2577 /* QEMU specific operations.  */
2578 
2579 void tcg_gen_goto_tb(unsigned idx)
2580 {
2581     /* We only support two chained exits.  */
2582     tcg_debug_assert(idx <= 1);
2583 #ifdef CONFIG_DEBUG_TCG
2584     /* Verify that we havn't seen this numbered exit before.  */
2585     tcg_debug_assert((tcg_ctx.goto_tb_issue_mask & (1 << idx)) == 0);
2586     tcg_ctx.goto_tb_issue_mask |= 1 << idx;
2587 #endif
2588     tcg_gen_op1i(INDEX_op_goto_tb, idx);
2589 }
2590 
2591 void tcg_gen_lookup_and_goto_ptr(TCGv addr)
2592 {
2593     if (TCG_TARGET_HAS_goto_ptr && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
2594         TCGv_ptr ptr = tcg_temp_new_ptr();
2595         gen_helper_lookup_tb_ptr(ptr, tcg_ctx.tcg_env, addr);
2596         tcg_gen_op1i(INDEX_op_goto_ptr, GET_TCGV_PTR(ptr));
2597         tcg_temp_free_ptr(ptr);
2598     } else {
2599         tcg_gen_exit_tb(0);
2600     }
2601 }
2602 
2603 static inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st)
2604 {
2605     /* Trigger the asserts within as early as possible.  */
2606     (void)get_alignment_bits(op);
2607 
2608     switch (op & MO_SIZE) {
2609     case MO_8:
2610         op &= ~MO_BSWAP;
2611         break;
2612     case MO_16:
2613         break;
2614     case MO_32:
2615         if (!is64) {
2616             op &= ~MO_SIGN;
2617         }
2618         break;
2619     case MO_64:
2620         if (!is64) {
2621             tcg_abort();
2622         }
2623         break;
2624     }
2625     if (st) {
2626         op &= ~MO_SIGN;
2627     }
2628     return op;
2629 }
2630 
2631 static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv addr,
2632                          TCGMemOp memop, TCGArg idx)
2633 {
2634     TCGMemOpIdx oi = make_memop_idx(memop, idx);
2635 #if TARGET_LONG_BITS == 32
2636     tcg_gen_op3i_i32(opc, val, addr, oi);
2637 #else
2638     if (TCG_TARGET_REG_BITS == 32) {
2639         tcg_gen_op4i_i32(opc, val, TCGV_LOW(addr), TCGV_HIGH(addr), oi);
2640     } else {
2641         tcg_gen_op3(&tcg_ctx, opc, GET_TCGV_I32(val), GET_TCGV_I64(addr), oi);
2642     }
2643 #endif
2644 }
2645 
2646 static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 val, TCGv addr,
2647                          TCGMemOp memop, TCGArg idx)
2648 {
2649     TCGMemOpIdx oi = make_memop_idx(memop, idx);
2650 #if TARGET_LONG_BITS == 32
2651     if (TCG_TARGET_REG_BITS == 32) {
2652         tcg_gen_op4i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), addr, oi);
2653     } else {
2654         tcg_gen_op3(&tcg_ctx, opc, GET_TCGV_I64(val), GET_TCGV_I32(addr), oi);
2655     }
2656 #else
2657     if (TCG_TARGET_REG_BITS == 32) {
2658         tcg_gen_op5i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val),
2659                          TCGV_LOW(addr), TCGV_HIGH(addr), oi);
2660     } else {
2661         tcg_gen_op3i_i64(opc, val, addr, oi);
2662     }
2663 #endif
2664 }
2665 
2666 static void tcg_gen_req_mo(TCGBar type)
2667 {
2668 #ifdef TCG_GUEST_DEFAULT_MO
2669     type &= TCG_GUEST_DEFAULT_MO;
2670 #endif
2671     type &= ~TCG_TARGET_DEFAULT_MO;
2672     if (type) {
2673         tcg_gen_mb(type | TCG_BAR_SC);
2674     }
2675 }
2676 
2677 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
2678 {
2679     tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
2680     memop = tcg_canonicalize_memop(memop, 0, 0);
2681     trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
2682                                addr, trace_mem_get_info(memop, 0));
2683     gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx);
2684 }
2685 
2686 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
2687 {
2688     tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
2689     memop = tcg_canonicalize_memop(memop, 0, 1);
2690     trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
2691                                addr, trace_mem_get_info(memop, 1));
2692     gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
2693 }
2694 
2695 void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
2696 {
2697     tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
2698     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
2699         tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop);
2700         if (memop & MO_SIGN) {
2701             tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31);
2702         } else {
2703             tcg_gen_movi_i32(TCGV_HIGH(val), 0);
2704         }
2705         return;
2706     }
2707 
2708     memop = tcg_canonicalize_memop(memop, 1, 0);
2709     trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
2710                                addr, trace_mem_get_info(memop, 0));
2711     gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx);
2712 }
2713 
2714 void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
2715 {
2716     tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
2717     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
2718         tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop);
2719         return;
2720     }
2721 
2722     memop = tcg_canonicalize_memop(memop, 1, 1);
2723     trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
2724                                addr, trace_mem_get_info(memop, 1));
2725     gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx);
2726 }
2727 
2728 static void tcg_gen_ext_i32(TCGv_i32 ret, TCGv_i32 val, TCGMemOp opc)
2729 {
2730     switch (opc & MO_SSIZE) {
2731     case MO_SB:
2732         tcg_gen_ext8s_i32(ret, val);
2733         break;
2734     case MO_UB:
2735         tcg_gen_ext8u_i32(ret, val);
2736         break;
2737     case MO_SW:
2738         tcg_gen_ext16s_i32(ret, val);
2739         break;
2740     case MO_UW:
2741         tcg_gen_ext16u_i32(ret, val);
2742         break;
2743     default:
2744         tcg_gen_mov_i32(ret, val);
2745         break;
2746     }
2747 }
2748 
2749 static void tcg_gen_ext_i64(TCGv_i64 ret, TCGv_i64 val, TCGMemOp opc)
2750 {
2751     switch (opc & MO_SSIZE) {
2752     case MO_SB:
2753         tcg_gen_ext8s_i64(ret, val);
2754         break;
2755     case MO_UB:
2756         tcg_gen_ext8u_i64(ret, val);
2757         break;
2758     case MO_SW:
2759         tcg_gen_ext16s_i64(ret, val);
2760         break;
2761     case MO_UW:
2762         tcg_gen_ext16u_i64(ret, val);
2763         break;
2764     case MO_SL:
2765         tcg_gen_ext32s_i64(ret, val);
2766         break;
2767     case MO_UL:
2768         tcg_gen_ext32u_i64(ret, val);
2769         break;
2770     default:
2771         tcg_gen_mov_i64(ret, val);
2772         break;
2773     }
2774 }
2775 
2776 #ifdef CONFIG_SOFTMMU
2777 typedef void (*gen_atomic_cx_i32)(TCGv_i32, TCGv_env, TCGv,
2778                                   TCGv_i32, TCGv_i32, TCGv_i32);
2779 typedef void (*gen_atomic_cx_i64)(TCGv_i64, TCGv_env, TCGv,
2780                                   TCGv_i64, TCGv_i64, TCGv_i32);
2781 typedef void (*gen_atomic_op_i32)(TCGv_i32, TCGv_env, TCGv,
2782                                   TCGv_i32, TCGv_i32);
2783 typedef void (*gen_atomic_op_i64)(TCGv_i64, TCGv_env, TCGv,
2784                                   TCGv_i64, TCGv_i32);
2785 #else
2786 typedef void (*gen_atomic_cx_i32)(TCGv_i32, TCGv_env, TCGv, TCGv_i32, TCGv_i32);
2787 typedef void (*gen_atomic_cx_i64)(TCGv_i64, TCGv_env, TCGv, TCGv_i64, TCGv_i64);
2788 typedef void (*gen_atomic_op_i32)(TCGv_i32, TCGv_env, TCGv, TCGv_i32);
2789 typedef void (*gen_atomic_op_i64)(TCGv_i64, TCGv_env, TCGv, TCGv_i64);
2790 #endif
2791 
2792 #ifdef CONFIG_ATOMIC64
2793 # define WITH_ATOMIC64(X) X,
2794 #else
2795 # define WITH_ATOMIC64(X)
2796 #endif
2797 
2798 static void * const table_cmpxchg[16] = {
2799     [MO_8] = gen_helper_atomic_cmpxchgb,
2800     [MO_16 | MO_LE] = gen_helper_atomic_cmpxchgw_le,
2801     [MO_16 | MO_BE] = gen_helper_atomic_cmpxchgw_be,
2802     [MO_32 | MO_LE] = gen_helper_atomic_cmpxchgl_le,
2803     [MO_32 | MO_BE] = gen_helper_atomic_cmpxchgl_be,
2804     WITH_ATOMIC64([MO_64 | MO_LE] = gen_helper_atomic_cmpxchgq_le)
2805     WITH_ATOMIC64([MO_64 | MO_BE] = gen_helper_atomic_cmpxchgq_be)
2806 };
2807 
2808 void tcg_gen_atomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, TCGv_i32 cmpv,
2809                                 TCGv_i32 newv, TCGArg idx, TCGMemOp memop)
2810 {
2811     memop = tcg_canonicalize_memop(memop, 0, 0);
2812 
2813     if (!parallel_cpus) {
2814         TCGv_i32 t1 = tcg_temp_new_i32();
2815         TCGv_i32 t2 = tcg_temp_new_i32();
2816 
2817         tcg_gen_ext_i32(t2, cmpv, memop & MO_SIZE);
2818 
2819         tcg_gen_qemu_ld_i32(t1, addr, idx, memop & ~MO_SIGN);
2820         tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, t2, newv, t1);
2821         tcg_gen_qemu_st_i32(t2, addr, idx, memop);
2822         tcg_temp_free_i32(t2);
2823 
2824         if (memop & MO_SIGN) {
2825             tcg_gen_ext_i32(retv, t1, memop);
2826         } else {
2827             tcg_gen_mov_i32(retv, t1);
2828         }
2829         tcg_temp_free_i32(t1);
2830     } else {
2831         gen_atomic_cx_i32 gen;
2832 
2833         gen = table_cmpxchg[memop & (MO_SIZE | MO_BSWAP)];
2834         tcg_debug_assert(gen != NULL);
2835 
2836 #ifdef CONFIG_SOFTMMU
2837         {
2838             TCGv_i32 oi = tcg_const_i32(make_memop_idx(memop & ~MO_SIGN, idx));
2839             gen(retv, tcg_ctx.tcg_env, addr, cmpv, newv, oi);
2840             tcg_temp_free_i32(oi);
2841         }
2842 #else
2843         gen(retv, tcg_ctx.tcg_env, addr, cmpv, newv);
2844 #endif
2845 
2846         if (memop & MO_SIGN) {
2847             tcg_gen_ext_i32(retv, retv, memop);
2848         }
2849     }
2850 }
2851 
2852 void tcg_gen_atomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, TCGv_i64 cmpv,
2853                                 TCGv_i64 newv, TCGArg idx, TCGMemOp memop)
2854 {
2855     memop = tcg_canonicalize_memop(memop, 1, 0);
2856 
2857     if (!parallel_cpus) {
2858         TCGv_i64 t1 = tcg_temp_new_i64();
2859         TCGv_i64 t2 = tcg_temp_new_i64();
2860 
2861         tcg_gen_ext_i64(t2, cmpv, memop & MO_SIZE);
2862 
2863         tcg_gen_qemu_ld_i64(t1, addr, idx, memop & ~MO_SIGN);
2864         tcg_gen_movcond_i64(TCG_COND_EQ, t2, t1, t2, newv, t1);
2865         tcg_gen_qemu_st_i64(t2, addr, idx, memop);
2866         tcg_temp_free_i64(t2);
2867 
2868         if (memop & MO_SIGN) {
2869             tcg_gen_ext_i64(retv, t1, memop);
2870         } else {
2871             tcg_gen_mov_i64(retv, t1);
2872         }
2873         tcg_temp_free_i64(t1);
2874     } else if ((memop & MO_SIZE) == MO_64) {
2875 #ifdef CONFIG_ATOMIC64
2876         gen_atomic_cx_i64 gen;
2877 
2878         gen = table_cmpxchg[memop & (MO_SIZE | MO_BSWAP)];
2879         tcg_debug_assert(gen != NULL);
2880 
2881 #ifdef CONFIG_SOFTMMU
2882         {
2883             TCGv_i32 oi = tcg_const_i32(make_memop_idx(memop, idx));
2884             gen(retv, tcg_ctx.tcg_env, addr, cmpv, newv, oi);
2885             tcg_temp_free_i32(oi);
2886         }
2887 #else
2888         gen(retv, tcg_ctx.tcg_env, addr, cmpv, newv);
2889 #endif
2890 #else
2891         gen_helper_exit_atomic(tcg_ctx.tcg_env);
2892         /* Produce a result, so that we have a well-formed opcode stream
2893            with respect to uses of the result in the (dead) code following.  */
2894         tcg_gen_movi_i64(retv, 0);
2895 #endif /* CONFIG_ATOMIC64 */
2896     } else {
2897         TCGv_i32 c32 = tcg_temp_new_i32();
2898         TCGv_i32 n32 = tcg_temp_new_i32();
2899         TCGv_i32 r32 = tcg_temp_new_i32();
2900 
2901         tcg_gen_extrl_i64_i32(c32, cmpv);
2902         tcg_gen_extrl_i64_i32(n32, newv);
2903         tcg_gen_atomic_cmpxchg_i32(r32, addr, c32, n32, idx, memop & ~MO_SIGN);
2904         tcg_temp_free_i32(c32);
2905         tcg_temp_free_i32(n32);
2906 
2907         tcg_gen_extu_i32_i64(retv, r32);
2908         tcg_temp_free_i32(r32);
2909 
2910         if (memop & MO_SIGN) {
2911             tcg_gen_ext_i64(retv, retv, memop);
2912         }
2913     }
2914 }
2915 
2916 static void do_nonatomic_op_i32(TCGv_i32 ret, TCGv addr, TCGv_i32 val,
2917                                 TCGArg idx, TCGMemOp memop, bool new_val,
2918                                 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
2919 {
2920     TCGv_i32 t1 = tcg_temp_new_i32();
2921     TCGv_i32 t2 = tcg_temp_new_i32();
2922 
2923     memop = tcg_canonicalize_memop(memop, 0, 0);
2924 
2925     tcg_gen_qemu_ld_i32(t1, addr, idx, memop & ~MO_SIGN);
2926     gen(t2, t1, val);
2927     tcg_gen_qemu_st_i32(t2, addr, idx, memop);
2928 
2929     tcg_gen_ext_i32(ret, (new_val ? t2 : t1), memop);
2930     tcg_temp_free_i32(t1);
2931     tcg_temp_free_i32(t2);
2932 }
2933 
2934 static void do_atomic_op_i32(TCGv_i32 ret, TCGv addr, TCGv_i32 val,
2935                              TCGArg idx, TCGMemOp memop, void * const table[])
2936 {
2937     gen_atomic_op_i32 gen;
2938 
2939     memop = tcg_canonicalize_memop(memop, 0, 0);
2940 
2941     gen = table[memop & (MO_SIZE | MO_BSWAP)];
2942     tcg_debug_assert(gen != NULL);
2943 
2944 #ifdef CONFIG_SOFTMMU
2945     {
2946         TCGv_i32 oi = tcg_const_i32(make_memop_idx(memop & ~MO_SIGN, idx));
2947         gen(ret, tcg_ctx.tcg_env, addr, val, oi);
2948         tcg_temp_free_i32(oi);
2949     }
2950 #else
2951     gen(ret, tcg_ctx.tcg_env, addr, val);
2952 #endif
2953 
2954     if (memop & MO_SIGN) {
2955         tcg_gen_ext_i32(ret, ret, memop);
2956     }
2957 }
2958 
2959 static void do_nonatomic_op_i64(TCGv_i64 ret, TCGv addr, TCGv_i64 val,
2960                                 TCGArg idx, TCGMemOp memop, bool new_val,
2961                                 void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
2962 {
2963     TCGv_i64 t1 = tcg_temp_new_i64();
2964     TCGv_i64 t2 = tcg_temp_new_i64();
2965 
2966     memop = tcg_canonicalize_memop(memop, 1, 0);
2967 
2968     tcg_gen_qemu_ld_i64(t1, addr, idx, memop & ~MO_SIGN);
2969     gen(t2, t1, val);
2970     tcg_gen_qemu_st_i64(t2, addr, idx, memop);
2971 
2972     tcg_gen_ext_i64(ret, (new_val ? t2 : t1), memop);
2973     tcg_temp_free_i64(t1);
2974     tcg_temp_free_i64(t2);
2975 }
2976 
2977 static void do_atomic_op_i64(TCGv_i64 ret, TCGv addr, TCGv_i64 val,
2978                              TCGArg idx, TCGMemOp memop, void * const table[])
2979 {
2980     memop = tcg_canonicalize_memop(memop, 1, 0);
2981 
2982     if ((memop & MO_SIZE) == MO_64) {
2983 #ifdef CONFIG_ATOMIC64
2984         gen_atomic_op_i64 gen;
2985 
2986         gen = table[memop & (MO_SIZE | MO_BSWAP)];
2987         tcg_debug_assert(gen != NULL);
2988 
2989 #ifdef CONFIG_SOFTMMU
2990         {
2991             TCGv_i32 oi = tcg_const_i32(make_memop_idx(memop & ~MO_SIGN, idx));
2992             gen(ret, tcg_ctx.tcg_env, addr, val, oi);
2993             tcg_temp_free_i32(oi);
2994         }
2995 #else
2996         gen(ret, tcg_ctx.tcg_env, addr, val);
2997 #endif
2998 #else
2999         gen_helper_exit_atomic(tcg_ctx.tcg_env);
3000         /* Produce a result, so that we have a well-formed opcode stream
3001            with respect to uses of the result in the (dead) code following.  */
3002         tcg_gen_movi_i64(ret, 0);
3003 #endif /* CONFIG_ATOMIC64 */
3004     } else {
3005         TCGv_i32 v32 = tcg_temp_new_i32();
3006         TCGv_i32 r32 = tcg_temp_new_i32();
3007 
3008         tcg_gen_extrl_i64_i32(v32, val);
3009         do_atomic_op_i32(r32, addr, v32, idx, memop & ~MO_SIGN, table);
3010         tcg_temp_free_i32(v32);
3011 
3012         tcg_gen_extu_i32_i64(ret, r32);
3013         tcg_temp_free_i32(r32);
3014 
3015         if (memop & MO_SIGN) {
3016             tcg_gen_ext_i64(ret, ret, memop);
3017         }
3018     }
3019 }
3020 
3021 #define GEN_ATOMIC_HELPER(NAME, OP, NEW)                                \
3022 static void * const table_##NAME[16] = {                                \
3023     [MO_8] = gen_helper_atomic_##NAME##b,                               \
3024     [MO_16 | MO_LE] = gen_helper_atomic_##NAME##w_le,                   \
3025     [MO_16 | MO_BE] = gen_helper_atomic_##NAME##w_be,                   \
3026     [MO_32 | MO_LE] = gen_helper_atomic_##NAME##l_le,                   \
3027     [MO_32 | MO_BE] = gen_helper_atomic_##NAME##l_be,                   \
3028     WITH_ATOMIC64([MO_64 | MO_LE] = gen_helper_atomic_##NAME##q_le)     \
3029     WITH_ATOMIC64([MO_64 | MO_BE] = gen_helper_atomic_##NAME##q_be)     \
3030 };                                                                      \
3031 void tcg_gen_atomic_##NAME##_i32                                        \
3032     (TCGv_i32 ret, TCGv addr, TCGv_i32 val, TCGArg idx, TCGMemOp memop) \
3033 {                                                                       \
3034     if (parallel_cpus) {                                                \
3035         do_atomic_op_i32(ret, addr, val, idx, memop, table_##NAME);     \
3036     } else {                                                            \
3037         do_nonatomic_op_i32(ret, addr, val, idx, memop, NEW,            \
3038                             tcg_gen_##OP##_i32);                        \
3039     }                                                                   \
3040 }                                                                       \
3041 void tcg_gen_atomic_##NAME##_i64                                        \
3042     (TCGv_i64 ret, TCGv addr, TCGv_i64 val, TCGArg idx, TCGMemOp memop) \
3043 {                                                                       \
3044     if (parallel_cpus) {                                                \
3045         do_atomic_op_i64(ret, addr, val, idx, memop, table_##NAME);     \
3046     } else {                                                            \
3047         do_nonatomic_op_i64(ret, addr, val, idx, memop, NEW,            \
3048                             tcg_gen_##OP##_i64);                        \
3049     }                                                                   \
3050 }
3051 
3052 GEN_ATOMIC_HELPER(fetch_add, add, 0)
3053 GEN_ATOMIC_HELPER(fetch_and, and, 0)
3054 GEN_ATOMIC_HELPER(fetch_or, or, 0)
3055 GEN_ATOMIC_HELPER(fetch_xor, xor, 0)
3056 
3057 GEN_ATOMIC_HELPER(add_fetch, add, 1)
3058 GEN_ATOMIC_HELPER(and_fetch, and, 1)
3059 GEN_ATOMIC_HELPER(or_fetch, or, 1)
3060 GEN_ATOMIC_HELPER(xor_fetch, xor, 1)
3061 
3062 static void tcg_gen_mov2_i32(TCGv_i32 r, TCGv_i32 a, TCGv_i32 b)
3063 {
3064     tcg_gen_mov_i32(r, b);
3065 }
3066 
3067 static void tcg_gen_mov2_i64(TCGv_i64 r, TCGv_i64 a, TCGv_i64 b)
3068 {
3069     tcg_gen_mov_i64(r, b);
3070 }
3071 
3072 GEN_ATOMIC_HELPER(xchg, mov2, 0)
3073 
3074 #undef GEN_ATOMIC_HELPER
3075