xref: /openbmc/qemu/tcg/tcg-op.c (revision 2cfb3b6c)
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 "exec/exec-all.h"
27 #include "tcg/tcg.h"
28 #include "tcg/tcg-op.h"
29 #include "tcg/tcg-mo.h"
30 #include "exec/plugin-gen.h"
31 #include "tcg-internal.h"
32 
33 
34 void tcg_gen_op1(TCGOpcode opc, TCGArg a1)
35 {
36     TCGOp *op = tcg_emit_op(opc, 1);
37     op->args[0] = a1;
38 }
39 
40 void tcg_gen_op2(TCGOpcode opc, TCGArg a1, TCGArg a2)
41 {
42     TCGOp *op = tcg_emit_op(opc, 2);
43     op->args[0] = a1;
44     op->args[1] = a2;
45 }
46 
47 void tcg_gen_op3(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3)
48 {
49     TCGOp *op = tcg_emit_op(opc, 3);
50     op->args[0] = a1;
51     op->args[1] = a2;
52     op->args[2] = a3;
53 }
54 
55 void tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3, TCGArg a4)
56 {
57     TCGOp *op = tcg_emit_op(opc, 4);
58     op->args[0] = a1;
59     op->args[1] = a2;
60     op->args[2] = a3;
61     op->args[3] = a4;
62 }
63 
64 void tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
65                  TCGArg a4, TCGArg a5)
66 {
67     TCGOp *op = tcg_emit_op(opc, 5);
68     op->args[0] = a1;
69     op->args[1] = a2;
70     op->args[2] = a3;
71     op->args[3] = a4;
72     op->args[4] = a5;
73 }
74 
75 void tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
76                  TCGArg a4, TCGArg a5, TCGArg a6)
77 {
78     TCGOp *op = tcg_emit_op(opc, 6);
79     op->args[0] = a1;
80     op->args[1] = a2;
81     op->args[2] = a3;
82     op->args[3] = a4;
83     op->args[4] = a5;
84     op->args[5] = a6;
85 }
86 
87 void tcg_gen_mb(TCGBar mb_type)
88 {
89     if (tcg_ctx->gen_tb->cflags & CF_PARALLEL) {
90         tcg_gen_op1(INDEX_op_mb, mb_type);
91     }
92 }
93 
94 /* 32 bit ops */
95 
96 void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg)
97 {
98     tcg_gen_mov_i32(ret, tcg_constant_i32(arg));
99 }
100 
101 void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
102 {
103     /* some cases can be optimized here */
104     if (arg2 == 0) {
105         tcg_gen_mov_i32(ret, arg1);
106     } else {
107         tcg_gen_add_i32(ret, arg1, tcg_constant_i32(arg2));
108     }
109 }
110 
111 void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2)
112 {
113     if (arg1 == 0 && TCG_TARGET_HAS_neg_i32) {
114         /* Don't recurse with tcg_gen_neg_i32.  */
115         tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg2);
116     } else {
117         tcg_gen_sub_i32(ret, tcg_constant_i32(arg1), arg2);
118     }
119 }
120 
121 void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
122 {
123     /* some cases can be optimized here */
124     if (arg2 == 0) {
125         tcg_gen_mov_i32(ret, arg1);
126     } else {
127         tcg_gen_sub_i32(ret, arg1, tcg_constant_i32(arg2));
128     }
129 }
130 
131 void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
132 {
133     /* Some cases can be optimized here.  */
134     switch (arg2) {
135     case 0:
136         tcg_gen_movi_i32(ret, 0);
137         return;
138     case -1:
139         tcg_gen_mov_i32(ret, arg1);
140         return;
141     case 0xff:
142         /* Don't recurse with tcg_gen_ext8u_i32.  */
143         if (TCG_TARGET_HAS_ext8u_i32) {
144             tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
145             return;
146         }
147         break;
148     case 0xffff:
149         if (TCG_TARGET_HAS_ext16u_i32) {
150             tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
151             return;
152         }
153         break;
154     }
155 
156     tcg_gen_and_i32(ret, arg1, tcg_constant_i32(arg2));
157 }
158 
159 void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
160 {
161     /* Some cases can be optimized here.  */
162     if (arg2 == -1) {
163         tcg_gen_movi_i32(ret, -1);
164     } else if (arg2 == 0) {
165         tcg_gen_mov_i32(ret, arg1);
166     } else {
167         tcg_gen_or_i32(ret, arg1, tcg_constant_i32(arg2));
168     }
169 }
170 
171 void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
172 {
173     /* Some cases can be optimized here.  */
174     if (arg2 == 0) {
175         tcg_gen_mov_i32(ret, arg1);
176     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) {
177         /* Don't recurse with tcg_gen_not_i32.  */
178         tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1);
179     } else {
180         tcg_gen_xor_i32(ret, arg1, tcg_constant_i32(arg2));
181     }
182 }
183 
184 void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
185 {
186     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
187     if (arg2 == 0) {
188         tcg_gen_mov_i32(ret, arg1);
189     } else {
190         tcg_gen_shl_i32(ret, arg1, tcg_constant_i32(arg2));
191     }
192 }
193 
194 void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
195 {
196     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
197     if (arg2 == 0) {
198         tcg_gen_mov_i32(ret, arg1);
199     } else {
200         tcg_gen_shr_i32(ret, arg1, tcg_constant_i32(arg2));
201     }
202 }
203 
204 void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
205 {
206     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
207     if (arg2 == 0) {
208         tcg_gen_mov_i32(ret, arg1);
209     } else {
210         tcg_gen_sar_i32(ret, arg1, tcg_constant_i32(arg2));
211     }
212 }
213 
214 void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l)
215 {
216     if (cond == TCG_COND_ALWAYS) {
217         tcg_gen_br(l);
218     } else if (cond != TCG_COND_NEVER) {
219         l->refs++;
220         tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l));
221     }
222 }
223 
224 void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l)
225 {
226     if (cond == TCG_COND_ALWAYS) {
227         tcg_gen_br(l);
228     } else if (cond != TCG_COND_NEVER) {
229         tcg_gen_brcond_i32(cond, arg1, tcg_constant_i32(arg2), l);
230     }
231 }
232 
233 void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
234                          TCGv_i32 arg1, TCGv_i32 arg2)
235 {
236     if (cond == TCG_COND_ALWAYS) {
237         tcg_gen_movi_i32(ret, 1);
238     } else if (cond == TCG_COND_NEVER) {
239         tcg_gen_movi_i32(ret, 0);
240     } else {
241         tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
242     }
243 }
244 
245 void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
246                           TCGv_i32 arg1, int32_t arg2)
247 {
248     tcg_gen_setcond_i32(cond, ret, arg1, tcg_constant_i32(arg2));
249 }
250 
251 void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
252 {
253     if (arg2 == 0) {
254         tcg_gen_movi_i32(ret, 0);
255     } else if (is_power_of_2(arg2)) {
256         tcg_gen_shli_i32(ret, arg1, ctz32(arg2));
257     } else {
258         tcg_gen_mul_i32(ret, arg1, tcg_constant_i32(arg2));
259     }
260 }
261 
262 void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
263 {
264     if (TCG_TARGET_HAS_div_i32) {
265         tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
266     } else if (TCG_TARGET_HAS_div2_i32) {
267         TCGv_i32 t0 = tcg_temp_new_i32();
268         tcg_gen_sari_i32(t0, arg1, 31);
269         tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
270         tcg_temp_free_i32(t0);
271     } else {
272         gen_helper_div_i32(ret, arg1, arg2);
273     }
274 }
275 
276 void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
277 {
278     if (TCG_TARGET_HAS_rem_i32) {
279         tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
280     } else if (TCG_TARGET_HAS_div_i32) {
281         TCGv_i32 t0 = tcg_temp_new_i32();
282         tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
283         tcg_gen_mul_i32(t0, t0, arg2);
284         tcg_gen_sub_i32(ret, arg1, t0);
285         tcg_temp_free_i32(t0);
286     } else if (TCG_TARGET_HAS_div2_i32) {
287         TCGv_i32 t0 = tcg_temp_new_i32();
288         tcg_gen_sari_i32(t0, arg1, 31);
289         tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
290         tcg_temp_free_i32(t0);
291     } else {
292         gen_helper_rem_i32(ret, arg1, arg2);
293     }
294 }
295 
296 void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
297 {
298     if (TCG_TARGET_HAS_div_i32) {
299         tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
300     } else if (TCG_TARGET_HAS_div2_i32) {
301         TCGv_i32 t0 = tcg_temp_new_i32();
302         tcg_gen_movi_i32(t0, 0);
303         tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
304         tcg_temp_free_i32(t0);
305     } else {
306         gen_helper_divu_i32(ret, arg1, arg2);
307     }
308 }
309 
310 void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
311 {
312     if (TCG_TARGET_HAS_rem_i32) {
313         tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
314     } else if (TCG_TARGET_HAS_div_i32) {
315         TCGv_i32 t0 = tcg_temp_new_i32();
316         tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
317         tcg_gen_mul_i32(t0, t0, arg2);
318         tcg_gen_sub_i32(ret, arg1, t0);
319         tcg_temp_free_i32(t0);
320     } else if (TCG_TARGET_HAS_div2_i32) {
321         TCGv_i32 t0 = tcg_temp_new_i32();
322         tcg_gen_movi_i32(t0, 0);
323         tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
324         tcg_temp_free_i32(t0);
325     } else {
326         gen_helper_remu_i32(ret, arg1, arg2);
327     }
328 }
329 
330 void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
331 {
332     if (TCG_TARGET_HAS_andc_i32) {
333         tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
334     } else {
335         TCGv_i32 t0 = tcg_temp_new_i32();
336         tcg_gen_not_i32(t0, arg2);
337         tcg_gen_and_i32(ret, arg1, t0);
338         tcg_temp_free_i32(t0);
339     }
340 }
341 
342 void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
343 {
344     if (TCG_TARGET_HAS_eqv_i32) {
345         tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
346     } else {
347         tcg_gen_xor_i32(ret, arg1, arg2);
348         tcg_gen_not_i32(ret, ret);
349     }
350 }
351 
352 void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
353 {
354     if (TCG_TARGET_HAS_nand_i32) {
355         tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
356     } else {
357         tcg_gen_and_i32(ret, arg1, arg2);
358         tcg_gen_not_i32(ret, ret);
359     }
360 }
361 
362 void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
363 {
364     if (TCG_TARGET_HAS_nor_i32) {
365         tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
366     } else {
367         tcg_gen_or_i32(ret, arg1, arg2);
368         tcg_gen_not_i32(ret, ret);
369     }
370 }
371 
372 void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
373 {
374     if (TCG_TARGET_HAS_orc_i32) {
375         tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
376     } else {
377         TCGv_i32 t0 = tcg_temp_new_i32();
378         tcg_gen_not_i32(t0, arg2);
379         tcg_gen_or_i32(ret, arg1, t0);
380         tcg_temp_free_i32(t0);
381     }
382 }
383 
384 void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
385 {
386     if (TCG_TARGET_HAS_clz_i32) {
387         tcg_gen_op3_i32(INDEX_op_clz_i32, ret, arg1, arg2);
388     } else if (TCG_TARGET_HAS_clz_i64) {
389         TCGv_i64 t1 = tcg_temp_new_i64();
390         TCGv_i64 t2 = tcg_temp_new_i64();
391         tcg_gen_extu_i32_i64(t1, arg1);
392         tcg_gen_extu_i32_i64(t2, arg2);
393         tcg_gen_addi_i64(t2, t2, 32);
394         tcg_gen_clz_i64(t1, t1, t2);
395         tcg_gen_extrl_i64_i32(ret, t1);
396         tcg_temp_free_i64(t1);
397         tcg_temp_free_i64(t2);
398         tcg_gen_subi_i32(ret, ret, 32);
399     } else {
400         gen_helper_clz_i32(ret, arg1, arg2);
401     }
402 }
403 
404 void tcg_gen_clzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
405 {
406     tcg_gen_clz_i32(ret, arg1, tcg_constant_i32(arg2));
407 }
408 
409 void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
410 {
411     if (TCG_TARGET_HAS_ctz_i32) {
412         tcg_gen_op3_i32(INDEX_op_ctz_i32, ret, arg1, arg2);
413     } else if (TCG_TARGET_HAS_ctz_i64) {
414         TCGv_i64 t1 = tcg_temp_new_i64();
415         TCGv_i64 t2 = tcg_temp_new_i64();
416         tcg_gen_extu_i32_i64(t1, arg1);
417         tcg_gen_extu_i32_i64(t2, arg2);
418         tcg_gen_ctz_i64(t1, t1, t2);
419         tcg_gen_extrl_i64_i32(ret, t1);
420         tcg_temp_free_i64(t1);
421         tcg_temp_free_i64(t2);
422     } else if (TCG_TARGET_HAS_ctpop_i32
423                || TCG_TARGET_HAS_ctpop_i64
424                || TCG_TARGET_HAS_clz_i32
425                || TCG_TARGET_HAS_clz_i64) {
426         TCGv_i32 z, t = tcg_temp_new_i32();
427 
428         if (TCG_TARGET_HAS_ctpop_i32 || TCG_TARGET_HAS_ctpop_i64) {
429             tcg_gen_subi_i32(t, arg1, 1);
430             tcg_gen_andc_i32(t, t, arg1);
431             tcg_gen_ctpop_i32(t, t);
432         } else {
433             /* Since all non-x86 hosts have clz(0) == 32, don't fight it.  */
434             tcg_gen_neg_i32(t, arg1);
435             tcg_gen_and_i32(t, t, arg1);
436             tcg_gen_clzi_i32(t, t, 32);
437             tcg_gen_xori_i32(t, t, 31);
438         }
439         z = tcg_constant_i32(0);
440         tcg_gen_movcond_i32(TCG_COND_EQ, ret, arg1, z, arg2, t);
441         tcg_temp_free_i32(t);
442     } else {
443         gen_helper_ctz_i32(ret, arg1, arg2);
444     }
445 }
446 
447 void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
448 {
449     if (!TCG_TARGET_HAS_ctz_i32 && TCG_TARGET_HAS_ctpop_i32 && arg2 == 32) {
450         /* This equivalence has the advantage of not requiring a fixup.  */
451         TCGv_i32 t = tcg_temp_new_i32();
452         tcg_gen_subi_i32(t, arg1, 1);
453         tcg_gen_andc_i32(t, t, arg1);
454         tcg_gen_ctpop_i32(ret, t);
455         tcg_temp_free_i32(t);
456     } else {
457         tcg_gen_ctz_i32(ret, arg1, tcg_constant_i32(arg2));
458     }
459 }
460 
461 void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg)
462 {
463     if (TCG_TARGET_HAS_clz_i32) {
464         TCGv_i32 t = tcg_temp_new_i32();
465         tcg_gen_sari_i32(t, arg, 31);
466         tcg_gen_xor_i32(t, t, arg);
467         tcg_gen_clzi_i32(t, t, 32);
468         tcg_gen_subi_i32(ret, t, 1);
469         tcg_temp_free_i32(t);
470     } else {
471         gen_helper_clrsb_i32(ret, arg);
472     }
473 }
474 
475 void tcg_gen_ctpop_i32(TCGv_i32 ret, TCGv_i32 arg1)
476 {
477     if (TCG_TARGET_HAS_ctpop_i32) {
478         tcg_gen_op2_i32(INDEX_op_ctpop_i32, ret, arg1);
479     } else if (TCG_TARGET_HAS_ctpop_i64) {
480         TCGv_i64 t = tcg_temp_new_i64();
481         tcg_gen_extu_i32_i64(t, arg1);
482         tcg_gen_ctpop_i64(t, t);
483         tcg_gen_extrl_i64_i32(ret, t);
484         tcg_temp_free_i64(t);
485     } else {
486         gen_helper_ctpop_i32(ret, arg1);
487     }
488 }
489 
490 void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
491 {
492     if (TCG_TARGET_HAS_rot_i32) {
493         tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
494     } else {
495         TCGv_i32 t0, t1;
496 
497         t0 = tcg_temp_new_i32();
498         t1 = tcg_temp_new_i32();
499         tcg_gen_shl_i32(t0, arg1, arg2);
500         tcg_gen_subfi_i32(t1, 32, arg2);
501         tcg_gen_shr_i32(t1, arg1, t1);
502         tcg_gen_or_i32(ret, t0, t1);
503         tcg_temp_free_i32(t0);
504         tcg_temp_free_i32(t1);
505     }
506 }
507 
508 void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
509 {
510     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
511     /* some cases can be optimized here */
512     if (arg2 == 0) {
513         tcg_gen_mov_i32(ret, arg1);
514     } else if (TCG_TARGET_HAS_rot_i32) {
515         tcg_gen_rotl_i32(ret, arg1, tcg_constant_i32(arg2));
516     } else {
517         TCGv_i32 t0, t1;
518         t0 = tcg_temp_new_i32();
519         t1 = tcg_temp_new_i32();
520         tcg_gen_shli_i32(t0, arg1, arg2);
521         tcg_gen_shri_i32(t1, arg1, 32 - arg2);
522         tcg_gen_or_i32(ret, t0, t1);
523         tcg_temp_free_i32(t0);
524         tcg_temp_free_i32(t1);
525     }
526 }
527 
528 void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
529 {
530     if (TCG_TARGET_HAS_rot_i32) {
531         tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
532     } else {
533         TCGv_i32 t0, t1;
534 
535         t0 = tcg_temp_new_i32();
536         t1 = tcg_temp_new_i32();
537         tcg_gen_shr_i32(t0, arg1, arg2);
538         tcg_gen_subfi_i32(t1, 32, arg2);
539         tcg_gen_shl_i32(t1, arg1, t1);
540         tcg_gen_or_i32(ret, t0, t1);
541         tcg_temp_free_i32(t0);
542         tcg_temp_free_i32(t1);
543     }
544 }
545 
546 void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
547 {
548     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
549     /* some cases can be optimized here */
550     if (arg2 == 0) {
551         tcg_gen_mov_i32(ret, arg1);
552     } else {
553         tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
554     }
555 }
556 
557 void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
558                          unsigned int ofs, unsigned int len)
559 {
560     uint32_t mask;
561     TCGv_i32 t1;
562 
563     tcg_debug_assert(ofs < 32);
564     tcg_debug_assert(len > 0);
565     tcg_debug_assert(len <= 32);
566     tcg_debug_assert(ofs + len <= 32);
567 
568     if (len == 32) {
569         tcg_gen_mov_i32(ret, arg2);
570         return;
571     }
572     if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
573         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
574         return;
575     }
576 
577     t1 = tcg_temp_new_i32();
578 
579     if (TCG_TARGET_HAS_extract2_i32) {
580         if (ofs + len == 32) {
581             tcg_gen_shli_i32(t1, arg1, len);
582             tcg_gen_extract2_i32(ret, t1, arg2, len);
583             goto done;
584         }
585         if (ofs == 0) {
586             tcg_gen_extract2_i32(ret, arg1, arg2, len);
587             tcg_gen_rotli_i32(ret, ret, len);
588             goto done;
589         }
590     }
591 
592     mask = (1u << len) - 1;
593     if (ofs + len < 32) {
594         tcg_gen_andi_i32(t1, arg2, mask);
595         tcg_gen_shli_i32(t1, t1, ofs);
596     } else {
597         tcg_gen_shli_i32(t1, arg2, ofs);
598     }
599     tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
600     tcg_gen_or_i32(ret, ret, t1);
601  done:
602     tcg_temp_free_i32(t1);
603 }
604 
605 void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
606                            unsigned int ofs, unsigned int len)
607 {
608     tcg_debug_assert(ofs < 32);
609     tcg_debug_assert(len > 0);
610     tcg_debug_assert(len <= 32);
611     tcg_debug_assert(ofs + len <= 32);
612 
613     if (ofs + len == 32) {
614         tcg_gen_shli_i32(ret, arg, ofs);
615     } else if (ofs == 0) {
616         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
617     } else if (TCG_TARGET_HAS_deposit_i32
618                && TCG_TARGET_deposit_i32_valid(ofs, len)) {
619         TCGv_i32 zero = tcg_constant_i32(0);
620         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len);
621     } else {
622         /* To help two-operand hosts we prefer to zero-extend first,
623            which allows ARG to stay live.  */
624         switch (len) {
625         case 16:
626             if (TCG_TARGET_HAS_ext16u_i32) {
627                 tcg_gen_ext16u_i32(ret, arg);
628                 tcg_gen_shli_i32(ret, ret, ofs);
629                 return;
630             }
631             break;
632         case 8:
633             if (TCG_TARGET_HAS_ext8u_i32) {
634                 tcg_gen_ext8u_i32(ret, arg);
635                 tcg_gen_shli_i32(ret, ret, ofs);
636                 return;
637             }
638             break;
639         }
640         /* Otherwise prefer zero-extension over AND for code size.  */
641         switch (ofs + len) {
642         case 16:
643             if (TCG_TARGET_HAS_ext16u_i32) {
644                 tcg_gen_shli_i32(ret, arg, ofs);
645                 tcg_gen_ext16u_i32(ret, ret);
646                 return;
647             }
648             break;
649         case 8:
650             if (TCG_TARGET_HAS_ext8u_i32) {
651                 tcg_gen_shli_i32(ret, arg, ofs);
652                 tcg_gen_ext8u_i32(ret, ret);
653                 return;
654             }
655             break;
656         }
657         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
658         tcg_gen_shli_i32(ret, ret, ofs);
659     }
660 }
661 
662 void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
663                          unsigned int ofs, unsigned int len)
664 {
665     tcg_debug_assert(ofs < 32);
666     tcg_debug_assert(len > 0);
667     tcg_debug_assert(len <= 32);
668     tcg_debug_assert(ofs + len <= 32);
669 
670     /* Canonicalize certain special cases, even if extract is supported.  */
671     if (ofs + len == 32) {
672         tcg_gen_shri_i32(ret, arg, 32 - len);
673         return;
674     }
675     if (ofs == 0) {
676         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
677         return;
678     }
679 
680     if (TCG_TARGET_HAS_extract_i32
681         && TCG_TARGET_extract_i32_valid(ofs, len)) {
682         tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, ofs, len);
683         return;
684     }
685 
686     /* Assume that zero-extension, if available, is cheaper than a shift.  */
687     switch (ofs + len) {
688     case 16:
689         if (TCG_TARGET_HAS_ext16u_i32) {
690             tcg_gen_ext16u_i32(ret, arg);
691             tcg_gen_shri_i32(ret, ret, ofs);
692             return;
693         }
694         break;
695     case 8:
696         if (TCG_TARGET_HAS_ext8u_i32) {
697             tcg_gen_ext8u_i32(ret, arg);
698             tcg_gen_shri_i32(ret, ret, ofs);
699             return;
700         }
701         break;
702     }
703 
704     /* ??? Ideally we'd know what values are available for immediate AND.
705        Assume that 8 bits are available, plus the special case of 16,
706        so that we get ext8u, ext16u.  */
707     switch (len) {
708     case 1 ... 8: case 16:
709         tcg_gen_shri_i32(ret, arg, ofs);
710         tcg_gen_andi_i32(ret, ret, (1u << len) - 1);
711         break;
712     default:
713         tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
714         tcg_gen_shri_i32(ret, ret, 32 - len);
715         break;
716     }
717 }
718 
719 void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
720                           unsigned int ofs, unsigned int len)
721 {
722     tcg_debug_assert(ofs < 32);
723     tcg_debug_assert(len > 0);
724     tcg_debug_assert(len <= 32);
725     tcg_debug_assert(ofs + len <= 32);
726 
727     /* Canonicalize certain special cases, even if extract is supported.  */
728     if (ofs + len == 32) {
729         tcg_gen_sari_i32(ret, arg, 32 - len);
730         return;
731     }
732     if (ofs == 0) {
733         switch (len) {
734         case 16:
735             tcg_gen_ext16s_i32(ret, arg);
736             return;
737         case 8:
738             tcg_gen_ext8s_i32(ret, arg);
739             return;
740         }
741     }
742 
743     if (TCG_TARGET_HAS_sextract_i32
744         && TCG_TARGET_extract_i32_valid(ofs, len)) {
745         tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len);
746         return;
747     }
748 
749     /* Assume that sign-extension, if available, is cheaper than a shift.  */
750     switch (ofs + len) {
751     case 16:
752         if (TCG_TARGET_HAS_ext16s_i32) {
753             tcg_gen_ext16s_i32(ret, arg);
754             tcg_gen_sari_i32(ret, ret, ofs);
755             return;
756         }
757         break;
758     case 8:
759         if (TCG_TARGET_HAS_ext8s_i32) {
760             tcg_gen_ext8s_i32(ret, arg);
761             tcg_gen_sari_i32(ret, ret, ofs);
762             return;
763         }
764         break;
765     }
766     switch (len) {
767     case 16:
768         if (TCG_TARGET_HAS_ext16s_i32) {
769             tcg_gen_shri_i32(ret, arg, ofs);
770             tcg_gen_ext16s_i32(ret, ret);
771             return;
772         }
773         break;
774     case 8:
775         if (TCG_TARGET_HAS_ext8s_i32) {
776             tcg_gen_shri_i32(ret, arg, ofs);
777             tcg_gen_ext8s_i32(ret, ret);
778             return;
779         }
780         break;
781     }
782 
783     tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
784     tcg_gen_sari_i32(ret, ret, 32 - len);
785 }
786 
787 /*
788  * Extract 32-bits from a 64-bit input, ah:al, starting from ofs.
789  * Unlike tcg_gen_extract_i32 above, len is fixed at 32.
790  */
791 void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
792                           unsigned int ofs)
793 {
794     tcg_debug_assert(ofs <= 32);
795     if (ofs == 0) {
796         tcg_gen_mov_i32(ret, al);
797     } else if (ofs == 32) {
798         tcg_gen_mov_i32(ret, ah);
799     } else if (al == ah) {
800         tcg_gen_rotri_i32(ret, al, ofs);
801     } else if (TCG_TARGET_HAS_extract2_i32) {
802         tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
803     } else {
804         TCGv_i32 t0 = tcg_temp_new_i32();
805         tcg_gen_shri_i32(t0, al, ofs);
806         tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs);
807         tcg_temp_free_i32(t0);
808     }
809 }
810 
811 void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
812                          TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2)
813 {
814     if (cond == TCG_COND_ALWAYS) {
815         tcg_gen_mov_i32(ret, v1);
816     } else if (cond == TCG_COND_NEVER) {
817         tcg_gen_mov_i32(ret, v2);
818     } else if (TCG_TARGET_HAS_movcond_i32) {
819         tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
820     } else {
821         TCGv_i32 t0 = tcg_temp_new_i32();
822         TCGv_i32 t1 = tcg_temp_new_i32();
823         tcg_gen_setcond_i32(cond, t0, c1, c2);
824         tcg_gen_neg_i32(t0, t0);
825         tcg_gen_and_i32(t1, v1, t0);
826         tcg_gen_andc_i32(ret, v2, t0);
827         tcg_gen_or_i32(ret, ret, t1);
828         tcg_temp_free_i32(t0);
829         tcg_temp_free_i32(t1);
830     }
831 }
832 
833 void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
834                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
835 {
836     if (TCG_TARGET_HAS_add2_i32) {
837         tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
838     } else {
839         TCGv_i64 t0 = tcg_temp_new_i64();
840         TCGv_i64 t1 = tcg_temp_new_i64();
841         tcg_gen_concat_i32_i64(t0, al, ah);
842         tcg_gen_concat_i32_i64(t1, bl, bh);
843         tcg_gen_add_i64(t0, t0, t1);
844         tcg_gen_extr_i64_i32(rl, rh, t0);
845         tcg_temp_free_i64(t0);
846         tcg_temp_free_i64(t1);
847     }
848 }
849 
850 void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
851                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
852 {
853     if (TCG_TARGET_HAS_sub2_i32) {
854         tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
855     } else {
856         TCGv_i64 t0 = tcg_temp_new_i64();
857         TCGv_i64 t1 = tcg_temp_new_i64();
858         tcg_gen_concat_i32_i64(t0, al, ah);
859         tcg_gen_concat_i32_i64(t1, bl, bh);
860         tcg_gen_sub_i64(t0, t0, t1);
861         tcg_gen_extr_i64_i32(rl, rh, t0);
862         tcg_temp_free_i64(t0);
863         tcg_temp_free_i64(t1);
864     }
865 }
866 
867 void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
868 {
869     if (TCG_TARGET_HAS_mulu2_i32) {
870         tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
871     } else if (TCG_TARGET_HAS_muluh_i32) {
872         TCGv_i32 t = tcg_temp_new_i32();
873         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
874         tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
875         tcg_gen_mov_i32(rl, t);
876         tcg_temp_free_i32(t);
877     } else if (TCG_TARGET_REG_BITS == 64) {
878         TCGv_i64 t0 = tcg_temp_new_i64();
879         TCGv_i64 t1 = tcg_temp_new_i64();
880         tcg_gen_extu_i32_i64(t0, arg1);
881         tcg_gen_extu_i32_i64(t1, arg2);
882         tcg_gen_mul_i64(t0, t0, t1);
883         tcg_gen_extr_i64_i32(rl, rh, t0);
884         tcg_temp_free_i64(t0);
885         tcg_temp_free_i64(t1);
886     } else {
887         qemu_build_not_reached();
888     }
889 }
890 
891 void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
892 {
893     if (TCG_TARGET_HAS_muls2_i32) {
894         tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
895     } else if (TCG_TARGET_HAS_mulsh_i32) {
896         TCGv_i32 t = tcg_temp_new_i32();
897         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
898         tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
899         tcg_gen_mov_i32(rl, t);
900         tcg_temp_free_i32(t);
901     } else if (TCG_TARGET_REG_BITS == 32) {
902         TCGv_i32 t0 = tcg_temp_new_i32();
903         TCGv_i32 t1 = tcg_temp_new_i32();
904         TCGv_i32 t2 = tcg_temp_new_i32();
905         TCGv_i32 t3 = tcg_temp_new_i32();
906         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
907         /* Adjust for negative inputs.  */
908         tcg_gen_sari_i32(t2, arg1, 31);
909         tcg_gen_sari_i32(t3, arg2, 31);
910         tcg_gen_and_i32(t2, t2, arg2);
911         tcg_gen_and_i32(t3, t3, arg1);
912         tcg_gen_sub_i32(rh, t1, t2);
913         tcg_gen_sub_i32(rh, rh, t3);
914         tcg_gen_mov_i32(rl, t0);
915         tcg_temp_free_i32(t0);
916         tcg_temp_free_i32(t1);
917         tcg_temp_free_i32(t2);
918         tcg_temp_free_i32(t3);
919     } else {
920         TCGv_i64 t0 = tcg_temp_new_i64();
921         TCGv_i64 t1 = tcg_temp_new_i64();
922         tcg_gen_ext_i32_i64(t0, arg1);
923         tcg_gen_ext_i32_i64(t1, arg2);
924         tcg_gen_mul_i64(t0, t0, t1);
925         tcg_gen_extr_i64_i32(rl, rh, t0);
926         tcg_temp_free_i64(t0);
927         tcg_temp_free_i64(t1);
928     }
929 }
930 
931 void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
932 {
933     if (TCG_TARGET_REG_BITS == 32) {
934         TCGv_i32 t0 = tcg_temp_new_i32();
935         TCGv_i32 t1 = tcg_temp_new_i32();
936         TCGv_i32 t2 = tcg_temp_new_i32();
937         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
938         /* Adjust for negative input for the signed arg1.  */
939         tcg_gen_sari_i32(t2, arg1, 31);
940         tcg_gen_and_i32(t2, t2, arg2);
941         tcg_gen_sub_i32(rh, t1, t2);
942         tcg_gen_mov_i32(rl, t0);
943         tcg_temp_free_i32(t0);
944         tcg_temp_free_i32(t1);
945         tcg_temp_free_i32(t2);
946     } else {
947         TCGv_i64 t0 = tcg_temp_new_i64();
948         TCGv_i64 t1 = tcg_temp_new_i64();
949         tcg_gen_ext_i32_i64(t0, arg1);
950         tcg_gen_extu_i32_i64(t1, arg2);
951         tcg_gen_mul_i64(t0, t0, t1);
952         tcg_gen_extr_i64_i32(rl, rh, t0);
953         tcg_temp_free_i64(t0);
954         tcg_temp_free_i64(t1);
955     }
956 }
957 
958 void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
959 {
960     if (TCG_TARGET_HAS_ext8s_i32) {
961         tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
962     } else {
963         tcg_gen_shli_i32(ret, arg, 24);
964         tcg_gen_sari_i32(ret, ret, 24);
965     }
966 }
967 
968 void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
969 {
970     if (TCG_TARGET_HAS_ext16s_i32) {
971         tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
972     } else {
973         tcg_gen_shli_i32(ret, arg, 16);
974         tcg_gen_sari_i32(ret, ret, 16);
975     }
976 }
977 
978 void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
979 {
980     if (TCG_TARGET_HAS_ext8u_i32) {
981         tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
982     } else {
983         tcg_gen_andi_i32(ret, arg, 0xffu);
984     }
985 }
986 
987 void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
988 {
989     if (TCG_TARGET_HAS_ext16u_i32) {
990         tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
991     } else {
992         tcg_gen_andi_i32(ret, arg, 0xffffu);
993     }
994 }
995 
996 void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags)
997 {
998     /* Only one extension flag may be present. */
999     tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
1000 
1001     if (TCG_TARGET_HAS_bswap16_i32) {
1002         tcg_gen_op3i_i32(INDEX_op_bswap16_i32, ret, arg, flags);
1003     } else {
1004         TCGv_i32 t0 = tcg_temp_new_i32();
1005         TCGv_i32 t1 = tcg_temp_new_i32();
1006 
1007         tcg_gen_shri_i32(t0, arg, 8);
1008         if (!(flags & TCG_BSWAP_IZ)) {
1009             tcg_gen_ext8u_i32(t0, t0);
1010         }
1011 
1012         if (flags & TCG_BSWAP_OS) {
1013             tcg_gen_shli_i32(t1, arg, 24);
1014             tcg_gen_sari_i32(t1, t1, 16);
1015         } else if (flags & TCG_BSWAP_OZ) {
1016             tcg_gen_ext8u_i32(t1, arg);
1017             tcg_gen_shli_i32(t1, t1, 8);
1018         } else {
1019             tcg_gen_shli_i32(t1, arg, 8);
1020         }
1021 
1022         tcg_gen_or_i32(ret, t0, t1);
1023         tcg_temp_free_i32(t0);
1024         tcg_temp_free_i32(t1);
1025     }
1026 }
1027 
1028 void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
1029 {
1030     if (TCG_TARGET_HAS_bswap32_i32) {
1031         tcg_gen_op3i_i32(INDEX_op_bswap32_i32, ret, arg, 0);
1032     } else {
1033         TCGv_i32 t0 = tcg_temp_new_i32();
1034         TCGv_i32 t1 = tcg_temp_new_i32();
1035         TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff);
1036 
1037                                         /* arg = abcd */
1038         tcg_gen_shri_i32(t0, arg, 8);   /*  t0 = .abc */
1039         tcg_gen_and_i32(t1, arg, t2);   /*  t1 = .b.d */
1040         tcg_gen_and_i32(t0, t0, t2);    /*  t0 = .a.c */
1041         tcg_gen_shli_i32(t1, t1, 8);    /*  t1 = b.d. */
1042         tcg_gen_or_i32(ret, t0, t1);    /* ret = badc */
1043 
1044         tcg_gen_shri_i32(t0, ret, 16);  /*  t0 = ..ba */
1045         tcg_gen_shli_i32(t1, ret, 16);  /*  t1 = dc.. */
1046         tcg_gen_or_i32(ret, t0, t1);    /* ret = dcba */
1047 
1048         tcg_temp_free_i32(t0);
1049         tcg_temp_free_i32(t1);
1050     }
1051 }
1052 
1053 void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg)
1054 {
1055     /* Swapping 2 16-bit elements is a rotate. */
1056     tcg_gen_rotli_i32(ret, arg, 16);
1057 }
1058 
1059 void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1060 {
1061     tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b);
1062 }
1063 
1064 void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1065 {
1066     tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b);
1067 }
1068 
1069 void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1070 {
1071     tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a);
1072 }
1073 
1074 void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1075 {
1076     tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a);
1077 }
1078 
1079 void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a)
1080 {
1081     TCGv_i32 t = tcg_temp_new_i32();
1082 
1083     tcg_gen_sari_i32(t, a, 31);
1084     tcg_gen_xor_i32(ret, a, t);
1085     tcg_gen_sub_i32(ret, ret, t);
1086     tcg_temp_free_i32(t);
1087 }
1088 
1089 /* 64-bit ops */
1090 
1091 #if TCG_TARGET_REG_BITS == 32
1092 /* These are all inline for TCG_TARGET_REG_BITS == 64.  */
1093 
1094 void tcg_gen_discard_i64(TCGv_i64 arg)
1095 {
1096     tcg_gen_discard_i32(TCGV_LOW(arg));
1097     tcg_gen_discard_i32(TCGV_HIGH(arg));
1098 }
1099 
1100 void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
1101 {
1102     TCGTemp *ts = tcgv_i64_temp(arg);
1103 
1104     /* Canonicalize TCGv_i64 TEMP_CONST into TCGv_i32 TEMP_CONST. */
1105     if (ts->kind == TEMP_CONST) {
1106         tcg_gen_movi_i64(ret, ts->val);
1107     } else {
1108         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1109         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
1110     }
1111 }
1112 
1113 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
1114 {
1115     tcg_gen_movi_i32(TCGV_LOW(ret), arg);
1116     tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
1117 }
1118 
1119 void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1120 {
1121     tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset);
1122     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1123 }
1124 
1125 void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1126 {
1127     tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
1128     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1129 }
1130 
1131 void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1132 {
1133     tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset);
1134     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1135 }
1136 
1137 void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1138 {
1139     tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset);
1140     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1141 }
1142 
1143 void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1144 {
1145     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1146     tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1147 }
1148 
1149 void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1150 {
1151     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1152     tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1153 }
1154 
1155 void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1156 {
1157     /* Since arg2 and ret have different types,
1158        they cannot be the same temporary */
1159 #if HOST_BIG_ENDIAN
1160     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
1161     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
1162 #else
1163     tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1164     tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
1165 #endif
1166 }
1167 
1168 void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1169 {
1170     tcg_gen_st8_i32(TCGV_LOW(arg1), arg2, offset);
1171 }
1172 
1173 void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1174 {
1175     tcg_gen_st16_i32(TCGV_LOW(arg1), arg2, offset);
1176 }
1177 
1178 void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1179 {
1180     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
1181 }
1182 
1183 void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1184 {
1185 #if HOST_BIG_ENDIAN
1186     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
1187     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
1188 #else
1189     tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
1190     tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
1191 #endif
1192 }
1193 
1194 void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1195 {
1196     tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1),
1197                      TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2));
1198 }
1199 
1200 void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1201 {
1202     tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1),
1203                      TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2));
1204 }
1205 
1206 void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1207 {
1208     tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1209     tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1210 }
1211 
1212 void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1213 {
1214     tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1215     tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1216 }
1217 
1218 void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1219 {
1220     tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1221     tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1222 }
1223 
1224 void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1225 {
1226     gen_helper_shl_i64(ret, arg1, arg2);
1227 }
1228 
1229 void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1230 {
1231     gen_helper_shr_i64(ret, arg1, arg2);
1232 }
1233 
1234 void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1235 {
1236     gen_helper_sar_i64(ret, arg1, arg2);
1237 }
1238 
1239 void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1240 {
1241     TCGv_i64 t0;
1242     TCGv_i32 t1;
1243 
1244     t0 = tcg_temp_new_i64();
1245     t1 = tcg_temp_new_i32();
1246 
1247     tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
1248                       TCGV_LOW(arg1), TCGV_LOW(arg2));
1249 
1250     tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
1251     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1252     tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2));
1253     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1254 
1255     tcg_gen_mov_i64(ret, t0);
1256     tcg_temp_free_i64(t0);
1257     tcg_temp_free_i32(t1);
1258 }
1259 
1260 #else
1261 
1262 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
1263 {
1264     tcg_gen_mov_i64(ret, tcg_constant_i64(arg));
1265 }
1266 
1267 #endif /* TCG_TARGET_REG_SIZE == 32 */
1268 
1269 void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1270 {
1271     /* some cases can be optimized here */
1272     if (arg2 == 0) {
1273         tcg_gen_mov_i64(ret, arg1);
1274     } else if (TCG_TARGET_REG_BITS == 64) {
1275         tcg_gen_add_i64(ret, arg1, tcg_constant_i64(arg2));
1276     } else {
1277         tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
1278                          TCGV_LOW(arg1), TCGV_HIGH(arg1),
1279                          tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32));
1280     }
1281 }
1282 
1283 void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2)
1284 {
1285     if (arg1 == 0 && TCG_TARGET_HAS_neg_i64) {
1286         /* Don't recurse with tcg_gen_neg_i64.  */
1287         tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg2);
1288     } else if (TCG_TARGET_REG_BITS == 64) {
1289         tcg_gen_sub_i64(ret, tcg_constant_i64(arg1), arg2);
1290     } else {
1291         tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
1292                          tcg_constant_i32(arg1), tcg_constant_i32(arg1 >> 32),
1293                          TCGV_LOW(arg2), TCGV_HIGH(arg2));
1294     }
1295 }
1296 
1297 void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1298 {
1299     /* some cases can be optimized here */
1300     if (arg2 == 0) {
1301         tcg_gen_mov_i64(ret, arg1);
1302     } else if (TCG_TARGET_REG_BITS == 64) {
1303         tcg_gen_sub_i64(ret, arg1, tcg_constant_i64(arg2));
1304     } else {
1305         tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
1306                          TCGV_LOW(arg1), TCGV_HIGH(arg1),
1307                          tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32));
1308     }
1309 }
1310 
1311 void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1312 {
1313     if (TCG_TARGET_REG_BITS == 32) {
1314         tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1315         tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
1316         return;
1317     }
1318 
1319     /* Some cases can be optimized here.  */
1320     switch (arg2) {
1321     case 0:
1322         tcg_gen_movi_i64(ret, 0);
1323         return;
1324     case -1:
1325         tcg_gen_mov_i64(ret, arg1);
1326         return;
1327     case 0xff:
1328         /* Don't recurse with tcg_gen_ext8u_i64.  */
1329         if (TCG_TARGET_HAS_ext8u_i64) {
1330             tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
1331             return;
1332         }
1333         break;
1334     case 0xffff:
1335         if (TCG_TARGET_HAS_ext16u_i64) {
1336             tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
1337             return;
1338         }
1339         break;
1340     case 0xffffffffu:
1341         if (TCG_TARGET_HAS_ext32u_i64) {
1342             tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
1343             return;
1344         }
1345         break;
1346     }
1347 
1348     tcg_gen_and_i64(ret, arg1, tcg_constant_i64(arg2));
1349 }
1350 
1351 void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1352 {
1353     if (TCG_TARGET_REG_BITS == 32) {
1354         tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1355         tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
1356         return;
1357     }
1358     /* Some cases can be optimized here.  */
1359     if (arg2 == -1) {
1360         tcg_gen_movi_i64(ret, -1);
1361     } else if (arg2 == 0) {
1362         tcg_gen_mov_i64(ret, arg1);
1363     } else {
1364         tcg_gen_or_i64(ret, arg1, tcg_constant_i64(arg2));
1365     }
1366 }
1367 
1368 void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1369 {
1370     if (TCG_TARGET_REG_BITS == 32) {
1371         tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1372         tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
1373         return;
1374     }
1375     /* Some cases can be optimized here.  */
1376     if (arg2 == 0) {
1377         tcg_gen_mov_i64(ret, arg1);
1378     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) {
1379         /* Don't recurse with tcg_gen_not_i64.  */
1380         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1);
1381     } else {
1382         tcg_gen_xor_i64(ret, arg1, tcg_constant_i64(arg2));
1383     }
1384 }
1385 
1386 static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
1387                                       unsigned c, bool right, bool arith)
1388 {
1389     tcg_debug_assert(c < 64);
1390     if (c == 0) {
1391         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1392         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1393     } else if (c >= 32) {
1394         c -= 32;
1395         if (right) {
1396             if (arith) {
1397                 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1398                 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
1399             } else {
1400                 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1401                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1402             }
1403         } else {
1404             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
1405             tcg_gen_movi_i32(TCGV_LOW(ret), 0);
1406         }
1407     } else if (right) {
1408         if (TCG_TARGET_HAS_extract2_i32) {
1409             tcg_gen_extract2_i32(TCGV_LOW(ret),
1410                                  TCGV_LOW(arg1), TCGV_HIGH(arg1), c);
1411         } else {
1412             tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
1413             tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(ret),
1414                                 TCGV_HIGH(arg1), 32 - c, c);
1415         }
1416         if (arith) {
1417             tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
1418         } else {
1419             tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
1420         }
1421     } else {
1422         if (TCG_TARGET_HAS_extract2_i32) {
1423             tcg_gen_extract2_i32(TCGV_HIGH(ret),
1424                                  TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
1425         } else {
1426             TCGv_i32 t0 = tcg_temp_new_i32();
1427             tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
1428             tcg_gen_deposit_i32(TCGV_HIGH(ret), t0,
1429                                 TCGV_HIGH(arg1), c, 32 - c);
1430             tcg_temp_free_i32(t0);
1431         }
1432         tcg_gen_shli_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
1433     }
1434 }
1435 
1436 void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1437 {
1438     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
1439     if (TCG_TARGET_REG_BITS == 32) {
1440         tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
1441     } else if (arg2 == 0) {
1442         tcg_gen_mov_i64(ret, arg1);
1443     } else {
1444         tcg_gen_shl_i64(ret, arg1, tcg_constant_i64(arg2));
1445     }
1446 }
1447 
1448 void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1449 {
1450     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
1451     if (TCG_TARGET_REG_BITS == 32) {
1452         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
1453     } else if (arg2 == 0) {
1454         tcg_gen_mov_i64(ret, arg1);
1455     } else {
1456         tcg_gen_shr_i64(ret, arg1, tcg_constant_i64(arg2));
1457     }
1458 }
1459 
1460 void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1461 {
1462     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
1463     if (TCG_TARGET_REG_BITS == 32) {
1464         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
1465     } else if (arg2 == 0) {
1466         tcg_gen_mov_i64(ret, arg1);
1467     } else {
1468         tcg_gen_sar_i64(ret, arg1, tcg_constant_i64(arg2));
1469     }
1470 }
1471 
1472 void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l)
1473 {
1474     if (cond == TCG_COND_ALWAYS) {
1475         tcg_gen_br(l);
1476     } else if (cond != TCG_COND_NEVER) {
1477         l->refs++;
1478         if (TCG_TARGET_REG_BITS == 32) {
1479             tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),
1480                               TCGV_HIGH(arg1), TCGV_LOW(arg2),
1481                               TCGV_HIGH(arg2), cond, label_arg(l));
1482         } else {
1483             tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond,
1484                               label_arg(l));
1485         }
1486     }
1487 }
1488 
1489 void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l)
1490 {
1491     if (TCG_TARGET_REG_BITS == 64) {
1492         tcg_gen_brcond_i64(cond, arg1, tcg_constant_i64(arg2), l);
1493     } else if (cond == TCG_COND_ALWAYS) {
1494         tcg_gen_br(l);
1495     } else if (cond != TCG_COND_NEVER) {
1496         l->refs++;
1497         tcg_gen_op6ii_i32(INDEX_op_brcond2_i32,
1498                           TCGV_LOW(arg1), TCGV_HIGH(arg1),
1499                           tcg_constant_i32(arg2),
1500                           tcg_constant_i32(arg2 >> 32),
1501                           cond, label_arg(l));
1502     }
1503 }
1504 
1505 void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
1506                          TCGv_i64 arg1, TCGv_i64 arg2)
1507 {
1508     if (cond == TCG_COND_ALWAYS) {
1509         tcg_gen_movi_i64(ret, 1);
1510     } else if (cond == TCG_COND_NEVER) {
1511         tcg_gen_movi_i64(ret, 0);
1512     } else {
1513         if (TCG_TARGET_REG_BITS == 32) {
1514             tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
1515                              TCGV_LOW(arg1), TCGV_HIGH(arg1),
1516                              TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
1517             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1518         } else {
1519             tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
1520         }
1521     }
1522 }
1523 
1524 void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
1525                           TCGv_i64 arg1, int64_t arg2)
1526 {
1527     if (TCG_TARGET_REG_BITS == 64) {
1528         tcg_gen_setcond_i64(cond, ret, arg1, tcg_constant_i64(arg2));
1529     } else if (cond == TCG_COND_ALWAYS) {
1530         tcg_gen_movi_i64(ret, 1);
1531     } else if (cond == TCG_COND_NEVER) {
1532         tcg_gen_movi_i64(ret, 0);
1533     } else {
1534         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
1535                          TCGV_LOW(arg1), TCGV_HIGH(arg1),
1536                          tcg_constant_i32(arg2),
1537                          tcg_constant_i32(arg2 >> 32), cond);
1538         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1539     }
1540 }
1541 
1542 void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1543 {
1544     if (arg2 == 0) {
1545         tcg_gen_movi_i64(ret, 0);
1546     } else if (is_power_of_2(arg2)) {
1547         tcg_gen_shli_i64(ret, arg1, ctz64(arg2));
1548     } else {
1549         TCGv_i64 t0 = tcg_const_i64(arg2);
1550         tcg_gen_mul_i64(ret, arg1, t0);
1551         tcg_temp_free_i64(t0);
1552     }
1553 }
1554 
1555 void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1556 {
1557     if (TCG_TARGET_HAS_div_i64) {
1558         tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
1559     } else if (TCG_TARGET_HAS_div2_i64) {
1560         TCGv_i64 t0 = tcg_temp_new_i64();
1561         tcg_gen_sari_i64(t0, arg1, 63);
1562         tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
1563         tcg_temp_free_i64(t0);
1564     } else {
1565         gen_helper_div_i64(ret, arg1, arg2);
1566     }
1567 }
1568 
1569 void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1570 {
1571     if (TCG_TARGET_HAS_rem_i64) {
1572         tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
1573     } else if (TCG_TARGET_HAS_div_i64) {
1574         TCGv_i64 t0 = tcg_temp_new_i64();
1575         tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
1576         tcg_gen_mul_i64(t0, t0, arg2);
1577         tcg_gen_sub_i64(ret, arg1, t0);
1578         tcg_temp_free_i64(t0);
1579     } else if (TCG_TARGET_HAS_div2_i64) {
1580         TCGv_i64 t0 = tcg_temp_new_i64();
1581         tcg_gen_sari_i64(t0, arg1, 63);
1582         tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
1583         tcg_temp_free_i64(t0);
1584     } else {
1585         gen_helper_rem_i64(ret, arg1, arg2);
1586     }
1587 }
1588 
1589 void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1590 {
1591     if (TCG_TARGET_HAS_div_i64) {
1592         tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
1593     } else if (TCG_TARGET_HAS_div2_i64) {
1594         TCGv_i64 t0 = tcg_temp_new_i64();
1595         tcg_gen_movi_i64(t0, 0);
1596         tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
1597         tcg_temp_free_i64(t0);
1598     } else {
1599         gen_helper_divu_i64(ret, arg1, arg2);
1600     }
1601 }
1602 
1603 void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1604 {
1605     if (TCG_TARGET_HAS_rem_i64) {
1606         tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
1607     } else if (TCG_TARGET_HAS_div_i64) {
1608         TCGv_i64 t0 = tcg_temp_new_i64();
1609         tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
1610         tcg_gen_mul_i64(t0, t0, arg2);
1611         tcg_gen_sub_i64(ret, arg1, t0);
1612         tcg_temp_free_i64(t0);
1613     } else if (TCG_TARGET_HAS_div2_i64) {
1614         TCGv_i64 t0 = tcg_temp_new_i64();
1615         tcg_gen_movi_i64(t0, 0);
1616         tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
1617         tcg_temp_free_i64(t0);
1618     } else {
1619         gen_helper_remu_i64(ret, arg1, arg2);
1620     }
1621 }
1622 
1623 void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
1624 {
1625     if (TCG_TARGET_REG_BITS == 32) {
1626         tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1627         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1628     } else if (TCG_TARGET_HAS_ext8s_i64) {
1629         tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
1630     } else {
1631         tcg_gen_shli_i64(ret, arg, 56);
1632         tcg_gen_sari_i64(ret, ret, 56);
1633     }
1634 }
1635 
1636 void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
1637 {
1638     if (TCG_TARGET_REG_BITS == 32) {
1639         tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1640         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1641     } else if (TCG_TARGET_HAS_ext16s_i64) {
1642         tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
1643     } else {
1644         tcg_gen_shli_i64(ret, arg, 48);
1645         tcg_gen_sari_i64(ret, ret, 48);
1646     }
1647 }
1648 
1649 void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
1650 {
1651     if (TCG_TARGET_REG_BITS == 32) {
1652         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1653         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1654     } else if (TCG_TARGET_HAS_ext32s_i64) {
1655         tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
1656     } else {
1657         tcg_gen_shli_i64(ret, arg, 32);
1658         tcg_gen_sari_i64(ret, ret, 32);
1659     }
1660 }
1661 
1662 void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
1663 {
1664     if (TCG_TARGET_REG_BITS == 32) {
1665         tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1666         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1667     } else if (TCG_TARGET_HAS_ext8u_i64) {
1668         tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
1669     } else {
1670         tcg_gen_andi_i64(ret, arg, 0xffu);
1671     }
1672 }
1673 
1674 void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
1675 {
1676     if (TCG_TARGET_REG_BITS == 32) {
1677         tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1678         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1679     } else if (TCG_TARGET_HAS_ext16u_i64) {
1680         tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
1681     } else {
1682         tcg_gen_andi_i64(ret, arg, 0xffffu);
1683     }
1684 }
1685 
1686 void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
1687 {
1688     if (TCG_TARGET_REG_BITS == 32) {
1689         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1690         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1691     } else if (TCG_TARGET_HAS_ext32u_i64) {
1692         tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
1693     } else {
1694         tcg_gen_andi_i64(ret, arg, 0xffffffffu);
1695     }
1696 }
1697 
1698 void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
1699 {
1700     /* Only one extension flag may be present. */
1701     tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
1702 
1703     if (TCG_TARGET_REG_BITS == 32) {
1704         tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg), flags);
1705         if (flags & TCG_BSWAP_OS) {
1706             tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1707         } else {
1708             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1709         }
1710     } else if (TCG_TARGET_HAS_bswap16_i64) {
1711         tcg_gen_op3i_i64(INDEX_op_bswap16_i64, ret, arg, flags);
1712     } else {
1713         TCGv_i64 t0 = tcg_temp_new_i64();
1714         TCGv_i64 t1 = tcg_temp_new_i64();
1715 
1716         tcg_gen_shri_i64(t0, arg, 8);
1717         if (!(flags & TCG_BSWAP_IZ)) {
1718             tcg_gen_ext8u_i64(t0, t0);
1719         }
1720 
1721         if (flags & TCG_BSWAP_OS) {
1722             tcg_gen_shli_i64(t1, arg, 56);
1723             tcg_gen_sari_i64(t1, t1, 48);
1724         } else if (flags & TCG_BSWAP_OZ) {
1725             tcg_gen_ext8u_i64(t1, arg);
1726             tcg_gen_shli_i64(t1, t1, 8);
1727         } else {
1728             tcg_gen_shli_i64(t1, arg, 8);
1729         }
1730 
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_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
1738 {
1739     /* Only one extension flag may be present. */
1740     tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
1741 
1742     if (TCG_TARGET_REG_BITS == 32) {
1743         tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1744         if (flags & TCG_BSWAP_OS) {
1745             tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1746         } else {
1747             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1748         }
1749     } else if (TCG_TARGET_HAS_bswap32_i64) {
1750         tcg_gen_op3i_i64(INDEX_op_bswap32_i64, ret, arg, flags);
1751     } else {
1752         TCGv_i64 t0 = tcg_temp_new_i64();
1753         TCGv_i64 t1 = tcg_temp_new_i64();
1754         TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff);
1755 
1756                                             /* arg = xxxxabcd */
1757         tcg_gen_shri_i64(t0, arg, 8);       /*  t0 = .xxxxabc */
1758         tcg_gen_and_i64(t1, arg, t2);       /*  t1 = .....b.d */
1759         tcg_gen_and_i64(t0, t0, t2);        /*  t0 = .....a.c */
1760         tcg_gen_shli_i64(t1, t1, 8);        /*  t1 = ....b.d. */
1761         tcg_gen_or_i64(ret, t0, t1);        /* ret = ....badc */
1762 
1763         tcg_gen_shli_i64(t1, ret, 48);      /*  t1 = dc...... */
1764         tcg_gen_shri_i64(t0, ret, 16);      /*  t0 = ......ba */
1765         if (flags & TCG_BSWAP_OS) {
1766             tcg_gen_sari_i64(t1, t1, 32);   /*  t1 = ssssdc.. */
1767         } else {
1768             tcg_gen_shri_i64(t1, t1, 32);   /*  t1 = ....dc.. */
1769         }
1770         tcg_gen_or_i64(ret, t0, t1);        /* ret = ssssdcba */
1771 
1772         tcg_temp_free_i64(t0);
1773         tcg_temp_free_i64(t1);
1774     }
1775 }
1776 
1777 void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
1778 {
1779     if (TCG_TARGET_REG_BITS == 32) {
1780         TCGv_i32 t0, t1;
1781         t0 = tcg_temp_new_i32();
1782         t1 = tcg_temp_new_i32();
1783 
1784         tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
1785         tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
1786         tcg_gen_mov_i32(TCGV_LOW(ret), t1);
1787         tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
1788         tcg_temp_free_i32(t0);
1789         tcg_temp_free_i32(t1);
1790     } else if (TCG_TARGET_HAS_bswap64_i64) {
1791         tcg_gen_op3i_i64(INDEX_op_bswap64_i64, ret, arg, 0);
1792     } else {
1793         TCGv_i64 t0 = tcg_temp_new_i64();
1794         TCGv_i64 t1 = tcg_temp_new_i64();
1795         TCGv_i64 t2 = tcg_temp_new_i64();
1796 
1797                                         /* arg = abcdefgh */
1798         tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull);
1799         tcg_gen_shri_i64(t0, arg, 8);   /*  t0 = .abcdefg */
1800         tcg_gen_and_i64(t1, arg, t2);   /*  t1 = .b.d.f.h */
1801         tcg_gen_and_i64(t0, t0, t2);    /*  t0 = .a.c.e.g */
1802         tcg_gen_shli_i64(t1, t1, 8);    /*  t1 = b.d.f.h. */
1803         tcg_gen_or_i64(ret, t0, t1);    /* ret = badcfehg */
1804 
1805         tcg_gen_movi_i64(t2, 0x0000ffff0000ffffull);
1806         tcg_gen_shri_i64(t0, ret, 16);  /*  t0 = ..badcfe */
1807         tcg_gen_and_i64(t1, ret, t2);   /*  t1 = ..dc..hg */
1808         tcg_gen_and_i64(t0, t0, t2);    /*  t0 = ..ba..fe */
1809         tcg_gen_shli_i64(t1, t1, 16);   /*  t1 = dc..hg.. */
1810         tcg_gen_or_i64(ret, t0, t1);    /* ret = dcbahgfe */
1811 
1812         tcg_gen_shri_i64(t0, ret, 32);  /*  t0 = ....dcba */
1813         tcg_gen_shli_i64(t1, ret, 32);  /*  t1 = hgfe.... */
1814         tcg_gen_or_i64(ret, t0, t1);    /* ret = hgfedcba */
1815 
1816         tcg_temp_free_i64(t0);
1817         tcg_temp_free_i64(t1);
1818         tcg_temp_free_i64(t2);
1819     }
1820 }
1821 
1822 void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg)
1823 {
1824     uint64_t m = 0x0000ffff0000ffffull;
1825     TCGv_i64 t0 = tcg_temp_new_i64();
1826     TCGv_i64 t1 = tcg_temp_new_i64();
1827 
1828     /* See include/qemu/bitops.h, hswap64. */
1829     tcg_gen_rotli_i64(t1, arg, 32);
1830     tcg_gen_andi_i64(t0, t1, m);
1831     tcg_gen_shli_i64(t0, t0, 16);
1832     tcg_gen_shri_i64(t1, t1, 16);
1833     tcg_gen_andi_i64(t1, t1, m);
1834     tcg_gen_or_i64(ret, t0, t1);
1835 
1836     tcg_temp_free_i64(t0);
1837     tcg_temp_free_i64(t1);
1838 }
1839 
1840 void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg)
1841 {
1842     /* Swapping 2 32-bit elements is a rotate. */
1843     tcg_gen_rotli_i64(ret, arg, 32);
1844 }
1845 
1846 void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
1847 {
1848     if (TCG_TARGET_REG_BITS == 32) {
1849         tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1850         tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
1851     } else if (TCG_TARGET_HAS_not_i64) {
1852         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
1853     } else {
1854         tcg_gen_xori_i64(ret, arg, -1);
1855     }
1856 }
1857 
1858 void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1859 {
1860     if (TCG_TARGET_REG_BITS == 32) {
1861         tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1862         tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1863     } else if (TCG_TARGET_HAS_andc_i64) {
1864         tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
1865     } else {
1866         TCGv_i64 t0 = tcg_temp_new_i64();
1867         tcg_gen_not_i64(t0, arg2);
1868         tcg_gen_and_i64(ret, arg1, t0);
1869         tcg_temp_free_i64(t0);
1870     }
1871 }
1872 
1873 void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1874 {
1875     if (TCG_TARGET_REG_BITS == 32) {
1876         tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1877         tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1878     } else if (TCG_TARGET_HAS_eqv_i64) {
1879         tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
1880     } else {
1881         tcg_gen_xor_i64(ret, arg1, arg2);
1882         tcg_gen_not_i64(ret, ret);
1883     }
1884 }
1885 
1886 void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1887 {
1888     if (TCG_TARGET_REG_BITS == 32) {
1889         tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1890         tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1891     } else if (TCG_TARGET_HAS_nand_i64) {
1892         tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
1893     } else {
1894         tcg_gen_and_i64(ret, arg1, arg2);
1895         tcg_gen_not_i64(ret, ret);
1896     }
1897 }
1898 
1899 void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1900 {
1901     if (TCG_TARGET_REG_BITS == 32) {
1902         tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1903         tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1904     } else if (TCG_TARGET_HAS_nor_i64) {
1905         tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
1906     } else {
1907         tcg_gen_or_i64(ret, arg1, arg2);
1908         tcg_gen_not_i64(ret, ret);
1909     }
1910 }
1911 
1912 void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1913 {
1914     if (TCG_TARGET_REG_BITS == 32) {
1915         tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1916         tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1917     } else if (TCG_TARGET_HAS_orc_i64) {
1918         tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
1919     } else {
1920         TCGv_i64 t0 = tcg_temp_new_i64();
1921         tcg_gen_not_i64(t0, arg2);
1922         tcg_gen_or_i64(ret, arg1, t0);
1923         tcg_temp_free_i64(t0);
1924     }
1925 }
1926 
1927 void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1928 {
1929     if (TCG_TARGET_HAS_clz_i64) {
1930         tcg_gen_op3_i64(INDEX_op_clz_i64, ret, arg1, arg2);
1931     } else {
1932         gen_helper_clz_i64(ret, arg1, arg2);
1933     }
1934 }
1935 
1936 void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
1937 {
1938     if (TCG_TARGET_REG_BITS == 32
1939         && TCG_TARGET_HAS_clz_i32
1940         && arg2 <= 0xffffffffu) {
1941         TCGv_i32 t = tcg_temp_new_i32();
1942         tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32);
1943         tcg_gen_addi_i32(t, t, 32);
1944         tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t);
1945         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1946         tcg_temp_free_i32(t);
1947     } else {
1948         TCGv_i64 t0 = tcg_const_i64(arg2);
1949         tcg_gen_clz_i64(ret, arg1, t0);
1950         tcg_temp_free_i64(t0);
1951     }
1952 }
1953 
1954 void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1955 {
1956     if (TCG_TARGET_HAS_ctz_i64) {
1957         tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2);
1958     } else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) {
1959         TCGv_i64 z, t = tcg_temp_new_i64();
1960 
1961         if (TCG_TARGET_HAS_ctpop_i64) {
1962             tcg_gen_subi_i64(t, arg1, 1);
1963             tcg_gen_andc_i64(t, t, arg1);
1964             tcg_gen_ctpop_i64(t, t);
1965         } else {
1966             /* Since all non-x86 hosts have clz(0) == 64, don't fight it.  */
1967             tcg_gen_neg_i64(t, arg1);
1968             tcg_gen_and_i64(t, t, arg1);
1969             tcg_gen_clzi_i64(t, t, 64);
1970             tcg_gen_xori_i64(t, t, 63);
1971         }
1972         z = tcg_constant_i64(0);
1973         tcg_gen_movcond_i64(TCG_COND_EQ, ret, arg1, z, arg2, t);
1974         tcg_temp_free_i64(t);
1975         tcg_temp_free_i64(z);
1976     } else {
1977         gen_helper_ctz_i64(ret, arg1, arg2);
1978     }
1979 }
1980 
1981 void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
1982 {
1983     if (TCG_TARGET_REG_BITS == 32
1984         && TCG_TARGET_HAS_ctz_i32
1985         && arg2 <= 0xffffffffu) {
1986         TCGv_i32 t32 = tcg_temp_new_i32();
1987         tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32);
1988         tcg_gen_addi_i32(t32, t32, 32);
1989         tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32);
1990         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1991         tcg_temp_free_i32(t32);
1992     } else if (!TCG_TARGET_HAS_ctz_i64
1993                && TCG_TARGET_HAS_ctpop_i64
1994                && arg2 == 64) {
1995         /* This equivalence has the advantage of not requiring a fixup.  */
1996         TCGv_i64 t = tcg_temp_new_i64();
1997         tcg_gen_subi_i64(t, arg1, 1);
1998         tcg_gen_andc_i64(t, t, arg1);
1999         tcg_gen_ctpop_i64(ret, t);
2000         tcg_temp_free_i64(t);
2001     } else {
2002         TCGv_i64 t0 = tcg_const_i64(arg2);
2003         tcg_gen_ctz_i64(ret, arg1, t0);
2004         tcg_temp_free_i64(t0);
2005     }
2006 }
2007 
2008 void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg)
2009 {
2010     if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) {
2011         TCGv_i64 t = tcg_temp_new_i64();
2012         tcg_gen_sari_i64(t, arg, 63);
2013         tcg_gen_xor_i64(t, t, arg);
2014         tcg_gen_clzi_i64(t, t, 64);
2015         tcg_gen_subi_i64(ret, t, 1);
2016         tcg_temp_free_i64(t);
2017     } else {
2018         gen_helper_clrsb_i64(ret, arg);
2019     }
2020 }
2021 
2022 void tcg_gen_ctpop_i64(TCGv_i64 ret, TCGv_i64 arg1)
2023 {
2024     if (TCG_TARGET_HAS_ctpop_i64) {
2025         tcg_gen_op2_i64(INDEX_op_ctpop_i64, ret, arg1);
2026     } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_ctpop_i32) {
2027         tcg_gen_ctpop_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
2028         tcg_gen_ctpop_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
2029         tcg_gen_add_i32(TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret));
2030         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2031     } else {
2032         gen_helper_ctpop_i64(ret, arg1);
2033     }
2034 }
2035 
2036 void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2037 {
2038     if (TCG_TARGET_HAS_rot_i64) {
2039         tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
2040     } else {
2041         TCGv_i64 t0, t1;
2042         t0 = tcg_temp_new_i64();
2043         t1 = tcg_temp_new_i64();
2044         tcg_gen_shl_i64(t0, arg1, arg2);
2045         tcg_gen_subfi_i64(t1, 64, arg2);
2046         tcg_gen_shr_i64(t1, arg1, t1);
2047         tcg_gen_or_i64(ret, t0, t1);
2048         tcg_temp_free_i64(t0);
2049         tcg_temp_free_i64(t1);
2050     }
2051 }
2052 
2053 void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2054 {
2055     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
2056     /* some cases can be optimized here */
2057     if (arg2 == 0) {
2058         tcg_gen_mov_i64(ret, arg1);
2059     } else if (TCG_TARGET_HAS_rot_i64) {
2060         tcg_gen_rotl_i64(ret, arg1, tcg_constant_i64(arg2));
2061     } else {
2062         TCGv_i64 t0, t1;
2063         t0 = tcg_temp_new_i64();
2064         t1 = tcg_temp_new_i64();
2065         tcg_gen_shli_i64(t0, arg1, arg2);
2066         tcg_gen_shri_i64(t1, arg1, 64 - arg2);
2067         tcg_gen_or_i64(ret, t0, t1);
2068         tcg_temp_free_i64(t0);
2069         tcg_temp_free_i64(t1);
2070     }
2071 }
2072 
2073 void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2074 {
2075     if (TCG_TARGET_HAS_rot_i64) {
2076         tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
2077     } else {
2078         TCGv_i64 t0, t1;
2079         t0 = tcg_temp_new_i64();
2080         t1 = tcg_temp_new_i64();
2081         tcg_gen_shr_i64(t0, arg1, arg2);
2082         tcg_gen_subfi_i64(t1, 64, arg2);
2083         tcg_gen_shl_i64(t1, arg1, t1);
2084         tcg_gen_or_i64(ret, t0, t1);
2085         tcg_temp_free_i64(t0);
2086         tcg_temp_free_i64(t1);
2087     }
2088 }
2089 
2090 void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2091 {
2092     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
2093     /* some cases can be optimized here */
2094     if (arg2 == 0) {
2095         tcg_gen_mov_i64(ret, arg1);
2096     } else {
2097         tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
2098     }
2099 }
2100 
2101 void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
2102                          unsigned int ofs, unsigned int len)
2103 {
2104     uint64_t mask;
2105     TCGv_i64 t1;
2106 
2107     tcg_debug_assert(ofs < 64);
2108     tcg_debug_assert(len > 0);
2109     tcg_debug_assert(len <= 64);
2110     tcg_debug_assert(ofs + len <= 64);
2111 
2112     if (len == 64) {
2113         tcg_gen_mov_i64(ret, arg2);
2114         return;
2115     }
2116     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
2117         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
2118         return;
2119     }
2120 
2121     if (TCG_TARGET_REG_BITS == 32) {
2122         if (ofs >= 32) {
2123             tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1),
2124                                 TCGV_LOW(arg2), ofs - 32, len);
2125             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
2126             return;
2127         }
2128         if (ofs + len <= 32) {
2129             tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1),
2130                                 TCGV_LOW(arg2), ofs, len);
2131             tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
2132             return;
2133         }
2134     }
2135 
2136     t1 = tcg_temp_new_i64();
2137 
2138     if (TCG_TARGET_HAS_extract2_i64) {
2139         if (ofs + len == 64) {
2140             tcg_gen_shli_i64(t1, arg1, len);
2141             tcg_gen_extract2_i64(ret, t1, arg2, len);
2142             goto done;
2143         }
2144         if (ofs == 0) {
2145             tcg_gen_extract2_i64(ret, arg1, arg2, len);
2146             tcg_gen_rotli_i64(ret, ret, len);
2147             goto done;
2148         }
2149     }
2150 
2151     mask = (1ull << len) - 1;
2152     if (ofs + len < 64) {
2153         tcg_gen_andi_i64(t1, arg2, mask);
2154         tcg_gen_shli_i64(t1, t1, ofs);
2155     } else {
2156         tcg_gen_shli_i64(t1, arg2, ofs);
2157     }
2158     tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
2159     tcg_gen_or_i64(ret, ret, t1);
2160  done:
2161     tcg_temp_free_i64(t1);
2162 }
2163 
2164 void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
2165                            unsigned int ofs, unsigned int len)
2166 {
2167     tcg_debug_assert(ofs < 64);
2168     tcg_debug_assert(len > 0);
2169     tcg_debug_assert(len <= 64);
2170     tcg_debug_assert(ofs + len <= 64);
2171 
2172     if (ofs + len == 64) {
2173         tcg_gen_shli_i64(ret, arg, ofs);
2174     } else if (ofs == 0) {
2175         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
2176     } else if (TCG_TARGET_HAS_deposit_i64
2177                && TCG_TARGET_deposit_i64_valid(ofs, len)) {
2178         TCGv_i64 zero = tcg_constant_i64(0);
2179         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len);
2180     } else {
2181         if (TCG_TARGET_REG_BITS == 32) {
2182             if (ofs >= 32) {
2183                 tcg_gen_deposit_z_i32(TCGV_HIGH(ret), TCGV_LOW(arg),
2184                                       ofs - 32, len);
2185                 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
2186                 return;
2187             }
2188             if (ofs + len <= 32) {
2189                 tcg_gen_deposit_z_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
2190                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2191                 return;
2192             }
2193         }
2194         /* To help two-operand hosts we prefer to zero-extend first,
2195            which allows ARG to stay live.  */
2196         switch (len) {
2197         case 32:
2198             if (TCG_TARGET_HAS_ext32u_i64) {
2199                 tcg_gen_ext32u_i64(ret, arg);
2200                 tcg_gen_shli_i64(ret, ret, ofs);
2201                 return;
2202             }
2203             break;
2204         case 16:
2205             if (TCG_TARGET_HAS_ext16u_i64) {
2206                 tcg_gen_ext16u_i64(ret, arg);
2207                 tcg_gen_shli_i64(ret, ret, ofs);
2208                 return;
2209             }
2210             break;
2211         case 8:
2212             if (TCG_TARGET_HAS_ext8u_i64) {
2213                 tcg_gen_ext8u_i64(ret, arg);
2214                 tcg_gen_shli_i64(ret, ret, ofs);
2215                 return;
2216             }
2217             break;
2218         }
2219         /* Otherwise prefer zero-extension over AND for code size.  */
2220         switch (ofs + len) {
2221         case 32:
2222             if (TCG_TARGET_HAS_ext32u_i64) {
2223                 tcg_gen_shli_i64(ret, arg, ofs);
2224                 tcg_gen_ext32u_i64(ret, ret);
2225                 return;
2226             }
2227             break;
2228         case 16:
2229             if (TCG_TARGET_HAS_ext16u_i64) {
2230                 tcg_gen_shli_i64(ret, arg, ofs);
2231                 tcg_gen_ext16u_i64(ret, ret);
2232                 return;
2233             }
2234             break;
2235         case 8:
2236             if (TCG_TARGET_HAS_ext8u_i64) {
2237                 tcg_gen_shli_i64(ret, arg, ofs);
2238                 tcg_gen_ext8u_i64(ret, ret);
2239                 return;
2240             }
2241             break;
2242         }
2243         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
2244         tcg_gen_shli_i64(ret, ret, ofs);
2245     }
2246 }
2247 
2248 void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
2249                          unsigned int ofs, unsigned int len)
2250 {
2251     tcg_debug_assert(ofs < 64);
2252     tcg_debug_assert(len > 0);
2253     tcg_debug_assert(len <= 64);
2254     tcg_debug_assert(ofs + len <= 64);
2255 
2256     /* Canonicalize certain special cases, even if extract is supported.  */
2257     if (ofs + len == 64) {
2258         tcg_gen_shri_i64(ret, arg, 64 - len);
2259         return;
2260     }
2261     if (ofs == 0) {
2262         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
2263         return;
2264     }
2265 
2266     if (TCG_TARGET_REG_BITS == 32) {
2267         /* Look for a 32-bit extract within one of the two words.  */
2268         if (ofs >= 32) {
2269             tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
2270             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2271             return;
2272         }
2273         if (ofs + len <= 32) {
2274             tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
2275             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2276             return;
2277         }
2278         /* The field is split across two words.  One double-word
2279            shift is better than two double-word shifts.  */
2280         goto do_shift_and;
2281     }
2282 
2283     if (TCG_TARGET_HAS_extract_i64
2284         && TCG_TARGET_extract_i64_valid(ofs, len)) {
2285         tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len);
2286         return;
2287     }
2288 
2289     /* Assume that zero-extension, if available, is cheaper than a shift.  */
2290     switch (ofs + len) {
2291     case 32:
2292         if (TCG_TARGET_HAS_ext32u_i64) {
2293             tcg_gen_ext32u_i64(ret, arg);
2294             tcg_gen_shri_i64(ret, ret, ofs);
2295             return;
2296         }
2297         break;
2298     case 16:
2299         if (TCG_TARGET_HAS_ext16u_i64) {
2300             tcg_gen_ext16u_i64(ret, arg);
2301             tcg_gen_shri_i64(ret, ret, ofs);
2302             return;
2303         }
2304         break;
2305     case 8:
2306         if (TCG_TARGET_HAS_ext8u_i64) {
2307             tcg_gen_ext8u_i64(ret, arg);
2308             tcg_gen_shri_i64(ret, ret, ofs);
2309             return;
2310         }
2311         break;
2312     }
2313 
2314     /* ??? Ideally we'd know what values are available for immediate AND.
2315        Assume that 8 bits are available, plus the special cases of 16 and 32,
2316        so that we get ext8u, ext16u, and ext32u.  */
2317     switch (len) {
2318     case 1 ... 8: case 16: case 32:
2319     do_shift_and:
2320         tcg_gen_shri_i64(ret, arg, ofs);
2321         tcg_gen_andi_i64(ret, ret, (1ull << len) - 1);
2322         break;
2323     default:
2324         tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
2325         tcg_gen_shri_i64(ret, ret, 64 - len);
2326         break;
2327     }
2328 }
2329 
2330 void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
2331                           unsigned int ofs, unsigned int len)
2332 {
2333     tcg_debug_assert(ofs < 64);
2334     tcg_debug_assert(len > 0);
2335     tcg_debug_assert(len <= 64);
2336     tcg_debug_assert(ofs + len <= 64);
2337 
2338     /* Canonicalize certain special cases, even if sextract is supported.  */
2339     if (ofs + len == 64) {
2340         tcg_gen_sari_i64(ret, arg, 64 - len);
2341         return;
2342     }
2343     if (ofs == 0) {
2344         switch (len) {
2345         case 32:
2346             tcg_gen_ext32s_i64(ret, arg);
2347             return;
2348         case 16:
2349             tcg_gen_ext16s_i64(ret, arg);
2350             return;
2351         case 8:
2352             tcg_gen_ext8s_i64(ret, arg);
2353             return;
2354         }
2355     }
2356 
2357     if (TCG_TARGET_REG_BITS == 32) {
2358         /* Look for a 32-bit extract within one of the two words.  */
2359         if (ofs >= 32) {
2360             tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
2361         } else if (ofs + len <= 32) {
2362             tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
2363         } else if (ofs == 0) {
2364             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2365             tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32);
2366             return;
2367         } else if (len > 32) {
2368             TCGv_i32 t = tcg_temp_new_i32();
2369             /* Extract the bits for the high word normally.  */
2370             tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32);
2371             /* Shift the field down for the low part.  */
2372             tcg_gen_shri_i64(ret, arg, ofs);
2373             /* Overwrite the shift into the high part.  */
2374             tcg_gen_mov_i32(TCGV_HIGH(ret), t);
2375             tcg_temp_free_i32(t);
2376             return;
2377         } else {
2378             /* Shift the field down for the low part, such that the
2379                field sits at the MSB.  */
2380             tcg_gen_shri_i64(ret, arg, ofs + len - 32);
2381             /* Shift the field down from the MSB, sign extending.  */
2382             tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_LOW(ret), 32 - len);
2383         }
2384         /* Sign-extend the field from 32 bits.  */
2385         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2386         return;
2387     }
2388 
2389     if (TCG_TARGET_HAS_sextract_i64
2390         && TCG_TARGET_extract_i64_valid(ofs, len)) {
2391         tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len);
2392         return;
2393     }
2394 
2395     /* Assume that sign-extension, if available, is cheaper than a shift.  */
2396     switch (ofs + len) {
2397     case 32:
2398         if (TCG_TARGET_HAS_ext32s_i64) {
2399             tcg_gen_ext32s_i64(ret, arg);
2400             tcg_gen_sari_i64(ret, ret, ofs);
2401             return;
2402         }
2403         break;
2404     case 16:
2405         if (TCG_TARGET_HAS_ext16s_i64) {
2406             tcg_gen_ext16s_i64(ret, arg);
2407             tcg_gen_sari_i64(ret, ret, ofs);
2408             return;
2409         }
2410         break;
2411     case 8:
2412         if (TCG_TARGET_HAS_ext8s_i64) {
2413             tcg_gen_ext8s_i64(ret, arg);
2414             tcg_gen_sari_i64(ret, ret, ofs);
2415             return;
2416         }
2417         break;
2418     }
2419     switch (len) {
2420     case 32:
2421         if (TCG_TARGET_HAS_ext32s_i64) {
2422             tcg_gen_shri_i64(ret, arg, ofs);
2423             tcg_gen_ext32s_i64(ret, ret);
2424             return;
2425         }
2426         break;
2427     case 16:
2428         if (TCG_TARGET_HAS_ext16s_i64) {
2429             tcg_gen_shri_i64(ret, arg, ofs);
2430             tcg_gen_ext16s_i64(ret, ret);
2431             return;
2432         }
2433         break;
2434     case 8:
2435         if (TCG_TARGET_HAS_ext8s_i64) {
2436             tcg_gen_shri_i64(ret, arg, ofs);
2437             tcg_gen_ext8s_i64(ret, ret);
2438             return;
2439         }
2440         break;
2441     }
2442     tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
2443     tcg_gen_sari_i64(ret, ret, 64 - len);
2444 }
2445 
2446 /*
2447  * Extract 64 bits from a 128-bit input, ah:al, starting from ofs.
2448  * Unlike tcg_gen_extract_i64 above, len is fixed at 64.
2449  */
2450 void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
2451                           unsigned int ofs)
2452 {
2453     tcg_debug_assert(ofs <= 64);
2454     if (ofs == 0) {
2455         tcg_gen_mov_i64(ret, al);
2456     } else if (ofs == 64) {
2457         tcg_gen_mov_i64(ret, ah);
2458     } else if (al == ah) {
2459         tcg_gen_rotri_i64(ret, al, ofs);
2460     } else if (TCG_TARGET_HAS_extract2_i64) {
2461         tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
2462     } else {
2463         TCGv_i64 t0 = tcg_temp_new_i64();
2464         tcg_gen_shri_i64(t0, al, ofs);
2465         tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs);
2466         tcg_temp_free_i64(t0);
2467     }
2468 }
2469 
2470 void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
2471                          TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2)
2472 {
2473     if (cond == TCG_COND_ALWAYS) {
2474         tcg_gen_mov_i64(ret, v1);
2475     } else if (cond == TCG_COND_NEVER) {
2476         tcg_gen_mov_i64(ret, v2);
2477     } else if (TCG_TARGET_REG_BITS == 32) {
2478         TCGv_i32 t0 = tcg_temp_new_i32();
2479         TCGv_i32 t1 = tcg_temp_new_i32();
2480         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
2481                          TCGV_LOW(c1), TCGV_HIGH(c1),
2482                          TCGV_LOW(c2), TCGV_HIGH(c2), cond);
2483 
2484         if (TCG_TARGET_HAS_movcond_i32) {
2485             tcg_gen_movi_i32(t1, 0);
2486             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, t1,
2487                                 TCGV_LOW(v1), TCGV_LOW(v2));
2488             tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, t1,
2489                                 TCGV_HIGH(v1), TCGV_HIGH(v2));
2490         } else {
2491             tcg_gen_neg_i32(t0, t0);
2492 
2493             tcg_gen_and_i32(t1, TCGV_LOW(v1), t0);
2494             tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0);
2495             tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1);
2496 
2497             tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0);
2498             tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0);
2499             tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1);
2500         }
2501         tcg_temp_free_i32(t0);
2502         tcg_temp_free_i32(t1);
2503     } else if (TCG_TARGET_HAS_movcond_i64) {
2504         tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
2505     } else {
2506         TCGv_i64 t0 = tcg_temp_new_i64();
2507         TCGv_i64 t1 = tcg_temp_new_i64();
2508         tcg_gen_setcond_i64(cond, t0, c1, c2);
2509         tcg_gen_neg_i64(t0, t0);
2510         tcg_gen_and_i64(t1, v1, t0);
2511         tcg_gen_andc_i64(ret, v2, t0);
2512         tcg_gen_or_i64(ret, ret, t1);
2513         tcg_temp_free_i64(t0);
2514         tcg_temp_free_i64(t1);
2515     }
2516 }
2517 
2518 void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
2519                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
2520 {
2521     if (TCG_TARGET_HAS_add2_i64) {
2522         tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
2523     } else {
2524         TCGv_i64 t0 = tcg_temp_new_i64();
2525         TCGv_i64 t1 = tcg_temp_new_i64();
2526         tcg_gen_add_i64(t0, al, bl);
2527         tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
2528         tcg_gen_add_i64(rh, ah, bh);
2529         tcg_gen_add_i64(rh, rh, t1);
2530         tcg_gen_mov_i64(rl, t0);
2531         tcg_temp_free_i64(t0);
2532         tcg_temp_free_i64(t1);
2533     }
2534 }
2535 
2536 void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
2537                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
2538 {
2539     if (TCG_TARGET_HAS_sub2_i64) {
2540         tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
2541     } else {
2542         TCGv_i64 t0 = tcg_temp_new_i64();
2543         TCGv_i64 t1 = tcg_temp_new_i64();
2544         tcg_gen_sub_i64(t0, al, bl);
2545         tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
2546         tcg_gen_sub_i64(rh, ah, bh);
2547         tcg_gen_sub_i64(rh, rh, t1);
2548         tcg_gen_mov_i64(rl, t0);
2549         tcg_temp_free_i64(t0);
2550         tcg_temp_free_i64(t1);
2551     }
2552 }
2553 
2554 void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
2555 {
2556     if (TCG_TARGET_HAS_mulu2_i64) {
2557         tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
2558     } else if (TCG_TARGET_HAS_muluh_i64) {
2559         TCGv_i64 t = tcg_temp_new_i64();
2560         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
2561         tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
2562         tcg_gen_mov_i64(rl, t);
2563         tcg_temp_free_i64(t);
2564     } else {
2565         TCGv_i64 t0 = tcg_temp_new_i64();
2566         tcg_gen_mul_i64(t0, arg1, arg2);
2567         gen_helper_muluh_i64(rh, arg1, arg2);
2568         tcg_gen_mov_i64(rl, t0);
2569         tcg_temp_free_i64(t0);
2570     }
2571 }
2572 
2573 void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
2574 {
2575     if (TCG_TARGET_HAS_muls2_i64) {
2576         tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
2577     } else if (TCG_TARGET_HAS_mulsh_i64) {
2578         TCGv_i64 t = tcg_temp_new_i64();
2579         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
2580         tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
2581         tcg_gen_mov_i64(rl, t);
2582         tcg_temp_free_i64(t);
2583     } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
2584         TCGv_i64 t0 = tcg_temp_new_i64();
2585         TCGv_i64 t1 = tcg_temp_new_i64();
2586         TCGv_i64 t2 = tcg_temp_new_i64();
2587         TCGv_i64 t3 = tcg_temp_new_i64();
2588         tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
2589         /* Adjust for negative inputs.  */
2590         tcg_gen_sari_i64(t2, arg1, 63);
2591         tcg_gen_sari_i64(t3, arg2, 63);
2592         tcg_gen_and_i64(t2, t2, arg2);
2593         tcg_gen_and_i64(t3, t3, arg1);
2594         tcg_gen_sub_i64(rh, t1, t2);
2595         tcg_gen_sub_i64(rh, rh, t3);
2596         tcg_gen_mov_i64(rl, t0);
2597         tcg_temp_free_i64(t0);
2598         tcg_temp_free_i64(t1);
2599         tcg_temp_free_i64(t2);
2600         tcg_temp_free_i64(t3);
2601     } else {
2602         TCGv_i64 t0 = tcg_temp_new_i64();
2603         tcg_gen_mul_i64(t0, arg1, arg2);
2604         gen_helper_mulsh_i64(rh, arg1, arg2);
2605         tcg_gen_mov_i64(rl, t0);
2606         tcg_temp_free_i64(t0);
2607     }
2608 }
2609 
2610 void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
2611 {
2612     TCGv_i64 t0 = tcg_temp_new_i64();
2613     TCGv_i64 t1 = tcg_temp_new_i64();
2614     TCGv_i64 t2 = tcg_temp_new_i64();
2615     tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
2616     /* Adjust for negative input for the signed arg1.  */
2617     tcg_gen_sari_i64(t2, arg1, 63);
2618     tcg_gen_and_i64(t2, t2, arg2);
2619     tcg_gen_sub_i64(rh, t1, t2);
2620     tcg_gen_mov_i64(rl, t0);
2621     tcg_temp_free_i64(t0);
2622     tcg_temp_free_i64(t1);
2623     tcg_temp_free_i64(t2);
2624 }
2625 
2626 void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
2627 {
2628     tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b);
2629 }
2630 
2631 void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
2632 {
2633     tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b);
2634 }
2635 
2636 void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
2637 {
2638     tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a);
2639 }
2640 
2641 void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
2642 {
2643     tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a);
2644 }
2645 
2646 void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a)
2647 {
2648     TCGv_i64 t = tcg_temp_new_i64();
2649 
2650     tcg_gen_sari_i64(t, a, 63);
2651     tcg_gen_xor_i64(ret, a, t);
2652     tcg_gen_sub_i64(ret, ret, t);
2653     tcg_temp_free_i64(t);
2654 }
2655 
2656 /* Size changing operations.  */
2657 
2658 void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
2659 {
2660     if (TCG_TARGET_REG_BITS == 32) {
2661         tcg_gen_mov_i32(ret, TCGV_LOW(arg));
2662     } else if (TCG_TARGET_HAS_extrl_i64_i32) {
2663         tcg_gen_op2(INDEX_op_extrl_i64_i32,
2664                     tcgv_i32_arg(ret), tcgv_i64_arg(arg));
2665     } else {
2666         tcg_gen_mov_i32(ret, (TCGv_i32)arg);
2667     }
2668 }
2669 
2670 void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
2671 {
2672     if (TCG_TARGET_REG_BITS == 32) {
2673         tcg_gen_mov_i32(ret, TCGV_HIGH(arg));
2674     } else if (TCG_TARGET_HAS_extrh_i64_i32) {
2675         tcg_gen_op2(INDEX_op_extrh_i64_i32,
2676                     tcgv_i32_arg(ret), tcgv_i64_arg(arg));
2677     } else {
2678         TCGv_i64 t = tcg_temp_new_i64();
2679         tcg_gen_shri_i64(t, arg, 32);
2680         tcg_gen_mov_i32(ret, (TCGv_i32)t);
2681         tcg_temp_free_i64(t);
2682     }
2683 }
2684 
2685 void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
2686 {
2687     if (TCG_TARGET_REG_BITS == 32) {
2688         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
2689         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2690     } else {
2691         tcg_gen_op2(INDEX_op_extu_i32_i64,
2692                     tcgv_i64_arg(ret), tcgv_i32_arg(arg));
2693     }
2694 }
2695 
2696 void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
2697 {
2698     if (TCG_TARGET_REG_BITS == 32) {
2699         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
2700         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2701     } else {
2702         tcg_gen_op2(INDEX_op_ext_i32_i64,
2703                     tcgv_i64_arg(ret), tcgv_i32_arg(arg));
2704     }
2705 }
2706 
2707 void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
2708 {
2709     TCGv_i64 tmp;
2710 
2711     if (TCG_TARGET_REG_BITS == 32) {
2712         tcg_gen_mov_i32(TCGV_LOW(dest), low);
2713         tcg_gen_mov_i32(TCGV_HIGH(dest), high);
2714         return;
2715     }
2716 
2717     tmp = tcg_temp_new_i64();
2718     /* These extensions are only needed for type correctness.
2719        We may be able to do better given target specific information.  */
2720     tcg_gen_extu_i32_i64(tmp, high);
2721     tcg_gen_extu_i32_i64(dest, low);
2722     /* If deposit is available, use it.  Otherwise use the extra
2723        knowledge that we have of the zero-extensions above.  */
2724     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
2725         tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
2726     } else {
2727         tcg_gen_shli_i64(tmp, tmp, 32);
2728         tcg_gen_or_i64(dest, dest, tmp);
2729     }
2730     tcg_temp_free_i64(tmp);
2731 }
2732 
2733 void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
2734 {
2735     if (TCG_TARGET_REG_BITS == 32) {
2736         tcg_gen_mov_i32(lo, TCGV_LOW(arg));
2737         tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
2738     } else {
2739         tcg_gen_extrl_i64_i32(lo, arg);
2740         tcg_gen_extrh_i64_i32(hi, arg);
2741     }
2742 }
2743 
2744 void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
2745 {
2746     tcg_gen_ext32u_i64(lo, arg);
2747     tcg_gen_shri_i64(hi, arg, 32);
2748 }
2749 
2750 void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg)
2751 {
2752     tcg_gen_mov_i64(lo, TCGV128_LOW(arg));
2753     tcg_gen_mov_i64(hi, TCGV128_HIGH(arg));
2754 }
2755 
2756 void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi)
2757 {
2758     tcg_gen_mov_i64(TCGV128_LOW(ret), lo);
2759     tcg_gen_mov_i64(TCGV128_HIGH(ret), hi);
2760 }
2761 
2762 void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src)
2763 {
2764     if (dst != src) {
2765         tcg_gen_mov_i64(TCGV128_LOW(dst), TCGV128_LOW(src));
2766         tcg_gen_mov_i64(TCGV128_HIGH(dst), TCGV128_HIGH(src));
2767     }
2768 }
2769 
2770 /* QEMU specific operations.  */
2771 
2772 void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
2773 {
2774     /*
2775      * Let the jit code return the read-only version of the
2776      * TranslationBlock, so that we minimize the pc-relative
2777      * distance of the address of the exit_tb code to TB.
2778      * This will improve utilization of pc-relative address loads.
2779      *
2780      * TODO: Move this to translator_loop, so that all const
2781      * TranslationBlock pointers refer to read-only memory.
2782      * This requires coordination with targets that do not use
2783      * the translator_loop.
2784      */
2785     uintptr_t val = (uintptr_t)tcg_splitwx_to_rx((void *)tb) + idx;
2786 
2787     if (tb == NULL) {
2788         tcg_debug_assert(idx == 0);
2789     } else if (idx <= TB_EXIT_IDXMAX) {
2790 #ifdef CONFIG_DEBUG_TCG
2791         /* This is an exit following a goto_tb.  Verify that we have
2792            seen this numbered exit before, via tcg_gen_goto_tb.  */
2793         tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx));
2794 #endif
2795     } else {
2796         /* This is an exit via the exitreq label.  */
2797         tcg_debug_assert(idx == TB_EXIT_REQUESTED);
2798     }
2799 
2800     plugin_gen_disable_mem_helpers();
2801     tcg_gen_op1i(INDEX_op_exit_tb, val);
2802 }
2803 
2804 void tcg_gen_goto_tb(unsigned idx)
2805 {
2806     /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */
2807     tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB));
2808     /* We only support two chained exits.  */
2809     tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
2810 #ifdef CONFIG_DEBUG_TCG
2811     /* Verify that we haven't seen this numbered exit before.  */
2812     tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
2813     tcg_ctx->goto_tb_issue_mask |= 1 << idx;
2814 #endif
2815     plugin_gen_disable_mem_helpers();
2816     tcg_gen_op1i(INDEX_op_goto_tb, idx);
2817 }
2818 
2819 void tcg_gen_lookup_and_goto_ptr(void)
2820 {
2821     TCGv_ptr ptr;
2822 
2823     if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) {
2824         tcg_gen_exit_tb(NULL, 0);
2825         return;
2826     }
2827 
2828     plugin_gen_disable_mem_helpers();
2829     ptr = tcg_temp_new_ptr();
2830     gen_helper_lookup_tb_ptr(ptr, cpu_env);
2831     tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr));
2832     tcg_temp_free_ptr(ptr);
2833 }
2834 
2835 static inline MemOp tcg_canonicalize_memop(MemOp op, bool is64, bool st)
2836 {
2837     /* Trigger the asserts within as early as possible.  */
2838     unsigned a_bits = get_alignment_bits(op);
2839 
2840     /* Prefer MO_ALIGN+MO_XX over MO_ALIGN_XX+MO_XX */
2841     if (a_bits == (op & MO_SIZE)) {
2842         op = (op & ~MO_AMASK) | MO_ALIGN;
2843     }
2844 
2845     switch (op & MO_SIZE) {
2846     case MO_8:
2847         op &= ~MO_BSWAP;
2848         break;
2849     case MO_16:
2850         break;
2851     case MO_32:
2852         if (!is64) {
2853             op &= ~MO_SIGN;
2854         }
2855         break;
2856     case MO_64:
2857         if (is64) {
2858             op &= ~MO_SIGN;
2859             break;
2860         }
2861         /* fall through */
2862     default:
2863         g_assert_not_reached();
2864     }
2865     if (st) {
2866         op &= ~MO_SIGN;
2867     }
2868     return op;
2869 }
2870 
2871 static void gen_ldst_i32(TCGOpcode opc, TCGv_i32 val, TCGv addr,
2872                          MemOp memop, TCGArg idx)
2873 {
2874     MemOpIdx oi = make_memop_idx(memop, idx);
2875 #if TARGET_LONG_BITS == 32
2876     tcg_gen_op3i_i32(opc, val, addr, oi);
2877 #else
2878     if (TCG_TARGET_REG_BITS == 32) {
2879         tcg_gen_op4i_i32(opc, val, TCGV_LOW(addr), TCGV_HIGH(addr), oi);
2880     } else {
2881         tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_i64_arg(addr), oi);
2882     }
2883 #endif
2884 }
2885 
2886 static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 val, TCGv addr,
2887                          MemOp memop, TCGArg idx)
2888 {
2889     MemOpIdx oi = make_memop_idx(memop, idx);
2890 #if TARGET_LONG_BITS == 32
2891     if (TCG_TARGET_REG_BITS == 32) {
2892         tcg_gen_op4i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val), addr, oi);
2893     } else {
2894         tcg_gen_op3(opc, tcgv_i64_arg(val), tcgv_i32_arg(addr), oi);
2895     }
2896 #else
2897     if (TCG_TARGET_REG_BITS == 32) {
2898         tcg_gen_op5i_i32(opc, TCGV_LOW(val), TCGV_HIGH(val),
2899                          TCGV_LOW(addr), TCGV_HIGH(addr), oi);
2900     } else {
2901         tcg_gen_op3i_i64(opc, val, addr, oi);
2902     }
2903 #endif
2904 }
2905 
2906 static void tcg_gen_req_mo(TCGBar type)
2907 {
2908 #ifdef TCG_GUEST_DEFAULT_MO
2909     type &= TCG_GUEST_DEFAULT_MO;
2910 #endif
2911     type &= ~TCG_TARGET_DEFAULT_MO;
2912     if (type) {
2913         tcg_gen_mb(type | TCG_BAR_SC);
2914     }
2915 }
2916 
2917 static inline TCGv plugin_prep_mem_callbacks(TCGv vaddr)
2918 {
2919 #ifdef CONFIG_PLUGIN
2920     if (tcg_ctx->plugin_insn != NULL) {
2921         /* Save a copy of the vaddr for use after a load.  */
2922         TCGv temp = tcg_temp_new();
2923         tcg_gen_mov_tl(temp, vaddr);
2924         return temp;
2925     }
2926 #endif
2927     return vaddr;
2928 }
2929 
2930 static void plugin_gen_mem_callbacks(TCGv vaddr, MemOpIdx oi,
2931                                      enum qemu_plugin_mem_rw rw)
2932 {
2933 #ifdef CONFIG_PLUGIN
2934     if (tcg_ctx->plugin_insn != NULL) {
2935         qemu_plugin_meminfo_t info = make_plugin_meminfo(oi, rw);
2936         plugin_gen_empty_mem_callback(vaddr, info);
2937         tcg_temp_free(vaddr);
2938     }
2939 #endif
2940 }
2941 
2942 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, MemOp memop)
2943 {
2944     MemOp orig_memop;
2945     MemOpIdx oi;
2946 
2947     tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
2948     memop = tcg_canonicalize_memop(memop, 0, 0);
2949     oi = make_memop_idx(memop, idx);
2950 
2951     orig_memop = memop;
2952     if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
2953         memop &= ~MO_BSWAP;
2954         /* The bswap primitive benefits from zero-extended input.  */
2955         if ((memop & MO_SSIZE) == MO_SW) {
2956             memop &= ~MO_SIGN;
2957         }
2958     }
2959 
2960     addr = plugin_prep_mem_callbacks(addr);
2961     gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx);
2962     plugin_gen_mem_callbacks(addr, oi, QEMU_PLUGIN_MEM_R);
2963 
2964     if ((orig_memop ^ memop) & MO_BSWAP) {
2965         switch (orig_memop & MO_SIZE) {
2966         case MO_16:
2967             tcg_gen_bswap16_i32(val, val, (orig_memop & MO_SIGN
2968                                            ? TCG_BSWAP_IZ | TCG_BSWAP_OS
2969                                            : TCG_BSWAP_IZ | TCG_BSWAP_OZ));
2970             break;
2971         case MO_32:
2972             tcg_gen_bswap32_i32(val, val);
2973             break;
2974         default:
2975             g_assert_not_reached();
2976         }
2977     }
2978 }
2979 
2980 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, MemOp memop)
2981 {
2982     TCGv_i32 swap = NULL;
2983     MemOpIdx oi;
2984 
2985     tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
2986     memop = tcg_canonicalize_memop(memop, 0, 1);
2987     oi = make_memop_idx(memop, idx);
2988 
2989     if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
2990         swap = tcg_temp_new_i32();
2991         switch (memop & MO_SIZE) {
2992         case MO_16:
2993             tcg_gen_bswap16_i32(swap, val, 0);
2994             break;
2995         case MO_32:
2996             tcg_gen_bswap32_i32(swap, val);
2997             break;
2998         default:
2999             g_assert_not_reached();
3000         }
3001         val = swap;
3002         memop &= ~MO_BSWAP;
3003     }
3004 
3005     addr = plugin_prep_mem_callbacks(addr);
3006     if (TCG_TARGET_HAS_qemu_st8_i32 && (memop & MO_SIZE) == MO_8) {
3007         gen_ldst_i32(INDEX_op_qemu_st8_i32, val, addr, memop, idx);
3008     } else {
3009         gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
3010     }
3011     plugin_gen_mem_callbacks(addr, oi, QEMU_PLUGIN_MEM_W);
3012 
3013     if (swap) {
3014         tcg_temp_free_i32(swap);
3015     }
3016 }
3017 
3018 void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, MemOp memop)
3019 {
3020     MemOp orig_memop;
3021     MemOpIdx oi;
3022 
3023     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
3024         tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop);
3025         if (memop & MO_SIGN) {
3026             tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31);
3027         } else {
3028             tcg_gen_movi_i32(TCGV_HIGH(val), 0);
3029         }
3030         return;
3031     }
3032 
3033     tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
3034     memop = tcg_canonicalize_memop(memop, 1, 0);
3035     oi = make_memop_idx(memop, idx);
3036 
3037     orig_memop = memop;
3038     if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
3039         memop &= ~MO_BSWAP;
3040         /* The bswap primitive benefits from zero-extended input.  */
3041         if ((memop & MO_SIGN) && (memop & MO_SIZE) < MO_64) {
3042             memop &= ~MO_SIGN;
3043         }
3044     }
3045 
3046     addr = plugin_prep_mem_callbacks(addr);
3047     gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx);
3048     plugin_gen_mem_callbacks(addr, oi, QEMU_PLUGIN_MEM_R);
3049 
3050     if ((orig_memop ^ memop) & MO_BSWAP) {
3051         int flags = (orig_memop & MO_SIGN
3052                      ? TCG_BSWAP_IZ | TCG_BSWAP_OS
3053                      : TCG_BSWAP_IZ | TCG_BSWAP_OZ);
3054         switch (orig_memop & MO_SIZE) {
3055         case MO_16:
3056             tcg_gen_bswap16_i64(val, val, flags);
3057             break;
3058         case MO_32:
3059             tcg_gen_bswap32_i64(val, val, flags);
3060             break;
3061         case MO_64:
3062             tcg_gen_bswap64_i64(val, val);
3063             break;
3064         default:
3065             g_assert_not_reached();
3066         }
3067     }
3068 }
3069 
3070 void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, MemOp memop)
3071 {
3072     TCGv_i64 swap = NULL;
3073     MemOpIdx oi;
3074 
3075     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
3076         tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop);
3077         return;
3078     }
3079 
3080     tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
3081     memop = tcg_canonicalize_memop(memop, 1, 1);
3082     oi = make_memop_idx(memop, idx);
3083 
3084     if (!TCG_TARGET_HAS_MEMORY_BSWAP && (memop & MO_BSWAP)) {
3085         swap = tcg_temp_new_i64();
3086         switch (memop & MO_SIZE) {
3087         case MO_16:
3088             tcg_gen_bswap16_i64(swap, val, 0);
3089             break;
3090         case MO_32:
3091             tcg_gen_bswap32_i64(swap, val, 0);
3092             break;
3093         case MO_64:
3094             tcg_gen_bswap64_i64(swap, val);
3095             break;
3096         default:
3097             g_assert_not_reached();
3098         }
3099         val = swap;
3100         memop &= ~MO_BSWAP;
3101     }
3102 
3103     addr = plugin_prep_mem_callbacks(addr);
3104     gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx);
3105     plugin_gen_mem_callbacks(addr, oi, QEMU_PLUGIN_MEM_W);
3106 
3107     if (swap) {
3108         tcg_temp_free_i64(swap);
3109     }
3110 }
3111 
3112 static void canonicalize_memop_i128_as_i64(MemOp ret[2], MemOp orig)
3113 {
3114     MemOp mop_1 = orig, mop_2;
3115 
3116     tcg_debug_assert((orig & MO_SIZE) == MO_128);
3117     tcg_debug_assert((orig & MO_SIGN) == 0);
3118 
3119     /* Use a memory ordering implemented by the host. */
3120     if (!TCG_TARGET_HAS_MEMORY_BSWAP && (orig & MO_BSWAP)) {
3121         mop_1 &= ~MO_BSWAP;
3122     }
3123 
3124     /* Reduce the size to 64-bit. */
3125     mop_1 = (mop_1 & ~MO_SIZE) | MO_64;
3126 
3127     /* Retain the alignment constraints of the original. */
3128     switch (orig & MO_AMASK) {
3129     case MO_UNALN:
3130     case MO_ALIGN_2:
3131     case MO_ALIGN_4:
3132         mop_2 = mop_1;
3133         break;
3134     case MO_ALIGN_8:
3135         /* Prefer MO_ALIGN+MO_64 to MO_ALIGN_8+MO_64. */
3136         mop_1 = (mop_1 & ~MO_AMASK) | MO_ALIGN;
3137         mop_2 = mop_1;
3138         break;
3139     case MO_ALIGN:
3140         /* Second has 8-byte alignment; first has 16-byte alignment. */
3141         mop_2 = mop_1;
3142         mop_1 = (mop_1 & ~MO_AMASK) | MO_ALIGN_16;
3143         break;
3144     case MO_ALIGN_16:
3145     case MO_ALIGN_32:
3146     case MO_ALIGN_64:
3147         /* Second has 8-byte alignment; first retains original. */
3148         mop_2 = (mop_1 & ~MO_AMASK) | MO_ALIGN;
3149         break;
3150     default:
3151         g_assert_not_reached();
3152     }
3153     ret[0] = mop_1;
3154     ret[1] = mop_2;
3155 }
3156 
3157 void tcg_gen_qemu_ld_i128(TCGv_i128 val, TCGv addr, TCGArg idx, MemOp memop)
3158 {
3159     MemOp mop[2];
3160     TCGv addr_p8;
3161     TCGv_i64 x, y;
3162 
3163     canonicalize_memop_i128_as_i64(mop, memop);
3164 
3165     tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
3166     addr = plugin_prep_mem_callbacks(addr);
3167 
3168     /* TODO: respect atomicity of the operation. */
3169     /* TODO: allow the tcg backend to see the whole operation. */
3170 
3171     /*
3172      * Since there are no global TCGv_i128, there is no visible state
3173      * changed if the second load faults.  Load directly into the two
3174      * subwords.
3175      */
3176     if ((memop & MO_BSWAP) == MO_LE) {
3177         x = TCGV128_LOW(val);
3178         y = TCGV128_HIGH(val);
3179     } else {
3180         x = TCGV128_HIGH(val);
3181         y = TCGV128_LOW(val);
3182     }
3183 
3184     gen_ldst_i64(INDEX_op_qemu_ld_i64, x, addr, mop[0], idx);
3185 
3186     if ((mop[0] ^ memop) & MO_BSWAP) {
3187         tcg_gen_bswap64_i64(x, x);
3188     }
3189 
3190     addr_p8 = tcg_temp_new();
3191     tcg_gen_addi_tl(addr_p8, addr, 8);
3192     gen_ldst_i64(INDEX_op_qemu_ld_i64, y, addr_p8, mop[1], idx);
3193     tcg_temp_free(addr_p8);
3194 
3195     if ((mop[0] ^ memop) & MO_BSWAP) {
3196         tcg_gen_bswap64_i64(y, y);
3197     }
3198 
3199     plugin_gen_mem_callbacks(addr, make_memop_idx(memop, idx),
3200                              QEMU_PLUGIN_MEM_R);
3201 }
3202 
3203 void tcg_gen_qemu_st_i128(TCGv_i128 val, TCGv addr, TCGArg idx, MemOp memop)
3204 {
3205     MemOp mop[2];
3206     TCGv addr_p8;
3207     TCGv_i64 x, y;
3208 
3209     canonicalize_memop_i128_as_i64(mop, memop);
3210 
3211     tcg_gen_req_mo(TCG_MO_ST_LD | TCG_MO_ST_ST);
3212     addr = plugin_prep_mem_callbacks(addr);
3213 
3214     /* TODO: respect atomicity of the operation. */
3215     /* TODO: allow the tcg backend to see the whole operation. */
3216 
3217     if ((memop & MO_BSWAP) == MO_LE) {
3218         x = TCGV128_LOW(val);
3219         y = TCGV128_HIGH(val);
3220     } else {
3221         x = TCGV128_HIGH(val);
3222         y = TCGV128_LOW(val);
3223     }
3224 
3225     addr_p8 = tcg_temp_new();
3226     if ((mop[0] ^ memop) & MO_BSWAP) {
3227         TCGv_i64 t = tcg_temp_new_i64();
3228 
3229         tcg_gen_bswap64_i64(t, x);
3230         gen_ldst_i64(INDEX_op_qemu_st_i64, t, addr, mop[0], idx);
3231         tcg_gen_bswap64_i64(t, y);
3232         tcg_gen_addi_tl(addr_p8, addr, 8);
3233         gen_ldst_i64(INDEX_op_qemu_st_i64, t, addr_p8, mop[1], idx);
3234         tcg_temp_free_i64(t);
3235     } else {
3236         gen_ldst_i64(INDEX_op_qemu_st_i64, x, addr, mop[0], idx);
3237         tcg_gen_addi_tl(addr_p8, addr, 8);
3238         gen_ldst_i64(INDEX_op_qemu_st_i64, y, addr_p8, mop[1], idx);
3239     }
3240     tcg_temp_free(addr_p8);
3241 
3242     plugin_gen_mem_callbacks(addr, make_memop_idx(memop, idx),
3243                              QEMU_PLUGIN_MEM_W);
3244 }
3245 
3246 static void tcg_gen_ext_i32(TCGv_i32 ret, TCGv_i32 val, MemOp opc)
3247 {
3248     switch (opc & MO_SSIZE) {
3249     case MO_SB:
3250         tcg_gen_ext8s_i32(ret, val);
3251         break;
3252     case MO_UB:
3253         tcg_gen_ext8u_i32(ret, val);
3254         break;
3255     case MO_SW:
3256         tcg_gen_ext16s_i32(ret, val);
3257         break;
3258     case MO_UW:
3259         tcg_gen_ext16u_i32(ret, val);
3260         break;
3261     default:
3262         tcg_gen_mov_i32(ret, val);
3263         break;
3264     }
3265 }
3266 
3267 static void tcg_gen_ext_i64(TCGv_i64 ret, TCGv_i64 val, MemOp opc)
3268 {
3269     switch (opc & MO_SSIZE) {
3270     case MO_SB:
3271         tcg_gen_ext8s_i64(ret, val);
3272         break;
3273     case MO_UB:
3274         tcg_gen_ext8u_i64(ret, val);
3275         break;
3276     case MO_SW:
3277         tcg_gen_ext16s_i64(ret, val);
3278         break;
3279     case MO_UW:
3280         tcg_gen_ext16u_i64(ret, val);
3281         break;
3282     case MO_SL:
3283         tcg_gen_ext32s_i64(ret, val);
3284         break;
3285     case MO_UL:
3286         tcg_gen_ext32u_i64(ret, val);
3287         break;
3288     default:
3289         tcg_gen_mov_i64(ret, val);
3290         break;
3291     }
3292 }
3293 
3294 typedef void (*gen_atomic_cx_i32)(TCGv_i32, TCGv_env, TCGv,
3295                                   TCGv_i32, TCGv_i32, TCGv_i32);
3296 typedef void (*gen_atomic_cx_i64)(TCGv_i64, TCGv_env, TCGv,
3297                                   TCGv_i64, TCGv_i64, TCGv_i32);
3298 typedef void (*gen_atomic_cx_i128)(TCGv_i128, TCGv_env, TCGv,
3299                                    TCGv_i128, TCGv_i128, TCGv_i32);
3300 typedef void (*gen_atomic_op_i32)(TCGv_i32, TCGv_env, TCGv,
3301                                   TCGv_i32, TCGv_i32);
3302 typedef void (*gen_atomic_op_i64)(TCGv_i64, TCGv_env, TCGv,
3303                                   TCGv_i64, TCGv_i32);
3304 
3305 #ifdef CONFIG_ATOMIC64
3306 # define WITH_ATOMIC64(X) X,
3307 #else
3308 # define WITH_ATOMIC64(X)
3309 #endif
3310 #ifdef CONFIG_CMPXCHG128
3311 # define WITH_ATOMIC128(X) X,
3312 #else
3313 # define WITH_ATOMIC128(X)
3314 #endif
3315 
3316 static void * const table_cmpxchg[(MO_SIZE | MO_BSWAP) + 1] = {
3317     [MO_8] = gen_helper_atomic_cmpxchgb,
3318     [MO_16 | MO_LE] = gen_helper_atomic_cmpxchgw_le,
3319     [MO_16 | MO_BE] = gen_helper_atomic_cmpxchgw_be,
3320     [MO_32 | MO_LE] = gen_helper_atomic_cmpxchgl_le,
3321     [MO_32 | MO_BE] = gen_helper_atomic_cmpxchgl_be,
3322     WITH_ATOMIC64([MO_64 | MO_LE] = gen_helper_atomic_cmpxchgq_le)
3323     WITH_ATOMIC64([MO_64 | MO_BE] = gen_helper_atomic_cmpxchgq_be)
3324     WITH_ATOMIC128([MO_128 | MO_LE] = gen_helper_atomic_cmpxchgo_le)
3325     WITH_ATOMIC128([MO_128 | MO_BE] = gen_helper_atomic_cmpxchgo_be)
3326 };
3327 
3328 void tcg_gen_nonatomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, TCGv_i32 cmpv,
3329                                    TCGv_i32 newv, TCGArg idx, MemOp memop)
3330 {
3331     TCGv_i32 t1 = tcg_temp_new_i32();
3332     TCGv_i32 t2 = tcg_temp_new_i32();
3333 
3334     tcg_gen_ext_i32(t2, cmpv, memop & MO_SIZE);
3335 
3336     tcg_gen_qemu_ld_i32(t1, addr, idx, memop & ~MO_SIGN);
3337     tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, t2, newv, t1);
3338     tcg_gen_qemu_st_i32(t2, addr, idx, memop);
3339     tcg_temp_free_i32(t2);
3340 
3341     if (memop & MO_SIGN) {
3342         tcg_gen_ext_i32(retv, t1, memop);
3343     } else {
3344         tcg_gen_mov_i32(retv, t1);
3345     }
3346     tcg_temp_free_i32(t1);
3347 }
3348 
3349 void tcg_gen_atomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, TCGv_i32 cmpv,
3350                                 TCGv_i32 newv, TCGArg idx, MemOp memop)
3351 {
3352     gen_atomic_cx_i32 gen;
3353     MemOpIdx oi;
3354 
3355     if (!(tcg_ctx->gen_tb->cflags & CF_PARALLEL)) {
3356         tcg_gen_nonatomic_cmpxchg_i32(retv, addr, cmpv, newv, idx, memop);
3357         return;
3358     }
3359 
3360     memop = tcg_canonicalize_memop(memop, 0, 0);
3361     gen = table_cmpxchg[memop & (MO_SIZE | MO_BSWAP)];
3362     tcg_debug_assert(gen != NULL);
3363 
3364     oi = make_memop_idx(memop & ~MO_SIGN, idx);
3365     gen(retv, cpu_env, addr, cmpv, newv, tcg_constant_i32(oi));
3366 
3367     if (memop & MO_SIGN) {
3368         tcg_gen_ext_i32(retv, retv, memop);
3369     }
3370 }
3371 
3372 void tcg_gen_nonatomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, TCGv_i64 cmpv,
3373                                    TCGv_i64 newv, TCGArg idx, MemOp memop)
3374 {
3375     TCGv_i64 t1, t2;
3376 
3377     if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) {
3378         tcg_gen_nonatomic_cmpxchg_i32(TCGV_LOW(retv), addr, TCGV_LOW(cmpv),
3379                                       TCGV_LOW(newv), idx, memop);
3380         if (memop & MO_SIGN) {
3381             tcg_gen_sari_i32(TCGV_HIGH(retv), TCGV_LOW(retv), 31);
3382         } else {
3383             tcg_gen_movi_i32(TCGV_HIGH(retv), 0);
3384         }
3385         return;
3386     }
3387 
3388     t1 = tcg_temp_new_i64();
3389     t2 = tcg_temp_new_i64();
3390 
3391     tcg_gen_ext_i64(t2, cmpv, memop & MO_SIZE);
3392 
3393     tcg_gen_qemu_ld_i64(t1, addr, idx, memop & ~MO_SIGN);
3394     tcg_gen_movcond_i64(TCG_COND_EQ, t2, t1, t2, newv, t1);
3395     tcg_gen_qemu_st_i64(t2, addr, idx, memop);
3396     tcg_temp_free_i64(t2);
3397 
3398     if (memop & MO_SIGN) {
3399         tcg_gen_ext_i64(retv, t1, memop);
3400     } else {
3401         tcg_gen_mov_i64(retv, t1);
3402     }
3403     tcg_temp_free_i64(t1);
3404 }
3405 
3406 void tcg_gen_atomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, TCGv_i64 cmpv,
3407                                 TCGv_i64 newv, TCGArg idx, MemOp memop)
3408 {
3409     if (!(tcg_ctx->gen_tb->cflags & CF_PARALLEL)) {
3410         tcg_gen_nonatomic_cmpxchg_i64(retv, addr, cmpv, newv, idx, memop);
3411         return;
3412     }
3413 
3414     if ((memop & MO_SIZE) == MO_64) {
3415         gen_atomic_cx_i64 gen;
3416 
3417         memop = tcg_canonicalize_memop(memop, 1, 0);
3418         gen = table_cmpxchg[memop & (MO_SIZE | MO_BSWAP)];
3419         if (gen) {
3420             MemOpIdx oi = make_memop_idx(memop, idx);
3421             gen(retv, cpu_env, addr, cmpv, newv, tcg_constant_i32(oi));
3422             return;
3423         }
3424 
3425         gen_helper_exit_atomic(cpu_env);
3426 
3427         /*
3428          * Produce a result for a well-formed opcode stream.  This satisfies
3429          * liveness for set before used, which happens before this dead code
3430          * is removed.
3431          */
3432         tcg_gen_movi_i64(retv, 0);
3433         return;
3434     }
3435 
3436     if (TCG_TARGET_REG_BITS == 32) {
3437         tcg_gen_atomic_cmpxchg_i32(TCGV_LOW(retv), addr, TCGV_LOW(cmpv),
3438                                    TCGV_LOW(newv), idx, memop);
3439         if (memop & MO_SIGN) {
3440             tcg_gen_sari_i32(TCGV_HIGH(retv), TCGV_LOW(retv), 31);
3441         } else {
3442             tcg_gen_movi_i32(TCGV_HIGH(retv), 0);
3443         }
3444     } else {
3445         TCGv_i32 c32 = tcg_temp_new_i32();
3446         TCGv_i32 n32 = tcg_temp_new_i32();
3447         TCGv_i32 r32 = tcg_temp_new_i32();
3448 
3449         tcg_gen_extrl_i64_i32(c32, cmpv);
3450         tcg_gen_extrl_i64_i32(n32, newv);
3451         tcg_gen_atomic_cmpxchg_i32(r32, addr, c32, n32, idx, memop & ~MO_SIGN);
3452         tcg_temp_free_i32(c32);
3453         tcg_temp_free_i32(n32);
3454 
3455         tcg_gen_extu_i32_i64(retv, r32);
3456         tcg_temp_free_i32(r32);
3457 
3458         if (memop & MO_SIGN) {
3459             tcg_gen_ext_i64(retv, retv, memop);
3460         }
3461     }
3462 }
3463 
3464 void tcg_gen_nonatomic_cmpxchg_i128(TCGv_i128 retv, TCGv addr, TCGv_i128 cmpv,
3465                                     TCGv_i128 newv, TCGArg idx, MemOp memop)
3466 {
3467     if (TCG_TARGET_REG_BITS == 32) {
3468         /* Inline expansion below is simply too large for 32-bit hosts. */
3469         gen_atomic_cx_i128 gen = ((memop & MO_BSWAP) == MO_LE
3470                                   ? gen_helper_nonatomic_cmpxchgo_le
3471                                   : gen_helper_nonatomic_cmpxchgo_be);
3472         MemOpIdx oi = make_memop_idx(memop, idx);
3473 
3474         tcg_debug_assert((memop & MO_SIZE) == MO_128);
3475         tcg_debug_assert((memop & MO_SIGN) == 0);
3476 
3477         gen(retv, cpu_env, addr, cmpv, newv, tcg_constant_i32(oi));
3478     } else {
3479         TCGv_i128 oldv = tcg_temp_new_i128();
3480         TCGv_i128 tmpv = tcg_temp_new_i128();
3481         TCGv_i64 t0 = tcg_temp_new_i64();
3482         TCGv_i64 t1 = tcg_temp_new_i64();
3483         TCGv_i64 z = tcg_constant_i64(0);
3484 
3485         tcg_gen_qemu_ld_i128(oldv, addr, idx, memop);
3486 
3487         /* Compare i128 */
3488         tcg_gen_xor_i64(t0, TCGV128_LOW(oldv), TCGV128_LOW(cmpv));
3489         tcg_gen_xor_i64(t1, TCGV128_HIGH(oldv), TCGV128_HIGH(cmpv));
3490         tcg_gen_or_i64(t0, t0, t1);
3491 
3492         /* tmpv = equal ? newv : oldv */
3493         tcg_gen_movcond_i64(TCG_COND_EQ, TCGV128_LOW(tmpv), t0, z,
3494                             TCGV128_LOW(newv), TCGV128_LOW(oldv));
3495         tcg_gen_movcond_i64(TCG_COND_EQ, TCGV128_HIGH(tmpv), t0, z,
3496                             TCGV128_HIGH(newv), TCGV128_HIGH(oldv));
3497 
3498         /* Unconditional writeback. */
3499         tcg_gen_qemu_st_i128(tmpv, addr, idx, memop);
3500         tcg_gen_mov_i128(retv, oldv);
3501 
3502         tcg_temp_free_i64(t0);
3503         tcg_temp_free_i64(t1);
3504         tcg_temp_free_i128(tmpv);
3505         tcg_temp_free_i128(oldv);
3506     }
3507 }
3508 
3509 void tcg_gen_atomic_cmpxchg_i128(TCGv_i128 retv, TCGv addr, TCGv_i128 cmpv,
3510                                  TCGv_i128 newv, TCGArg idx, MemOp memop)
3511 {
3512     gen_atomic_cx_i128 gen;
3513 
3514     if (!(tcg_ctx->gen_tb->cflags & CF_PARALLEL)) {
3515         tcg_gen_nonatomic_cmpxchg_i128(retv, addr, cmpv, newv, idx, memop);
3516         return;
3517     }
3518 
3519     tcg_debug_assert((memop & MO_SIZE) == MO_128);
3520     tcg_debug_assert((memop & MO_SIGN) == 0);
3521     gen = table_cmpxchg[memop & (MO_SIZE | MO_BSWAP)];
3522 
3523     if (gen) {
3524         MemOpIdx oi = make_memop_idx(memop, idx);
3525         gen(retv, cpu_env, addr, cmpv, newv, tcg_constant_i32(oi));
3526         return;
3527     }
3528 
3529     gen_helper_exit_atomic(cpu_env);
3530 
3531     /*
3532      * Produce a result for a well-formed opcode stream.  This satisfies
3533      * liveness for set before used, which happens before this dead code
3534      * is removed.
3535      */
3536     tcg_gen_movi_i64(TCGV128_LOW(retv), 0);
3537     tcg_gen_movi_i64(TCGV128_HIGH(retv), 0);
3538 }
3539 
3540 static void do_nonatomic_op_i32(TCGv_i32 ret, TCGv addr, TCGv_i32 val,
3541                                 TCGArg idx, MemOp memop, bool new_val,
3542                                 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
3543 {
3544     TCGv_i32 t1 = tcg_temp_new_i32();
3545     TCGv_i32 t2 = tcg_temp_new_i32();
3546 
3547     memop = tcg_canonicalize_memop(memop, 0, 0);
3548 
3549     tcg_gen_qemu_ld_i32(t1, addr, idx, memop);
3550     tcg_gen_ext_i32(t2, val, memop);
3551     gen(t2, t1, t2);
3552     tcg_gen_qemu_st_i32(t2, addr, idx, memop);
3553 
3554     tcg_gen_ext_i32(ret, (new_val ? t2 : t1), memop);
3555     tcg_temp_free_i32(t1);
3556     tcg_temp_free_i32(t2);
3557 }
3558 
3559 static void do_atomic_op_i32(TCGv_i32 ret, TCGv addr, TCGv_i32 val,
3560                              TCGArg idx, MemOp memop, void * const table[])
3561 {
3562     gen_atomic_op_i32 gen;
3563     MemOpIdx oi;
3564 
3565     memop = tcg_canonicalize_memop(memop, 0, 0);
3566 
3567     gen = table[memop & (MO_SIZE | MO_BSWAP)];
3568     tcg_debug_assert(gen != NULL);
3569 
3570     oi = make_memop_idx(memop & ~MO_SIGN, idx);
3571     gen(ret, cpu_env, addr, val, tcg_constant_i32(oi));
3572 
3573     if (memop & MO_SIGN) {
3574         tcg_gen_ext_i32(ret, ret, memop);
3575     }
3576 }
3577 
3578 static void do_nonatomic_op_i64(TCGv_i64 ret, TCGv addr, TCGv_i64 val,
3579                                 TCGArg idx, MemOp memop, bool new_val,
3580                                 void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
3581 {
3582     TCGv_i64 t1 = tcg_temp_new_i64();
3583     TCGv_i64 t2 = tcg_temp_new_i64();
3584 
3585     memop = tcg_canonicalize_memop(memop, 1, 0);
3586 
3587     tcg_gen_qemu_ld_i64(t1, addr, idx, memop);
3588     tcg_gen_ext_i64(t2, val, memop);
3589     gen(t2, t1, t2);
3590     tcg_gen_qemu_st_i64(t2, addr, idx, memop);
3591 
3592     tcg_gen_ext_i64(ret, (new_val ? t2 : t1), memop);
3593     tcg_temp_free_i64(t1);
3594     tcg_temp_free_i64(t2);
3595 }
3596 
3597 static void do_atomic_op_i64(TCGv_i64 ret, TCGv addr, TCGv_i64 val,
3598                              TCGArg idx, MemOp memop, void * const table[])
3599 {
3600     memop = tcg_canonicalize_memop(memop, 1, 0);
3601 
3602     if ((memop & MO_SIZE) == MO_64) {
3603 #ifdef CONFIG_ATOMIC64
3604         gen_atomic_op_i64 gen;
3605         MemOpIdx oi;
3606 
3607         gen = table[memop & (MO_SIZE | MO_BSWAP)];
3608         tcg_debug_assert(gen != NULL);
3609 
3610         oi = make_memop_idx(memop & ~MO_SIGN, idx);
3611         gen(ret, cpu_env, addr, val, tcg_constant_i32(oi));
3612 #else
3613         gen_helper_exit_atomic(cpu_env);
3614         /* Produce a result, so that we have a well-formed opcode stream
3615            with respect to uses of the result in the (dead) code following.  */
3616         tcg_gen_movi_i64(ret, 0);
3617 #endif /* CONFIG_ATOMIC64 */
3618     } else {
3619         TCGv_i32 v32 = tcg_temp_new_i32();
3620         TCGv_i32 r32 = tcg_temp_new_i32();
3621 
3622         tcg_gen_extrl_i64_i32(v32, val);
3623         do_atomic_op_i32(r32, addr, v32, idx, memop & ~MO_SIGN, table);
3624         tcg_temp_free_i32(v32);
3625 
3626         tcg_gen_extu_i32_i64(ret, r32);
3627         tcg_temp_free_i32(r32);
3628 
3629         if (memop & MO_SIGN) {
3630             tcg_gen_ext_i64(ret, ret, memop);
3631         }
3632     }
3633 }
3634 
3635 #define GEN_ATOMIC_HELPER(NAME, OP, NEW)                                \
3636 static void * const table_##NAME[(MO_SIZE | MO_BSWAP) + 1] = {          \
3637     [MO_8] = gen_helper_atomic_##NAME##b,                               \
3638     [MO_16 | MO_LE] = gen_helper_atomic_##NAME##w_le,                   \
3639     [MO_16 | MO_BE] = gen_helper_atomic_##NAME##w_be,                   \
3640     [MO_32 | MO_LE] = gen_helper_atomic_##NAME##l_le,                   \
3641     [MO_32 | MO_BE] = gen_helper_atomic_##NAME##l_be,                   \
3642     WITH_ATOMIC64([MO_64 | MO_LE] = gen_helper_atomic_##NAME##q_le)     \
3643     WITH_ATOMIC64([MO_64 | MO_BE] = gen_helper_atomic_##NAME##q_be)     \
3644 };                                                                      \
3645 void tcg_gen_atomic_##NAME##_i32                                        \
3646     (TCGv_i32 ret, TCGv addr, TCGv_i32 val, TCGArg idx, MemOp memop)    \
3647 {                                                                       \
3648     if (tcg_ctx->gen_tb->cflags & CF_PARALLEL) {                        \
3649         do_atomic_op_i32(ret, addr, val, idx, memop, table_##NAME);     \
3650     } else {                                                            \
3651         do_nonatomic_op_i32(ret, addr, val, idx, memop, NEW,            \
3652                             tcg_gen_##OP##_i32);                        \
3653     }                                                                   \
3654 }                                                                       \
3655 void tcg_gen_atomic_##NAME##_i64                                        \
3656     (TCGv_i64 ret, TCGv addr, TCGv_i64 val, TCGArg idx, MemOp memop)    \
3657 {                                                                       \
3658     if (tcg_ctx->gen_tb->cflags & CF_PARALLEL) {                        \
3659         do_atomic_op_i64(ret, addr, val, idx, memop, table_##NAME);     \
3660     } else {                                                            \
3661         do_nonatomic_op_i64(ret, addr, val, idx, memop, NEW,            \
3662                             tcg_gen_##OP##_i64);                        \
3663     }                                                                   \
3664 }
3665 
3666 GEN_ATOMIC_HELPER(fetch_add, add, 0)
3667 GEN_ATOMIC_HELPER(fetch_and, and, 0)
3668 GEN_ATOMIC_HELPER(fetch_or, or, 0)
3669 GEN_ATOMIC_HELPER(fetch_xor, xor, 0)
3670 GEN_ATOMIC_HELPER(fetch_smin, smin, 0)
3671 GEN_ATOMIC_HELPER(fetch_umin, umin, 0)
3672 GEN_ATOMIC_HELPER(fetch_smax, smax, 0)
3673 GEN_ATOMIC_HELPER(fetch_umax, umax, 0)
3674 
3675 GEN_ATOMIC_HELPER(add_fetch, add, 1)
3676 GEN_ATOMIC_HELPER(and_fetch, and, 1)
3677 GEN_ATOMIC_HELPER(or_fetch, or, 1)
3678 GEN_ATOMIC_HELPER(xor_fetch, xor, 1)
3679 GEN_ATOMIC_HELPER(smin_fetch, smin, 1)
3680 GEN_ATOMIC_HELPER(umin_fetch, umin, 1)
3681 GEN_ATOMIC_HELPER(smax_fetch, smax, 1)
3682 GEN_ATOMIC_HELPER(umax_fetch, umax, 1)
3683 
3684 static void tcg_gen_mov2_i32(TCGv_i32 r, TCGv_i32 a, TCGv_i32 b)
3685 {
3686     tcg_gen_mov_i32(r, b);
3687 }
3688 
3689 static void tcg_gen_mov2_i64(TCGv_i64 r, TCGv_i64 a, TCGv_i64 b)
3690 {
3691     tcg_gen_mov_i64(r, b);
3692 }
3693 
3694 GEN_ATOMIC_HELPER(xchg, mov2, 0)
3695 
3696 #undef GEN_ATOMIC_HELPER
3697