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