xref: /openbmc/qemu/tcg/tcg-op.c (revision 1551004e)
1951c6300SRichard Henderson /*
2951c6300SRichard Henderson  * Tiny Code Generator for QEMU
3951c6300SRichard Henderson  *
4951c6300SRichard Henderson  * Copyright (c) 2008 Fabrice Bellard
5951c6300SRichard Henderson  *
6951c6300SRichard Henderson  * Permission is hereby granted, free of charge, to any person obtaining a copy
7951c6300SRichard Henderson  * of this software and associated documentation files (the "Software"), to deal
8951c6300SRichard Henderson  * in the Software without restriction, including without limitation the rights
9951c6300SRichard Henderson  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10951c6300SRichard Henderson  * copies of the Software, and to permit persons to whom the Software is
11951c6300SRichard Henderson  * furnished to do so, subject to the following conditions:
12951c6300SRichard Henderson  *
13951c6300SRichard Henderson  * The above copyright notice and this permission notice shall be included in
14951c6300SRichard Henderson  * all copies or substantial portions of the Software.
15951c6300SRichard Henderson  *
16951c6300SRichard Henderson  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17951c6300SRichard Henderson  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18951c6300SRichard Henderson  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19951c6300SRichard Henderson  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20951c6300SRichard Henderson  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21951c6300SRichard Henderson  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22951c6300SRichard Henderson  * THE SOFTWARE.
23951c6300SRichard Henderson  */
24951c6300SRichard Henderson 
25757e725bSPeter Maydell #include "qemu/osdep.h"
26dcb32f1dSPhilippe Mathieu-Daudé #include "tcg/tcg.h"
2747f7313dSRichard Henderson #include "tcg/tcg-temp-internal.h"
28ad3d0e4dSRichard Henderson #include "tcg/tcg-op-common.h"
29cac9b0fdSRichard Henderson #include "exec/translation-block.h"
30e6d86bedSEmilio G. Cota #include "exec/plugin-gen.h"
31d56fea79SRichard Henderson #include "tcg-internal.h"
32951c6300SRichard Henderson 
33951c6300SRichard Henderson 
34ecfa1877SRichard Henderson /*
35ecfa1877SRichard Henderson  * Encourage the compiler to tail-call to a function, rather than inlining.
36ecfa1877SRichard Henderson  * Minimizes code size across 99 bottles of beer on the wall.
37ecfa1877SRichard Henderson  */
38ecfa1877SRichard Henderson #define NI  __attribute__((noinline))
39ecfa1877SRichard Henderson 
tcg_gen_op1(TCGOpcode opc,TCGArg a1)40ecfa1877SRichard Henderson void NI tcg_gen_op1(TCGOpcode opc, TCGArg a1)
41951c6300SRichard Henderson {
42d4478943SPhilippe Mathieu-Daudé     TCGOp *op = tcg_emit_op(opc, 1);
4375e8b9b7SRichard Henderson     op->args[0] = a1;
44951c6300SRichard Henderson }
45951c6300SRichard Henderson 
tcg_gen_op2(TCGOpcode opc,TCGArg a1,TCGArg a2)46ecfa1877SRichard Henderson void NI tcg_gen_op2(TCGOpcode opc, TCGArg a1, TCGArg a2)
47951c6300SRichard Henderson {
48d4478943SPhilippe Mathieu-Daudé     TCGOp *op = tcg_emit_op(opc, 2);
4975e8b9b7SRichard Henderson     op->args[0] = a1;
5075e8b9b7SRichard Henderson     op->args[1] = a2;
51951c6300SRichard Henderson }
52951c6300SRichard Henderson 
tcg_gen_op3(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3)53ecfa1877SRichard Henderson void NI tcg_gen_op3(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3)
54951c6300SRichard Henderson {
55d4478943SPhilippe Mathieu-Daudé     TCGOp *op = tcg_emit_op(opc, 3);
5675e8b9b7SRichard Henderson     op->args[0] = a1;
5775e8b9b7SRichard Henderson     op->args[1] = a2;
5875e8b9b7SRichard Henderson     op->args[2] = a3;
59951c6300SRichard Henderson }
60951c6300SRichard Henderson 
tcg_gen_op4(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3,TCGArg a4)61ecfa1877SRichard Henderson void NI tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3, TCGArg a4)
62951c6300SRichard Henderson {
63d4478943SPhilippe Mathieu-Daudé     TCGOp *op = tcg_emit_op(opc, 4);
6475e8b9b7SRichard Henderson     op->args[0] = a1;
6575e8b9b7SRichard Henderson     op->args[1] = a2;
6675e8b9b7SRichard Henderson     op->args[2] = a3;
6775e8b9b7SRichard Henderson     op->args[3] = a4;
68951c6300SRichard Henderson }
69951c6300SRichard Henderson 
tcg_gen_op5(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3,TCGArg a4,TCGArg a5)70ecfa1877SRichard Henderson void NI tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
71b7e8b17aSRichard Henderson                      TCGArg a4, TCGArg a5)
72951c6300SRichard Henderson {
73d4478943SPhilippe Mathieu-Daudé     TCGOp *op = tcg_emit_op(opc, 5);
7475e8b9b7SRichard Henderson     op->args[0] = a1;
7575e8b9b7SRichard Henderson     op->args[1] = a2;
7675e8b9b7SRichard Henderson     op->args[2] = a3;
7775e8b9b7SRichard Henderson     op->args[3] = a4;
7875e8b9b7SRichard Henderson     op->args[4] = a5;
79951c6300SRichard Henderson }
80951c6300SRichard Henderson 
tcg_gen_op6(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3,TCGArg a4,TCGArg a5,TCGArg a6)81ecfa1877SRichard Henderson void NI tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
82b7e8b17aSRichard Henderson                      TCGArg a4, TCGArg a5, TCGArg a6)
83951c6300SRichard Henderson {
84d4478943SPhilippe Mathieu-Daudé     TCGOp *op = tcg_emit_op(opc, 6);
8575e8b9b7SRichard Henderson     op->args[0] = a1;
8675e8b9b7SRichard Henderson     op->args[1] = a2;
8775e8b9b7SRichard Henderson     op->args[2] = a3;
8875e8b9b7SRichard Henderson     op->args[3] = a4;
8975e8b9b7SRichard Henderson     op->args[4] = a5;
9075e8b9b7SRichard Henderson     op->args[5] = a6;
91951c6300SRichard Henderson }
92951c6300SRichard Henderson 
936fc75d50SRichard Henderson /*
946fc75d50SRichard Henderson  * With CONFIG_DEBUG_TCG, tcgv_*_tmp via tcgv_*_arg, is an out-of-line
956fc75d50SRichard Henderson  * assertion check.  Force tail calls to avoid too much code expansion.
966fc75d50SRichard Henderson  */
976fc75d50SRichard Henderson #ifdef CONFIG_DEBUG_TCG
986fc75d50SRichard Henderson # define DNI NI
996fc75d50SRichard Henderson #else
1006fc75d50SRichard Henderson # define DNI
1016fc75d50SRichard Henderson #endif
1026fc75d50SRichard Henderson 
tcg_gen_op1_i32(TCGOpcode opc,TCGv_i32 a1)10317b9fadbSRichard Henderson static void DNI tcg_gen_op1_i32(TCGOpcode opc, TCGv_i32 a1)
1046fc75d50SRichard Henderson {
1056fc75d50SRichard Henderson     tcg_gen_op1(opc, tcgv_i32_arg(a1));
1066fc75d50SRichard Henderson }
1076fc75d50SRichard Henderson 
tcg_gen_op1_i64(TCGOpcode opc,TCGv_i64 a1)10817b9fadbSRichard Henderson static void DNI tcg_gen_op1_i64(TCGOpcode opc, TCGv_i64 a1)
1096fc75d50SRichard Henderson {
1106fc75d50SRichard Henderson     tcg_gen_op1(opc, tcgv_i64_arg(a1));
1116fc75d50SRichard Henderson }
1126fc75d50SRichard Henderson 
tcg_gen_op1i(TCGOpcode opc,TCGArg a1)11317b9fadbSRichard Henderson static void DNI tcg_gen_op1i(TCGOpcode opc, TCGArg a1)
1146fc75d50SRichard Henderson {
1156fc75d50SRichard Henderson     tcg_gen_op1(opc, a1);
1166fc75d50SRichard Henderson }
1176fc75d50SRichard Henderson 
tcg_gen_op2_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2)11817b9fadbSRichard Henderson static void DNI tcg_gen_op2_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2)
1196fc75d50SRichard Henderson {
1206fc75d50SRichard Henderson     tcg_gen_op2(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2));
1216fc75d50SRichard Henderson }
1226fc75d50SRichard Henderson 
tcg_gen_op2_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2)12317b9fadbSRichard Henderson static void DNI tcg_gen_op2_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2)
1246fc75d50SRichard Henderson {
1256fc75d50SRichard Henderson     tcg_gen_op2(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2));
1266fc75d50SRichard Henderson }
1276fc75d50SRichard Henderson 
tcg_gen_op3_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3)12817b9fadbSRichard Henderson static void DNI tcg_gen_op3_i32(TCGOpcode opc, TCGv_i32 a1,
12917b9fadbSRichard Henderson                                 TCGv_i32 a2, TCGv_i32 a3)
1306fc75d50SRichard Henderson {
1316fc75d50SRichard Henderson     tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), tcgv_i32_arg(a3));
1326fc75d50SRichard Henderson }
1336fc75d50SRichard Henderson 
tcg_gen_op3_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3)13417b9fadbSRichard Henderson static void DNI tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 a1,
13517b9fadbSRichard Henderson                                 TCGv_i64 a2, TCGv_i64 a3)
1366fc75d50SRichard Henderson {
1376fc75d50SRichard Henderson     tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), tcgv_i64_arg(a3));
1386fc75d50SRichard Henderson }
1396fc75d50SRichard Henderson 
tcg_gen_op3i_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGArg a3)14017b9fadbSRichard Henderson static void DNI tcg_gen_op3i_i32(TCGOpcode opc, TCGv_i32 a1,
14117b9fadbSRichard Henderson                                  TCGv_i32 a2, TCGArg a3)
1426fc75d50SRichard Henderson {
1436fc75d50SRichard Henderson     tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3);
1446fc75d50SRichard Henderson }
1456fc75d50SRichard Henderson 
tcg_gen_op3i_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGArg a3)14617b9fadbSRichard Henderson static void DNI tcg_gen_op3i_i64(TCGOpcode opc, TCGv_i64 a1,
14717b9fadbSRichard Henderson                                  TCGv_i64 a2, TCGArg a3)
1486fc75d50SRichard Henderson {
1496fc75d50SRichard Henderson     tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3);
1506fc75d50SRichard Henderson }
1516fc75d50SRichard Henderson 
tcg_gen_ldst_op_i32(TCGOpcode opc,TCGv_i32 val,TCGv_ptr base,TCGArg offset)15217b9fadbSRichard Henderson static void DNI tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val,
1536fc75d50SRichard Henderson                                     TCGv_ptr base, TCGArg offset)
1546fc75d50SRichard Henderson {
1556fc75d50SRichard Henderson     tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_ptr_arg(base), offset);
1566fc75d50SRichard Henderson }
1576fc75d50SRichard Henderson 
tcg_gen_ldst_op_i64(TCGOpcode opc,TCGv_i64 val,TCGv_ptr base,TCGArg offset)15817b9fadbSRichard Henderson static void DNI tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val,
1596fc75d50SRichard Henderson                                     TCGv_ptr base, TCGArg offset)
1606fc75d50SRichard Henderson {
1616fc75d50SRichard Henderson     tcg_gen_op3(opc, tcgv_i64_arg(val), tcgv_ptr_arg(base), offset);
1626fc75d50SRichard Henderson }
1636fc75d50SRichard Henderson 
tcg_gen_op4_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4)16417b9fadbSRichard Henderson static void DNI tcg_gen_op4_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1656fc75d50SRichard Henderson                                 TCGv_i32 a3, TCGv_i32 a4)
1666fc75d50SRichard Henderson {
1676fc75d50SRichard Henderson     tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1686fc75d50SRichard Henderson                 tcgv_i32_arg(a3), tcgv_i32_arg(a4));
1696fc75d50SRichard Henderson }
1706fc75d50SRichard Henderson 
tcg_gen_op4_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4)17117b9fadbSRichard Henderson static void DNI tcg_gen_op4_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1726fc75d50SRichard Henderson                                 TCGv_i64 a3, TCGv_i64 a4)
1736fc75d50SRichard Henderson {
1746fc75d50SRichard Henderson     tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1756fc75d50SRichard Henderson                 tcgv_i64_arg(a3), tcgv_i64_arg(a4));
1766fc75d50SRichard Henderson }
1776fc75d50SRichard Henderson 
tcg_gen_op4i_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGArg a4)17817b9fadbSRichard Henderson static void DNI tcg_gen_op4i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1796fc75d50SRichard Henderson                                  TCGv_i32 a3, TCGArg a4)
1806fc75d50SRichard Henderson {
1816fc75d50SRichard Henderson     tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1826fc75d50SRichard Henderson                 tcgv_i32_arg(a3), a4);
1836fc75d50SRichard Henderson }
1846fc75d50SRichard Henderson 
tcg_gen_op4i_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGArg a4)18517b9fadbSRichard Henderson static void DNI tcg_gen_op4i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1866fc75d50SRichard Henderson                                  TCGv_i64 a3, TCGArg a4)
1876fc75d50SRichard Henderson {
1886fc75d50SRichard Henderson     tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1896fc75d50SRichard Henderson                 tcgv_i64_arg(a3), a4);
1906fc75d50SRichard Henderson }
1916fc75d50SRichard Henderson 
tcg_gen_op4ii_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGArg a3,TCGArg a4)19217b9fadbSRichard Henderson static void DNI tcg_gen_op4ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1936fc75d50SRichard Henderson                                   TCGArg a3, TCGArg a4)
1946fc75d50SRichard Henderson {
1956fc75d50SRichard Henderson     tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3, a4);
1966fc75d50SRichard Henderson }
1976fc75d50SRichard Henderson 
tcg_gen_op4ii_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGArg a3,TCGArg a4)19817b9fadbSRichard Henderson static void DNI tcg_gen_op4ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1996fc75d50SRichard Henderson                                   TCGArg a3, TCGArg a4)
2006fc75d50SRichard Henderson {
2016fc75d50SRichard Henderson     tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3, a4);
2026fc75d50SRichard Henderson }
2036fc75d50SRichard Henderson 
tcg_gen_op5_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGv_i32 a5)20417b9fadbSRichard Henderson static void DNI tcg_gen_op5_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
2056fc75d50SRichard Henderson                                 TCGv_i32 a3, TCGv_i32 a4, TCGv_i32 a5)
2066fc75d50SRichard Henderson {
2076fc75d50SRichard Henderson     tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2086fc75d50SRichard Henderson                 tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5));
2096fc75d50SRichard Henderson }
2106fc75d50SRichard Henderson 
tcg_gen_op5_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4,TCGv_i64 a5)21117b9fadbSRichard Henderson static void DNI tcg_gen_op5_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
2126fc75d50SRichard Henderson                                 TCGv_i64 a3, TCGv_i64 a4, TCGv_i64 a5)
2136fc75d50SRichard Henderson {
2146fc75d50SRichard Henderson     tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
2156fc75d50SRichard Henderson                 tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5));
2166fc75d50SRichard Henderson }
2176fc75d50SRichard Henderson 
tcg_gen_op5ii_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGArg a4,TCGArg a5)21817b9fadbSRichard Henderson static void DNI tcg_gen_op5ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
2196fc75d50SRichard Henderson                                   TCGv_i32 a3, TCGArg a4, TCGArg a5)
2206fc75d50SRichard Henderson {
2216fc75d50SRichard Henderson     tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2226fc75d50SRichard Henderson                 tcgv_i32_arg(a3), a4, a5);
2236fc75d50SRichard Henderson }
2246fc75d50SRichard Henderson 
tcg_gen_op5ii_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGArg a4,TCGArg a5)22517b9fadbSRichard Henderson static void DNI tcg_gen_op5ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
2266fc75d50SRichard Henderson                                   TCGv_i64 a3, TCGArg a4, TCGArg a5)
2276fc75d50SRichard Henderson {
2286fc75d50SRichard Henderson     tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
2296fc75d50SRichard Henderson                 tcgv_i64_arg(a3), a4, a5);
2306fc75d50SRichard Henderson }
2316fc75d50SRichard Henderson 
tcg_gen_op6_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGv_i32 a5,TCGv_i32 a6)23217b9fadbSRichard Henderson static void DNI tcg_gen_op6_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
23317b9fadbSRichard Henderson                                 TCGv_i32 a3, TCGv_i32 a4,
23417b9fadbSRichard Henderson                                 TCGv_i32 a5, TCGv_i32 a6)
2356fc75d50SRichard Henderson {
2366fc75d50SRichard Henderson     tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2376fc75d50SRichard Henderson                 tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5),
2386fc75d50SRichard Henderson                 tcgv_i32_arg(a6));
2396fc75d50SRichard Henderson }
2406fc75d50SRichard Henderson 
tcg_gen_op6_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4,TCGv_i64 a5,TCGv_i64 a6)24117b9fadbSRichard Henderson static void DNI tcg_gen_op6_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
24217b9fadbSRichard Henderson                                 TCGv_i64 a3, TCGv_i64 a4,
24317b9fadbSRichard Henderson                                 TCGv_i64 a5, TCGv_i64 a6)
2446fc75d50SRichard Henderson {
2456fc75d50SRichard Henderson     tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
2466fc75d50SRichard Henderson                 tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5),
2476fc75d50SRichard Henderson                 tcgv_i64_arg(a6));
2486fc75d50SRichard Henderson }
2496fc75d50SRichard Henderson 
tcg_gen_op6i_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGv_i32 a5,TCGArg a6)25017b9fadbSRichard Henderson static void DNI tcg_gen_op6i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
25117b9fadbSRichard Henderson                                  TCGv_i32 a3, TCGv_i32 a4,
25217b9fadbSRichard Henderson                                  TCGv_i32 a5, TCGArg a6)
2536fc75d50SRichard Henderson {
2546fc75d50SRichard Henderson     tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2556fc75d50SRichard Henderson                 tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5), a6);
2566fc75d50SRichard Henderson }
2576fc75d50SRichard Henderson 
tcg_gen_op6i_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4,TCGv_i64 a5,TCGArg a6)25817b9fadbSRichard Henderson static void DNI tcg_gen_op6i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
25917b9fadbSRichard Henderson                                  TCGv_i64 a3, TCGv_i64 a4,
26017b9fadbSRichard Henderson                                  TCGv_i64 a5, TCGArg a6)
2616fc75d50SRichard Henderson {
2626fc75d50SRichard Henderson     tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
2636fc75d50SRichard Henderson                 tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5), a6);
2646fc75d50SRichard Henderson }
2656fc75d50SRichard Henderson 
tcg_gen_op6ii_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGArg a5,TCGArg a6)26617b9fadbSRichard Henderson static void DNI tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
26717b9fadbSRichard Henderson                                   TCGv_i32 a3, TCGv_i32 a4,
26817b9fadbSRichard Henderson                                   TCGArg a5, TCGArg a6)
2696fc75d50SRichard Henderson {
2706fc75d50SRichard Henderson     tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2716fc75d50SRichard Henderson                 tcgv_i32_arg(a3), tcgv_i32_arg(a4), a5, a6);
2726fc75d50SRichard Henderson }
2736fc75d50SRichard Henderson 
274f85b1fc4SRichard Henderson /* Generic ops.  */
275f85b1fc4SRichard Henderson 
gen_set_label(TCGLabel * l)27601bbb6e3SRichard Henderson void gen_set_label(TCGLabel *l)
27701bbb6e3SRichard Henderson {
27801bbb6e3SRichard Henderson     l->present = 1;
27901bbb6e3SRichard Henderson     tcg_gen_op1(INDEX_op_set_label, label_arg(l));
28001bbb6e3SRichard Henderson }
28101bbb6e3SRichard Henderson 
add_last_as_label_use(TCGLabel * l)282f85b1fc4SRichard Henderson static void add_last_as_label_use(TCGLabel *l)
283f85b1fc4SRichard Henderson {
284f85b1fc4SRichard Henderson     TCGLabelUse *u = tcg_malloc(sizeof(TCGLabelUse));
285f85b1fc4SRichard Henderson 
286f85b1fc4SRichard Henderson     u->op = tcg_last_op();
287f85b1fc4SRichard Henderson     QSIMPLEQ_INSERT_TAIL(&l->branches, u, next);
288f85b1fc4SRichard Henderson }
289f85b1fc4SRichard Henderson 
tcg_gen_br(TCGLabel * l)290f85b1fc4SRichard Henderson void tcg_gen_br(TCGLabel *l)
291f85b1fc4SRichard Henderson {
292f85b1fc4SRichard Henderson     tcg_gen_op1(INDEX_op_br, label_arg(l));
293f85b1fc4SRichard Henderson     add_last_as_label_use(l);
294f85b1fc4SRichard Henderson }
295f85b1fc4SRichard Henderson 
tcg_gen_mb(TCGBar mb_type)296f65e19bcSPranith Kumar void tcg_gen_mb(TCGBar mb_type)
297f65e19bcSPranith Kumar {
298c914d46dSRichard Henderson #ifdef CONFIG_USER_ONLY
299c914d46dSRichard Henderson     bool parallel = tcg_ctx->gen_tb->cflags & CF_PARALLEL;
300c914d46dSRichard Henderson #else
301c914d46dSRichard Henderson     /*
302c914d46dSRichard Henderson      * It is tempting to elide the barrier in a uniprocessor context.
303c914d46dSRichard Henderson      * However, even with a single cpu we have i/o threads running in
304c914d46dSRichard Henderson      * parallel, and lack of memory order can result in e.g. virtio
305c914d46dSRichard Henderson      * queue entries being read incorrectly.
306c914d46dSRichard Henderson      */
307c914d46dSRichard Henderson     bool parallel = true;
308c914d46dSRichard Henderson #endif
309c914d46dSRichard Henderson 
310c914d46dSRichard Henderson     if (parallel) {
311b7e8b17aSRichard Henderson         tcg_gen_op1(INDEX_op_mb, mb_type);
312f65e19bcSPranith Kumar     }
313f65e19bcSPranith Kumar }
314f65e19bcSPranith Kumar 
tcg_gen_plugin_cb_start(unsigned from,unsigned type,unsigned wr)31501bbb6e3SRichard Henderson void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr)
31601bbb6e3SRichard Henderson {
31701bbb6e3SRichard Henderson     tcg_gen_op3(INDEX_op_plugin_cb_start, from, type, wr);
31801bbb6e3SRichard Henderson }
31901bbb6e3SRichard Henderson 
tcg_gen_plugin_cb_end(void)32001bbb6e3SRichard Henderson void tcg_gen_plugin_cb_end(void)
32101bbb6e3SRichard Henderson {
32201bbb6e3SRichard Henderson     tcg_emit_op(INDEX_op_plugin_cb_end, 0);
32301bbb6e3SRichard Henderson }
32401bbb6e3SRichard Henderson 
325951c6300SRichard Henderson /* 32 bit ops */
326951c6300SRichard Henderson 
tcg_gen_discard_i32(TCGv_i32 arg)32709607d35SRichard Henderson void tcg_gen_discard_i32(TCGv_i32 arg)
32809607d35SRichard Henderson {
32909607d35SRichard Henderson     tcg_gen_op1_i32(INDEX_op_discard, arg);
33009607d35SRichard Henderson }
33109607d35SRichard Henderson 
tcg_gen_mov_i32(TCGv_i32 ret,TCGv_i32 arg)33209607d35SRichard Henderson void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
33309607d35SRichard Henderson {
33409607d35SRichard Henderson     if (ret != arg) {
33509607d35SRichard Henderson         tcg_gen_op2_i32(INDEX_op_mov_i32, ret, arg);
33609607d35SRichard Henderson     }
33709607d35SRichard Henderson }
33809607d35SRichard Henderson 
tcg_gen_movi_i32(TCGv_i32 ret,int32_t arg)33911d11d61SRichard Henderson void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg)
34011d11d61SRichard Henderson {
34111d11d61SRichard Henderson     tcg_gen_mov_i32(ret, tcg_constant_i32(arg));
34211d11d61SRichard Henderson }
34311d11d61SRichard Henderson 
tcg_gen_add_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)34409607d35SRichard Henderson void tcg_gen_add_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
34509607d35SRichard Henderson {
34609607d35SRichard Henderson     tcg_gen_op3_i32(INDEX_op_add_i32, ret, arg1, arg2);
34709607d35SRichard Henderson }
34809607d35SRichard Henderson 
tcg_gen_addi_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)349951c6300SRichard Henderson void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
350951c6300SRichard Henderson {
351951c6300SRichard Henderson     /* some cases can be optimized here */
352951c6300SRichard Henderson     if (arg2 == 0) {
353951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
354951c6300SRichard Henderson     } else {
35511d11d61SRichard Henderson         tcg_gen_add_i32(ret, arg1, tcg_constant_i32(arg2));
356951c6300SRichard Henderson     }
357951c6300SRichard Henderson }
358951c6300SRichard Henderson 
tcg_gen_sub_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)35909607d35SRichard Henderson void tcg_gen_sub_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
36009607d35SRichard Henderson {
36109607d35SRichard Henderson     tcg_gen_op3_i32(INDEX_op_sub_i32, ret, arg1, arg2);
36209607d35SRichard Henderson }
36309607d35SRichard Henderson 
tcg_gen_subfi_i32(TCGv_i32 ret,int32_t arg1,TCGv_i32 arg2)364951c6300SRichard Henderson void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2)
365951c6300SRichard Henderson {
366b701f195SRichard Henderson     if (arg1 == 0) {
367b701f195SRichard Henderson         tcg_gen_neg_i32(ret, arg2);
368951c6300SRichard Henderson     } else {
36911d11d61SRichard Henderson         tcg_gen_sub_i32(ret, tcg_constant_i32(arg1), arg2);
370951c6300SRichard Henderson     }
371951c6300SRichard Henderson }
372951c6300SRichard Henderson 
tcg_gen_subi_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)373951c6300SRichard Henderson void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
374951c6300SRichard Henderson {
375*1551004eSRichard Henderson     tcg_gen_addi_i32(ret, arg1, -arg2);
376951c6300SRichard Henderson }
377951c6300SRichard Henderson 
tcg_gen_neg_i32(TCGv_i32 ret,TCGv_i32 arg)37809607d35SRichard Henderson void tcg_gen_neg_i32(TCGv_i32 ret, TCGv_i32 arg)
37909607d35SRichard Henderson {
38009607d35SRichard Henderson     tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg);
38109607d35SRichard Henderson }
38209607d35SRichard Henderson 
tcg_gen_and_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)38309607d35SRichard Henderson void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
38409607d35SRichard Henderson {
38509607d35SRichard Henderson     tcg_gen_op3_i32(INDEX_op_and_i32, ret, arg1, arg2);
38609607d35SRichard Henderson }
38709607d35SRichard Henderson 
tcg_gen_andi_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)388474b2e8fSRichard Henderson void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
389951c6300SRichard Henderson {
390951c6300SRichard Henderson     /* Some cases can be optimized here.  */
391951c6300SRichard Henderson     switch (arg2) {
392951c6300SRichard Henderson     case 0:
393951c6300SRichard Henderson         tcg_gen_movi_i32(ret, 0);
394951c6300SRichard Henderson         return;
395474b2e8fSRichard Henderson     case -1:
396951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
397951c6300SRichard Henderson         return;
398474b2e8fSRichard Henderson     case 0xff:
399951c6300SRichard Henderson         /* Don't recurse with tcg_gen_ext8u_i32.  */
400951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext8u_i32) {
401951c6300SRichard Henderson             tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
402951c6300SRichard Henderson             return;
403951c6300SRichard Henderson         }
404951c6300SRichard Henderson         break;
405474b2e8fSRichard Henderson     case 0xffff:
406951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext16u_i32) {
407951c6300SRichard Henderson             tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
408951c6300SRichard Henderson             return;
409951c6300SRichard Henderson         }
410951c6300SRichard Henderson         break;
411951c6300SRichard Henderson     }
41211d11d61SRichard Henderson 
41311d11d61SRichard Henderson     tcg_gen_and_i32(ret, arg1, tcg_constant_i32(arg2));
414951c6300SRichard Henderson }
415951c6300SRichard Henderson 
tcg_gen_or_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)41609607d35SRichard Henderson void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
41709607d35SRichard Henderson {
41809607d35SRichard Henderson     tcg_gen_op3_i32(INDEX_op_or_i32, ret, arg1, arg2);
41909607d35SRichard Henderson }
42009607d35SRichard Henderson 
tcg_gen_ori_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)421951c6300SRichard Henderson void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
422951c6300SRichard Henderson {
423951c6300SRichard Henderson     /* Some cases can be optimized here.  */
424951c6300SRichard Henderson     if (arg2 == -1) {
425951c6300SRichard Henderson         tcg_gen_movi_i32(ret, -1);
426951c6300SRichard Henderson     } else if (arg2 == 0) {
427951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
428951c6300SRichard Henderson     } else {
42911d11d61SRichard Henderson         tcg_gen_or_i32(ret, arg1, tcg_constant_i32(arg2));
430951c6300SRichard Henderson     }
431951c6300SRichard Henderson }
432951c6300SRichard Henderson 
tcg_gen_xor_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)43309607d35SRichard Henderson void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
43409607d35SRichard Henderson {
43509607d35SRichard Henderson     tcg_gen_op3_i32(INDEX_op_xor_i32, ret, arg1, arg2);
43609607d35SRichard Henderson }
43709607d35SRichard Henderson 
tcg_gen_xori_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)438951c6300SRichard Henderson void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
439951c6300SRichard Henderson {
440951c6300SRichard Henderson     /* Some cases can be optimized here.  */
441951c6300SRichard Henderson     if (arg2 == 0) {
442951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
443951c6300SRichard Henderson     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) {
444951c6300SRichard Henderson         /* Don't recurse with tcg_gen_not_i32.  */
445951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1);
446951c6300SRichard Henderson     } else {
44711d11d61SRichard Henderson         tcg_gen_xor_i32(ret, arg1, tcg_constant_i32(arg2));
448951c6300SRichard Henderson     }
449951c6300SRichard Henderson }
450951c6300SRichard Henderson 
tcg_gen_not_i32(TCGv_i32 ret,TCGv_i32 arg)45109607d35SRichard Henderson void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg)
45209607d35SRichard Henderson {
45309607d35SRichard Henderson     if (TCG_TARGET_HAS_not_i32) {
45409607d35SRichard Henderson         tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg);
45509607d35SRichard Henderson     } else {
45609607d35SRichard Henderson         tcg_gen_xori_i32(ret, arg, -1);
45709607d35SRichard Henderson     }
45809607d35SRichard Henderson }
45909607d35SRichard Henderson 
tcg_gen_shl_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)46009607d35SRichard Henderson void tcg_gen_shl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
46109607d35SRichard Henderson {
46209607d35SRichard Henderson     tcg_gen_op3_i32(INDEX_op_shl_i32, ret, arg1, arg2);
46309607d35SRichard Henderson }
46409607d35SRichard Henderson 
tcg_gen_shli_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)465474b2e8fSRichard Henderson void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
466951c6300SRichard Henderson {
467474b2e8fSRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
468951c6300SRichard Henderson     if (arg2 == 0) {
469951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
470951c6300SRichard Henderson     } else {
47111d11d61SRichard Henderson         tcg_gen_shl_i32(ret, arg1, tcg_constant_i32(arg2));
472951c6300SRichard Henderson     }
473951c6300SRichard Henderson }
474951c6300SRichard Henderson 
tcg_gen_shr_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)47509607d35SRichard Henderson void tcg_gen_shr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
47609607d35SRichard Henderson {
47709607d35SRichard Henderson     tcg_gen_op3_i32(INDEX_op_shr_i32, ret, arg1, arg2);
47809607d35SRichard Henderson }
47909607d35SRichard Henderson 
tcg_gen_shri_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)480474b2e8fSRichard Henderson void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
481951c6300SRichard Henderson {
482474b2e8fSRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
483951c6300SRichard Henderson     if (arg2 == 0) {
484951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
485951c6300SRichard Henderson     } else {
48611d11d61SRichard Henderson         tcg_gen_shr_i32(ret, arg1, tcg_constant_i32(arg2));
487951c6300SRichard Henderson     }
488951c6300SRichard Henderson }
489951c6300SRichard Henderson 
tcg_gen_sar_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)49009607d35SRichard Henderson void tcg_gen_sar_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
49109607d35SRichard Henderson {
49209607d35SRichard Henderson     tcg_gen_op3_i32(INDEX_op_sar_i32, ret, arg1, arg2);
49309607d35SRichard Henderson }
49409607d35SRichard Henderson 
tcg_gen_sari_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)495474b2e8fSRichard Henderson void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
496951c6300SRichard Henderson {
497474b2e8fSRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
498951c6300SRichard Henderson     if (arg2 == 0) {
499951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
500951c6300SRichard Henderson     } else {
50111d11d61SRichard Henderson         tcg_gen_sar_i32(ret, arg1, tcg_constant_i32(arg2));
502951c6300SRichard Henderson     }
503951c6300SRichard Henderson }
504951c6300SRichard Henderson 
tcg_gen_brcond_i32(TCGCond cond,TCGv_i32 arg1,TCGv_i32 arg2,TCGLabel * l)50542a268c2SRichard Henderson void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l)
506951c6300SRichard Henderson {
507951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
50842a268c2SRichard Henderson         tcg_gen_br(l);
509951c6300SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
51042a268c2SRichard Henderson         tcg_gen_op4ii_i32(INDEX_op_brcond_i32, arg1, arg2, cond, label_arg(l));
511f85b1fc4SRichard Henderson         add_last_as_label_use(l);
512951c6300SRichard Henderson     }
513951c6300SRichard Henderson }
514951c6300SRichard Henderson 
tcg_gen_brcondi_i32(TCGCond cond,TCGv_i32 arg1,int32_t arg2,TCGLabel * l)51542a268c2SRichard Henderson void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l)
516951c6300SRichard Henderson {
51737ed3bf1SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
51837ed3bf1SRichard Henderson         tcg_gen_br(l);
51937ed3bf1SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
52011d11d61SRichard Henderson         tcg_gen_brcond_i32(cond, arg1, tcg_constant_i32(arg2), l);
521951c6300SRichard Henderson     }
52237ed3bf1SRichard Henderson }
523951c6300SRichard Henderson 
tcg_gen_setcond_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)524951c6300SRichard Henderson void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
525951c6300SRichard Henderson                          TCGv_i32 arg1, TCGv_i32 arg2)
526951c6300SRichard Henderson {
527951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
528951c6300SRichard Henderson         tcg_gen_movi_i32(ret, 1);
529951c6300SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
530951c6300SRichard Henderson         tcg_gen_movi_i32(ret, 0);
531951c6300SRichard Henderson     } else {
532951c6300SRichard Henderson         tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
533951c6300SRichard Henderson     }
534951c6300SRichard Henderson }
535951c6300SRichard Henderson 
tcg_gen_setcondi_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)536951c6300SRichard Henderson void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
537951c6300SRichard Henderson                           TCGv_i32 arg1, int32_t arg2)
538951c6300SRichard Henderson {
53911d11d61SRichard Henderson     tcg_gen_setcond_i32(cond, ret, arg1, tcg_constant_i32(arg2));
540951c6300SRichard Henderson }
541951c6300SRichard Henderson 
tcg_gen_negsetcond_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)5423635502dSRichard Henderson void tcg_gen_negsetcond_i32(TCGCond cond, TCGv_i32 ret,
5433635502dSRichard Henderson                             TCGv_i32 arg1, TCGv_i32 arg2)
5443635502dSRichard Henderson {
5453635502dSRichard Henderson     if (cond == TCG_COND_ALWAYS) {
5463635502dSRichard Henderson         tcg_gen_movi_i32(ret, -1);
5473635502dSRichard Henderson     } else if (cond == TCG_COND_NEVER) {
5483635502dSRichard Henderson         tcg_gen_movi_i32(ret, 0);
5493635502dSRichard Henderson     } else if (TCG_TARGET_HAS_negsetcond_i32) {
5503635502dSRichard Henderson         tcg_gen_op4i_i32(INDEX_op_negsetcond_i32, ret, arg1, arg2, cond);
5513635502dSRichard Henderson     } else {
5523635502dSRichard Henderson         tcg_gen_setcond_i32(cond, ret, arg1, arg2);
5533635502dSRichard Henderson         tcg_gen_neg_i32(ret, ret);
5543635502dSRichard Henderson     }
5553635502dSRichard Henderson }
5563635502dSRichard Henderson 
tcg_gen_negsetcondi_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)55793c86ecdSPaolo Bonzini void tcg_gen_negsetcondi_i32(TCGCond cond, TCGv_i32 ret,
55893c86ecdSPaolo Bonzini                              TCGv_i32 arg1, int32_t arg2)
55993c86ecdSPaolo Bonzini {
56093c86ecdSPaolo Bonzini     tcg_gen_negsetcond_i32(cond, ret, arg1, tcg_constant_i32(arg2));
56193c86ecdSPaolo Bonzini }
56293c86ecdSPaolo Bonzini 
tcg_gen_mul_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)56309607d35SRichard Henderson void tcg_gen_mul_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
56409607d35SRichard Henderson {
56509607d35SRichard Henderson     tcg_gen_op3_i32(INDEX_op_mul_i32, ret, arg1, arg2);
56609607d35SRichard Henderson }
56709607d35SRichard Henderson 
tcg_gen_muli_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)568951c6300SRichard Henderson void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
569951c6300SRichard Henderson {
570b2e3ae94SRichard Henderson     if (arg2 == 0) {
571b2e3ae94SRichard Henderson         tcg_gen_movi_i32(ret, 0);
572b2e3ae94SRichard Henderson     } else if (is_power_of_2(arg2)) {
573b2e3ae94SRichard Henderson         tcg_gen_shli_i32(ret, arg1, ctz32(arg2));
574b2e3ae94SRichard Henderson     } else {
57511d11d61SRichard Henderson         tcg_gen_mul_i32(ret, arg1, tcg_constant_i32(arg2));
576951c6300SRichard Henderson     }
577b2e3ae94SRichard Henderson }
578951c6300SRichard Henderson 
tcg_gen_div_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)579951c6300SRichard Henderson void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
580951c6300SRichard Henderson {
581951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i32) {
582951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
583951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
5845dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
585951c6300SRichard Henderson         tcg_gen_sari_i32(t0, arg1, 31);
586951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
587951c6300SRichard Henderson         tcg_temp_free_i32(t0);
588951c6300SRichard Henderson     } else {
589951c6300SRichard Henderson         gen_helper_div_i32(ret, arg1, arg2);
590951c6300SRichard Henderson     }
591951c6300SRichard Henderson }
592951c6300SRichard Henderson 
tcg_gen_rem_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)593951c6300SRichard Henderson void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
594951c6300SRichard Henderson {
595951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i32) {
596951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
597951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i32) {
5985dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
599951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
600951c6300SRichard Henderson         tcg_gen_mul_i32(t0, t0, arg2);
601951c6300SRichard Henderson         tcg_gen_sub_i32(ret, arg1, t0);
602951c6300SRichard Henderson         tcg_temp_free_i32(t0);
603951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
6045dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
605951c6300SRichard Henderson         tcg_gen_sari_i32(t0, arg1, 31);
606951c6300SRichard Henderson         tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
607951c6300SRichard Henderson         tcg_temp_free_i32(t0);
608951c6300SRichard Henderson     } else {
609951c6300SRichard Henderson         gen_helper_rem_i32(ret, arg1, arg2);
610951c6300SRichard Henderson     }
611951c6300SRichard Henderson }
612951c6300SRichard Henderson 
tcg_gen_divu_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)613951c6300SRichard Henderson void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
614951c6300SRichard Henderson {
615951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i32) {
616951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
617951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
6185dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
619bfefdbeaSRichard Henderson         TCGv_i32 zero = tcg_constant_i32(0);
620bfefdbeaSRichard Henderson         tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, zero, arg2);
621951c6300SRichard Henderson         tcg_temp_free_i32(t0);
622951c6300SRichard Henderson     } else {
623951c6300SRichard Henderson         gen_helper_divu_i32(ret, arg1, arg2);
624951c6300SRichard Henderson     }
625951c6300SRichard Henderson }
626951c6300SRichard Henderson 
tcg_gen_remu_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)627951c6300SRichard Henderson void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
628951c6300SRichard Henderson {
629951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i32) {
630951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
631951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i32) {
6325dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
633951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
634951c6300SRichard Henderson         tcg_gen_mul_i32(t0, t0, arg2);
635951c6300SRichard Henderson         tcg_gen_sub_i32(ret, arg1, t0);
636951c6300SRichard Henderson         tcg_temp_free_i32(t0);
637951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i32) {
6385dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
639bfefdbeaSRichard Henderson         TCGv_i32 zero = tcg_constant_i32(0);
640bfefdbeaSRichard Henderson         tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, zero, arg2);
641951c6300SRichard Henderson         tcg_temp_free_i32(t0);
642951c6300SRichard Henderson     } else {
643951c6300SRichard Henderson         gen_helper_remu_i32(ret, arg1, arg2);
644951c6300SRichard Henderson     }
645951c6300SRichard Henderson }
646951c6300SRichard Henderson 
tcg_gen_andc_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)647951c6300SRichard Henderson void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
648951c6300SRichard Henderson {
649951c6300SRichard Henderson     if (TCG_TARGET_HAS_andc_i32) {
650951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
651951c6300SRichard Henderson     } else {
6525dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
653951c6300SRichard Henderson         tcg_gen_not_i32(t0, arg2);
654951c6300SRichard Henderson         tcg_gen_and_i32(ret, arg1, t0);
655951c6300SRichard Henderson         tcg_temp_free_i32(t0);
656951c6300SRichard Henderson     }
657951c6300SRichard Henderson }
658951c6300SRichard Henderson 
tcg_gen_eqv_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)659951c6300SRichard Henderson void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
660951c6300SRichard Henderson {
661951c6300SRichard Henderson     if (TCG_TARGET_HAS_eqv_i32) {
662951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
663951c6300SRichard Henderson     } else {
664951c6300SRichard Henderson         tcg_gen_xor_i32(ret, arg1, arg2);
665951c6300SRichard Henderson         tcg_gen_not_i32(ret, ret);
666951c6300SRichard Henderson     }
667951c6300SRichard Henderson }
668951c6300SRichard Henderson 
tcg_gen_nand_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)669951c6300SRichard Henderson void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
670951c6300SRichard Henderson {
671951c6300SRichard Henderson     if (TCG_TARGET_HAS_nand_i32) {
672951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
673951c6300SRichard Henderson     } else {
674951c6300SRichard Henderson         tcg_gen_and_i32(ret, arg1, arg2);
675951c6300SRichard Henderson         tcg_gen_not_i32(ret, ret);
676951c6300SRichard Henderson     }
677951c6300SRichard Henderson }
678951c6300SRichard Henderson 
tcg_gen_nor_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)679951c6300SRichard Henderson void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
680951c6300SRichard Henderson {
681951c6300SRichard Henderson     if (TCG_TARGET_HAS_nor_i32) {
682951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
683951c6300SRichard Henderson     } else {
684951c6300SRichard Henderson         tcg_gen_or_i32(ret, arg1, arg2);
685951c6300SRichard Henderson         tcg_gen_not_i32(ret, ret);
686951c6300SRichard Henderson     }
687951c6300SRichard Henderson }
688951c6300SRichard Henderson 
tcg_gen_orc_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)689951c6300SRichard Henderson void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
690951c6300SRichard Henderson {
691951c6300SRichard Henderson     if (TCG_TARGET_HAS_orc_i32) {
692951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
693951c6300SRichard Henderson     } else {
6945dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
695951c6300SRichard Henderson         tcg_gen_not_i32(t0, arg2);
696951c6300SRichard Henderson         tcg_gen_or_i32(ret, arg1, t0);
697951c6300SRichard Henderson         tcg_temp_free_i32(t0);
698951c6300SRichard Henderson     }
699951c6300SRichard Henderson }
700951c6300SRichard Henderson 
tcg_gen_clz_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)7010e28d006SRichard Henderson void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7020e28d006SRichard Henderson {
7030e28d006SRichard Henderson     if (TCG_TARGET_HAS_clz_i32) {
7040e28d006SRichard Henderson         tcg_gen_op3_i32(INDEX_op_clz_i32, ret, arg1, arg2);
7050e28d006SRichard Henderson     } else if (TCG_TARGET_HAS_clz_i64) {
7065dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
7075dd48602SRichard Henderson         TCGv_i64 t2 = tcg_temp_ebb_new_i64();
7080e28d006SRichard Henderson         tcg_gen_extu_i32_i64(t1, arg1);
7090e28d006SRichard Henderson         tcg_gen_extu_i32_i64(t2, arg2);
7100e28d006SRichard Henderson         tcg_gen_addi_i64(t2, t2, 32);
7110e28d006SRichard Henderson         tcg_gen_clz_i64(t1, t1, t2);
7120e28d006SRichard Henderson         tcg_gen_extrl_i64_i32(ret, t1);
7130e28d006SRichard Henderson         tcg_temp_free_i64(t1);
7140e28d006SRichard Henderson         tcg_temp_free_i64(t2);
7150e28d006SRichard Henderson         tcg_gen_subi_i32(ret, ret, 32);
7160e28d006SRichard Henderson     } else {
7170e28d006SRichard Henderson         gen_helper_clz_i32(ret, arg1, arg2);
7180e28d006SRichard Henderson     }
7190e28d006SRichard Henderson }
7200e28d006SRichard Henderson 
tcg_gen_clzi_i32(TCGv_i32 ret,TCGv_i32 arg1,uint32_t arg2)7210e28d006SRichard Henderson void tcg_gen_clzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
7220e28d006SRichard Henderson {
72311d11d61SRichard Henderson     tcg_gen_clz_i32(ret, arg1, tcg_constant_i32(arg2));
7240e28d006SRichard Henderson }
7250e28d006SRichard Henderson 
tcg_gen_ctz_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)7260e28d006SRichard Henderson void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7270e28d006SRichard Henderson {
7280e28d006SRichard Henderson     if (TCG_TARGET_HAS_ctz_i32) {
7290e28d006SRichard Henderson         tcg_gen_op3_i32(INDEX_op_ctz_i32, ret, arg1, arg2);
7300e28d006SRichard Henderson     } else if (TCG_TARGET_HAS_ctz_i64) {
7315dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
7325dd48602SRichard Henderson         TCGv_i64 t2 = tcg_temp_ebb_new_i64();
7330e28d006SRichard Henderson         tcg_gen_extu_i32_i64(t1, arg1);
7340e28d006SRichard Henderson         tcg_gen_extu_i32_i64(t2, arg2);
7350e28d006SRichard Henderson         tcg_gen_ctz_i64(t1, t1, t2);
7360e28d006SRichard Henderson         tcg_gen_extrl_i64_i32(ret, t1);
7370e28d006SRichard Henderson         tcg_temp_free_i64(t1);
7380e28d006SRichard Henderson         tcg_temp_free_i64(t2);
73914e99210SRichard Henderson     } else if (TCG_TARGET_HAS_ctpop_i32
74014e99210SRichard Henderson                || TCG_TARGET_HAS_ctpop_i64
74114e99210SRichard Henderson                || TCG_TARGET_HAS_clz_i32
74214e99210SRichard Henderson                || TCG_TARGET_HAS_clz_i64) {
7435dd48602SRichard Henderson         TCGv_i32 z, t = tcg_temp_ebb_new_i32();
74414e99210SRichard Henderson 
74514e99210SRichard Henderson         if (TCG_TARGET_HAS_ctpop_i32 || TCG_TARGET_HAS_ctpop_i64) {
74614e99210SRichard Henderson             tcg_gen_subi_i32(t, arg1, 1);
74714e99210SRichard Henderson             tcg_gen_andc_i32(t, t, arg1);
74814e99210SRichard Henderson             tcg_gen_ctpop_i32(t, t);
74914e99210SRichard Henderson         } else {
75014e99210SRichard Henderson             /* Since all non-x86 hosts have clz(0) == 32, don't fight it.  */
75114e99210SRichard Henderson             tcg_gen_neg_i32(t, arg1);
75214e99210SRichard Henderson             tcg_gen_and_i32(t, t, arg1);
75314e99210SRichard Henderson             tcg_gen_clzi_i32(t, t, 32);
75414e99210SRichard Henderson             tcg_gen_xori_i32(t, t, 31);
75514e99210SRichard Henderson         }
75611d11d61SRichard Henderson         z = tcg_constant_i32(0);
75714e99210SRichard Henderson         tcg_gen_movcond_i32(TCG_COND_EQ, ret, arg1, z, arg2, t);
75814e99210SRichard Henderson         tcg_temp_free_i32(t);
7590e28d006SRichard Henderson     } else {
7600e28d006SRichard Henderson         gen_helper_ctz_i32(ret, arg1, arg2);
7610e28d006SRichard Henderson     }
7620e28d006SRichard Henderson }
7630e28d006SRichard Henderson 
tcg_gen_ctzi_i32(TCGv_i32 ret,TCGv_i32 arg1,uint32_t arg2)7640e28d006SRichard Henderson void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
7650e28d006SRichard Henderson {
76614e99210SRichard Henderson     if (!TCG_TARGET_HAS_ctz_i32 && TCG_TARGET_HAS_ctpop_i32 && arg2 == 32) {
76714e99210SRichard Henderson         /* This equivalence has the advantage of not requiring a fixup.  */
7685dd48602SRichard Henderson         TCGv_i32 t = tcg_temp_ebb_new_i32();
76914e99210SRichard Henderson         tcg_gen_subi_i32(t, arg1, 1);
77014e99210SRichard Henderson         tcg_gen_andc_i32(t, t, arg1);
77114e99210SRichard Henderson         tcg_gen_ctpop_i32(ret, t);
77214e99210SRichard Henderson         tcg_temp_free_i32(t);
77314e99210SRichard Henderson     } else {
77411d11d61SRichard Henderson         tcg_gen_ctz_i32(ret, arg1, tcg_constant_i32(arg2));
7750e28d006SRichard Henderson     }
77614e99210SRichard Henderson }
7770e28d006SRichard Henderson 
tcg_gen_clrsb_i32(TCGv_i32 ret,TCGv_i32 arg)778086920c2SRichard Henderson void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg)
779086920c2SRichard Henderson {
780086920c2SRichard Henderson     if (TCG_TARGET_HAS_clz_i32) {
7815dd48602SRichard Henderson         TCGv_i32 t = tcg_temp_ebb_new_i32();
782086920c2SRichard Henderson         tcg_gen_sari_i32(t, arg, 31);
783086920c2SRichard Henderson         tcg_gen_xor_i32(t, t, arg);
784086920c2SRichard Henderson         tcg_gen_clzi_i32(t, t, 32);
785086920c2SRichard Henderson         tcg_gen_subi_i32(ret, t, 1);
786086920c2SRichard Henderson         tcg_temp_free_i32(t);
787086920c2SRichard Henderson     } else {
788086920c2SRichard Henderson         gen_helper_clrsb_i32(ret, arg);
789086920c2SRichard Henderson     }
790086920c2SRichard Henderson }
791086920c2SRichard Henderson 
tcg_gen_ctpop_i32(TCGv_i32 ret,TCGv_i32 arg1)792a768e4e9SRichard Henderson void tcg_gen_ctpop_i32(TCGv_i32 ret, TCGv_i32 arg1)
793a768e4e9SRichard Henderson {
794a768e4e9SRichard Henderson     if (TCG_TARGET_HAS_ctpop_i32) {
795a768e4e9SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ctpop_i32, ret, arg1);
796a768e4e9SRichard Henderson     } else if (TCG_TARGET_HAS_ctpop_i64) {
7975dd48602SRichard Henderson         TCGv_i64 t = tcg_temp_ebb_new_i64();
798a768e4e9SRichard Henderson         tcg_gen_extu_i32_i64(t, arg1);
799a768e4e9SRichard Henderson         tcg_gen_ctpop_i64(t, t);
800a768e4e9SRichard Henderson         tcg_gen_extrl_i64_i32(ret, t);
801a768e4e9SRichard Henderson         tcg_temp_free_i64(t);
802a768e4e9SRichard Henderson     } else {
803a768e4e9SRichard Henderson         gen_helper_ctpop_i32(ret, arg1);
804a768e4e9SRichard Henderson     }
805a768e4e9SRichard Henderson }
806a768e4e9SRichard Henderson 
tcg_gen_rotl_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)807951c6300SRichard Henderson void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
808951c6300SRichard Henderson {
809951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i32) {
810951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
811951c6300SRichard Henderson     } else {
812951c6300SRichard Henderson         TCGv_i32 t0, t1;
813951c6300SRichard Henderson 
8145dd48602SRichard Henderson         t0 = tcg_temp_ebb_new_i32();
8155dd48602SRichard Henderson         t1 = tcg_temp_ebb_new_i32();
816951c6300SRichard Henderson         tcg_gen_shl_i32(t0, arg1, arg2);
817951c6300SRichard Henderson         tcg_gen_subfi_i32(t1, 32, arg2);
818951c6300SRichard Henderson         tcg_gen_shr_i32(t1, arg1, t1);
819951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
820951c6300SRichard Henderson         tcg_temp_free_i32(t0);
821951c6300SRichard Henderson         tcg_temp_free_i32(t1);
822951c6300SRichard Henderson     }
823951c6300SRichard Henderson }
824951c6300SRichard Henderson 
tcg_gen_rotli_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)82507dada03SRichard Henderson void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
826951c6300SRichard Henderson {
82707dada03SRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
828951c6300SRichard Henderson     /* some cases can be optimized here */
829951c6300SRichard Henderson     if (arg2 == 0) {
830951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
831951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_rot_i32) {
83211d11d61SRichard Henderson         tcg_gen_rotl_i32(ret, arg1, tcg_constant_i32(arg2));
833951c6300SRichard Henderson     } else {
834951c6300SRichard Henderson         TCGv_i32 t0, t1;
8355dd48602SRichard Henderson         t0 = tcg_temp_ebb_new_i32();
8365dd48602SRichard Henderson         t1 = tcg_temp_ebb_new_i32();
837951c6300SRichard Henderson         tcg_gen_shli_i32(t0, arg1, arg2);
838951c6300SRichard Henderson         tcg_gen_shri_i32(t1, arg1, 32 - arg2);
839951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
840951c6300SRichard Henderson         tcg_temp_free_i32(t0);
841951c6300SRichard Henderson         tcg_temp_free_i32(t1);
842951c6300SRichard Henderson     }
843951c6300SRichard Henderson }
844951c6300SRichard Henderson 
tcg_gen_rotr_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)845951c6300SRichard Henderson void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
846951c6300SRichard Henderson {
847951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i32) {
848951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
849951c6300SRichard Henderson     } else {
850951c6300SRichard Henderson         TCGv_i32 t0, t1;
851951c6300SRichard Henderson 
8525dd48602SRichard Henderson         t0 = tcg_temp_ebb_new_i32();
8535dd48602SRichard Henderson         t1 = tcg_temp_ebb_new_i32();
854951c6300SRichard Henderson         tcg_gen_shr_i32(t0, arg1, arg2);
855951c6300SRichard Henderson         tcg_gen_subfi_i32(t1, 32, arg2);
856951c6300SRichard Henderson         tcg_gen_shl_i32(t1, arg1, t1);
857951c6300SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);
858951c6300SRichard Henderson         tcg_temp_free_i32(t0);
859951c6300SRichard Henderson         tcg_temp_free_i32(t1);
860951c6300SRichard Henderson     }
861951c6300SRichard Henderson }
862951c6300SRichard Henderson 
tcg_gen_rotri_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)86307dada03SRichard Henderson void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
864951c6300SRichard Henderson {
86507dada03SRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 32);
866951c6300SRichard Henderson     /* some cases can be optimized here */
867951c6300SRichard Henderson     if (arg2 == 0) {
868951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg1);
869951c6300SRichard Henderson     } else {
870951c6300SRichard Henderson         tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
871951c6300SRichard Henderson     }
872951c6300SRichard Henderson }
873951c6300SRichard Henderson 
tcg_gen_deposit_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2,unsigned int ofs,unsigned int len)874951c6300SRichard Henderson void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
875951c6300SRichard Henderson                          unsigned int ofs, unsigned int len)
876951c6300SRichard Henderson {
877951c6300SRichard Henderson     uint32_t mask;
878951c6300SRichard Henderson     TCGv_i32 t1;
879951c6300SRichard Henderson 
880951c6300SRichard Henderson     tcg_debug_assert(ofs < 32);
8810d0d309dSRichard Henderson     tcg_debug_assert(len > 0);
882951c6300SRichard Henderson     tcg_debug_assert(len <= 32);
883951c6300SRichard Henderson     tcg_debug_assert(ofs + len <= 32);
884951c6300SRichard Henderson 
8850d0d309dSRichard Henderson     if (len == 32) {
886951c6300SRichard Henderson         tcg_gen_mov_i32(ret, arg2);
887951c6300SRichard Henderson         return;
888951c6300SRichard Henderson     }
889951c6300SRichard Henderson     if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
890951c6300SRichard Henderson         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
891951c6300SRichard Henderson         return;
892951c6300SRichard Henderson     }
893951c6300SRichard Henderson 
8945dd48602SRichard Henderson     t1 = tcg_temp_ebb_new_i32();
895951c6300SRichard Henderson 
896b0a60567SRichard Henderson     if (TCG_TARGET_HAS_extract2_i32) {
897b0a60567SRichard Henderson         if (ofs + len == 32) {
898b0a60567SRichard Henderson             tcg_gen_shli_i32(t1, arg1, len);
899b0a60567SRichard Henderson             tcg_gen_extract2_i32(ret, t1, arg2, len);
900b0a60567SRichard Henderson             goto done;
901b0a60567SRichard Henderson         }
902b0a60567SRichard Henderson         if (ofs == 0) {
903b0a60567SRichard Henderson             tcg_gen_extract2_i32(ret, arg1, arg2, len);
904b0a60567SRichard Henderson             tcg_gen_rotli_i32(ret, ret, len);
905b0a60567SRichard Henderson             goto done;
906b0a60567SRichard Henderson         }
907b0a60567SRichard Henderson     }
908b0a60567SRichard Henderson 
909b0a60567SRichard Henderson     mask = (1u << len) - 1;
910951c6300SRichard Henderson     if (ofs + len < 32) {
911951c6300SRichard Henderson         tcg_gen_andi_i32(t1, arg2, mask);
912951c6300SRichard Henderson         tcg_gen_shli_i32(t1, t1, ofs);
913951c6300SRichard Henderson     } else {
914951c6300SRichard Henderson         tcg_gen_shli_i32(t1, arg2, ofs);
915951c6300SRichard Henderson     }
916951c6300SRichard Henderson     tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
917951c6300SRichard Henderson     tcg_gen_or_i32(ret, ret, t1);
918b0a60567SRichard Henderson  done:
919951c6300SRichard Henderson     tcg_temp_free_i32(t1);
920951c6300SRichard Henderson }
921951c6300SRichard Henderson 
tcg_gen_deposit_z_i32(TCGv_i32 ret,TCGv_i32 arg,unsigned int ofs,unsigned int len)92207cc68d5SRichard Henderson void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
92307cc68d5SRichard Henderson                            unsigned int ofs, unsigned int len)
92407cc68d5SRichard Henderson {
92507cc68d5SRichard Henderson     tcg_debug_assert(ofs < 32);
92607cc68d5SRichard Henderson     tcg_debug_assert(len > 0);
92707cc68d5SRichard Henderson     tcg_debug_assert(len <= 32);
92807cc68d5SRichard Henderson     tcg_debug_assert(ofs + len <= 32);
92907cc68d5SRichard Henderson 
93007cc68d5SRichard Henderson     if (ofs + len == 32) {
93107cc68d5SRichard Henderson         tcg_gen_shli_i32(ret, arg, ofs);
93207cc68d5SRichard Henderson     } else if (ofs == 0) {
93307cc68d5SRichard Henderson         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
93407cc68d5SRichard Henderson     } else if (TCG_TARGET_HAS_deposit_i32
93507cc68d5SRichard Henderson                && TCG_TARGET_deposit_i32_valid(ofs, len)) {
93611d11d61SRichard Henderson         TCGv_i32 zero = tcg_constant_i32(0);
93707cc68d5SRichard Henderson         tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len);
93807cc68d5SRichard Henderson     } else {
93907cc68d5SRichard Henderson         /* To help two-operand hosts we prefer to zero-extend first,
94007cc68d5SRichard Henderson            which allows ARG to stay live.  */
94107cc68d5SRichard Henderson         switch (len) {
94207cc68d5SRichard Henderson         case 16:
94307cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext16u_i32) {
94407cc68d5SRichard Henderson                 tcg_gen_ext16u_i32(ret, arg);
94507cc68d5SRichard Henderson                 tcg_gen_shli_i32(ret, ret, ofs);
94607cc68d5SRichard Henderson                 return;
94707cc68d5SRichard Henderson             }
94807cc68d5SRichard Henderson             break;
94907cc68d5SRichard Henderson         case 8:
95007cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext8u_i32) {
95107cc68d5SRichard Henderson                 tcg_gen_ext8u_i32(ret, arg);
95207cc68d5SRichard Henderson                 tcg_gen_shli_i32(ret, ret, ofs);
95307cc68d5SRichard Henderson                 return;
95407cc68d5SRichard Henderson             }
95507cc68d5SRichard Henderson             break;
95607cc68d5SRichard Henderson         }
95707cc68d5SRichard Henderson         /* Otherwise prefer zero-extension over AND for code size.  */
95807cc68d5SRichard Henderson         switch (ofs + len) {
95907cc68d5SRichard Henderson         case 16:
96007cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext16u_i32) {
96107cc68d5SRichard Henderson                 tcg_gen_shli_i32(ret, arg, ofs);
96207cc68d5SRichard Henderson                 tcg_gen_ext16u_i32(ret, ret);
96307cc68d5SRichard Henderson                 return;
96407cc68d5SRichard Henderson             }
96507cc68d5SRichard Henderson             break;
96607cc68d5SRichard Henderson         case 8:
96707cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext8u_i32) {
96807cc68d5SRichard Henderson                 tcg_gen_shli_i32(ret, arg, ofs);
96907cc68d5SRichard Henderson                 tcg_gen_ext8u_i32(ret, ret);
97007cc68d5SRichard Henderson                 return;
97107cc68d5SRichard Henderson             }
97207cc68d5SRichard Henderson             break;
97307cc68d5SRichard Henderson         }
97407cc68d5SRichard Henderson         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
97507cc68d5SRichard Henderson         tcg_gen_shli_i32(ret, ret, ofs);
97607cc68d5SRichard Henderson     }
97707cc68d5SRichard Henderson }
97807cc68d5SRichard Henderson 
tcg_gen_extract_i32(TCGv_i32 ret,TCGv_i32 arg,unsigned int ofs,unsigned int len)9797ec8bab3SRichard Henderson void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
9807ec8bab3SRichard Henderson                          unsigned int ofs, unsigned int len)
9817ec8bab3SRichard Henderson {
9827ec8bab3SRichard Henderson     tcg_debug_assert(ofs < 32);
9837ec8bab3SRichard Henderson     tcg_debug_assert(len > 0);
9847ec8bab3SRichard Henderson     tcg_debug_assert(len <= 32);
9857ec8bab3SRichard Henderson     tcg_debug_assert(ofs + len <= 32);
9867ec8bab3SRichard Henderson 
9877ec8bab3SRichard Henderson     /* Canonicalize certain special cases, even if extract is supported.  */
9887ec8bab3SRichard Henderson     if (ofs + len == 32) {
9897ec8bab3SRichard Henderson         tcg_gen_shri_i32(ret, arg, 32 - len);
9907ec8bab3SRichard Henderson         return;
9917ec8bab3SRichard Henderson     }
9927ec8bab3SRichard Henderson     if (ofs == 0) {
9937ec8bab3SRichard Henderson         tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
9947ec8bab3SRichard Henderson         return;
9957ec8bab3SRichard Henderson     }
9967ec8bab3SRichard Henderson 
9977ec8bab3SRichard Henderson     if (TCG_TARGET_HAS_extract_i32
9987ec8bab3SRichard Henderson         && TCG_TARGET_extract_i32_valid(ofs, len)) {
9997ec8bab3SRichard Henderson         tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, ofs, len);
10007ec8bab3SRichard Henderson         return;
10017ec8bab3SRichard Henderson     }
10027ec8bab3SRichard Henderson 
10037ec8bab3SRichard Henderson     /* Assume that zero-extension, if available, is cheaper than a shift.  */
10047ec8bab3SRichard Henderson     switch (ofs + len) {
10057ec8bab3SRichard Henderson     case 16:
10067ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext16u_i32) {
10077ec8bab3SRichard Henderson             tcg_gen_ext16u_i32(ret, arg);
10087ec8bab3SRichard Henderson             tcg_gen_shri_i32(ret, ret, ofs);
10097ec8bab3SRichard Henderson             return;
10107ec8bab3SRichard Henderson         }
10117ec8bab3SRichard Henderson         break;
10127ec8bab3SRichard Henderson     case 8:
10137ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext8u_i32) {
10147ec8bab3SRichard Henderson             tcg_gen_ext8u_i32(ret, arg);
10157ec8bab3SRichard Henderson             tcg_gen_shri_i32(ret, ret, ofs);
10167ec8bab3SRichard Henderson             return;
10177ec8bab3SRichard Henderson         }
10187ec8bab3SRichard Henderson         break;
10197ec8bab3SRichard Henderson     }
10207ec8bab3SRichard Henderson 
10217ec8bab3SRichard Henderson     /* ??? Ideally we'd know what values are available for immediate AND.
10227ec8bab3SRichard Henderson        Assume that 8 bits are available, plus the special case of 16,
10237ec8bab3SRichard Henderson        so that we get ext8u, ext16u.  */
10247ec8bab3SRichard Henderson     switch (len) {
10257ec8bab3SRichard Henderson     case 1 ... 8: case 16:
10267ec8bab3SRichard Henderson         tcg_gen_shri_i32(ret, arg, ofs);
10277ec8bab3SRichard Henderson         tcg_gen_andi_i32(ret, ret, (1u << len) - 1);
10287ec8bab3SRichard Henderson         break;
10297ec8bab3SRichard Henderson     default:
10307ec8bab3SRichard Henderson         tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
10317ec8bab3SRichard Henderson         tcg_gen_shri_i32(ret, ret, 32 - len);
10327ec8bab3SRichard Henderson         break;
10337ec8bab3SRichard Henderson     }
10347ec8bab3SRichard Henderson }
10357ec8bab3SRichard Henderson 
tcg_gen_sextract_i32(TCGv_i32 ret,TCGv_i32 arg,unsigned int ofs,unsigned int len)10367ec8bab3SRichard Henderson void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
10377ec8bab3SRichard Henderson                           unsigned int ofs, unsigned int len)
10387ec8bab3SRichard Henderson {
10397ec8bab3SRichard Henderson     tcg_debug_assert(ofs < 32);
10407ec8bab3SRichard Henderson     tcg_debug_assert(len > 0);
10417ec8bab3SRichard Henderson     tcg_debug_assert(len <= 32);
10427ec8bab3SRichard Henderson     tcg_debug_assert(ofs + len <= 32);
10437ec8bab3SRichard Henderson 
10447ec8bab3SRichard Henderson     /* Canonicalize certain special cases, even if extract is supported.  */
10457ec8bab3SRichard Henderson     if (ofs + len == 32) {
10467ec8bab3SRichard Henderson         tcg_gen_sari_i32(ret, arg, 32 - len);
10477ec8bab3SRichard Henderson         return;
10487ec8bab3SRichard Henderson     }
10497ec8bab3SRichard Henderson     if (ofs == 0) {
10507ec8bab3SRichard Henderson         switch (len) {
10517ec8bab3SRichard Henderson         case 16:
10527ec8bab3SRichard Henderson             tcg_gen_ext16s_i32(ret, arg);
10537ec8bab3SRichard Henderson             return;
10547ec8bab3SRichard Henderson         case 8:
10557ec8bab3SRichard Henderson             tcg_gen_ext8s_i32(ret, arg);
10567ec8bab3SRichard Henderson             return;
10577ec8bab3SRichard Henderson         }
10587ec8bab3SRichard Henderson     }
10597ec8bab3SRichard Henderson 
10607ec8bab3SRichard Henderson     if (TCG_TARGET_HAS_sextract_i32
10617ec8bab3SRichard Henderson         && TCG_TARGET_extract_i32_valid(ofs, len)) {
10627ec8bab3SRichard Henderson         tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len);
10637ec8bab3SRichard Henderson         return;
10647ec8bab3SRichard Henderson     }
10657ec8bab3SRichard Henderson 
10667ec8bab3SRichard Henderson     /* Assume that sign-extension, if available, is cheaper than a shift.  */
10677ec8bab3SRichard Henderson     switch (ofs + len) {
10687ec8bab3SRichard Henderson     case 16:
10697ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext16s_i32) {
10707ec8bab3SRichard Henderson             tcg_gen_ext16s_i32(ret, arg);
10717ec8bab3SRichard Henderson             tcg_gen_sari_i32(ret, ret, ofs);
10727ec8bab3SRichard Henderson             return;
10737ec8bab3SRichard Henderson         }
10747ec8bab3SRichard Henderson         break;
10757ec8bab3SRichard Henderson     case 8:
10767ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext8s_i32) {
10777ec8bab3SRichard Henderson             tcg_gen_ext8s_i32(ret, arg);
10787ec8bab3SRichard Henderson             tcg_gen_sari_i32(ret, ret, ofs);
10797ec8bab3SRichard Henderson             return;
10807ec8bab3SRichard Henderson         }
10817ec8bab3SRichard Henderson         break;
10827ec8bab3SRichard Henderson     }
10837ec8bab3SRichard Henderson     switch (len) {
10847ec8bab3SRichard Henderson     case 16:
10857ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext16s_i32) {
10867ec8bab3SRichard Henderson             tcg_gen_shri_i32(ret, arg, ofs);
10877ec8bab3SRichard Henderson             tcg_gen_ext16s_i32(ret, ret);
10887ec8bab3SRichard Henderson             return;
10897ec8bab3SRichard Henderson         }
10907ec8bab3SRichard Henderson         break;
10917ec8bab3SRichard Henderson     case 8:
10927ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext8s_i32) {
10937ec8bab3SRichard Henderson             tcg_gen_shri_i32(ret, arg, ofs);
10947ec8bab3SRichard Henderson             tcg_gen_ext8s_i32(ret, ret);
10957ec8bab3SRichard Henderson             return;
10967ec8bab3SRichard Henderson         }
10977ec8bab3SRichard Henderson         break;
10987ec8bab3SRichard Henderson     }
10997ec8bab3SRichard Henderson 
11007ec8bab3SRichard Henderson     tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
11017ec8bab3SRichard Henderson     tcg_gen_sari_i32(ret, ret, 32 - len);
11027ec8bab3SRichard Henderson }
11037ec8bab3SRichard Henderson 
11042089fcc9SDavid Hildenbrand /*
11052089fcc9SDavid Hildenbrand  * Extract 32-bits from a 64-bit input, ah:al, starting from ofs.
11062089fcc9SDavid Hildenbrand  * Unlike tcg_gen_extract_i32 above, len is fixed at 32.
11072089fcc9SDavid Hildenbrand  */
tcg_gen_extract2_i32(TCGv_i32 ret,TCGv_i32 al,TCGv_i32 ah,unsigned int ofs)11082089fcc9SDavid Hildenbrand void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
11092089fcc9SDavid Hildenbrand                           unsigned int ofs)
11102089fcc9SDavid Hildenbrand {
11112089fcc9SDavid Hildenbrand     tcg_debug_assert(ofs <= 32);
11122089fcc9SDavid Hildenbrand     if (ofs == 0) {
11132089fcc9SDavid Hildenbrand         tcg_gen_mov_i32(ret, al);
11142089fcc9SDavid Hildenbrand     } else if (ofs == 32) {
11152089fcc9SDavid Hildenbrand         tcg_gen_mov_i32(ret, ah);
11162089fcc9SDavid Hildenbrand     } else if (al == ah) {
11172089fcc9SDavid Hildenbrand         tcg_gen_rotri_i32(ret, al, ofs);
1118fce1296fSRichard Henderson     } else if (TCG_TARGET_HAS_extract2_i32) {
1119fce1296fSRichard Henderson         tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
11202089fcc9SDavid Hildenbrand     } else {
11215dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
11222089fcc9SDavid Hildenbrand         tcg_gen_shri_i32(t0, al, ofs);
11232089fcc9SDavid Hildenbrand         tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs);
11242089fcc9SDavid Hildenbrand         tcg_temp_free_i32(t0);
11252089fcc9SDavid Hildenbrand     }
11262089fcc9SDavid Hildenbrand }
11272089fcc9SDavid Hildenbrand 
tcg_gen_movcond_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 c1,TCGv_i32 c2,TCGv_i32 v1,TCGv_i32 v2)1128951c6300SRichard Henderson void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
1129951c6300SRichard Henderson                          TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2)
1130951c6300SRichard Henderson {
113137ed3bf1SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
113237ed3bf1SRichard Henderson         tcg_gen_mov_i32(ret, v1);
113337ed3bf1SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
113437ed3bf1SRichard Henderson         tcg_gen_mov_i32(ret, v2);
1135951c6300SRichard Henderson     } else {
11363871be75SRichard Henderson         tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
1137951c6300SRichard Henderson     }
1138951c6300SRichard Henderson }
1139951c6300SRichard Henderson 
tcg_gen_add2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 al,TCGv_i32 ah,TCGv_i32 bl,TCGv_i32 bh)1140951c6300SRichard Henderson void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
1141951c6300SRichard Henderson                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
1142951c6300SRichard Henderson {
1143951c6300SRichard Henderson     if (TCG_TARGET_HAS_add2_i32) {
1144951c6300SRichard Henderson         tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
1145951c6300SRichard Henderson     } else {
11465dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
11475dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1148951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t0, al, ah);
1149951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t1, bl, bh);
1150951c6300SRichard Henderson         tcg_gen_add_i64(t0, t0, t1);
1151951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
1152951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1153951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1154951c6300SRichard Henderson     }
1155951c6300SRichard Henderson }
1156951c6300SRichard Henderson 
tcg_gen_sub2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 al,TCGv_i32 ah,TCGv_i32 bl,TCGv_i32 bh)1157951c6300SRichard Henderson void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
1158951c6300SRichard Henderson                       TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
1159951c6300SRichard Henderson {
1160951c6300SRichard Henderson     if (TCG_TARGET_HAS_sub2_i32) {
1161951c6300SRichard Henderson         tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
1162951c6300SRichard Henderson     } else {
11635dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
11645dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1165951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t0, al, ah);
1166951c6300SRichard Henderson         tcg_gen_concat_i32_i64(t1, bl, bh);
1167951c6300SRichard Henderson         tcg_gen_sub_i64(t0, t0, t1);
1168951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
1169951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1170951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1171951c6300SRichard Henderson     }
1172951c6300SRichard Henderson }
1173951c6300SRichard Henderson 
tcg_gen_mulu2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 arg1,TCGv_i32 arg2)1174951c6300SRichard Henderson void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
1175951c6300SRichard Henderson {
1176951c6300SRichard Henderson     if (TCG_TARGET_HAS_mulu2_i32) {
1177951c6300SRichard Henderson         tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
1178951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_muluh_i32) {
11795dd48602SRichard Henderson         TCGv_i32 t = tcg_temp_ebb_new_i32();
1180951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
1181951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
1182951c6300SRichard Henderson         tcg_gen_mov_i32(rl, t);
1183951c6300SRichard Henderson         tcg_temp_free_i32(t);
11849fd86b51SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 64) {
11855dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
11865dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1187951c6300SRichard Henderson         tcg_gen_extu_i32_i64(t0, arg1);
1188951c6300SRichard Henderson         tcg_gen_extu_i32_i64(t1, arg2);
1189951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, t1);
1190951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
1191951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1192951c6300SRichard Henderson         tcg_temp_free_i64(t1);
11939fd86b51SRichard Henderson     } else {
11949fd86b51SRichard Henderson         qemu_build_not_reached();
1195951c6300SRichard Henderson     }
1196951c6300SRichard Henderson }
1197951c6300SRichard Henderson 
tcg_gen_muls2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 arg1,TCGv_i32 arg2)1198951c6300SRichard Henderson void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
1199951c6300SRichard Henderson {
1200951c6300SRichard Henderson     if (TCG_TARGET_HAS_muls2_i32) {
1201951c6300SRichard Henderson         tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
1202951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_mulsh_i32) {
12035dd48602SRichard Henderson         TCGv_i32 t = tcg_temp_ebb_new_i32();
1204951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
1205951c6300SRichard Henderson         tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
1206951c6300SRichard Henderson         tcg_gen_mov_i32(rl, t);
1207951c6300SRichard Henderson         tcg_temp_free_i32(t);
1208951c6300SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 32) {
12095dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
12105dd48602SRichard Henderson         TCGv_i32 t1 = tcg_temp_ebb_new_i32();
12115dd48602SRichard Henderson         TCGv_i32 t2 = tcg_temp_ebb_new_i32();
12125dd48602SRichard Henderson         TCGv_i32 t3 = tcg_temp_ebb_new_i32();
1213951c6300SRichard Henderson         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
1214951c6300SRichard Henderson         /* Adjust for negative inputs.  */
1215951c6300SRichard Henderson         tcg_gen_sari_i32(t2, arg1, 31);
1216951c6300SRichard Henderson         tcg_gen_sari_i32(t3, arg2, 31);
1217951c6300SRichard Henderson         tcg_gen_and_i32(t2, t2, arg2);
1218951c6300SRichard Henderson         tcg_gen_and_i32(t3, t3, arg1);
1219951c6300SRichard Henderson         tcg_gen_sub_i32(rh, t1, t2);
1220951c6300SRichard Henderson         tcg_gen_sub_i32(rh, rh, t3);
1221951c6300SRichard Henderson         tcg_gen_mov_i32(rl, t0);
1222951c6300SRichard Henderson         tcg_temp_free_i32(t0);
1223951c6300SRichard Henderson         tcg_temp_free_i32(t1);
1224951c6300SRichard Henderson         tcg_temp_free_i32(t2);
1225951c6300SRichard Henderson         tcg_temp_free_i32(t3);
1226951c6300SRichard Henderson     } else {
12275dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
12285dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1229951c6300SRichard Henderson         tcg_gen_ext_i32_i64(t0, arg1);
1230951c6300SRichard Henderson         tcg_gen_ext_i32_i64(t1, arg2);
1231951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, t1);
1232951c6300SRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
1233951c6300SRichard Henderson         tcg_temp_free_i64(t0);
1234951c6300SRichard Henderson         tcg_temp_free_i64(t1);
1235951c6300SRichard Henderson     }
1236951c6300SRichard Henderson }
1237951c6300SRichard Henderson 
tcg_gen_mulsu2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 arg1,TCGv_i32 arg2)12385087abfbSRichard Henderson void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
12395087abfbSRichard Henderson {
12405087abfbSRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
12415dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
12425dd48602SRichard Henderson         TCGv_i32 t1 = tcg_temp_ebb_new_i32();
12435dd48602SRichard Henderson         TCGv_i32 t2 = tcg_temp_ebb_new_i32();
12445087abfbSRichard Henderson         tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
12455087abfbSRichard Henderson         /* Adjust for negative input for the signed arg1.  */
12465087abfbSRichard Henderson         tcg_gen_sari_i32(t2, arg1, 31);
12475087abfbSRichard Henderson         tcg_gen_and_i32(t2, t2, arg2);
12485087abfbSRichard Henderson         tcg_gen_sub_i32(rh, t1, t2);
12495087abfbSRichard Henderson         tcg_gen_mov_i32(rl, t0);
12505087abfbSRichard Henderson         tcg_temp_free_i32(t0);
12515087abfbSRichard Henderson         tcg_temp_free_i32(t1);
12525087abfbSRichard Henderson         tcg_temp_free_i32(t2);
12535087abfbSRichard Henderson     } else {
12545dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
12555dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
12565087abfbSRichard Henderson         tcg_gen_ext_i32_i64(t0, arg1);
12575087abfbSRichard Henderson         tcg_gen_extu_i32_i64(t1, arg2);
12585087abfbSRichard Henderson         tcg_gen_mul_i64(t0, t0, t1);
12595087abfbSRichard Henderson         tcg_gen_extr_i64_i32(rl, rh, t0);
12605087abfbSRichard Henderson         tcg_temp_free_i64(t0);
12615087abfbSRichard Henderson         tcg_temp_free_i64(t1);
12625087abfbSRichard Henderson     }
12635087abfbSRichard Henderson }
12645087abfbSRichard Henderson 
tcg_gen_ext8s_i32(TCGv_i32 ret,TCGv_i32 arg)1265951c6300SRichard Henderson void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
1266951c6300SRichard Henderson {
1267951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext8s_i32) {
1268951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
1269951c6300SRichard Henderson     } else {
1270951c6300SRichard Henderson         tcg_gen_shli_i32(ret, arg, 24);
1271951c6300SRichard Henderson         tcg_gen_sari_i32(ret, ret, 24);
1272951c6300SRichard Henderson     }
1273951c6300SRichard Henderson }
1274951c6300SRichard Henderson 
tcg_gen_ext16s_i32(TCGv_i32 ret,TCGv_i32 arg)1275951c6300SRichard Henderson void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
1276951c6300SRichard Henderson {
1277951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext16s_i32) {
1278951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
1279951c6300SRichard Henderson     } else {
1280951c6300SRichard Henderson         tcg_gen_shli_i32(ret, arg, 16);
1281951c6300SRichard Henderson         tcg_gen_sari_i32(ret, ret, 16);
1282951c6300SRichard Henderson     }
1283951c6300SRichard Henderson }
1284951c6300SRichard Henderson 
tcg_gen_ext8u_i32(TCGv_i32 ret,TCGv_i32 arg)1285951c6300SRichard Henderson void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
1286951c6300SRichard Henderson {
1287951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext8u_i32) {
1288951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
1289951c6300SRichard Henderson     } else {
1290951c6300SRichard Henderson         tcg_gen_andi_i32(ret, arg, 0xffu);
1291951c6300SRichard Henderson     }
1292951c6300SRichard Henderson }
1293951c6300SRichard Henderson 
tcg_gen_ext16u_i32(TCGv_i32 ret,TCGv_i32 arg)1294951c6300SRichard Henderson void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
1295951c6300SRichard Henderson {
1296951c6300SRichard Henderson     if (TCG_TARGET_HAS_ext16u_i32) {
1297951c6300SRichard Henderson         tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
1298951c6300SRichard Henderson     } else {
1299951c6300SRichard Henderson         tcg_gen_andi_i32(ret, arg, 0xffffu);
1300951c6300SRichard Henderson     }
1301951c6300SRichard Henderson }
1302951c6300SRichard Henderson 
13034de5a76aSPhilippe Mathieu-Daudé /*
13044de5a76aSPhilippe Mathieu-Daudé  * bswap16_i32: 16-bit byte swap on the low bits of a 32-bit value.
13054de5a76aSPhilippe Mathieu-Daudé  *
13064de5a76aSPhilippe Mathieu-Daudé  * Byte pattern: xxab -> yyba
13074de5a76aSPhilippe Mathieu-Daudé  *
13084de5a76aSPhilippe Mathieu-Daudé  * With TCG_BSWAP_IZ, x == zero, else undefined.
13094de5a76aSPhilippe Mathieu-Daudé  * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
13104de5a76aSPhilippe Mathieu-Daudé  */
tcg_gen_bswap16_i32(TCGv_i32 ret,TCGv_i32 arg,int flags)13112b836c2aSRichard Henderson void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags)
1312951c6300SRichard Henderson {
13132b836c2aSRichard Henderson     /* Only one extension flag may be present. */
13142b836c2aSRichard Henderson     tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
13152b836c2aSRichard Henderson 
1316951c6300SRichard Henderson     if (TCG_TARGET_HAS_bswap16_i32) {
13172b836c2aSRichard Henderson         tcg_gen_op3i_i32(INDEX_op_bswap16_i32, ret, arg, flags);
1318951c6300SRichard Henderson     } else {
13195dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
13205dd48602SRichard Henderson         TCGv_i32 t1 = tcg_temp_ebb_new_i32();
1321951c6300SRichard Henderson 
13224de5a76aSPhilippe Mathieu-Daudé                                             /* arg = ..ab (IZ) xxab (!IZ) */
13234de5a76aSPhilippe Mathieu-Daudé         tcg_gen_shri_i32(t0, arg, 8);       /*  t0 = ...a (IZ) .xxa (!IZ) */
13242b836c2aSRichard Henderson         if (!(flags & TCG_BSWAP_IZ)) {
13254de5a76aSPhilippe Mathieu-Daudé             tcg_gen_ext8u_i32(t0, t0);      /*  t0 = ...a */
13262b836c2aSRichard Henderson         }
13272b836c2aSRichard Henderson 
13282b836c2aSRichard Henderson         if (flags & TCG_BSWAP_OS) {
13294de5a76aSPhilippe Mathieu-Daudé             tcg_gen_shli_i32(t1, arg, 24);  /*  t1 = b... */
13304de5a76aSPhilippe Mathieu-Daudé             tcg_gen_sari_i32(t1, t1, 16);   /*  t1 = ssb. */
13312b836c2aSRichard Henderson         } else if (flags & TCG_BSWAP_OZ) {
13324de5a76aSPhilippe Mathieu-Daudé             tcg_gen_ext8u_i32(t1, arg);     /*  t1 = ...b */
13334de5a76aSPhilippe Mathieu-Daudé             tcg_gen_shli_i32(t1, t1, 8);    /*  t1 = ..b. */
13342b836c2aSRichard Henderson         } else {
13354de5a76aSPhilippe Mathieu-Daudé             tcg_gen_shli_i32(t1, arg, 8);   /*  t1 = xab. */
13362b836c2aSRichard Henderson         }
13372b836c2aSRichard Henderson 
13384de5a76aSPhilippe Mathieu-Daudé         tcg_gen_or_i32(ret, t0, t1);        /* ret = ..ba (OZ) */
13394de5a76aSPhilippe Mathieu-Daudé                                             /*     = ssba (OS) */
13404de5a76aSPhilippe Mathieu-Daudé                                             /*     = xaba (no flag) */
1341951c6300SRichard Henderson         tcg_temp_free_i32(t0);
13422b836c2aSRichard Henderson         tcg_temp_free_i32(t1);
1343951c6300SRichard Henderson     }
1344951c6300SRichard Henderson }
1345951c6300SRichard Henderson 
134692964556SPhilippe Mathieu-Daudé /*
134792964556SPhilippe Mathieu-Daudé  * bswap32_i32: 32-bit byte swap on a 32-bit value.
134892964556SPhilippe Mathieu-Daudé  *
134992964556SPhilippe Mathieu-Daudé  * Byte pattern: abcd -> dcba
135092964556SPhilippe Mathieu-Daudé  */
tcg_gen_bswap32_i32(TCGv_i32 ret,TCGv_i32 arg)1351951c6300SRichard Henderson void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
1352951c6300SRichard Henderson {
1353951c6300SRichard Henderson     if (TCG_TARGET_HAS_bswap32_i32) {
1354587195bdSRichard Henderson         tcg_gen_op3i_i32(INDEX_op_bswap32_i32, ret, arg, 0);
1355951c6300SRichard Henderson     } else {
13565dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
13575dd48602SRichard Henderson         TCGv_i32 t1 = tcg_temp_ebb_new_i32();
135811d11d61SRichard Henderson         TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff);
1359951c6300SRichard Henderson 
1360a686dc71SRichard Henderson                                         /* arg = abcd */
1361a686dc71SRichard Henderson         tcg_gen_shri_i32(t0, arg, 8);   /*  t0 = .abc */
1362a686dc71SRichard Henderson         tcg_gen_and_i32(t1, arg, t2);   /*  t1 = .b.d */
1363a686dc71SRichard Henderson         tcg_gen_and_i32(t0, t0, t2);    /*  t0 = .a.c */
1364a686dc71SRichard Henderson         tcg_gen_shli_i32(t1, t1, 8);    /*  t1 = b.d. */
1365a686dc71SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);    /* ret = badc */
1366951c6300SRichard Henderson 
1367a686dc71SRichard Henderson         tcg_gen_shri_i32(t0, ret, 16);  /*  t0 = ..ba */
1368a686dc71SRichard Henderson         tcg_gen_shli_i32(t1, ret, 16);  /*  t1 = dc.. */
1369a686dc71SRichard Henderson         tcg_gen_or_i32(ret, t0, t1);    /* ret = dcba */
1370951c6300SRichard Henderson 
1371951c6300SRichard Henderson         tcg_temp_free_i32(t0);
1372951c6300SRichard Henderson         tcg_temp_free_i32(t1);
1373951c6300SRichard Henderson     }
1374951c6300SRichard Henderson }
1375951c6300SRichard Henderson 
1376b8976aa5SPhilippe Mathieu-Daudé /*
1377b8976aa5SPhilippe Mathieu-Daudé  * hswap_i32: Swap 16-bit halfwords within a 32-bit value.
1378b8976aa5SPhilippe Mathieu-Daudé  *
1379b8976aa5SPhilippe Mathieu-Daudé  * Byte pattern: abcd -> cdab
1380b8976aa5SPhilippe Mathieu-Daudé  */
tcg_gen_hswap_i32(TCGv_i32 ret,TCGv_i32 arg)138146be8425SRichard Henderson void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg)
138246be8425SRichard Henderson {
138346be8425SRichard Henderson     /* Swapping 2 16-bit elements is a rotate. */
138446be8425SRichard Henderson     tcg_gen_rotli_i32(ret, arg, 16);
138546be8425SRichard Henderson }
138646be8425SRichard Henderson 
tcg_gen_smin_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1387b87fb8cdSRichard Henderson void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1388b87fb8cdSRichard Henderson {
1389b87fb8cdSRichard Henderson     tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b);
1390b87fb8cdSRichard Henderson }
1391b87fb8cdSRichard Henderson 
tcg_gen_umin_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1392b87fb8cdSRichard Henderson void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1393b87fb8cdSRichard Henderson {
1394b87fb8cdSRichard Henderson     tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b);
1395b87fb8cdSRichard Henderson }
1396b87fb8cdSRichard Henderson 
tcg_gen_smax_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1397b87fb8cdSRichard Henderson void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1398b87fb8cdSRichard Henderson {
1399b87fb8cdSRichard Henderson     tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a);
1400b87fb8cdSRichard Henderson }
1401b87fb8cdSRichard Henderson 
tcg_gen_umax_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1402b87fb8cdSRichard Henderson void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1403b87fb8cdSRichard Henderson {
1404b87fb8cdSRichard Henderson     tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a);
1405b87fb8cdSRichard Henderson }
1406b87fb8cdSRichard Henderson 
tcg_gen_abs_i32(TCGv_i32 ret,TCGv_i32 a)1407ff1f11f7SRichard Henderson void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a)
1408ff1f11f7SRichard Henderson {
14095dd48602SRichard Henderson     TCGv_i32 t = tcg_temp_ebb_new_i32();
1410ff1f11f7SRichard Henderson 
1411ff1f11f7SRichard Henderson     tcg_gen_sari_i32(t, a, 31);
1412ff1f11f7SRichard Henderson     tcg_gen_xor_i32(ret, a, t);
1413ff1f11f7SRichard Henderson     tcg_gen_sub_i32(ret, ret, t);
1414ff1f11f7SRichard Henderson     tcg_temp_free_i32(t);
1415ff1f11f7SRichard Henderson }
1416ff1f11f7SRichard Henderson 
tcg_gen_ld8u_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)141709607d35SRichard Henderson void tcg_gen_ld8u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
141809607d35SRichard Henderson {
141909607d35SRichard Henderson     tcg_gen_ldst_op_i32(INDEX_op_ld8u_i32, ret, arg2, offset);
142009607d35SRichard Henderson }
142109607d35SRichard Henderson 
tcg_gen_ld8s_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)142209607d35SRichard Henderson void tcg_gen_ld8s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
142309607d35SRichard Henderson {
142409607d35SRichard Henderson     tcg_gen_ldst_op_i32(INDEX_op_ld8s_i32, ret, arg2, offset);
142509607d35SRichard Henderson }
142609607d35SRichard Henderson 
tcg_gen_ld16u_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)142709607d35SRichard Henderson void tcg_gen_ld16u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
142809607d35SRichard Henderson {
142909607d35SRichard Henderson     tcg_gen_ldst_op_i32(INDEX_op_ld16u_i32, ret, arg2, offset);
143009607d35SRichard Henderson }
143109607d35SRichard Henderson 
tcg_gen_ld16s_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)143209607d35SRichard Henderson void tcg_gen_ld16s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
143309607d35SRichard Henderson {
143409607d35SRichard Henderson     tcg_gen_ldst_op_i32(INDEX_op_ld16s_i32, ret, arg2, offset);
143509607d35SRichard Henderson }
143609607d35SRichard Henderson 
tcg_gen_ld_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)143709607d35SRichard Henderson void tcg_gen_ld_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
143809607d35SRichard Henderson {
143909607d35SRichard Henderson     tcg_gen_ldst_op_i32(INDEX_op_ld_i32, ret, arg2, offset);
144009607d35SRichard Henderson }
144109607d35SRichard Henderson 
tcg_gen_st8_i32(TCGv_i32 arg1,TCGv_ptr arg2,tcg_target_long offset)144209607d35SRichard Henderson void tcg_gen_st8_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
144309607d35SRichard Henderson {
144409607d35SRichard Henderson     tcg_gen_ldst_op_i32(INDEX_op_st8_i32, arg1, arg2, offset);
144509607d35SRichard Henderson }
144609607d35SRichard Henderson 
tcg_gen_st16_i32(TCGv_i32 arg1,TCGv_ptr arg2,tcg_target_long offset)144709607d35SRichard Henderson void tcg_gen_st16_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
144809607d35SRichard Henderson {
144909607d35SRichard Henderson     tcg_gen_ldst_op_i32(INDEX_op_st16_i32, arg1, arg2, offset);
145009607d35SRichard Henderson }
145109607d35SRichard Henderson 
tcg_gen_st_i32(TCGv_i32 arg1,TCGv_ptr arg2,tcg_target_long offset)145209607d35SRichard Henderson void tcg_gen_st_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
145309607d35SRichard Henderson {
145409607d35SRichard Henderson     tcg_gen_ldst_op_i32(INDEX_op_st_i32, arg1, arg2, offset);
145509607d35SRichard Henderson }
145609607d35SRichard Henderson 
145709607d35SRichard Henderson 
1458951c6300SRichard Henderson /* 64-bit ops */
1459951c6300SRichard Henderson 
tcg_gen_discard_i64(TCGv_i64 arg)1460951c6300SRichard Henderson void tcg_gen_discard_i64(TCGv_i64 arg)
1461951c6300SRichard Henderson {
1462e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1463e0de2f55SRichard Henderson         tcg_gen_op1_i64(INDEX_op_discard, arg);
1464e0de2f55SRichard Henderson     } else {
1465951c6300SRichard Henderson         tcg_gen_discard_i32(TCGV_LOW(arg));
1466951c6300SRichard Henderson         tcg_gen_discard_i32(TCGV_HIGH(arg));
1467951c6300SRichard Henderson     }
1468e0de2f55SRichard Henderson }
1469951c6300SRichard Henderson 
tcg_gen_mov_i64(TCGv_i64 ret,TCGv_i64 arg)1470951c6300SRichard Henderson void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
1471951c6300SRichard Henderson {
1472e0de2f55SRichard Henderson     if (ret == arg) {
1473e0de2f55SRichard Henderson         return;
1474e0de2f55SRichard Henderson     }
1475e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1476e0de2f55SRichard Henderson         tcg_gen_op2_i64(INDEX_op_mov_i64, ret, arg);
1477e0de2f55SRichard Henderson     } else {
147811d11d61SRichard Henderson         TCGTemp *ts = tcgv_i64_temp(arg);
147911d11d61SRichard Henderson 
148011d11d61SRichard Henderson         /* Canonicalize TCGv_i64 TEMP_CONST into TCGv_i32 TEMP_CONST. */
148111d11d61SRichard Henderson         if (ts->kind == TEMP_CONST) {
148211d11d61SRichard Henderson             tcg_gen_movi_i64(ret, ts->val);
148311d11d61SRichard Henderson         } else {
1484951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1485951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
1486951c6300SRichard Henderson         }
148711d11d61SRichard Henderson     }
1488e0de2f55SRichard Henderson }
1489951c6300SRichard Henderson 
tcg_gen_movi_i64(TCGv_i64 ret,int64_t arg)1490951c6300SRichard Henderson void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
1491951c6300SRichard Henderson {
1492e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1493e0de2f55SRichard Henderson         tcg_gen_mov_i64(ret, tcg_constant_i64(arg));
1494e0de2f55SRichard Henderson     } else {
1495951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_LOW(ret), arg);
1496951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
1497951c6300SRichard Henderson     }
1498e0de2f55SRichard Henderson }
1499951c6300SRichard Henderson 
tcg_gen_ld8u_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1500951c6300SRichard Henderson void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1501951c6300SRichard Henderson {
1502e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1503e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_ld8u_i64, ret, arg2, offset);
1504e0de2f55SRichard Henderson     } else {
1505951c6300SRichard Henderson         tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset);
1506951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1507951c6300SRichard Henderson     }
1508e0de2f55SRichard Henderson }
1509951c6300SRichard Henderson 
tcg_gen_ld8s_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1510951c6300SRichard Henderson void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1511951c6300SRichard Henderson {
1512e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1513e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_ld8s_i64, ret, arg2, offset);
1514e0de2f55SRichard Henderson     } else {
1515951c6300SRichard Henderson         tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
15163ff91d7eSJoseph Myers         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1517951c6300SRichard Henderson     }
1518e0de2f55SRichard Henderson }
1519951c6300SRichard Henderson 
tcg_gen_ld16u_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1520951c6300SRichard Henderson void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1521951c6300SRichard Henderson {
1522e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1523e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_ld16u_i64, ret, arg2, offset);
1524e0de2f55SRichard Henderson     } else {
1525951c6300SRichard Henderson         tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset);
1526951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1527951c6300SRichard Henderson     }
1528e0de2f55SRichard Henderson }
1529951c6300SRichard Henderson 
tcg_gen_ld16s_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1530951c6300SRichard Henderson void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1531951c6300SRichard Henderson {
1532e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1533e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_ld16s_i64, ret, arg2, offset);
1534e0de2f55SRichard Henderson     } else {
1535951c6300SRichard Henderson         tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset);
1536951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1537951c6300SRichard Henderson     }
1538e0de2f55SRichard Henderson }
1539951c6300SRichard Henderson 
tcg_gen_ld32u_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1540951c6300SRichard Henderson void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1541951c6300SRichard Henderson {
1542e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1543e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_ld32u_i64, ret, arg2, offset);
1544e0de2f55SRichard Henderson     } else {
1545951c6300SRichard Henderson         tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1546951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1547951c6300SRichard Henderson     }
1548e0de2f55SRichard Henderson }
1549951c6300SRichard Henderson 
tcg_gen_ld32s_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1550951c6300SRichard Henderson void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1551951c6300SRichard Henderson {
1552e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1553e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_ld32s_i64, ret, arg2, offset);
1554e0de2f55SRichard Henderson     } else {
1555951c6300SRichard Henderson         tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1556951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1557951c6300SRichard Henderson     }
1558e0de2f55SRichard Henderson }
1559951c6300SRichard Henderson 
tcg_gen_ld_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1560951c6300SRichard Henderson void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1561951c6300SRichard Henderson {
1562e0de2f55SRichard Henderson     /*
1563e0de2f55SRichard Henderson      * For 32-bit host, since arg2 and ret have different types,
1564e0de2f55SRichard Henderson      * they cannot be the same temporary -- no chance of overlap.
1565e0de2f55SRichard Henderson      */
1566e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1567e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_ld_i64, ret, arg2, offset);
1568e0de2f55SRichard Henderson     } else if (HOST_BIG_ENDIAN) {
1569951c6300SRichard Henderson         tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
1570951c6300SRichard Henderson         tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
1571e0de2f55SRichard Henderson     } else {
1572951c6300SRichard Henderson         tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1573951c6300SRichard Henderson         tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
1574e0de2f55SRichard Henderson     }
1575951c6300SRichard Henderson }
1576951c6300SRichard Henderson 
tcg_gen_st8_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1577d56fea79SRichard Henderson void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1578d56fea79SRichard Henderson {
1579e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1580e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_st8_i64, arg1, arg2, offset);
1581e0de2f55SRichard Henderson     } else {
1582d56fea79SRichard Henderson         tcg_gen_st8_i32(TCGV_LOW(arg1), arg2, offset);
1583d56fea79SRichard Henderson     }
1584e0de2f55SRichard Henderson }
1585d56fea79SRichard Henderson 
tcg_gen_st16_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1586d56fea79SRichard Henderson void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1587d56fea79SRichard Henderson {
1588e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1589e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_st16_i64, arg1, arg2, offset);
1590e0de2f55SRichard Henderson     } else {
1591d56fea79SRichard Henderson         tcg_gen_st16_i32(TCGV_LOW(arg1), arg2, offset);
1592d56fea79SRichard Henderson     }
1593e0de2f55SRichard Henderson }
1594d56fea79SRichard Henderson 
tcg_gen_st32_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1595d56fea79SRichard Henderson void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1596d56fea79SRichard Henderson {
1597e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1598e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_st32_i64, arg1, arg2, offset);
1599e0de2f55SRichard Henderson     } else {
1600d56fea79SRichard Henderson         tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
1601d56fea79SRichard Henderson     }
1602e0de2f55SRichard Henderson }
1603d56fea79SRichard Henderson 
tcg_gen_st_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1604951c6300SRichard Henderson void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1605951c6300SRichard Henderson {
1606e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1607e0de2f55SRichard Henderson         tcg_gen_ldst_op_i64(INDEX_op_st_i64, arg1, arg2, offset);
1608e0de2f55SRichard Henderson     } else if (HOST_BIG_ENDIAN) {
1609951c6300SRichard Henderson         tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
1610951c6300SRichard Henderson         tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
1611e0de2f55SRichard Henderson     } else {
1612951c6300SRichard Henderson         tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
1613951c6300SRichard Henderson         tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
1614e0de2f55SRichard Henderson     }
1615951c6300SRichard Henderson }
1616951c6300SRichard Henderson 
tcg_gen_add_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1617d56fea79SRichard Henderson void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1618d56fea79SRichard Henderson {
1619e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1620e0de2f55SRichard Henderson         tcg_gen_op3_i64(INDEX_op_add_i64, ret, arg1, arg2);
1621e0de2f55SRichard Henderson     } else {
1622d56fea79SRichard Henderson         tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1),
1623d56fea79SRichard Henderson                          TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2));
1624d56fea79SRichard Henderson     }
1625e0de2f55SRichard Henderson }
1626d56fea79SRichard Henderson 
tcg_gen_sub_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1627d56fea79SRichard Henderson void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1628d56fea79SRichard Henderson {
1629e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1630e0de2f55SRichard Henderson         tcg_gen_op3_i64(INDEX_op_sub_i64, ret, arg1, arg2);
1631e0de2f55SRichard Henderson     } else {
1632d56fea79SRichard Henderson         tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1),
1633d56fea79SRichard Henderson                          TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2));
1634d56fea79SRichard Henderson     }
1635e0de2f55SRichard Henderson }
1636d56fea79SRichard Henderson 
tcg_gen_and_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1637951c6300SRichard Henderson void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1638951c6300SRichard Henderson {
1639e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1640e0de2f55SRichard Henderson         tcg_gen_op3_i64(INDEX_op_and_i64, ret, arg1, arg2);
1641e0de2f55SRichard Henderson     } else {
1642951c6300SRichard Henderson         tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1643951c6300SRichard Henderson         tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1644951c6300SRichard Henderson     }
1645e0de2f55SRichard Henderson }
1646951c6300SRichard Henderson 
tcg_gen_or_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1647951c6300SRichard Henderson void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1648951c6300SRichard Henderson {
1649e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1650e0de2f55SRichard Henderson         tcg_gen_op3_i64(INDEX_op_or_i64, ret, arg1, arg2);
1651e0de2f55SRichard Henderson     } else {
1652951c6300SRichard Henderson         tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1653951c6300SRichard Henderson         tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1654951c6300SRichard Henderson     }
1655e0de2f55SRichard Henderson }
1656951c6300SRichard Henderson 
tcg_gen_xor_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1657951c6300SRichard Henderson void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1658951c6300SRichard Henderson {
1659e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1660e0de2f55SRichard Henderson         tcg_gen_op3_i64(INDEX_op_xor_i64, ret, arg1, arg2);
1661e0de2f55SRichard Henderson     } else {
1662951c6300SRichard Henderson         tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1663951c6300SRichard Henderson         tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1664951c6300SRichard Henderson     }
1665e0de2f55SRichard Henderson }
1666951c6300SRichard Henderson 
tcg_gen_shl_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1667951c6300SRichard Henderson void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1668951c6300SRichard Henderson {
1669e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1670e0de2f55SRichard Henderson         tcg_gen_op3_i64(INDEX_op_shl_i64, ret, arg1, arg2);
1671e0de2f55SRichard Henderson     } else {
1672951c6300SRichard Henderson         gen_helper_shl_i64(ret, arg1, arg2);
1673951c6300SRichard Henderson     }
1674e0de2f55SRichard Henderson }
1675951c6300SRichard Henderson 
tcg_gen_shr_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1676951c6300SRichard Henderson void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1677951c6300SRichard Henderson {
1678e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1679e0de2f55SRichard Henderson         tcg_gen_op3_i64(INDEX_op_shr_i64, ret, arg1, arg2);
1680e0de2f55SRichard Henderson     } else {
1681951c6300SRichard Henderson         gen_helper_shr_i64(ret, arg1, arg2);
1682951c6300SRichard Henderson     }
1683e0de2f55SRichard Henderson }
1684951c6300SRichard Henderson 
tcg_gen_sar_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1685951c6300SRichard Henderson void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1686951c6300SRichard Henderson {
1687e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1688e0de2f55SRichard Henderson         tcg_gen_op3_i64(INDEX_op_sar_i64, ret, arg1, arg2);
1689e0de2f55SRichard Henderson     } else {
1690951c6300SRichard Henderson         gen_helper_sar_i64(ret, arg1, arg2);
1691951c6300SRichard Henderson     }
1692e0de2f55SRichard Henderson }
1693951c6300SRichard Henderson 
tcg_gen_mul_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1694951c6300SRichard Henderson void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1695951c6300SRichard Henderson {
1696951c6300SRichard Henderson     TCGv_i64 t0;
1697951c6300SRichard Henderson     TCGv_i32 t1;
1698951c6300SRichard Henderson 
1699e0de2f55SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1700e0de2f55SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2);
1701e0de2f55SRichard Henderson         return;
1702e0de2f55SRichard Henderson     }
1703e0de2f55SRichard Henderson 
1704e0de2f55SRichard Henderson 
17055dd48602SRichard Henderson     t0 = tcg_temp_ebb_new_i64();
17065dd48602SRichard Henderson     t1 = tcg_temp_ebb_new_i32();
1707951c6300SRichard Henderson 
1708951c6300SRichard Henderson     tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
1709951c6300SRichard Henderson                       TCGV_LOW(arg1), TCGV_LOW(arg2));
1710951c6300SRichard Henderson 
1711951c6300SRichard Henderson     tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
1712951c6300SRichard Henderson     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1713951c6300SRichard Henderson     tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2));
1714951c6300SRichard Henderson     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1715951c6300SRichard Henderson 
1716951c6300SRichard Henderson     tcg_gen_mov_i64(ret, t0);
1717951c6300SRichard Henderson     tcg_temp_free_i64(t0);
1718951c6300SRichard Henderson     tcg_temp_free_i32(t1);
1719951c6300SRichard Henderson }
172011d11d61SRichard Henderson 
tcg_gen_addi_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1721951c6300SRichard Henderson void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1722951c6300SRichard Henderson {
1723951c6300SRichard Henderson     /* some cases can be optimized here */
1724951c6300SRichard Henderson     if (arg2 == 0) {
1725951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
172611d11d61SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 64) {
172711d11d61SRichard Henderson         tcg_gen_add_i64(ret, arg1, tcg_constant_i64(arg2));
1728951c6300SRichard Henderson     } else {
172911d11d61SRichard Henderson         tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
173011d11d61SRichard Henderson                          TCGV_LOW(arg1), TCGV_HIGH(arg1),
173111d11d61SRichard Henderson                          tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32));
1732951c6300SRichard Henderson     }
1733951c6300SRichard Henderson }
1734951c6300SRichard Henderson 
tcg_gen_subfi_i64(TCGv_i64 ret,int64_t arg1,TCGv_i64 arg2)1735951c6300SRichard Henderson void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2)
1736951c6300SRichard Henderson {
1737b701f195SRichard Henderson     if (arg1 == 0) {
1738b701f195SRichard Henderson         tcg_gen_neg_i64(ret, arg2);
173911d11d61SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 64) {
174011d11d61SRichard Henderson         tcg_gen_sub_i64(ret, tcg_constant_i64(arg1), arg2);
1741951c6300SRichard Henderson     } else {
174211d11d61SRichard Henderson         tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
174311d11d61SRichard Henderson                          tcg_constant_i32(arg1), tcg_constant_i32(arg1 >> 32),
174411d11d61SRichard Henderson                          TCGV_LOW(arg2), TCGV_HIGH(arg2));
1745951c6300SRichard Henderson     }
1746951c6300SRichard Henderson }
1747951c6300SRichard Henderson 
tcg_gen_subi_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1748951c6300SRichard Henderson void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1749951c6300SRichard Henderson {
1750*1551004eSRichard Henderson     tcg_gen_addi_i64(ret, arg1, -arg2);
1751951c6300SRichard Henderson }
1752951c6300SRichard Henderson 
tcg_gen_neg_i64(TCGv_i64 ret,TCGv_i64 arg)1753e0de2f55SRichard Henderson void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg)
1754e0de2f55SRichard Henderson {
1755b701f195SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
1756e0de2f55SRichard Henderson         tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg);
1757e0de2f55SRichard Henderson     } else {
1758b701f195SRichard Henderson         TCGv_i32 zero = tcg_constant_i32(0);
1759b701f195SRichard Henderson         tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
1760b701f195SRichard Henderson                          zero, zero, TCGV_LOW(arg), TCGV_HIGH(arg));
1761e0de2f55SRichard Henderson     }
1762e0de2f55SRichard Henderson }
1763e0de2f55SRichard Henderson 
tcg_gen_andi_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1764474b2e8fSRichard Henderson void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1765951c6300SRichard Henderson {
17663a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1767951c6300SRichard Henderson         tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1768951c6300SRichard Henderson         tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
17693a13c3f3SRichard Henderson         return;
17703a13c3f3SRichard Henderson     }
17713a13c3f3SRichard Henderson 
1772951c6300SRichard Henderson     /* Some cases can be optimized here.  */
1773951c6300SRichard Henderson     switch (arg2) {
1774951c6300SRichard Henderson     case 0:
1775951c6300SRichard Henderson         tcg_gen_movi_i64(ret, 0);
1776951c6300SRichard Henderson         return;
1777474b2e8fSRichard Henderson     case -1:
1778951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1779951c6300SRichard Henderson         return;
1780474b2e8fSRichard Henderson     case 0xff:
1781951c6300SRichard Henderson         /* Don't recurse with tcg_gen_ext8u_i64.  */
1782951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext8u_i64) {
1783951c6300SRichard Henderson             tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
1784951c6300SRichard Henderson             return;
1785951c6300SRichard Henderson         }
1786951c6300SRichard Henderson         break;
1787474b2e8fSRichard Henderson     case 0xffff:
1788951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext16u_i64) {
1789951c6300SRichard Henderson             tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
1790951c6300SRichard Henderson             return;
1791951c6300SRichard Henderson         }
1792951c6300SRichard Henderson         break;
1793474b2e8fSRichard Henderson     case 0xffffffffu:
1794951c6300SRichard Henderson         if (TCG_TARGET_HAS_ext32u_i64) {
1795951c6300SRichard Henderson             tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
1796951c6300SRichard Henderson             return;
1797951c6300SRichard Henderson         }
1798951c6300SRichard Henderson         break;
1799951c6300SRichard Henderson     }
180011d11d61SRichard Henderson 
180111d11d61SRichard Henderson     tcg_gen_and_i64(ret, arg1, tcg_constant_i64(arg2));
1802951c6300SRichard Henderson }
1803951c6300SRichard Henderson 
tcg_gen_ori_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1804951c6300SRichard Henderson void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1805951c6300SRichard Henderson {
18063a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1807951c6300SRichard Henderson         tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1808951c6300SRichard Henderson         tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
18093a13c3f3SRichard Henderson         return;
18103a13c3f3SRichard Henderson     }
1811951c6300SRichard Henderson     /* Some cases can be optimized here.  */
1812951c6300SRichard Henderson     if (arg2 == -1) {
1813951c6300SRichard Henderson         tcg_gen_movi_i64(ret, -1);
1814951c6300SRichard Henderson     } else if (arg2 == 0) {
1815951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1816951c6300SRichard Henderson     } else {
181711d11d61SRichard Henderson         tcg_gen_or_i64(ret, arg1, tcg_constant_i64(arg2));
1818951c6300SRichard Henderson     }
1819951c6300SRichard Henderson }
1820951c6300SRichard Henderson 
tcg_gen_xori_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1821951c6300SRichard Henderson void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1822951c6300SRichard Henderson {
18233a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
1824951c6300SRichard Henderson         tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1825951c6300SRichard Henderson         tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
18263a13c3f3SRichard Henderson         return;
18273a13c3f3SRichard Henderson     }
1828951c6300SRichard Henderson     /* Some cases can be optimized here.  */
1829951c6300SRichard Henderson     if (arg2 == 0) {
1830951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1831951c6300SRichard Henderson     } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) {
1832951c6300SRichard Henderson         /* Don't recurse with tcg_gen_not_i64.  */
1833951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1);
1834951c6300SRichard Henderson     } else {
183511d11d61SRichard Henderson         tcg_gen_xor_i64(ret, arg1, tcg_constant_i64(arg2));
1836951c6300SRichard Henderson     }
1837951c6300SRichard Henderson }
1838951c6300SRichard Henderson 
tcg_gen_shifti_i64(TCGv_i64 ret,TCGv_i64 arg1,unsigned c,bool right,bool arith)1839951c6300SRichard Henderson static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
1840951c6300SRichard Henderson                                       unsigned c, bool right, bool arith)
1841951c6300SRichard Henderson {
1842951c6300SRichard Henderson     tcg_debug_assert(c < 64);
1843951c6300SRichard Henderson     if (c == 0) {
1844951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1845951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1846951c6300SRichard Henderson     } else if (c >= 32) {
1847951c6300SRichard Henderson         c -= 32;
1848951c6300SRichard Henderson         if (right) {
1849951c6300SRichard Henderson             if (arith) {
1850951c6300SRichard Henderson                 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1851951c6300SRichard Henderson                 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
1852951c6300SRichard Henderson             } else {
1853951c6300SRichard Henderson                 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1854951c6300SRichard Henderson                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1855951c6300SRichard Henderson             }
1856951c6300SRichard Henderson         } else {
1857951c6300SRichard Henderson             tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
1858951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_LOW(ret), 0);
1859951c6300SRichard Henderson         }
186002616badSRichard Henderson     } else if (right) {
186102616badSRichard Henderson         if (TCG_TARGET_HAS_extract2_i32) {
186202616badSRichard Henderson             tcg_gen_extract2_i32(TCGV_LOW(ret),
186302616badSRichard Henderson                                  TCGV_LOW(arg1), TCGV_HIGH(arg1), c);
1864951c6300SRichard Henderson         } else {
1865951c6300SRichard Henderson             tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
186602616badSRichard Henderson             tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(ret),
186702616badSRichard Henderson                                 TCGV_HIGH(arg1), 32 - c, c);
1868951c6300SRichard Henderson         }
186902616badSRichard Henderson         if (arith) {
187002616badSRichard Henderson             tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
187102616badSRichard Henderson         } else {
187202616badSRichard Henderson             tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
187302616badSRichard Henderson         }
187402616badSRichard Henderson     } else {
187502616badSRichard Henderson         if (TCG_TARGET_HAS_extract2_i32) {
187602616badSRichard Henderson             tcg_gen_extract2_i32(TCGV_HIGH(ret),
187702616badSRichard Henderson                                  TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
187802616badSRichard Henderson         } else {
18795dd48602SRichard Henderson             TCGv_i32 t0 = tcg_temp_ebb_new_i32();
188002616badSRichard Henderson             tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
188102616badSRichard Henderson             tcg_gen_deposit_i32(TCGV_HIGH(ret), t0,
188202616badSRichard Henderson                                 TCGV_HIGH(arg1), c, 32 - c);
1883951c6300SRichard Henderson             tcg_temp_free_i32(t0);
188402616badSRichard Henderson         }
188502616badSRichard Henderson         tcg_gen_shli_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
1886951c6300SRichard Henderson     }
1887951c6300SRichard Henderson }
1888951c6300SRichard Henderson 
tcg_gen_shli_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1889474b2e8fSRichard Henderson void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1890951c6300SRichard Henderson {
1891474b2e8fSRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
18923a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
18933a13c3f3SRichard Henderson         tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
18943a13c3f3SRichard Henderson     } else if (arg2 == 0) {
1895951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1896951c6300SRichard Henderson     } else {
189711d11d61SRichard Henderson         tcg_gen_shl_i64(ret, arg1, tcg_constant_i64(arg2));
1898951c6300SRichard Henderson     }
1899951c6300SRichard Henderson }
1900951c6300SRichard Henderson 
tcg_gen_shri_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1901474b2e8fSRichard Henderson void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1902951c6300SRichard Henderson {
1903474b2e8fSRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
19043a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
19053a13c3f3SRichard Henderson         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
19063a13c3f3SRichard Henderson     } else if (arg2 == 0) {
1907951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1908951c6300SRichard Henderson     } else {
190911d11d61SRichard Henderson         tcg_gen_shr_i64(ret, arg1, tcg_constant_i64(arg2));
1910951c6300SRichard Henderson     }
1911951c6300SRichard Henderson }
1912951c6300SRichard Henderson 
tcg_gen_sari_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1913474b2e8fSRichard Henderson void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1914951c6300SRichard Henderson {
1915474b2e8fSRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
19163a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
19173a13c3f3SRichard Henderson         tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
19183a13c3f3SRichard Henderson     } else if (arg2 == 0) {
1919951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
1920951c6300SRichard Henderson     } else {
192111d11d61SRichard Henderson         tcg_gen_sar_i64(ret, arg1, tcg_constant_i64(arg2));
1922951c6300SRichard Henderson     }
1923951c6300SRichard Henderson }
1924951c6300SRichard Henderson 
tcg_gen_brcond_i64(TCGCond cond,TCGv_i64 arg1,TCGv_i64 arg2,TCGLabel * l)192542a268c2SRichard Henderson void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l)
1926951c6300SRichard Henderson {
1927951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
192842a268c2SRichard Henderson         tcg_gen_br(l);
1929951c6300SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
19303a13c3f3SRichard Henderson         if (TCG_TARGET_REG_BITS == 32) {
1931951c6300SRichard Henderson             tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),
1932951c6300SRichard Henderson                               TCGV_HIGH(arg1), TCGV_LOW(arg2),
193342a268c2SRichard Henderson                               TCGV_HIGH(arg2), cond, label_arg(l));
19343a13c3f3SRichard Henderson         } else {
193542a268c2SRichard Henderson             tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond,
193642a268c2SRichard Henderson                               label_arg(l));
19373a13c3f3SRichard Henderson         }
1938f85b1fc4SRichard Henderson         add_last_as_label_use(l);
1939951c6300SRichard Henderson     }
1940951c6300SRichard Henderson }
1941951c6300SRichard Henderson 
tcg_gen_brcondi_i64(TCGCond cond,TCGv_i64 arg1,int64_t arg2,TCGLabel * l)194242a268c2SRichard Henderson void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l)
1943951c6300SRichard Henderson {
194411d11d61SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
194511d11d61SRichard Henderson         tcg_gen_brcond_i64(cond, arg1, tcg_constant_i64(arg2), l);
194611d11d61SRichard Henderson     } else if (cond == TCG_COND_ALWAYS) {
194742a268c2SRichard Henderson         tcg_gen_br(l);
1948951c6300SRichard Henderson     } else if (cond != TCG_COND_NEVER) {
194911d11d61SRichard Henderson         tcg_gen_op6ii_i32(INDEX_op_brcond2_i32,
195011d11d61SRichard Henderson                           TCGV_LOW(arg1), TCGV_HIGH(arg1),
195111d11d61SRichard Henderson                           tcg_constant_i32(arg2),
195211d11d61SRichard Henderson                           tcg_constant_i32(arg2 >> 32),
195311d11d61SRichard Henderson                           cond, label_arg(l));
1954f85b1fc4SRichard Henderson         add_last_as_label_use(l);
1955951c6300SRichard Henderson     }
1956951c6300SRichard Henderson }
1957951c6300SRichard Henderson 
tcg_gen_setcond_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1958951c6300SRichard Henderson void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
1959951c6300SRichard Henderson                          TCGv_i64 arg1, TCGv_i64 arg2)
1960951c6300SRichard Henderson {
1961951c6300SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
1962951c6300SRichard Henderson         tcg_gen_movi_i64(ret, 1);
1963951c6300SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
1964951c6300SRichard Henderson         tcg_gen_movi_i64(ret, 0);
1965951c6300SRichard Henderson     } else {
19663a13c3f3SRichard Henderson         if (TCG_TARGET_REG_BITS == 32) {
1967951c6300SRichard Henderson             tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
1968951c6300SRichard Henderson                              TCGV_LOW(arg1), TCGV_HIGH(arg1),
1969951c6300SRichard Henderson                              TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
1970951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
19713a13c3f3SRichard Henderson         } else {
1972951c6300SRichard Henderson             tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
19733a13c3f3SRichard Henderson         }
1974951c6300SRichard Henderson     }
1975951c6300SRichard Henderson }
1976951c6300SRichard Henderson 
tcg_gen_setcondi_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1977951c6300SRichard Henderson void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
1978951c6300SRichard Henderson                           TCGv_i64 arg1, int64_t arg2)
1979951c6300SRichard Henderson {
198011d11d61SRichard Henderson     if (TCG_TARGET_REG_BITS == 64) {
198111d11d61SRichard Henderson         tcg_gen_setcond_i64(cond, ret, arg1, tcg_constant_i64(arg2));
198211d11d61SRichard Henderson     } else if (cond == TCG_COND_ALWAYS) {
198311d11d61SRichard Henderson         tcg_gen_movi_i64(ret, 1);
198411d11d61SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
198511d11d61SRichard Henderson         tcg_gen_movi_i64(ret, 0);
198611d11d61SRichard Henderson     } else {
198711d11d61SRichard Henderson         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
198811d11d61SRichard Henderson                          TCGV_LOW(arg1), TCGV_HIGH(arg1),
198911d11d61SRichard Henderson                          tcg_constant_i32(arg2),
199011d11d61SRichard Henderson                          tcg_constant_i32(arg2 >> 32), cond);
199111d11d61SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
199211d11d61SRichard Henderson     }
1993951c6300SRichard Henderson }
1994951c6300SRichard Henderson 
tcg_gen_negsetcondi_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)199593c86ecdSPaolo Bonzini void tcg_gen_negsetcondi_i64(TCGCond cond, TCGv_i64 ret,
199693c86ecdSPaolo Bonzini                              TCGv_i64 arg1, int64_t arg2)
199793c86ecdSPaolo Bonzini {
199893c86ecdSPaolo Bonzini     tcg_gen_negsetcond_i64(cond, ret, arg1, tcg_constant_i64(arg2));
199993c86ecdSPaolo Bonzini }
200093c86ecdSPaolo Bonzini 
tcg_gen_negsetcond_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)20013635502dSRichard Henderson void tcg_gen_negsetcond_i64(TCGCond cond, TCGv_i64 ret,
20023635502dSRichard Henderson                             TCGv_i64 arg1, TCGv_i64 arg2)
20033635502dSRichard Henderson {
20043635502dSRichard Henderson     if (cond == TCG_COND_ALWAYS) {
20053635502dSRichard Henderson         tcg_gen_movi_i64(ret, -1);
20063635502dSRichard Henderson     } else if (cond == TCG_COND_NEVER) {
20073635502dSRichard Henderson         tcg_gen_movi_i64(ret, 0);
20083635502dSRichard Henderson     } else if (TCG_TARGET_HAS_negsetcond_i64) {
20093635502dSRichard Henderson         tcg_gen_op4i_i64(INDEX_op_negsetcond_i64, ret, arg1, arg2, cond);
20103635502dSRichard Henderson     } else if (TCG_TARGET_REG_BITS == 32) {
20113635502dSRichard Henderson         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
20123635502dSRichard Henderson                          TCGV_LOW(arg1), TCGV_HIGH(arg1),
20133635502dSRichard Henderson                          TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
20143635502dSRichard Henderson         tcg_gen_neg_i32(TCGV_LOW(ret), TCGV_LOW(ret));
20153635502dSRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_LOW(ret));
20163635502dSRichard Henderson     } else {
20173635502dSRichard Henderson         tcg_gen_setcond_i64(cond, ret, arg1, arg2);
20183635502dSRichard Henderson         tcg_gen_neg_i64(ret, ret);
20193635502dSRichard Henderson     }
20203635502dSRichard Henderson }
20213635502dSRichard Henderson 
tcg_gen_muli_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)2022951c6300SRichard Henderson void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2023951c6300SRichard Henderson {
2024b2e3ae94SRichard Henderson     if (arg2 == 0) {
2025b2e3ae94SRichard Henderson         tcg_gen_movi_i64(ret, 0);
2026b2e3ae94SRichard Henderson     } else if (is_power_of_2(arg2)) {
2027b2e3ae94SRichard Henderson         tcg_gen_shli_i64(ret, arg1, ctz64(arg2));
2028b2e3ae94SRichard Henderson     } else {
2029f04de891SRichard Henderson         tcg_gen_mul_i64(ret, arg1, tcg_constant_i64(arg2));
2030951c6300SRichard Henderson     }
2031b2e3ae94SRichard Henderson }
2032951c6300SRichard Henderson 
tcg_gen_div_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2033951c6300SRichard Henderson void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2034951c6300SRichard Henderson {
2035951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i64) {
2036951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
2037951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
20385dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2039951c6300SRichard Henderson         tcg_gen_sari_i64(t0, arg1, 63);
2040951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
2041951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2042951c6300SRichard Henderson     } else {
2043951c6300SRichard Henderson         gen_helper_div_i64(ret, arg1, arg2);
2044951c6300SRichard Henderson     }
2045951c6300SRichard Henderson }
2046951c6300SRichard Henderson 
tcg_gen_rem_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2047951c6300SRichard Henderson void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2048951c6300SRichard Henderson {
2049951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i64) {
2050951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
2051951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i64) {
20525dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2053951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
2054951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, arg2);
2055951c6300SRichard Henderson         tcg_gen_sub_i64(ret, arg1, t0);
2056951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2057951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
20585dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2059951c6300SRichard Henderson         tcg_gen_sari_i64(t0, arg1, 63);
2060951c6300SRichard Henderson         tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
2061951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2062951c6300SRichard Henderson     } else {
2063951c6300SRichard Henderson         gen_helper_rem_i64(ret, arg1, arg2);
2064951c6300SRichard Henderson     }
2065951c6300SRichard Henderson }
2066951c6300SRichard Henderson 
tcg_gen_divu_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2067951c6300SRichard Henderson void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2068951c6300SRichard Henderson {
2069951c6300SRichard Henderson     if (TCG_TARGET_HAS_div_i64) {
2070951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
2071951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
20725dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2073bfefdbeaSRichard Henderson         TCGv_i64 zero = tcg_constant_i64(0);
2074bfefdbeaSRichard Henderson         tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, zero, arg2);
2075951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2076951c6300SRichard Henderson     } else {
2077951c6300SRichard Henderson         gen_helper_divu_i64(ret, arg1, arg2);
2078951c6300SRichard Henderson     }
2079951c6300SRichard Henderson }
2080951c6300SRichard Henderson 
tcg_gen_remu_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2081951c6300SRichard Henderson void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2082951c6300SRichard Henderson {
2083951c6300SRichard Henderson     if (TCG_TARGET_HAS_rem_i64) {
2084951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
2085951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div_i64) {
20865dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2087951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
2088951c6300SRichard Henderson         tcg_gen_mul_i64(t0, t0, arg2);
2089951c6300SRichard Henderson         tcg_gen_sub_i64(ret, arg1, t0);
2090951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2091951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_div2_i64) {
20925dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2093bfefdbeaSRichard Henderson         TCGv_i64 zero = tcg_constant_i64(0);
2094bfefdbeaSRichard Henderson         tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, zero, arg2);
2095951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2096951c6300SRichard Henderson     } else {
2097951c6300SRichard Henderson         gen_helper_remu_i64(ret, arg1, arg2);
2098951c6300SRichard Henderson     }
2099951c6300SRichard Henderson }
2100951c6300SRichard Henderson 
tcg_gen_ext8s_i64(TCGv_i64 ret,TCGv_i64 arg)2101951c6300SRichard Henderson void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
2102951c6300SRichard Henderson {
21033a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
2104951c6300SRichard Henderson         tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2105951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
21063a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext8s_i64) {
2107951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
2108951c6300SRichard Henderson     } else {
2109951c6300SRichard Henderson         tcg_gen_shli_i64(ret, arg, 56);
2110951c6300SRichard Henderson         tcg_gen_sari_i64(ret, ret, 56);
2111951c6300SRichard Henderson     }
2112951c6300SRichard Henderson }
2113951c6300SRichard Henderson 
tcg_gen_ext16s_i64(TCGv_i64 ret,TCGv_i64 arg)2114951c6300SRichard Henderson void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
2115951c6300SRichard Henderson {
21163a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
2117951c6300SRichard Henderson         tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2118951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
21193a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext16s_i64) {
2120951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
2121951c6300SRichard Henderson     } else {
2122951c6300SRichard Henderson         tcg_gen_shli_i64(ret, arg, 48);
2123951c6300SRichard Henderson         tcg_gen_sari_i64(ret, ret, 48);
2124951c6300SRichard Henderson     }
2125951c6300SRichard Henderson }
2126951c6300SRichard Henderson 
tcg_gen_ext32s_i64(TCGv_i64 ret,TCGv_i64 arg)2127951c6300SRichard Henderson void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
2128951c6300SRichard Henderson {
21293a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
2130951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2131951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
21323a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext32s_i64) {
2133951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
2134951c6300SRichard Henderson     } else {
2135951c6300SRichard Henderson         tcg_gen_shli_i64(ret, arg, 32);
2136951c6300SRichard Henderson         tcg_gen_sari_i64(ret, ret, 32);
2137951c6300SRichard Henderson     }
2138951c6300SRichard Henderson }
2139951c6300SRichard Henderson 
tcg_gen_ext8u_i64(TCGv_i64 ret,TCGv_i64 arg)2140951c6300SRichard Henderson void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
2141951c6300SRichard Henderson {
21423a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
2143951c6300SRichard Henderson         tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2144951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
21453a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext8u_i64) {
2146951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
2147951c6300SRichard Henderson     } else {
2148951c6300SRichard Henderson         tcg_gen_andi_i64(ret, arg, 0xffu);
2149951c6300SRichard Henderson     }
2150951c6300SRichard Henderson }
2151951c6300SRichard Henderson 
tcg_gen_ext16u_i64(TCGv_i64 ret,TCGv_i64 arg)2152951c6300SRichard Henderson void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
2153951c6300SRichard Henderson {
21543a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
2155951c6300SRichard Henderson         tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2156951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
21573a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext16u_i64) {
2158951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
2159951c6300SRichard Henderson     } else {
2160951c6300SRichard Henderson         tcg_gen_andi_i64(ret, arg, 0xffffu);
2161951c6300SRichard Henderson     }
2162951c6300SRichard Henderson }
2163951c6300SRichard Henderson 
tcg_gen_ext32u_i64(TCGv_i64 ret,TCGv_i64 arg)2164951c6300SRichard Henderson void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
2165951c6300SRichard Henderson {
21663a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
2167951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2168951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
21693a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_ext32u_i64) {
2170951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
2171951c6300SRichard Henderson     } else {
2172951c6300SRichard Henderson         tcg_gen_andi_i64(ret, arg, 0xffffffffu);
2173951c6300SRichard Henderson     }
2174951c6300SRichard Henderson }
2175951c6300SRichard Henderson 
21768b078800SPhilippe Mathieu-Daudé /*
21778b078800SPhilippe Mathieu-Daudé  * bswap16_i64: 16-bit byte swap on the low bits of a 64-bit value.
21788b078800SPhilippe Mathieu-Daudé  *
21798b078800SPhilippe Mathieu-Daudé  * Byte pattern: xxxxxxxxab -> yyyyyyyyba
21808b078800SPhilippe Mathieu-Daudé  *
21818b078800SPhilippe Mathieu-Daudé  * With TCG_BSWAP_IZ, x == zero, else undefined.
21828b078800SPhilippe Mathieu-Daudé  * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
21838b078800SPhilippe Mathieu-Daudé  */
tcg_gen_bswap16_i64(TCGv_i64 ret,TCGv_i64 arg,int flags)21842b836c2aSRichard Henderson void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
2185951c6300SRichard Henderson {
21862b836c2aSRichard Henderson     /* Only one extension flag may be present. */
21872b836c2aSRichard Henderson     tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
21882b836c2aSRichard Henderson 
21893a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
21902b836c2aSRichard Henderson         tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg), flags);
21912b836c2aSRichard Henderson         if (flags & TCG_BSWAP_OS) {
21922b836c2aSRichard Henderson             tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
21932b836c2aSRichard Henderson         } else {
2194951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
21952b836c2aSRichard Henderson         }
21963a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_bswap16_i64) {
21972b836c2aSRichard Henderson         tcg_gen_op3i_i64(INDEX_op_bswap16_i64, ret, arg, flags);
2198951c6300SRichard Henderson     } else {
21995dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
22005dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
2201951c6300SRichard Henderson 
22028b078800SPhilippe Mathieu-Daudé                                             /* arg = ......ab or xxxxxxab */
22038b078800SPhilippe Mathieu-Daudé         tcg_gen_shri_i64(t0, arg, 8);       /*  t0 = .......a or .xxxxxxa */
22042b836c2aSRichard Henderson         if (!(flags & TCG_BSWAP_IZ)) {
22058b078800SPhilippe Mathieu-Daudé             tcg_gen_ext8u_i64(t0, t0);      /*  t0 = .......a */
22062b836c2aSRichard Henderson         }
22072b836c2aSRichard Henderson 
22082b836c2aSRichard Henderson         if (flags & TCG_BSWAP_OS) {
22098b078800SPhilippe Mathieu-Daudé             tcg_gen_shli_i64(t1, arg, 56);  /*  t1 = b....... */
22108b078800SPhilippe Mathieu-Daudé             tcg_gen_sari_i64(t1, t1, 48);   /*  t1 = ssssssb. */
22112b836c2aSRichard Henderson         } else if (flags & TCG_BSWAP_OZ) {
22128b078800SPhilippe Mathieu-Daudé             tcg_gen_ext8u_i64(t1, arg);     /*  t1 = .......b */
22138b078800SPhilippe Mathieu-Daudé             tcg_gen_shli_i64(t1, t1, 8);    /*  t1 = ......b. */
22142b836c2aSRichard Henderson         } else {
22158b078800SPhilippe Mathieu-Daudé             tcg_gen_shli_i64(t1, arg, 8);   /*  t1 = xxxxxab. */
22162b836c2aSRichard Henderson         }
22172b836c2aSRichard Henderson 
22188b078800SPhilippe Mathieu-Daudé         tcg_gen_or_i64(ret, t0, t1);        /* ret = ......ba (OZ) */
22198b078800SPhilippe Mathieu-Daudé                                             /*       ssssssba (OS) */
22208b078800SPhilippe Mathieu-Daudé                                             /*       xxxxxaba (no flag) */
2221951c6300SRichard Henderson         tcg_temp_free_i64(t0);
22222b836c2aSRichard Henderson         tcg_temp_free_i64(t1);
2223951c6300SRichard Henderson     }
2224951c6300SRichard Henderson }
2225951c6300SRichard Henderson 
22269c406215SPhilippe Mathieu-Daudé /*
22279c406215SPhilippe Mathieu-Daudé  * bswap32_i64: 32-bit byte swap on the low bits of a 64-bit value.
22289c406215SPhilippe Mathieu-Daudé  *
22299c406215SPhilippe Mathieu-Daudé  * Byte pattern: xxxxabcd -> yyyydcba
22309c406215SPhilippe Mathieu-Daudé  *
22319c406215SPhilippe Mathieu-Daudé  * With TCG_BSWAP_IZ, x == zero, else undefined.
22329c406215SPhilippe Mathieu-Daudé  * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
22339c406215SPhilippe Mathieu-Daudé  */
tcg_gen_bswap32_i64(TCGv_i64 ret,TCGv_i64 arg,int flags)22342b836c2aSRichard Henderson void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
2235951c6300SRichard Henderson {
22362b836c2aSRichard Henderson     /* Only one extension flag may be present. */
22372b836c2aSRichard Henderson     tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
22382b836c2aSRichard Henderson 
22393a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
2240951c6300SRichard Henderson         tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg));
22412b836c2aSRichard Henderson         if (flags & TCG_BSWAP_OS) {
22422b836c2aSRichard Henderson             tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
22432b836c2aSRichard Henderson         } else {
2244951c6300SRichard Henderson             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
22452b836c2aSRichard Henderson         }
22463a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_bswap32_i64) {
22472b836c2aSRichard Henderson         tcg_gen_op3i_i64(INDEX_op_bswap32_i64, ret, arg, flags);
2248951c6300SRichard Henderson     } else {
22495dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
22505dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
225111d11d61SRichard Henderson         TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff);
2252951c6300SRichard Henderson 
22532b836c2aSRichard Henderson                                             /* arg = xxxxabcd */
22542b836c2aSRichard Henderson         tcg_gen_shri_i64(t0, arg, 8);       /*  t0 = .xxxxabc */
2255a686dc71SRichard Henderson         tcg_gen_and_i64(t1, arg, t2);       /*  t1 = .....b.d */
2256a686dc71SRichard Henderson         tcg_gen_and_i64(t0, t0, t2);        /*  t0 = .....a.c */
2257a686dc71SRichard Henderson         tcg_gen_shli_i64(t1, t1, 8);        /*  t1 = ....b.d. */
2258a686dc71SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);        /* ret = ....badc */
2259951c6300SRichard Henderson 
2260a686dc71SRichard Henderson         tcg_gen_shli_i64(t1, ret, 48);      /*  t1 = dc...... */
2261a686dc71SRichard Henderson         tcg_gen_shri_i64(t0, ret, 16);      /*  t0 = ......ba */
22622b836c2aSRichard Henderson         if (flags & TCG_BSWAP_OS) {
22632b836c2aSRichard Henderson             tcg_gen_sari_i64(t1, t1, 32);   /*  t1 = ssssdc.. */
22642b836c2aSRichard Henderson         } else {
2265a686dc71SRichard Henderson             tcg_gen_shri_i64(t1, t1, 32);   /*  t1 = ....dc.. */
22662b836c2aSRichard Henderson         }
22679c406215SPhilippe Mathieu-Daudé         tcg_gen_or_i64(ret, t0, t1);        /* ret = ssssdcba (OS) */
22689c406215SPhilippe Mathieu-Daudé                                             /*       ....dcba (else) */
2269951c6300SRichard Henderson 
2270951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2271951c6300SRichard Henderson         tcg_temp_free_i64(t1);
2272951c6300SRichard Henderson     }
2273951c6300SRichard Henderson }
2274951c6300SRichard Henderson 
227595180e75SPhilippe Mathieu-Daudé /*
227695180e75SPhilippe Mathieu-Daudé  * bswap64_i64: 64-bit byte swap on a 64-bit value.
227795180e75SPhilippe Mathieu-Daudé  *
227895180e75SPhilippe Mathieu-Daudé  * Byte pattern: abcdefgh -> hgfedcba
227995180e75SPhilippe Mathieu-Daudé  */
tcg_gen_bswap64_i64(TCGv_i64 ret,TCGv_i64 arg)2280951c6300SRichard Henderson void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
2281951c6300SRichard Henderson {
22823a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
2283951c6300SRichard Henderson         TCGv_i32 t0, t1;
22845dd48602SRichard Henderson         t0 = tcg_temp_ebb_new_i32();
22855dd48602SRichard Henderson         t1 = tcg_temp_ebb_new_i32();
2286951c6300SRichard Henderson 
2287951c6300SRichard Henderson         tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
2288951c6300SRichard Henderson         tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
2289951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), t1);
2290951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
2291951c6300SRichard Henderson         tcg_temp_free_i32(t0);
2292951c6300SRichard Henderson         tcg_temp_free_i32(t1);
22933a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_bswap64_i64) {
2294587195bdSRichard Henderson         tcg_gen_op3i_i64(INDEX_op_bswap64_i64, ret, arg, 0);
2295951c6300SRichard Henderson     } else {
22965dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
22975dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
22985dd48602SRichard Henderson         TCGv_i64 t2 = tcg_temp_ebb_new_i64();
2299951c6300SRichard Henderson 
23009e821eabSRichard Henderson                                         /* arg = abcdefgh */
23019e821eabSRichard Henderson         tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull);
23029e821eabSRichard Henderson         tcg_gen_shri_i64(t0, arg, 8);   /*  t0 = .abcdefg */
23039e821eabSRichard Henderson         tcg_gen_and_i64(t1, arg, t2);   /*  t1 = .b.d.f.h */
23049e821eabSRichard Henderson         tcg_gen_and_i64(t0, t0, t2);    /*  t0 = .a.c.e.g */
23059e821eabSRichard Henderson         tcg_gen_shli_i64(t1, t1, 8);    /*  t1 = b.d.f.h. */
23069e821eabSRichard Henderson         tcg_gen_or_i64(ret, t0, t1);    /* ret = badcfehg */
2307951c6300SRichard Henderson 
23089e821eabSRichard Henderson         tcg_gen_movi_i64(t2, 0x0000ffff0000ffffull);
23099e821eabSRichard Henderson         tcg_gen_shri_i64(t0, ret, 16);  /*  t0 = ..badcfe */
23109e821eabSRichard Henderson         tcg_gen_and_i64(t1, ret, t2);   /*  t1 = ..dc..hg */
23119e821eabSRichard Henderson         tcg_gen_and_i64(t0, t0, t2);    /*  t0 = ..ba..fe */
23129e821eabSRichard Henderson         tcg_gen_shli_i64(t1, t1, 16);   /*  t1 = dc..hg.. */
23139e821eabSRichard Henderson         tcg_gen_or_i64(ret, t0, t1);    /* ret = dcbahgfe */
2314951c6300SRichard Henderson 
23159e821eabSRichard Henderson         tcg_gen_shri_i64(t0, ret, 32);  /*  t0 = ....dcba */
23169e821eabSRichard Henderson         tcg_gen_shli_i64(t1, ret, 32);  /*  t1 = hgfe.... */
23179e821eabSRichard Henderson         tcg_gen_or_i64(ret, t0, t1);    /* ret = hgfedcba */
2318951c6300SRichard Henderson 
2319951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2320951c6300SRichard Henderson         tcg_temp_free_i64(t1);
23219e821eabSRichard Henderson         tcg_temp_free_i64(t2);
2322951c6300SRichard Henderson     }
2323951c6300SRichard Henderson }
2324951c6300SRichard Henderson 
2325b8976aa5SPhilippe Mathieu-Daudé /*
2326b8976aa5SPhilippe Mathieu-Daudé  * hswap_i64: Swap 16-bit halfwords within a 64-bit value.
2327b8976aa5SPhilippe Mathieu-Daudé  * See also include/qemu/bitops.h, hswap64.
2328b8976aa5SPhilippe Mathieu-Daudé  *
2329b8976aa5SPhilippe Mathieu-Daudé  * Byte pattern: abcdefgh -> ghefcdab
2330b8976aa5SPhilippe Mathieu-Daudé  */
tcg_gen_hswap_i64(TCGv_i64 ret,TCGv_i64 arg)233146be8425SRichard Henderson void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg)
233246be8425SRichard Henderson {
233346be8425SRichard Henderson     uint64_t m = 0x0000ffff0000ffffull;
23345dd48602SRichard Henderson     TCGv_i64 t0 = tcg_temp_ebb_new_i64();
23355dd48602SRichard Henderson     TCGv_i64 t1 = tcg_temp_ebb_new_i64();
233646be8425SRichard Henderson 
2337b8976aa5SPhilippe Mathieu-Daudé                                         /* arg = abcdefgh */
2338b8976aa5SPhilippe Mathieu-Daudé     tcg_gen_rotli_i64(t1, arg, 32);     /*  t1 = efghabcd */
2339b8976aa5SPhilippe Mathieu-Daudé     tcg_gen_andi_i64(t0, t1, m);        /*  t0 = ..gh..cd */
2340b8976aa5SPhilippe Mathieu-Daudé     tcg_gen_shli_i64(t0, t0, 16);       /*  t0 = gh..cd.. */
2341b8976aa5SPhilippe Mathieu-Daudé     tcg_gen_shri_i64(t1, t1, 16);       /*  t1 = ..efghab */
2342b8976aa5SPhilippe Mathieu-Daudé     tcg_gen_andi_i64(t1, t1, m);        /*  t1 = ..ef..ab */
2343b8976aa5SPhilippe Mathieu-Daudé     tcg_gen_or_i64(ret, t0, t1);        /* ret = ghefcdab */
234446be8425SRichard Henderson 
234546be8425SRichard Henderson     tcg_temp_free_i64(t0);
234646be8425SRichard Henderson     tcg_temp_free_i64(t1);
234746be8425SRichard Henderson }
234846be8425SRichard Henderson 
2349ad262fb5SPhilippe Mathieu-Daudé /*
2350ad262fb5SPhilippe Mathieu-Daudé  * wswap_i64: Swap 32-bit words within a 64-bit value.
2351ad262fb5SPhilippe Mathieu-Daudé  *
2352ad262fb5SPhilippe Mathieu-Daudé  * Byte pattern: abcdefgh -> efghabcd
2353ad262fb5SPhilippe Mathieu-Daudé  */
tcg_gen_wswap_i64(TCGv_i64 ret,TCGv_i64 arg)235446be8425SRichard Henderson void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg)
235546be8425SRichard Henderson {
235646be8425SRichard Henderson     /* Swapping 2 32-bit elements is a rotate. */
235746be8425SRichard Henderson     tcg_gen_rotli_i64(ret, arg, 32);
235846be8425SRichard Henderson }
235946be8425SRichard Henderson 
tcg_gen_not_i64(TCGv_i64 ret,TCGv_i64 arg)2360951c6300SRichard Henderson void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
2361951c6300SRichard Henderson {
23623a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
23633a13c3f3SRichard Henderson         tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
23643a13c3f3SRichard Henderson         tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
23653a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_not_i64) {
2366951c6300SRichard Henderson         tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
2367951c6300SRichard Henderson     } else {
2368951c6300SRichard Henderson         tcg_gen_xori_i64(ret, arg, -1);
2369951c6300SRichard Henderson     }
2370951c6300SRichard Henderson }
2371951c6300SRichard Henderson 
tcg_gen_andc_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2372951c6300SRichard Henderson void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2373951c6300SRichard Henderson {
23743a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
23753a13c3f3SRichard Henderson         tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
23763a13c3f3SRichard Henderson         tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
23773a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_andc_i64) {
2378951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
2379951c6300SRichard Henderson     } else {
23805dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2381951c6300SRichard Henderson         tcg_gen_not_i64(t0, arg2);
2382951c6300SRichard Henderson         tcg_gen_and_i64(ret, arg1, t0);
2383951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2384951c6300SRichard Henderson     }
2385951c6300SRichard Henderson }
2386951c6300SRichard Henderson 
tcg_gen_eqv_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2387951c6300SRichard Henderson void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2388951c6300SRichard Henderson {
23893a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
23903a13c3f3SRichard Henderson         tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
23913a13c3f3SRichard Henderson         tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
23923a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_eqv_i64) {
2393951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
2394951c6300SRichard Henderson     } else {
2395951c6300SRichard Henderson         tcg_gen_xor_i64(ret, arg1, arg2);
2396951c6300SRichard Henderson         tcg_gen_not_i64(ret, ret);
2397951c6300SRichard Henderson     }
2398951c6300SRichard Henderson }
2399951c6300SRichard Henderson 
tcg_gen_nand_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2400951c6300SRichard Henderson void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2401951c6300SRichard Henderson {
24023a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
24033a13c3f3SRichard Henderson         tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
24043a13c3f3SRichard Henderson         tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
24053a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_nand_i64) {
2406951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
2407951c6300SRichard Henderson     } else {
2408951c6300SRichard Henderson         tcg_gen_and_i64(ret, arg1, arg2);
2409951c6300SRichard Henderson         tcg_gen_not_i64(ret, ret);
2410951c6300SRichard Henderson     }
2411951c6300SRichard Henderson }
2412951c6300SRichard Henderson 
tcg_gen_nor_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2413951c6300SRichard Henderson void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2414951c6300SRichard Henderson {
24153a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
24163a13c3f3SRichard Henderson         tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
24173a13c3f3SRichard Henderson         tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
24183a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_nor_i64) {
2419951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
2420951c6300SRichard Henderson     } else {
2421951c6300SRichard Henderson         tcg_gen_or_i64(ret, arg1, arg2);
2422951c6300SRichard Henderson         tcg_gen_not_i64(ret, ret);
2423951c6300SRichard Henderson     }
2424951c6300SRichard Henderson }
2425951c6300SRichard Henderson 
tcg_gen_orc_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2426951c6300SRichard Henderson void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2427951c6300SRichard Henderson {
24283a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
24293a13c3f3SRichard Henderson         tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
24303a13c3f3SRichard Henderson         tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
24313a13c3f3SRichard Henderson     } else if (TCG_TARGET_HAS_orc_i64) {
2432951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
2433951c6300SRichard Henderson     } else {
24345dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2435951c6300SRichard Henderson         tcg_gen_not_i64(t0, arg2);
2436951c6300SRichard Henderson         tcg_gen_or_i64(ret, arg1, t0);
2437951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2438951c6300SRichard Henderson     }
2439951c6300SRichard Henderson }
2440951c6300SRichard Henderson 
tcg_gen_clz_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)24410e28d006SRichard Henderson void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
24420e28d006SRichard Henderson {
24430e28d006SRichard Henderson     if (TCG_TARGET_HAS_clz_i64) {
24440e28d006SRichard Henderson         tcg_gen_op3_i64(INDEX_op_clz_i64, ret, arg1, arg2);
24450e28d006SRichard Henderson     } else {
24460e28d006SRichard Henderson         gen_helper_clz_i64(ret, arg1, arg2);
24470e28d006SRichard Henderson     }
24480e28d006SRichard Henderson }
24490e28d006SRichard Henderson 
tcg_gen_clzi_i64(TCGv_i64 ret,TCGv_i64 arg1,uint64_t arg2)24500e28d006SRichard Henderson void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
24510e28d006SRichard Henderson {
24520e28d006SRichard Henderson     if (TCG_TARGET_REG_BITS == 32
24530e28d006SRichard Henderson         && TCG_TARGET_HAS_clz_i32
24540e28d006SRichard Henderson         && arg2 <= 0xffffffffu) {
24555dd48602SRichard Henderson         TCGv_i32 t = tcg_temp_ebb_new_i32();
245611d11d61SRichard Henderson         tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32);
24570e28d006SRichard Henderson         tcg_gen_addi_i32(t, t, 32);
24580e28d006SRichard Henderson         tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t);
24590e28d006SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
24600e28d006SRichard Henderson         tcg_temp_free_i32(t);
24610e28d006SRichard Henderson     } else {
2462f04de891SRichard Henderson         tcg_gen_clz_i64(ret, arg1, tcg_constant_i64(arg2));
24630e28d006SRichard Henderson     }
24640e28d006SRichard Henderson }
24650e28d006SRichard Henderson 
tcg_gen_ctz_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)24660e28d006SRichard Henderson void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
24670e28d006SRichard Henderson {
24680e28d006SRichard Henderson     if (TCG_TARGET_HAS_ctz_i64) {
24690e28d006SRichard Henderson         tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2);
247014e99210SRichard Henderson     } else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) {
24715dd48602SRichard Henderson         TCGv_i64 z, t = tcg_temp_ebb_new_i64();
247214e99210SRichard Henderson 
247314e99210SRichard Henderson         if (TCG_TARGET_HAS_ctpop_i64) {
247414e99210SRichard Henderson             tcg_gen_subi_i64(t, arg1, 1);
247514e99210SRichard Henderson             tcg_gen_andc_i64(t, t, arg1);
247614e99210SRichard Henderson             tcg_gen_ctpop_i64(t, t);
247714e99210SRichard Henderson         } else {
247814e99210SRichard Henderson             /* Since all non-x86 hosts have clz(0) == 64, don't fight it.  */
247914e99210SRichard Henderson             tcg_gen_neg_i64(t, arg1);
248014e99210SRichard Henderson             tcg_gen_and_i64(t, t, arg1);
248114e99210SRichard Henderson             tcg_gen_clzi_i64(t, t, 64);
248214e99210SRichard Henderson             tcg_gen_xori_i64(t, t, 63);
248314e99210SRichard Henderson         }
248411d11d61SRichard Henderson         z = tcg_constant_i64(0);
248514e99210SRichard Henderson         tcg_gen_movcond_i64(TCG_COND_EQ, ret, arg1, z, arg2, t);
248614e99210SRichard Henderson         tcg_temp_free_i64(t);
248714e99210SRichard Henderson         tcg_temp_free_i64(z);
24880e28d006SRichard Henderson     } else {
24890e28d006SRichard Henderson         gen_helper_ctz_i64(ret, arg1, arg2);
24900e28d006SRichard Henderson     }
24910e28d006SRichard Henderson }
24920e28d006SRichard Henderson 
tcg_gen_ctzi_i64(TCGv_i64 ret,TCGv_i64 arg1,uint64_t arg2)24930e28d006SRichard Henderson void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
24940e28d006SRichard Henderson {
24950e28d006SRichard Henderson     if (TCG_TARGET_REG_BITS == 32
24960e28d006SRichard Henderson         && TCG_TARGET_HAS_ctz_i32
24970e28d006SRichard Henderson         && arg2 <= 0xffffffffu) {
24985dd48602SRichard Henderson         TCGv_i32 t32 = tcg_temp_ebb_new_i32();
249911d11d61SRichard Henderson         tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32);
25000e28d006SRichard Henderson         tcg_gen_addi_i32(t32, t32, 32);
25010e28d006SRichard Henderson         tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32);
25020e28d006SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
25030e28d006SRichard Henderson         tcg_temp_free_i32(t32);
250414e99210SRichard Henderson     } else if (!TCG_TARGET_HAS_ctz_i64
250514e99210SRichard Henderson                && TCG_TARGET_HAS_ctpop_i64
250614e99210SRichard Henderson                && arg2 == 64) {
250714e99210SRichard Henderson         /* This equivalence has the advantage of not requiring a fixup.  */
25085dd48602SRichard Henderson         TCGv_i64 t = tcg_temp_ebb_new_i64();
250914e99210SRichard Henderson         tcg_gen_subi_i64(t, arg1, 1);
251014e99210SRichard Henderson         tcg_gen_andc_i64(t, t, arg1);
251114e99210SRichard Henderson         tcg_gen_ctpop_i64(ret, t);
251214e99210SRichard Henderson         tcg_temp_free_i64(t);
25130e28d006SRichard Henderson     } else {
2514f04de891SRichard Henderson         tcg_gen_ctz_i64(ret, arg1, tcg_constant_i64(arg2));
25150e28d006SRichard Henderson     }
25160e28d006SRichard Henderson }
25170e28d006SRichard Henderson 
tcg_gen_clrsb_i64(TCGv_i64 ret,TCGv_i64 arg)2518086920c2SRichard Henderson void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg)
2519086920c2SRichard Henderson {
2520086920c2SRichard Henderson     if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) {
25215dd48602SRichard Henderson         TCGv_i64 t = tcg_temp_ebb_new_i64();
2522086920c2SRichard Henderson         tcg_gen_sari_i64(t, arg, 63);
2523086920c2SRichard Henderson         tcg_gen_xor_i64(t, t, arg);
2524086920c2SRichard Henderson         tcg_gen_clzi_i64(t, t, 64);
2525086920c2SRichard Henderson         tcg_gen_subi_i64(ret, t, 1);
2526086920c2SRichard Henderson         tcg_temp_free_i64(t);
2527086920c2SRichard Henderson     } else {
2528086920c2SRichard Henderson         gen_helper_clrsb_i64(ret, arg);
2529086920c2SRichard Henderson     }
2530086920c2SRichard Henderson }
2531086920c2SRichard Henderson 
tcg_gen_ctpop_i64(TCGv_i64 ret,TCGv_i64 arg1)2532a768e4e9SRichard Henderson void tcg_gen_ctpop_i64(TCGv_i64 ret, TCGv_i64 arg1)
2533a768e4e9SRichard Henderson {
2534a768e4e9SRichard Henderson     if (TCG_TARGET_HAS_ctpop_i64) {
2535a768e4e9SRichard Henderson         tcg_gen_op2_i64(INDEX_op_ctpop_i64, ret, arg1);
2536a768e4e9SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_ctpop_i32) {
2537a768e4e9SRichard Henderson         tcg_gen_ctpop_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
2538a768e4e9SRichard Henderson         tcg_gen_ctpop_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
2539a768e4e9SRichard Henderson         tcg_gen_add_i32(TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret));
2540a768e4e9SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2541a768e4e9SRichard Henderson     } else {
2542a768e4e9SRichard Henderson         gen_helper_ctpop_i64(ret, arg1);
2543a768e4e9SRichard Henderson     }
2544a768e4e9SRichard Henderson }
2545a768e4e9SRichard Henderson 
tcg_gen_rotl_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2546951c6300SRichard Henderson void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2547951c6300SRichard Henderson {
2548951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i64) {
2549951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
2550951c6300SRichard Henderson     } else {
2551951c6300SRichard Henderson         TCGv_i64 t0, t1;
25525dd48602SRichard Henderson         t0 = tcg_temp_ebb_new_i64();
25535dd48602SRichard Henderson         t1 = tcg_temp_ebb_new_i64();
2554951c6300SRichard Henderson         tcg_gen_shl_i64(t0, arg1, arg2);
2555951c6300SRichard Henderson         tcg_gen_subfi_i64(t1, 64, arg2);
2556951c6300SRichard Henderson         tcg_gen_shr_i64(t1, arg1, t1);
2557951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
2558951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2559951c6300SRichard Henderson         tcg_temp_free_i64(t1);
2560951c6300SRichard Henderson     }
2561951c6300SRichard Henderson }
2562951c6300SRichard Henderson 
tcg_gen_rotli_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)256307dada03SRichard Henderson void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2564951c6300SRichard Henderson {
256507dada03SRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
2566951c6300SRichard Henderson     /* some cases can be optimized here */
2567951c6300SRichard Henderson     if (arg2 == 0) {
2568951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
2569951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_rot_i64) {
257011d11d61SRichard Henderson         tcg_gen_rotl_i64(ret, arg1, tcg_constant_i64(arg2));
2571951c6300SRichard Henderson     } else {
2572951c6300SRichard Henderson         TCGv_i64 t0, t1;
25735dd48602SRichard Henderson         t0 = tcg_temp_ebb_new_i64();
25745dd48602SRichard Henderson         t1 = tcg_temp_ebb_new_i64();
2575951c6300SRichard Henderson         tcg_gen_shli_i64(t0, arg1, arg2);
2576951c6300SRichard Henderson         tcg_gen_shri_i64(t1, arg1, 64 - arg2);
2577951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
2578951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2579951c6300SRichard Henderson         tcg_temp_free_i64(t1);
2580951c6300SRichard Henderson     }
2581951c6300SRichard Henderson }
2582951c6300SRichard Henderson 
tcg_gen_rotr_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2583951c6300SRichard Henderson void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2584951c6300SRichard Henderson {
2585951c6300SRichard Henderson     if (TCG_TARGET_HAS_rot_i64) {
2586951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
2587951c6300SRichard Henderson     } else {
2588951c6300SRichard Henderson         TCGv_i64 t0, t1;
25895dd48602SRichard Henderson         t0 = tcg_temp_ebb_new_i64();
25905dd48602SRichard Henderson         t1 = tcg_temp_ebb_new_i64();
2591951c6300SRichard Henderson         tcg_gen_shr_i64(t0, arg1, arg2);
2592951c6300SRichard Henderson         tcg_gen_subfi_i64(t1, 64, arg2);
2593951c6300SRichard Henderson         tcg_gen_shl_i64(t1, arg1, t1);
2594951c6300SRichard Henderson         tcg_gen_or_i64(ret, t0, t1);
2595951c6300SRichard Henderson         tcg_temp_free_i64(t0);
2596951c6300SRichard Henderson         tcg_temp_free_i64(t1);
2597951c6300SRichard Henderson     }
2598951c6300SRichard Henderson }
2599951c6300SRichard Henderson 
tcg_gen_rotri_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)260007dada03SRichard Henderson void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2601951c6300SRichard Henderson {
260207dada03SRichard Henderson     tcg_debug_assert(arg2 >= 0 && arg2 < 64);
2603951c6300SRichard Henderson     /* some cases can be optimized here */
2604951c6300SRichard Henderson     if (arg2 == 0) {
2605951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg1);
2606951c6300SRichard Henderson     } else {
2607951c6300SRichard Henderson         tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
2608951c6300SRichard Henderson     }
2609951c6300SRichard Henderson }
2610951c6300SRichard Henderson 
tcg_gen_deposit_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2,unsigned int ofs,unsigned int len)2611951c6300SRichard Henderson void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
2612951c6300SRichard Henderson                          unsigned int ofs, unsigned int len)
2613951c6300SRichard Henderson {
2614951c6300SRichard Henderson     uint64_t mask;
2615951c6300SRichard Henderson     TCGv_i64 t1;
2616951c6300SRichard Henderson 
2617951c6300SRichard Henderson     tcg_debug_assert(ofs < 64);
26180d0d309dSRichard Henderson     tcg_debug_assert(len > 0);
2619951c6300SRichard Henderson     tcg_debug_assert(len <= 64);
2620951c6300SRichard Henderson     tcg_debug_assert(ofs + len <= 64);
2621951c6300SRichard Henderson 
26220d0d309dSRichard Henderson     if (len == 64) {
2623951c6300SRichard Henderson         tcg_gen_mov_i64(ret, arg2);
2624951c6300SRichard Henderson         return;
2625951c6300SRichard Henderson     }
2626951c6300SRichard Henderson     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
2627951c6300SRichard Henderson         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
2628951c6300SRichard Henderson         return;
2629951c6300SRichard Henderson     }
2630951c6300SRichard Henderson 
26313a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
2632951c6300SRichard Henderson         if (ofs >= 32) {
2633951c6300SRichard Henderson             tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1),
2634951c6300SRichard Henderson                                 TCGV_LOW(arg2), ofs - 32, len);
2635951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
2636951c6300SRichard Henderson             return;
2637951c6300SRichard Henderson         }
2638951c6300SRichard Henderson         if (ofs + len <= 32) {
2639951c6300SRichard Henderson             tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1),
2640951c6300SRichard Henderson                                 TCGV_LOW(arg2), ofs, len);
2641951c6300SRichard Henderson             tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
2642951c6300SRichard Henderson             return;
2643951c6300SRichard Henderson         }
26443a13c3f3SRichard Henderson     }
2645951c6300SRichard Henderson 
26465dd48602SRichard Henderson     t1 = tcg_temp_ebb_new_i64();
2647951c6300SRichard Henderson 
2648b0a60567SRichard Henderson     if (TCG_TARGET_HAS_extract2_i64) {
2649b0a60567SRichard Henderson         if (ofs + len == 64) {
2650b0a60567SRichard Henderson             tcg_gen_shli_i64(t1, arg1, len);
2651b0a60567SRichard Henderson             tcg_gen_extract2_i64(ret, t1, arg2, len);
2652b0a60567SRichard Henderson             goto done;
2653b0a60567SRichard Henderson         }
2654b0a60567SRichard Henderson         if (ofs == 0) {
2655b0a60567SRichard Henderson             tcg_gen_extract2_i64(ret, arg1, arg2, len);
2656b0a60567SRichard Henderson             tcg_gen_rotli_i64(ret, ret, len);
2657b0a60567SRichard Henderson             goto done;
2658b0a60567SRichard Henderson         }
2659b0a60567SRichard Henderson     }
2660b0a60567SRichard Henderson 
2661b0a60567SRichard Henderson     mask = (1ull << len) - 1;
2662951c6300SRichard Henderson     if (ofs + len < 64) {
2663951c6300SRichard Henderson         tcg_gen_andi_i64(t1, arg2, mask);
2664951c6300SRichard Henderson         tcg_gen_shli_i64(t1, t1, ofs);
2665951c6300SRichard Henderson     } else {
2666951c6300SRichard Henderson         tcg_gen_shli_i64(t1, arg2, ofs);
2667951c6300SRichard Henderson     }
2668951c6300SRichard Henderson     tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
2669951c6300SRichard Henderson     tcg_gen_or_i64(ret, ret, t1);
2670b0a60567SRichard Henderson  done:
2671951c6300SRichard Henderson     tcg_temp_free_i64(t1);
2672951c6300SRichard Henderson }
2673951c6300SRichard Henderson 
tcg_gen_deposit_z_i64(TCGv_i64 ret,TCGv_i64 arg,unsigned int ofs,unsigned int len)267407cc68d5SRichard Henderson void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
267507cc68d5SRichard Henderson                            unsigned int ofs, unsigned int len)
267607cc68d5SRichard Henderson {
267707cc68d5SRichard Henderson     tcg_debug_assert(ofs < 64);
267807cc68d5SRichard Henderson     tcg_debug_assert(len > 0);
267907cc68d5SRichard Henderson     tcg_debug_assert(len <= 64);
268007cc68d5SRichard Henderson     tcg_debug_assert(ofs + len <= 64);
268107cc68d5SRichard Henderson 
268207cc68d5SRichard Henderson     if (ofs + len == 64) {
268307cc68d5SRichard Henderson         tcg_gen_shli_i64(ret, arg, ofs);
268407cc68d5SRichard Henderson     } else if (ofs == 0) {
268507cc68d5SRichard Henderson         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
268607cc68d5SRichard Henderson     } else if (TCG_TARGET_HAS_deposit_i64
268707cc68d5SRichard Henderson                && TCG_TARGET_deposit_i64_valid(ofs, len)) {
268811d11d61SRichard Henderson         TCGv_i64 zero = tcg_constant_i64(0);
268907cc68d5SRichard Henderson         tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len);
269007cc68d5SRichard Henderson     } else {
269107cc68d5SRichard Henderson         if (TCG_TARGET_REG_BITS == 32) {
269207cc68d5SRichard Henderson             if (ofs >= 32) {
269307cc68d5SRichard Henderson                 tcg_gen_deposit_z_i32(TCGV_HIGH(ret), TCGV_LOW(arg),
269407cc68d5SRichard Henderson                                       ofs - 32, len);
269507cc68d5SRichard Henderson                 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
269607cc68d5SRichard Henderson                 return;
269707cc68d5SRichard Henderson             }
269807cc68d5SRichard Henderson             if (ofs + len <= 32) {
269907cc68d5SRichard Henderson                 tcg_gen_deposit_z_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
270007cc68d5SRichard Henderson                 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
270107cc68d5SRichard Henderson                 return;
270207cc68d5SRichard Henderson             }
270307cc68d5SRichard Henderson         }
270407cc68d5SRichard Henderson         /* To help two-operand hosts we prefer to zero-extend first,
270507cc68d5SRichard Henderson            which allows ARG to stay live.  */
270607cc68d5SRichard Henderson         switch (len) {
270707cc68d5SRichard Henderson         case 32:
270807cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext32u_i64) {
270907cc68d5SRichard Henderson                 tcg_gen_ext32u_i64(ret, arg);
271007cc68d5SRichard Henderson                 tcg_gen_shli_i64(ret, ret, ofs);
271107cc68d5SRichard Henderson                 return;
271207cc68d5SRichard Henderson             }
271307cc68d5SRichard Henderson             break;
271407cc68d5SRichard Henderson         case 16:
271507cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext16u_i64) {
271607cc68d5SRichard Henderson                 tcg_gen_ext16u_i64(ret, arg);
271707cc68d5SRichard Henderson                 tcg_gen_shli_i64(ret, ret, ofs);
271807cc68d5SRichard Henderson                 return;
271907cc68d5SRichard Henderson             }
272007cc68d5SRichard Henderson             break;
272107cc68d5SRichard Henderson         case 8:
272207cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext8u_i64) {
272307cc68d5SRichard Henderson                 tcg_gen_ext8u_i64(ret, arg);
272407cc68d5SRichard Henderson                 tcg_gen_shli_i64(ret, ret, ofs);
272507cc68d5SRichard Henderson                 return;
272607cc68d5SRichard Henderson             }
272707cc68d5SRichard Henderson             break;
272807cc68d5SRichard Henderson         }
272907cc68d5SRichard Henderson         /* Otherwise prefer zero-extension over AND for code size.  */
273007cc68d5SRichard Henderson         switch (ofs + len) {
273107cc68d5SRichard Henderson         case 32:
273207cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext32u_i64) {
273307cc68d5SRichard Henderson                 tcg_gen_shli_i64(ret, arg, ofs);
273407cc68d5SRichard Henderson                 tcg_gen_ext32u_i64(ret, ret);
273507cc68d5SRichard Henderson                 return;
273607cc68d5SRichard Henderson             }
273707cc68d5SRichard Henderson             break;
273807cc68d5SRichard Henderson         case 16:
273907cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext16u_i64) {
274007cc68d5SRichard Henderson                 tcg_gen_shli_i64(ret, arg, ofs);
274107cc68d5SRichard Henderson                 tcg_gen_ext16u_i64(ret, ret);
274207cc68d5SRichard Henderson                 return;
274307cc68d5SRichard Henderson             }
274407cc68d5SRichard Henderson             break;
274507cc68d5SRichard Henderson         case 8:
274607cc68d5SRichard Henderson             if (TCG_TARGET_HAS_ext8u_i64) {
274707cc68d5SRichard Henderson                 tcg_gen_shli_i64(ret, arg, ofs);
274807cc68d5SRichard Henderson                 tcg_gen_ext8u_i64(ret, ret);
274907cc68d5SRichard Henderson                 return;
275007cc68d5SRichard Henderson             }
275107cc68d5SRichard Henderson             break;
275207cc68d5SRichard Henderson         }
275307cc68d5SRichard Henderson         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
275407cc68d5SRichard Henderson         tcg_gen_shli_i64(ret, ret, ofs);
275507cc68d5SRichard Henderson     }
275607cc68d5SRichard Henderson }
275707cc68d5SRichard Henderson 
tcg_gen_extract_i64(TCGv_i64 ret,TCGv_i64 arg,unsigned int ofs,unsigned int len)27587ec8bab3SRichard Henderson void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
27597ec8bab3SRichard Henderson                          unsigned int ofs, unsigned int len)
27607ec8bab3SRichard Henderson {
27617ec8bab3SRichard Henderson     tcg_debug_assert(ofs < 64);
27627ec8bab3SRichard Henderson     tcg_debug_assert(len > 0);
27637ec8bab3SRichard Henderson     tcg_debug_assert(len <= 64);
27647ec8bab3SRichard Henderson     tcg_debug_assert(ofs + len <= 64);
27657ec8bab3SRichard Henderson 
27667ec8bab3SRichard Henderson     /* Canonicalize certain special cases, even if extract is supported.  */
27677ec8bab3SRichard Henderson     if (ofs + len == 64) {
27687ec8bab3SRichard Henderson         tcg_gen_shri_i64(ret, arg, 64 - len);
27697ec8bab3SRichard Henderson         return;
27707ec8bab3SRichard Henderson     }
27717ec8bab3SRichard Henderson     if (ofs == 0) {
27727ec8bab3SRichard Henderson         tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
27737ec8bab3SRichard Henderson         return;
27747ec8bab3SRichard Henderson     }
27757ec8bab3SRichard Henderson 
27767ec8bab3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
27777ec8bab3SRichard Henderson         /* Look for a 32-bit extract within one of the two words.  */
27787ec8bab3SRichard Henderson         if (ofs >= 32) {
27797ec8bab3SRichard Henderson             tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
27807ec8bab3SRichard Henderson             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
27817ec8bab3SRichard Henderson             return;
27827ec8bab3SRichard Henderson         }
27837ec8bab3SRichard Henderson         if (ofs + len <= 32) {
27847ec8bab3SRichard Henderson             tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
27857ec8bab3SRichard Henderson             tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
27867ec8bab3SRichard Henderson             return;
27877ec8bab3SRichard Henderson         }
27887ec8bab3SRichard Henderson         /* The field is split across two words.  One double-word
27897ec8bab3SRichard Henderson            shift is better than two double-word shifts.  */
27907ec8bab3SRichard Henderson         goto do_shift_and;
27917ec8bab3SRichard Henderson     }
27927ec8bab3SRichard Henderson 
27937ec8bab3SRichard Henderson     if (TCG_TARGET_HAS_extract_i64
27947ec8bab3SRichard Henderson         && TCG_TARGET_extract_i64_valid(ofs, len)) {
27957ec8bab3SRichard Henderson         tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len);
27967ec8bab3SRichard Henderson         return;
27977ec8bab3SRichard Henderson     }
27987ec8bab3SRichard Henderson 
27997ec8bab3SRichard Henderson     /* Assume that zero-extension, if available, is cheaper than a shift.  */
28007ec8bab3SRichard Henderson     switch (ofs + len) {
28017ec8bab3SRichard Henderson     case 32:
28027ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext32u_i64) {
28037ec8bab3SRichard Henderson             tcg_gen_ext32u_i64(ret, arg);
28047ec8bab3SRichard Henderson             tcg_gen_shri_i64(ret, ret, ofs);
28057ec8bab3SRichard Henderson             return;
28067ec8bab3SRichard Henderson         }
28077ec8bab3SRichard Henderson         break;
28087ec8bab3SRichard Henderson     case 16:
28097ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext16u_i64) {
28107ec8bab3SRichard Henderson             tcg_gen_ext16u_i64(ret, arg);
28117ec8bab3SRichard Henderson             tcg_gen_shri_i64(ret, ret, ofs);
28127ec8bab3SRichard Henderson             return;
28137ec8bab3SRichard Henderson         }
28147ec8bab3SRichard Henderson         break;
28157ec8bab3SRichard Henderson     case 8:
28167ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext8u_i64) {
28177ec8bab3SRichard Henderson             tcg_gen_ext8u_i64(ret, arg);
28187ec8bab3SRichard Henderson             tcg_gen_shri_i64(ret, ret, ofs);
28197ec8bab3SRichard Henderson             return;
28207ec8bab3SRichard Henderson         }
28217ec8bab3SRichard Henderson         break;
28227ec8bab3SRichard Henderson     }
28237ec8bab3SRichard Henderson 
28247ec8bab3SRichard Henderson     /* ??? Ideally we'd know what values are available for immediate AND.
28257ec8bab3SRichard Henderson        Assume that 8 bits are available, plus the special cases of 16 and 32,
28267ec8bab3SRichard Henderson        so that we get ext8u, ext16u, and ext32u.  */
28277ec8bab3SRichard Henderson     switch (len) {
28287ec8bab3SRichard Henderson     case 1 ... 8: case 16: case 32:
28297ec8bab3SRichard Henderson     do_shift_and:
28307ec8bab3SRichard Henderson         tcg_gen_shri_i64(ret, arg, ofs);
28317ec8bab3SRichard Henderson         tcg_gen_andi_i64(ret, ret, (1ull << len) - 1);
28327ec8bab3SRichard Henderson         break;
28337ec8bab3SRichard Henderson     default:
28347ec8bab3SRichard Henderson         tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
28357ec8bab3SRichard Henderson         tcg_gen_shri_i64(ret, ret, 64 - len);
28367ec8bab3SRichard Henderson         break;
28377ec8bab3SRichard Henderson     }
28387ec8bab3SRichard Henderson }
28397ec8bab3SRichard Henderson 
tcg_gen_sextract_i64(TCGv_i64 ret,TCGv_i64 arg,unsigned int ofs,unsigned int len)28407ec8bab3SRichard Henderson void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
28417ec8bab3SRichard Henderson                           unsigned int ofs, unsigned int len)
28427ec8bab3SRichard Henderson {
28437ec8bab3SRichard Henderson     tcg_debug_assert(ofs < 64);
28447ec8bab3SRichard Henderson     tcg_debug_assert(len > 0);
28457ec8bab3SRichard Henderson     tcg_debug_assert(len <= 64);
28467ec8bab3SRichard Henderson     tcg_debug_assert(ofs + len <= 64);
28477ec8bab3SRichard Henderson 
28487ec8bab3SRichard Henderson     /* Canonicalize certain special cases, even if sextract is supported.  */
28497ec8bab3SRichard Henderson     if (ofs + len == 64) {
28507ec8bab3SRichard Henderson         tcg_gen_sari_i64(ret, arg, 64 - len);
28517ec8bab3SRichard Henderson         return;
28527ec8bab3SRichard Henderson     }
28537ec8bab3SRichard Henderson     if (ofs == 0) {
28547ec8bab3SRichard Henderson         switch (len) {
28557ec8bab3SRichard Henderson         case 32:
28567ec8bab3SRichard Henderson             tcg_gen_ext32s_i64(ret, arg);
28577ec8bab3SRichard Henderson             return;
28587ec8bab3SRichard Henderson         case 16:
28597ec8bab3SRichard Henderson             tcg_gen_ext16s_i64(ret, arg);
28607ec8bab3SRichard Henderson             return;
28617ec8bab3SRichard Henderson         case 8:
28627ec8bab3SRichard Henderson             tcg_gen_ext8s_i64(ret, arg);
28637ec8bab3SRichard Henderson             return;
28647ec8bab3SRichard Henderson         }
28657ec8bab3SRichard Henderson     }
28667ec8bab3SRichard Henderson 
28677ec8bab3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
28687ec8bab3SRichard Henderson         /* Look for a 32-bit extract within one of the two words.  */
28697ec8bab3SRichard Henderson         if (ofs >= 32) {
28707ec8bab3SRichard Henderson             tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
28717ec8bab3SRichard Henderson         } else if (ofs + len <= 32) {
28727ec8bab3SRichard Henderson             tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
28737ec8bab3SRichard Henderson         } else if (ofs == 0) {
28747ec8bab3SRichard Henderson             tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
28757ec8bab3SRichard Henderson             tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32);
28767ec8bab3SRichard Henderson             return;
28777ec8bab3SRichard Henderson         } else if (len > 32) {
28785dd48602SRichard Henderson             TCGv_i32 t = tcg_temp_ebb_new_i32();
28797ec8bab3SRichard Henderson             /* Extract the bits for the high word normally.  */
28807ec8bab3SRichard Henderson             tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32);
28817ec8bab3SRichard Henderson             /* Shift the field down for the low part.  */
28827ec8bab3SRichard Henderson             tcg_gen_shri_i64(ret, arg, ofs);
28837ec8bab3SRichard Henderson             /* Overwrite the shift into the high part.  */
28847ec8bab3SRichard Henderson             tcg_gen_mov_i32(TCGV_HIGH(ret), t);
28857ec8bab3SRichard Henderson             tcg_temp_free_i32(t);
28867ec8bab3SRichard Henderson             return;
28877ec8bab3SRichard Henderson         } else {
28887ec8bab3SRichard Henderson             /* Shift the field down for the low part, such that the
28897ec8bab3SRichard Henderson                field sits at the MSB.  */
28907ec8bab3SRichard Henderson             tcg_gen_shri_i64(ret, arg, ofs + len - 32);
28917ec8bab3SRichard Henderson             /* Shift the field down from the MSB, sign extending.  */
28927ec8bab3SRichard Henderson             tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_LOW(ret), 32 - len);
28937ec8bab3SRichard Henderson         }
28947ec8bab3SRichard Henderson         /* Sign-extend the field from 32 bits.  */
28957ec8bab3SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
28967ec8bab3SRichard Henderson         return;
28977ec8bab3SRichard Henderson     }
28987ec8bab3SRichard Henderson 
28997ec8bab3SRichard Henderson     if (TCG_TARGET_HAS_sextract_i64
29007ec8bab3SRichard Henderson         && TCG_TARGET_extract_i64_valid(ofs, len)) {
29017ec8bab3SRichard Henderson         tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len);
29027ec8bab3SRichard Henderson         return;
29037ec8bab3SRichard Henderson     }
29047ec8bab3SRichard Henderson 
29057ec8bab3SRichard Henderson     /* Assume that sign-extension, if available, is cheaper than a shift.  */
29067ec8bab3SRichard Henderson     switch (ofs + len) {
29077ec8bab3SRichard Henderson     case 32:
29087ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext32s_i64) {
29097ec8bab3SRichard Henderson             tcg_gen_ext32s_i64(ret, arg);
29107ec8bab3SRichard Henderson             tcg_gen_sari_i64(ret, ret, ofs);
29117ec8bab3SRichard Henderson             return;
29127ec8bab3SRichard Henderson         }
29137ec8bab3SRichard Henderson         break;
29147ec8bab3SRichard Henderson     case 16:
29157ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext16s_i64) {
29167ec8bab3SRichard Henderson             tcg_gen_ext16s_i64(ret, arg);
29177ec8bab3SRichard Henderson             tcg_gen_sari_i64(ret, ret, ofs);
29187ec8bab3SRichard Henderson             return;
29197ec8bab3SRichard Henderson         }
29207ec8bab3SRichard Henderson         break;
29217ec8bab3SRichard Henderson     case 8:
29227ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext8s_i64) {
29237ec8bab3SRichard Henderson             tcg_gen_ext8s_i64(ret, arg);
29247ec8bab3SRichard Henderson             tcg_gen_sari_i64(ret, ret, ofs);
29257ec8bab3SRichard Henderson             return;
29267ec8bab3SRichard Henderson         }
29277ec8bab3SRichard Henderson         break;
29287ec8bab3SRichard Henderson     }
29297ec8bab3SRichard Henderson     switch (len) {
29307ec8bab3SRichard Henderson     case 32:
29317ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext32s_i64) {
29327ec8bab3SRichard Henderson             tcg_gen_shri_i64(ret, arg, ofs);
29337ec8bab3SRichard Henderson             tcg_gen_ext32s_i64(ret, ret);
29347ec8bab3SRichard Henderson             return;
29357ec8bab3SRichard Henderson         }
29367ec8bab3SRichard Henderson         break;
29377ec8bab3SRichard Henderson     case 16:
29387ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext16s_i64) {
29397ec8bab3SRichard Henderson             tcg_gen_shri_i64(ret, arg, ofs);
29407ec8bab3SRichard Henderson             tcg_gen_ext16s_i64(ret, ret);
29417ec8bab3SRichard Henderson             return;
29427ec8bab3SRichard Henderson         }
29437ec8bab3SRichard Henderson         break;
29447ec8bab3SRichard Henderson     case 8:
29457ec8bab3SRichard Henderson         if (TCG_TARGET_HAS_ext8s_i64) {
29467ec8bab3SRichard Henderson             tcg_gen_shri_i64(ret, arg, ofs);
29477ec8bab3SRichard Henderson             tcg_gen_ext8s_i64(ret, ret);
29487ec8bab3SRichard Henderson             return;
29497ec8bab3SRichard Henderson         }
29507ec8bab3SRichard Henderson         break;
29517ec8bab3SRichard Henderson     }
29527ec8bab3SRichard Henderson     tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
29537ec8bab3SRichard Henderson     tcg_gen_sari_i64(ret, ret, 64 - len);
29547ec8bab3SRichard Henderson }
29557ec8bab3SRichard Henderson 
29562089fcc9SDavid Hildenbrand /*
29572089fcc9SDavid Hildenbrand  * Extract 64 bits from a 128-bit input, ah:al, starting from ofs.
29582089fcc9SDavid Hildenbrand  * Unlike tcg_gen_extract_i64 above, len is fixed at 64.
29592089fcc9SDavid Hildenbrand  */
tcg_gen_extract2_i64(TCGv_i64 ret,TCGv_i64 al,TCGv_i64 ah,unsigned int ofs)29602089fcc9SDavid Hildenbrand void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
29612089fcc9SDavid Hildenbrand                           unsigned int ofs)
29622089fcc9SDavid Hildenbrand {
29632089fcc9SDavid Hildenbrand     tcg_debug_assert(ofs <= 64);
29642089fcc9SDavid Hildenbrand     if (ofs == 0) {
29652089fcc9SDavid Hildenbrand         tcg_gen_mov_i64(ret, al);
29662089fcc9SDavid Hildenbrand     } else if (ofs == 64) {
29672089fcc9SDavid Hildenbrand         tcg_gen_mov_i64(ret, ah);
29682089fcc9SDavid Hildenbrand     } else if (al == ah) {
29692089fcc9SDavid Hildenbrand         tcg_gen_rotri_i64(ret, al, ofs);
2970fce1296fSRichard Henderson     } else if (TCG_TARGET_HAS_extract2_i64) {
2971fce1296fSRichard Henderson         tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
29722089fcc9SDavid Hildenbrand     } else {
29735dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
29742089fcc9SDavid Hildenbrand         tcg_gen_shri_i64(t0, al, ofs);
29752089fcc9SDavid Hildenbrand         tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs);
29762089fcc9SDavid Hildenbrand         tcg_temp_free_i64(t0);
29772089fcc9SDavid Hildenbrand     }
29782089fcc9SDavid Hildenbrand }
29792089fcc9SDavid Hildenbrand 
tcg_gen_movcond_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 c1,TCGv_i64 c2,TCGv_i64 v1,TCGv_i64 v2)2980951c6300SRichard Henderson void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
2981951c6300SRichard Henderson                          TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2)
2982951c6300SRichard Henderson {
298337ed3bf1SRichard Henderson     if (cond == TCG_COND_ALWAYS) {
298437ed3bf1SRichard Henderson         tcg_gen_mov_i64(ret, v1);
298537ed3bf1SRichard Henderson     } else if (cond == TCG_COND_NEVER) {
298637ed3bf1SRichard Henderson         tcg_gen_mov_i64(ret, v2);
29873871be75SRichard Henderson     } else if (TCG_TARGET_REG_BITS == 64) {
29883871be75SRichard Henderson         tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
29893871be75SRichard Henderson     } else {
29905dd48602SRichard Henderson         TCGv_i32 t0 = tcg_temp_ebb_new_i32();
29913871be75SRichard Henderson         TCGv_i32 zero = tcg_constant_i32(0);
29923871be75SRichard Henderson 
2993951c6300SRichard Henderson         tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
2994951c6300SRichard Henderson                          TCGV_LOW(c1), TCGV_HIGH(c1),
2995951c6300SRichard Henderson                          TCGV_LOW(c2), TCGV_HIGH(c2), cond);
2996951c6300SRichard Henderson 
29973871be75SRichard Henderson         tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, zero,
2998951c6300SRichard Henderson                             TCGV_LOW(v1), TCGV_LOW(v2));
29993871be75SRichard Henderson         tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, zero,
3000951c6300SRichard Henderson                             TCGV_HIGH(v1), TCGV_HIGH(v2));
3001951c6300SRichard Henderson 
3002951c6300SRichard Henderson         tcg_temp_free_i32(t0);
3003951c6300SRichard Henderson     }
3004951c6300SRichard Henderson }
3005951c6300SRichard Henderson 
tcg_gen_add2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 al,TCGv_i64 ah,TCGv_i64 bl,TCGv_i64 bh)3006951c6300SRichard Henderson void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
3007951c6300SRichard Henderson                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
3008951c6300SRichard Henderson {
3009951c6300SRichard Henderson     if (TCG_TARGET_HAS_add2_i64) {
3010951c6300SRichard Henderson         tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
3011951c6300SRichard Henderson     } else {
30125dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
30135dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
3014951c6300SRichard Henderson         tcg_gen_add_i64(t0, al, bl);
3015951c6300SRichard Henderson         tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
3016951c6300SRichard Henderson         tcg_gen_add_i64(rh, ah, bh);
3017951c6300SRichard Henderson         tcg_gen_add_i64(rh, rh, t1);
3018951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
3019951c6300SRichard Henderson         tcg_temp_free_i64(t0);
3020951c6300SRichard Henderson         tcg_temp_free_i64(t1);
3021951c6300SRichard Henderson     }
3022951c6300SRichard Henderson }
3023951c6300SRichard Henderson 
tcg_gen_sub2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 al,TCGv_i64 ah,TCGv_i64 bl,TCGv_i64 bh)3024951c6300SRichard Henderson void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
3025951c6300SRichard Henderson                       TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
3026951c6300SRichard Henderson {
3027951c6300SRichard Henderson     if (TCG_TARGET_HAS_sub2_i64) {
3028951c6300SRichard Henderson         tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
3029951c6300SRichard Henderson     } else {
30305dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
30315dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
3032951c6300SRichard Henderson         tcg_gen_sub_i64(t0, al, bl);
3033951c6300SRichard Henderson         tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
3034951c6300SRichard Henderson         tcg_gen_sub_i64(rh, ah, bh);
3035951c6300SRichard Henderson         tcg_gen_sub_i64(rh, rh, t1);
3036951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
3037951c6300SRichard Henderson         tcg_temp_free_i64(t0);
3038951c6300SRichard Henderson         tcg_temp_free_i64(t1);
3039951c6300SRichard Henderson     }
3040951c6300SRichard Henderson }
3041951c6300SRichard Henderson 
tcg_gen_mulu2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 arg1,TCGv_i64 arg2)3042951c6300SRichard Henderson void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
3043951c6300SRichard Henderson {
3044951c6300SRichard Henderson     if (TCG_TARGET_HAS_mulu2_i64) {
3045951c6300SRichard Henderson         tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
3046951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_muluh_i64) {
30475dd48602SRichard Henderson         TCGv_i64 t = tcg_temp_ebb_new_i64();
3048951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
3049951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
3050951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t);
3051951c6300SRichard Henderson         tcg_temp_free_i64(t);
3052951c6300SRichard Henderson     } else {
30535dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3054951c6300SRichard Henderson         tcg_gen_mul_i64(t0, arg1, arg2);
3055951c6300SRichard Henderson         gen_helper_muluh_i64(rh, arg1, arg2);
3056951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
3057951c6300SRichard Henderson         tcg_temp_free_i64(t0);
3058951c6300SRichard Henderson     }
3059951c6300SRichard Henderson }
3060951c6300SRichard Henderson 
tcg_gen_muls2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 arg1,TCGv_i64 arg2)3061951c6300SRichard Henderson void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
3062951c6300SRichard Henderson {
3063951c6300SRichard Henderson     if (TCG_TARGET_HAS_muls2_i64) {
3064951c6300SRichard Henderson         tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
3065951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_mulsh_i64) {
30665dd48602SRichard Henderson         TCGv_i64 t = tcg_temp_ebb_new_i64();
3067951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
3068951c6300SRichard Henderson         tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
3069951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t);
3070951c6300SRichard Henderson         tcg_temp_free_i64(t);
3071951c6300SRichard Henderson     } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
30725dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
30735dd48602SRichard Henderson         TCGv_i64 t1 = tcg_temp_ebb_new_i64();
30745dd48602SRichard Henderson         TCGv_i64 t2 = tcg_temp_ebb_new_i64();
30755dd48602SRichard Henderson         TCGv_i64 t3 = tcg_temp_ebb_new_i64();
3076951c6300SRichard Henderson         tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
3077951c6300SRichard Henderson         /* Adjust for negative inputs.  */
3078951c6300SRichard Henderson         tcg_gen_sari_i64(t2, arg1, 63);
3079951c6300SRichard Henderson         tcg_gen_sari_i64(t3, arg2, 63);
3080951c6300SRichard Henderson         tcg_gen_and_i64(t2, t2, arg2);
3081951c6300SRichard Henderson         tcg_gen_and_i64(t3, t3, arg1);
3082951c6300SRichard Henderson         tcg_gen_sub_i64(rh, t1, t2);
3083951c6300SRichard Henderson         tcg_gen_sub_i64(rh, rh, t3);
3084951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
3085951c6300SRichard Henderson         tcg_temp_free_i64(t0);
3086951c6300SRichard Henderson         tcg_temp_free_i64(t1);
3087951c6300SRichard Henderson         tcg_temp_free_i64(t2);
3088951c6300SRichard Henderson         tcg_temp_free_i64(t3);
3089951c6300SRichard Henderson     } else {
30905dd48602SRichard Henderson         TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3091951c6300SRichard Henderson         tcg_gen_mul_i64(t0, arg1, arg2);
3092951c6300SRichard Henderson         gen_helper_mulsh_i64(rh, arg1, arg2);
3093951c6300SRichard Henderson         tcg_gen_mov_i64(rl, t0);
3094951c6300SRichard Henderson         tcg_temp_free_i64(t0);
3095951c6300SRichard Henderson     }
3096951c6300SRichard Henderson }
3097951c6300SRichard Henderson 
tcg_gen_mulsu2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 arg1,TCGv_i64 arg2)30985087abfbSRichard Henderson void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
30995087abfbSRichard Henderson {
31005dd48602SRichard Henderson     TCGv_i64 t0 = tcg_temp_ebb_new_i64();
31015dd48602SRichard Henderson     TCGv_i64 t1 = tcg_temp_ebb_new_i64();
31025dd48602SRichard Henderson     TCGv_i64 t2 = tcg_temp_ebb_new_i64();
31035087abfbSRichard Henderson     tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
31045087abfbSRichard Henderson     /* Adjust for negative input for the signed arg1.  */
31055087abfbSRichard Henderson     tcg_gen_sari_i64(t2, arg1, 63);
31065087abfbSRichard Henderson     tcg_gen_and_i64(t2, t2, arg2);
31075087abfbSRichard Henderson     tcg_gen_sub_i64(rh, t1, t2);
31085087abfbSRichard Henderson     tcg_gen_mov_i64(rl, t0);
31095087abfbSRichard Henderson     tcg_temp_free_i64(t0);
31105087abfbSRichard Henderson     tcg_temp_free_i64(t1);
31115087abfbSRichard Henderson     tcg_temp_free_i64(t2);
31125087abfbSRichard Henderson }
31135087abfbSRichard Henderson 
tcg_gen_smin_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3114b87fb8cdSRichard Henderson void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3115b87fb8cdSRichard Henderson {
3116b87fb8cdSRichard Henderson     tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b);
3117b87fb8cdSRichard Henderson }
3118b87fb8cdSRichard Henderson 
tcg_gen_umin_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3119b87fb8cdSRichard Henderson void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3120b87fb8cdSRichard Henderson {
3121b87fb8cdSRichard Henderson     tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b);
3122b87fb8cdSRichard Henderson }
3123b87fb8cdSRichard Henderson 
tcg_gen_smax_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3124b87fb8cdSRichard Henderson void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3125b87fb8cdSRichard Henderson {
3126b87fb8cdSRichard Henderson     tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a);
3127b87fb8cdSRichard Henderson }
3128b87fb8cdSRichard Henderson 
tcg_gen_umax_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3129b87fb8cdSRichard Henderson void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3130b87fb8cdSRichard Henderson {
3131b87fb8cdSRichard Henderson     tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a);
3132b87fb8cdSRichard Henderson }
3133b87fb8cdSRichard Henderson 
tcg_gen_abs_i64(TCGv_i64 ret,TCGv_i64 a)3134ff1f11f7SRichard Henderson void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a)
3135ff1f11f7SRichard Henderson {
31365dd48602SRichard Henderson     TCGv_i64 t = tcg_temp_ebb_new_i64();
3137ff1f11f7SRichard Henderson 
3138ff1f11f7SRichard Henderson     tcg_gen_sari_i64(t, a, 63);
3139ff1f11f7SRichard Henderson     tcg_gen_xor_i64(ret, a, t);
3140ff1f11f7SRichard Henderson     tcg_gen_sub_i64(ret, ret, t);
3141ff1f11f7SRichard Henderson     tcg_temp_free_i64(t);
3142ff1f11f7SRichard Henderson }
3143ff1f11f7SRichard Henderson 
3144951c6300SRichard Henderson /* Size changing operations.  */
3145951c6300SRichard Henderson 
tcg_gen_extrl_i64_i32(TCGv_i32 ret,TCGv_i64 arg)3146609ad705SRichard Henderson void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
3147951c6300SRichard Henderson {
31483a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
3149951c6300SRichard Henderson         tcg_gen_mov_i32(ret, TCGV_LOW(arg));
315013d885b0SRichard Henderson     } else if (TCG_TARGET_HAS_extr_i64_i32) {
3151b7e8b17aSRichard Henderson         tcg_gen_op2(INDEX_op_extrl_i64_i32,
3152ae8b75dcSRichard Henderson                     tcgv_i32_arg(ret), tcgv_i64_arg(arg));
3153951c6300SRichard Henderson     } else {
3154dc41aa7dSRichard Henderson         tcg_gen_mov_i32(ret, (TCGv_i32)arg);
3155609ad705SRichard Henderson     }
3156609ad705SRichard Henderson }
3157609ad705SRichard Henderson 
tcg_gen_extrh_i64_i32(TCGv_i32 ret,TCGv_i64 arg)3158609ad705SRichard Henderson void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
3159609ad705SRichard Henderson {
3160609ad705SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
3161609ad705SRichard Henderson         tcg_gen_mov_i32(ret, TCGV_HIGH(arg));
316213d885b0SRichard Henderson     } else if (TCG_TARGET_HAS_extr_i64_i32) {
3163b7e8b17aSRichard Henderson         tcg_gen_op2(INDEX_op_extrh_i64_i32,
3164ae8b75dcSRichard Henderson                     tcgv_i32_arg(ret), tcgv_i64_arg(arg));
3165951c6300SRichard Henderson     } else {
31665dd48602SRichard Henderson         TCGv_i64 t = tcg_temp_ebb_new_i64();
3167609ad705SRichard Henderson         tcg_gen_shri_i64(t, arg, 32);
3168dc41aa7dSRichard Henderson         tcg_gen_mov_i32(ret, (TCGv_i32)t);
3169951c6300SRichard Henderson         tcg_temp_free_i64(t);
3170951c6300SRichard Henderson     }
3171951c6300SRichard Henderson }
3172951c6300SRichard Henderson 
tcg_gen_extu_i32_i64(TCGv_i64 ret,TCGv_i32 arg)3173951c6300SRichard Henderson void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
3174951c6300SRichard Henderson {
31753a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
3176951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
3177951c6300SRichard Henderson         tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
31783a13c3f3SRichard Henderson     } else {
3179b7e8b17aSRichard Henderson         tcg_gen_op2(INDEX_op_extu_i32_i64,
3180ae8b75dcSRichard Henderson                     tcgv_i64_arg(ret), tcgv_i32_arg(arg));
31813a13c3f3SRichard Henderson     }
3182951c6300SRichard Henderson }
3183951c6300SRichard Henderson 
tcg_gen_ext_i32_i64(TCGv_i64 ret,TCGv_i32 arg)3184951c6300SRichard Henderson void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
3185951c6300SRichard Henderson {
31863a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
3187951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(ret), arg);
3188951c6300SRichard Henderson         tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
31893a13c3f3SRichard Henderson     } else {
3190b7e8b17aSRichard Henderson         tcg_gen_op2(INDEX_op_ext_i32_i64,
3191ae8b75dcSRichard Henderson                     tcgv_i64_arg(ret), tcgv_i32_arg(arg));
31923a13c3f3SRichard Henderson     }
3193951c6300SRichard Henderson }
3194951c6300SRichard Henderson 
tcg_gen_concat_i32_i64(TCGv_i64 dest,TCGv_i32 low,TCGv_i32 high)3195951c6300SRichard Henderson void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
3196951c6300SRichard Henderson {
31973a13c3f3SRichard Henderson     TCGv_i64 tmp;
31983a13c3f3SRichard Henderson 
31993a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
3200951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_LOW(dest), low);
3201951c6300SRichard Henderson         tcg_gen_mov_i32(TCGV_HIGH(dest), high);
32023a13c3f3SRichard Henderson         return;
32033a13c3f3SRichard Henderson     }
32043a13c3f3SRichard Henderson 
32055dd48602SRichard Henderson     tmp = tcg_temp_ebb_new_i64();
3206951c6300SRichard Henderson     /* These extensions are only needed for type correctness.
3207951c6300SRichard Henderson        We may be able to do better given target specific information.  */
3208951c6300SRichard Henderson     tcg_gen_extu_i32_i64(tmp, high);
3209951c6300SRichard Henderson     tcg_gen_extu_i32_i64(dest, low);
3210951c6300SRichard Henderson     /* If deposit is available, use it.  Otherwise use the extra
3211951c6300SRichard Henderson        knowledge that we have of the zero-extensions above.  */
3212951c6300SRichard Henderson     if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
3213951c6300SRichard Henderson         tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
3214951c6300SRichard Henderson     } else {
3215951c6300SRichard Henderson         tcg_gen_shli_i64(tmp, tmp, 32);
3216951c6300SRichard Henderson         tcg_gen_or_i64(dest, dest, tmp);
3217951c6300SRichard Henderson     }
3218951c6300SRichard Henderson     tcg_temp_free_i64(tmp);
3219951c6300SRichard Henderson }
3220951c6300SRichard Henderson 
tcg_gen_extr_i64_i32(TCGv_i32 lo,TCGv_i32 hi,TCGv_i64 arg)3221951c6300SRichard Henderson void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
3222951c6300SRichard Henderson {
32233a13c3f3SRichard Henderson     if (TCG_TARGET_REG_BITS == 32) {
3224951c6300SRichard Henderson         tcg_gen_mov_i32(lo, TCGV_LOW(arg));
3225951c6300SRichard Henderson         tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
32263a13c3f3SRichard Henderson     } else {
3227609ad705SRichard Henderson         tcg_gen_extrl_i64_i32(lo, arg);
3228609ad705SRichard Henderson         tcg_gen_extrh_i64_i32(hi, arg);
32293a13c3f3SRichard Henderson     }
3230951c6300SRichard Henderson }
3231951c6300SRichard Henderson 
tcg_gen_extr32_i64(TCGv_i64 lo,TCGv_i64 hi,TCGv_i64 arg)3232951c6300SRichard Henderson void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
3233951c6300SRichard Henderson {
3234951c6300SRichard Henderson     tcg_gen_ext32u_i64(lo, arg);
3235951c6300SRichard Henderson     tcg_gen_shri_i64(hi, arg, 32);
3236951c6300SRichard Henderson }
3237951c6300SRichard Henderson 
tcg_gen_concat32_i64(TCGv_i64 ret,TCGv_i64 lo,TCGv_i64 hi)3238e0de2f55SRichard Henderson void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 hi)
3239e0de2f55SRichard Henderson {
3240e0de2f55SRichard Henderson     tcg_gen_deposit_i64(ret, lo, hi, 32, 32);
3241e0de2f55SRichard Henderson }
3242e0de2f55SRichard Henderson 
tcg_gen_extr_i128_i64(TCGv_i64 lo,TCGv_i64 hi,TCGv_i128 arg)32434771e71cSRichard Henderson void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg)
32444771e71cSRichard Henderson {
32454771e71cSRichard Henderson     tcg_gen_mov_i64(lo, TCGV128_LOW(arg));
32464771e71cSRichard Henderson     tcg_gen_mov_i64(hi, TCGV128_HIGH(arg));
32474771e71cSRichard Henderson }
32484771e71cSRichard Henderson 
tcg_gen_concat_i64_i128(TCGv_i128 ret,TCGv_i64 lo,TCGv_i64 hi)32494771e71cSRichard Henderson void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi)
32504771e71cSRichard Henderson {
32514771e71cSRichard Henderson     tcg_gen_mov_i64(TCGV128_LOW(ret), lo);
32524771e71cSRichard Henderson     tcg_gen_mov_i64(TCGV128_HIGH(ret), hi);
32534771e71cSRichard Henderson }
32544771e71cSRichard Henderson 
tcg_gen_mov_i128(TCGv_i128 dst,TCGv_i128 src)32554771e71cSRichard Henderson void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src)
32564771e71cSRichard Henderson {
32574771e71cSRichard Henderson     if (dst != src) {
32584771e71cSRichard Henderson         tcg_gen_mov_i64(TCGV128_LOW(dst), TCGV128_LOW(src));
32594771e71cSRichard Henderson         tcg_gen_mov_i64(TCGV128_HIGH(dst), TCGV128_HIGH(src));
32604771e71cSRichard Henderson     }
32614771e71cSRichard Henderson }
32624771e71cSRichard Henderson 
tcg_gen_ld_i128(TCGv_i128 ret,TCGv_ptr base,tcg_target_long offset)3263a01d9792SRichard Henderson void tcg_gen_ld_i128(TCGv_i128 ret, TCGv_ptr base, tcg_target_long offset)
3264a01d9792SRichard Henderson {
3265a01d9792SRichard Henderson     if (HOST_BIG_ENDIAN) {
3266a01d9792SRichard Henderson         tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset);
3267a01d9792SRichard Henderson         tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset + 8);
3268a01d9792SRichard Henderson     } else {
3269a01d9792SRichard Henderson         tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset);
3270a01d9792SRichard Henderson         tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset + 8);
3271a01d9792SRichard Henderson     }
3272a01d9792SRichard Henderson }
3273a01d9792SRichard Henderson 
tcg_gen_st_i128(TCGv_i128 val,TCGv_ptr base,tcg_target_long offset)3274a01d9792SRichard Henderson void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, tcg_target_long offset)
3275a01d9792SRichard Henderson {
3276a01d9792SRichard Henderson     if (HOST_BIG_ENDIAN) {
3277a01d9792SRichard Henderson         tcg_gen_st_i64(TCGV128_HIGH(val), base, offset);
3278a01d9792SRichard Henderson         tcg_gen_st_i64(TCGV128_LOW(val), base, offset + 8);
3279a01d9792SRichard Henderson     } else {
3280a01d9792SRichard Henderson         tcg_gen_st_i64(TCGV128_LOW(val), base, offset);
3281a01d9792SRichard Henderson         tcg_gen_st_i64(TCGV128_HIGH(val), base, offset + 8);
3282a01d9792SRichard Henderson     }
3283a01d9792SRichard Henderson }
3284a01d9792SRichard Henderson 
3285951c6300SRichard Henderson /* QEMU specific operations.  */
3286951c6300SRichard Henderson 
tcg_gen_exit_tb(const TranslationBlock * tb,unsigned idx)3287d9971435SRichard Henderson void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
328807ea28b4SRichard Henderson {
3289eba40358SRichard Henderson     /*
3290eba40358SRichard Henderson      * Let the jit code return the read-only version of the
3291eba40358SRichard Henderson      * TranslationBlock, so that we minimize the pc-relative
3292eba40358SRichard Henderson      * distance of the address of the exit_tb code to TB.
3293eba40358SRichard Henderson      * This will improve utilization of pc-relative address loads.
3294eba40358SRichard Henderson      *
3295eba40358SRichard Henderson      * TODO: Move this to translator_loop, so that all const
3296eba40358SRichard Henderson      * TranslationBlock pointers refer to read-only memory.
3297eba40358SRichard Henderson      * This requires coordination with targets that do not use
3298eba40358SRichard Henderson      * the translator_loop.
3299eba40358SRichard Henderson      */
3300eba40358SRichard Henderson     uintptr_t val = (uintptr_t)tcg_splitwx_to_rx((void *)tb) + idx;
330107ea28b4SRichard Henderson 
330207ea28b4SRichard Henderson     if (tb == NULL) {
330307ea28b4SRichard Henderson         tcg_debug_assert(idx == 0);
330407ea28b4SRichard Henderson     } else if (idx <= TB_EXIT_IDXMAX) {
330507ea28b4SRichard Henderson #ifdef CONFIG_DEBUG_TCG
330607ea28b4SRichard Henderson         /* This is an exit following a goto_tb.  Verify that we have
330707ea28b4SRichard Henderson            seen this numbered exit before, via tcg_gen_goto_tb.  */
330807ea28b4SRichard Henderson         tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx));
330907ea28b4SRichard Henderson #endif
331007ea28b4SRichard Henderson     } else {
331107ea28b4SRichard Henderson         /* This is an exit via the exitreq label.  */
331207ea28b4SRichard Henderson         tcg_debug_assert(idx == TB_EXIT_REQUESTED);
331307ea28b4SRichard Henderson     }
331407ea28b4SRichard Henderson 
331507ea28b4SRichard Henderson     tcg_gen_op1i(INDEX_op_exit_tb, val);
331607ea28b4SRichard Henderson }
331707ea28b4SRichard Henderson 
tcg_gen_goto_tb(unsigned idx)3318951c6300SRichard Henderson void tcg_gen_goto_tb(unsigned idx)
3319951c6300SRichard Henderson {
332084f15616SRichard Henderson     /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */
3321b7e4afbdSRichard Henderson     tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB));
3322951c6300SRichard Henderson     /* We only support two chained exits.  */
332307ea28b4SRichard Henderson     tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
3324951c6300SRichard Henderson #ifdef CONFIG_DEBUG_TCG
3325a4761232SPhilippe Mathieu-Daudé     /* Verify that we haven't seen this numbered exit before.  */
3326b1311c4aSEmilio G. Cota     tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
3327b1311c4aSEmilio G. Cota     tcg_ctx->goto_tb_issue_mask |= 1 << idx;
3328951c6300SRichard Henderson #endif
3329e6d86bedSEmilio G. Cota     plugin_gen_disable_mem_helpers();
3330951c6300SRichard Henderson     tcg_gen_op1i(INDEX_op_goto_tb, idx);
3331951c6300SRichard Henderson }
3332951c6300SRichard Henderson 
tcg_gen_lookup_and_goto_ptr(void)33337f11636dSEmilio G. Cota void tcg_gen_lookup_and_goto_ptr(void)
3334cedbcb01SEmilio G. Cota {
3335e6d86bedSEmilio G. Cota     TCGv_ptr ptr;
3336e6d86bedSEmilio G. Cota 
3337b7e4afbdSRichard Henderson     if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) {
333884f15616SRichard Henderson         tcg_gen_exit_tb(NULL, 0);
333984f15616SRichard Henderson         return;
334084f15616SRichard Henderson     }
334184f15616SRichard Henderson 
3342e6d86bedSEmilio G. Cota     plugin_gen_disable_mem_helpers();
33435dd48602SRichard Henderson     ptr = tcg_temp_ebb_new_ptr();
3344ad75a51eSRichard Henderson     gen_helper_lookup_tb_ptr(ptr, tcg_env);
3345ae8b75dcSRichard Henderson     tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr));
3346cedbcb01SEmilio G. Cota     tcg_temp_free_ptr(ptr);
3347cedbcb01SEmilio G. Cota }
3348