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