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)40409b9e39SRichard Henderson TCGOp * 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;
44409b9e39SRichard Henderson return op;
45951c6300SRichard Henderson }
46951c6300SRichard Henderson
tcg_gen_op2(TCGOpcode opc,TCGArg a1,TCGArg a2)47409b9e39SRichard Henderson TCGOp * NI tcg_gen_op2(TCGOpcode opc, TCGArg a1, TCGArg a2)
48951c6300SRichard Henderson {
49d4478943SPhilippe Mathieu-Daudé TCGOp *op = tcg_emit_op(opc, 2);
5075e8b9b7SRichard Henderson op->args[0] = a1;
5175e8b9b7SRichard Henderson op->args[1] = a2;
52409b9e39SRichard Henderson return op;
53951c6300SRichard Henderson }
54951c6300SRichard Henderson
tcg_gen_op3(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3)55409b9e39SRichard Henderson TCGOp * NI tcg_gen_op3(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3)
56951c6300SRichard Henderson {
57d4478943SPhilippe Mathieu-Daudé TCGOp *op = tcg_emit_op(opc, 3);
5875e8b9b7SRichard Henderson op->args[0] = a1;
5975e8b9b7SRichard Henderson op->args[1] = a2;
6075e8b9b7SRichard Henderson op->args[2] = a3;
61409b9e39SRichard Henderson return op;
62951c6300SRichard Henderson }
63951c6300SRichard Henderson
tcg_gen_op4(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3,TCGArg a4)64409b9e39SRichard Henderson TCGOp * NI tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2,
65409b9e39SRichard Henderson TCGArg a3, TCGArg a4)
66951c6300SRichard Henderson {
67d4478943SPhilippe Mathieu-Daudé TCGOp *op = tcg_emit_op(opc, 4);
6875e8b9b7SRichard Henderson op->args[0] = a1;
6975e8b9b7SRichard Henderson op->args[1] = a2;
7075e8b9b7SRichard Henderson op->args[2] = a3;
7175e8b9b7SRichard Henderson op->args[3] = a4;
72409b9e39SRichard Henderson return op;
73951c6300SRichard Henderson }
74951c6300SRichard Henderson
tcg_gen_op5(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3,TCGArg a4,TCGArg a5)75409b9e39SRichard Henderson TCGOp * NI tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2,
76409b9e39SRichard Henderson TCGArg a3, TCGArg a4, TCGArg a5)
77951c6300SRichard Henderson {
78d4478943SPhilippe Mathieu-Daudé TCGOp *op = tcg_emit_op(opc, 5);
7975e8b9b7SRichard Henderson op->args[0] = a1;
8075e8b9b7SRichard Henderson op->args[1] = a2;
8175e8b9b7SRichard Henderson op->args[2] = a3;
8275e8b9b7SRichard Henderson op->args[3] = a4;
8375e8b9b7SRichard Henderson op->args[4] = a5;
84409b9e39SRichard Henderson return op;
85951c6300SRichard Henderson }
86951c6300SRichard Henderson
tcg_gen_op6(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3,TCGArg a4,TCGArg a5,TCGArg a6)87409b9e39SRichard Henderson TCGOp * NI tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
88b7e8b17aSRichard Henderson TCGArg a4, TCGArg a5, TCGArg a6)
89951c6300SRichard Henderson {
90d4478943SPhilippe Mathieu-Daudé TCGOp *op = tcg_emit_op(opc, 6);
9175e8b9b7SRichard Henderson op->args[0] = a1;
9275e8b9b7SRichard Henderson op->args[1] = a2;
9375e8b9b7SRichard Henderson op->args[2] = a3;
9475e8b9b7SRichard Henderson op->args[3] = a4;
9575e8b9b7SRichard Henderson op->args[4] = a5;
9675e8b9b7SRichard Henderson op->args[5] = a6;
97409b9e39SRichard Henderson return op;
98951c6300SRichard Henderson }
99951c6300SRichard Henderson
1006fc75d50SRichard Henderson /*
1016fc75d50SRichard Henderson * With CONFIG_DEBUG_TCG, tcgv_*_tmp via tcgv_*_arg, is an out-of-line
1026fc75d50SRichard Henderson * assertion check. Force tail calls to avoid too much code expansion.
1036fc75d50SRichard Henderson */
1046fc75d50SRichard Henderson #ifdef CONFIG_DEBUG_TCG
1056fc75d50SRichard Henderson # define DNI NI
1066fc75d50SRichard Henderson #else
1076fc75d50SRichard Henderson # define DNI
1086fc75d50SRichard Henderson #endif
1096fc75d50SRichard Henderson
tcg_gen_op1_i32(TCGOpcode opc,TCGv_i32 a1)11017b9fadbSRichard Henderson static void DNI tcg_gen_op1_i32(TCGOpcode opc, TCGv_i32 a1)
1116fc75d50SRichard Henderson {
1126fc75d50SRichard Henderson tcg_gen_op1(opc, tcgv_i32_arg(a1));
1136fc75d50SRichard Henderson }
1146fc75d50SRichard Henderson
tcg_gen_op1_i64(TCGOpcode opc,TCGv_i64 a1)11517b9fadbSRichard Henderson static void DNI tcg_gen_op1_i64(TCGOpcode opc, TCGv_i64 a1)
1166fc75d50SRichard Henderson {
1176fc75d50SRichard Henderson tcg_gen_op1(opc, tcgv_i64_arg(a1));
1186fc75d50SRichard Henderson }
1196fc75d50SRichard Henderson
tcg_gen_op1i(TCGOpcode opc,TCGArg a1)120*83ac625cSRichard Henderson static TCGOp * DNI tcg_gen_op1i(TCGOpcode opc, TCGArg a1)
1216fc75d50SRichard Henderson {
122*83ac625cSRichard Henderson return tcg_gen_op1(opc, a1);
1236fc75d50SRichard Henderson }
1246fc75d50SRichard Henderson
tcg_gen_op2_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2)12517b9fadbSRichard Henderson static void DNI tcg_gen_op2_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2)
1266fc75d50SRichard Henderson {
1276fc75d50SRichard Henderson tcg_gen_op2(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2));
1286fc75d50SRichard Henderson }
1296fc75d50SRichard Henderson
tcg_gen_op2_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2)13017b9fadbSRichard Henderson static void DNI tcg_gen_op2_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2)
1316fc75d50SRichard Henderson {
1326fc75d50SRichard Henderson tcg_gen_op2(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2));
1336fc75d50SRichard Henderson }
1346fc75d50SRichard Henderson
tcg_gen_op3_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3)13517b9fadbSRichard Henderson static void DNI tcg_gen_op3_i32(TCGOpcode opc, TCGv_i32 a1,
13617b9fadbSRichard Henderson TCGv_i32 a2, TCGv_i32 a3)
1376fc75d50SRichard Henderson {
1386fc75d50SRichard Henderson tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), tcgv_i32_arg(a3));
1396fc75d50SRichard Henderson }
1406fc75d50SRichard Henderson
tcg_gen_op3_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3)14117b9fadbSRichard Henderson static void DNI tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 a1,
14217b9fadbSRichard Henderson TCGv_i64 a2, TCGv_i64 a3)
1436fc75d50SRichard Henderson {
1446fc75d50SRichard Henderson tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), tcgv_i64_arg(a3));
1456fc75d50SRichard Henderson }
1466fc75d50SRichard Henderson
tcg_gen_op3i_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGArg a3)14717b9fadbSRichard Henderson static void DNI tcg_gen_op3i_i32(TCGOpcode opc, TCGv_i32 a1,
14817b9fadbSRichard Henderson TCGv_i32 a2, TCGArg a3)
1496fc75d50SRichard Henderson {
1506fc75d50SRichard Henderson tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3);
1516fc75d50SRichard Henderson }
1526fc75d50SRichard Henderson
tcg_gen_op3i_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGArg a3)15317b9fadbSRichard Henderson static void DNI tcg_gen_op3i_i64(TCGOpcode opc, TCGv_i64 a1,
15417b9fadbSRichard Henderson TCGv_i64 a2, TCGArg a3)
1556fc75d50SRichard Henderson {
1566fc75d50SRichard Henderson tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3);
1576fc75d50SRichard Henderson }
1586fc75d50SRichard Henderson
tcg_gen_ldst_op_i32(TCGOpcode opc,TCGv_i32 val,TCGv_ptr base,TCGArg offset)15917b9fadbSRichard Henderson static void DNI tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val,
1606fc75d50SRichard Henderson TCGv_ptr base, TCGArg offset)
1616fc75d50SRichard Henderson {
1626fc75d50SRichard Henderson tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_ptr_arg(base), offset);
1636fc75d50SRichard Henderson }
1646fc75d50SRichard Henderson
tcg_gen_ldst_op_i64(TCGOpcode opc,TCGv_i64 val,TCGv_ptr base,TCGArg offset)16517b9fadbSRichard Henderson static void DNI tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val,
1666fc75d50SRichard Henderson TCGv_ptr base, TCGArg offset)
1676fc75d50SRichard Henderson {
1686fc75d50SRichard Henderson tcg_gen_op3(opc, tcgv_i64_arg(val), tcgv_ptr_arg(base), offset);
1696fc75d50SRichard Henderson }
1706fc75d50SRichard Henderson
tcg_gen_op4_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4)17117b9fadbSRichard Henderson static void DNI tcg_gen_op4_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1726fc75d50SRichard Henderson TCGv_i32 a3, TCGv_i32 a4)
1736fc75d50SRichard Henderson {
1746fc75d50SRichard Henderson tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1756fc75d50SRichard Henderson tcgv_i32_arg(a3), tcgv_i32_arg(a4));
1766fc75d50SRichard Henderson }
1776fc75d50SRichard Henderson
tcg_gen_op4_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4)17817b9fadbSRichard Henderson static void DNI tcg_gen_op4_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1796fc75d50SRichard Henderson TCGv_i64 a3, TCGv_i64 a4)
1806fc75d50SRichard Henderson {
1816fc75d50SRichard Henderson tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1826fc75d50SRichard Henderson tcgv_i64_arg(a3), tcgv_i64_arg(a4));
1836fc75d50SRichard Henderson }
1846fc75d50SRichard Henderson
tcg_gen_op4i_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGArg a4)18517b9fadbSRichard Henderson static void DNI tcg_gen_op4i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
1866fc75d50SRichard Henderson TCGv_i32 a3, TCGArg a4)
1876fc75d50SRichard Henderson {
1886fc75d50SRichard Henderson tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
1896fc75d50SRichard Henderson tcgv_i32_arg(a3), a4);
1906fc75d50SRichard Henderson }
1916fc75d50SRichard Henderson
tcg_gen_op4i_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGArg a4)19217b9fadbSRichard Henderson static void DNI tcg_gen_op4i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
1936fc75d50SRichard Henderson TCGv_i64 a3, TCGArg a4)
1946fc75d50SRichard Henderson {
1956fc75d50SRichard Henderson tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
1966fc75d50SRichard Henderson tcgv_i64_arg(a3), a4);
1976fc75d50SRichard Henderson }
1986fc75d50SRichard Henderson
tcg_gen_op4ii_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGArg a3,TCGArg a4)199*83ac625cSRichard Henderson static TCGOp * DNI tcg_gen_op4ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
2006fc75d50SRichard Henderson TCGArg a3, TCGArg a4)
2016fc75d50SRichard Henderson {
202*83ac625cSRichard Henderson return tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3, a4);
2036fc75d50SRichard Henderson }
2046fc75d50SRichard Henderson
tcg_gen_op4ii_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGArg a3,TCGArg a4)205*83ac625cSRichard Henderson static TCGOp * DNI tcg_gen_op4ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
2066fc75d50SRichard Henderson TCGArg a3, TCGArg a4)
2076fc75d50SRichard Henderson {
208*83ac625cSRichard Henderson return tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3, a4);
2096fc75d50SRichard Henderson }
2106fc75d50SRichard Henderson
tcg_gen_op5_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGv_i32 a5)21117b9fadbSRichard Henderson static void DNI tcg_gen_op5_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
2126fc75d50SRichard Henderson TCGv_i32 a3, TCGv_i32 a4, TCGv_i32 a5)
2136fc75d50SRichard Henderson {
2146fc75d50SRichard Henderson tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2156fc75d50SRichard Henderson tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5));
2166fc75d50SRichard Henderson }
2176fc75d50SRichard Henderson
tcg_gen_op5_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4,TCGv_i64 a5)21817b9fadbSRichard Henderson static void DNI tcg_gen_op5_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
2196fc75d50SRichard Henderson TCGv_i64 a3, TCGv_i64 a4, TCGv_i64 a5)
2206fc75d50SRichard Henderson {
2216fc75d50SRichard Henderson tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
2226fc75d50SRichard Henderson tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5));
2236fc75d50SRichard Henderson }
2246fc75d50SRichard Henderson
tcg_gen_op5ii_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGArg a4,TCGArg a5)22517b9fadbSRichard Henderson static void DNI tcg_gen_op5ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
2266fc75d50SRichard Henderson TCGv_i32 a3, TCGArg a4, TCGArg a5)
2276fc75d50SRichard Henderson {
2286fc75d50SRichard Henderson tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2296fc75d50SRichard Henderson tcgv_i32_arg(a3), a4, a5);
2306fc75d50SRichard Henderson }
2316fc75d50SRichard Henderson
tcg_gen_op5ii_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGArg a4,TCGArg a5)23217b9fadbSRichard Henderson static void DNI tcg_gen_op5ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
2336fc75d50SRichard Henderson TCGv_i64 a3, TCGArg a4, TCGArg a5)
2346fc75d50SRichard Henderson {
2356fc75d50SRichard Henderson tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
2366fc75d50SRichard Henderson tcgv_i64_arg(a3), a4, a5);
2376fc75d50SRichard Henderson }
2386fc75d50SRichard 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)23917b9fadbSRichard Henderson static void DNI tcg_gen_op6_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
24017b9fadbSRichard Henderson TCGv_i32 a3, TCGv_i32 a4,
24117b9fadbSRichard Henderson TCGv_i32 a5, TCGv_i32 a6)
2426fc75d50SRichard Henderson {
2436fc75d50SRichard Henderson tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2446fc75d50SRichard Henderson tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5),
2456fc75d50SRichard Henderson tcgv_i32_arg(a6));
2466fc75d50SRichard Henderson }
2476fc75d50SRichard 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)24817b9fadbSRichard Henderson static void DNI tcg_gen_op6_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
24917b9fadbSRichard Henderson TCGv_i64 a3, TCGv_i64 a4,
25017b9fadbSRichard Henderson TCGv_i64 a5, TCGv_i64 a6)
2516fc75d50SRichard Henderson {
2526fc75d50SRichard Henderson tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
2536fc75d50SRichard Henderson tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5),
2546fc75d50SRichard Henderson tcgv_i64_arg(a6));
2556fc75d50SRichard Henderson }
2566fc75d50SRichard Henderson
tcg_gen_op6i_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGv_i32 a5,TCGArg a6)25717b9fadbSRichard Henderson static void DNI tcg_gen_op6i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
25817b9fadbSRichard Henderson TCGv_i32 a3, TCGv_i32 a4,
25917b9fadbSRichard Henderson TCGv_i32 a5, TCGArg a6)
2606fc75d50SRichard Henderson {
2616fc75d50SRichard Henderson tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2626fc75d50SRichard Henderson tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5), a6);
2636fc75d50SRichard Henderson }
2646fc75d50SRichard Henderson
tcg_gen_op6i_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4,TCGv_i64 a5,TCGArg a6)26517b9fadbSRichard Henderson static void DNI tcg_gen_op6i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
26617b9fadbSRichard Henderson TCGv_i64 a3, TCGv_i64 a4,
26717b9fadbSRichard Henderson TCGv_i64 a5, TCGArg a6)
2686fc75d50SRichard Henderson {
2696fc75d50SRichard Henderson tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
2706fc75d50SRichard Henderson tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5), a6);
2716fc75d50SRichard Henderson }
2726fc75d50SRichard Henderson
tcg_gen_op6ii_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGArg a5,TCGArg a6)273*83ac625cSRichard Henderson static TCGOp * DNI tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
27417b9fadbSRichard Henderson TCGv_i32 a3, TCGv_i32 a4,
27517b9fadbSRichard Henderson TCGArg a5, TCGArg a6)
2766fc75d50SRichard Henderson {
277*83ac625cSRichard Henderson return tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
2786fc75d50SRichard Henderson tcgv_i32_arg(a3), tcgv_i32_arg(a4), a5, a6);
2796fc75d50SRichard Henderson }
2806fc75d50SRichard Henderson
281f85b1fc4SRichard Henderson /* Generic ops. */
282f85b1fc4SRichard Henderson
gen_set_label(TCGLabel * l)28301bbb6e3SRichard Henderson void gen_set_label(TCGLabel *l)
28401bbb6e3SRichard Henderson {
28501bbb6e3SRichard Henderson l->present = 1;
28601bbb6e3SRichard Henderson tcg_gen_op1(INDEX_op_set_label, label_arg(l));
28701bbb6e3SRichard Henderson }
28801bbb6e3SRichard Henderson
add_as_label_use(TCGLabel * l,TCGOp * op)289*83ac625cSRichard Henderson static void add_as_label_use(TCGLabel *l, TCGOp *op)
290f85b1fc4SRichard Henderson {
291f85b1fc4SRichard Henderson TCGLabelUse *u = tcg_malloc(sizeof(TCGLabelUse));
292f85b1fc4SRichard Henderson
293*83ac625cSRichard Henderson u->op = op;
294f85b1fc4SRichard Henderson QSIMPLEQ_INSERT_TAIL(&l->branches, u, next);
295f85b1fc4SRichard Henderson }
296f85b1fc4SRichard Henderson
tcg_gen_br(TCGLabel * l)297f85b1fc4SRichard Henderson void tcg_gen_br(TCGLabel *l)
298f85b1fc4SRichard Henderson {
299*83ac625cSRichard Henderson add_as_label_use(l, tcg_gen_op1(INDEX_op_br, label_arg(l)));
300f85b1fc4SRichard Henderson }
301f85b1fc4SRichard Henderson
tcg_gen_mb(TCGBar mb_type)302f65e19bcSPranith Kumar void tcg_gen_mb(TCGBar mb_type)
303f65e19bcSPranith Kumar {
304c914d46dSRichard Henderson #ifdef CONFIG_USER_ONLY
305c914d46dSRichard Henderson bool parallel = tcg_ctx->gen_tb->cflags & CF_PARALLEL;
306c914d46dSRichard Henderson #else
307c914d46dSRichard Henderson /*
308c914d46dSRichard Henderson * It is tempting to elide the barrier in a uniprocessor context.
309c914d46dSRichard Henderson * However, even with a single cpu we have i/o threads running in
310c914d46dSRichard Henderson * parallel, and lack of memory order can result in e.g. virtio
311c914d46dSRichard Henderson * queue entries being read incorrectly.
312c914d46dSRichard Henderson */
313c914d46dSRichard Henderson bool parallel = true;
314c914d46dSRichard Henderson #endif
315c914d46dSRichard Henderson
316c914d46dSRichard Henderson if (parallel) {
317b7e8b17aSRichard Henderson tcg_gen_op1(INDEX_op_mb, mb_type);
318f65e19bcSPranith Kumar }
319f65e19bcSPranith Kumar }
320f65e19bcSPranith Kumar
tcg_gen_plugin_cb(unsigned from)321a0948bb7SRichard Henderson void tcg_gen_plugin_cb(unsigned from)
322a0948bb7SRichard Henderson {
323a0948bb7SRichard Henderson tcg_gen_op1(INDEX_op_plugin_cb, from);
324a0948bb7SRichard Henderson }
325a0948bb7SRichard Henderson
tcg_gen_plugin_mem_cb(TCGv_i64 addr,unsigned meminfo)3268a2927f2SRichard Henderson void tcg_gen_plugin_mem_cb(TCGv_i64 addr, unsigned meminfo)
3278a2927f2SRichard Henderson {
3288a2927f2SRichard Henderson tcg_gen_op2(INDEX_op_plugin_mem_cb, tcgv_i64_arg(addr), meminfo);
3298a2927f2SRichard Henderson }
3308a2927f2SRichard Henderson
331951c6300SRichard Henderson /* 32 bit ops */
332951c6300SRichard Henderson
tcg_gen_discard_i32(TCGv_i32 arg)33309607d35SRichard Henderson void tcg_gen_discard_i32(TCGv_i32 arg)
33409607d35SRichard Henderson {
33509607d35SRichard Henderson tcg_gen_op1_i32(INDEX_op_discard, arg);
33609607d35SRichard Henderson }
33709607d35SRichard Henderson
tcg_gen_mov_i32(TCGv_i32 ret,TCGv_i32 arg)33809607d35SRichard Henderson void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
33909607d35SRichard Henderson {
34009607d35SRichard Henderson if (ret != arg) {
34109607d35SRichard Henderson tcg_gen_op2_i32(INDEX_op_mov_i32, ret, arg);
34209607d35SRichard Henderson }
34309607d35SRichard Henderson }
34409607d35SRichard Henderson
tcg_gen_movi_i32(TCGv_i32 ret,int32_t arg)34511d11d61SRichard Henderson void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg)
34611d11d61SRichard Henderson {
34711d11d61SRichard Henderson tcg_gen_mov_i32(ret, tcg_constant_i32(arg));
34811d11d61SRichard Henderson }
34911d11d61SRichard Henderson
tcg_gen_add_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)35009607d35SRichard Henderson void tcg_gen_add_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
35109607d35SRichard Henderson {
35209607d35SRichard Henderson tcg_gen_op3_i32(INDEX_op_add_i32, ret, arg1, arg2);
35309607d35SRichard Henderson }
35409607d35SRichard Henderson
tcg_gen_addi_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)355951c6300SRichard Henderson void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
356951c6300SRichard Henderson {
357951c6300SRichard Henderson /* some cases can be optimized here */
358951c6300SRichard Henderson if (arg2 == 0) {
359951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1);
360951c6300SRichard Henderson } else {
36111d11d61SRichard Henderson tcg_gen_add_i32(ret, arg1, tcg_constant_i32(arg2));
362951c6300SRichard Henderson }
363951c6300SRichard Henderson }
364951c6300SRichard Henderson
tcg_gen_sub_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)36509607d35SRichard Henderson void tcg_gen_sub_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
36609607d35SRichard Henderson {
36709607d35SRichard Henderson tcg_gen_op3_i32(INDEX_op_sub_i32, ret, arg1, arg2);
36809607d35SRichard Henderson }
36909607d35SRichard Henderson
tcg_gen_subfi_i32(TCGv_i32 ret,int32_t arg1,TCGv_i32 arg2)370951c6300SRichard Henderson void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2)
371951c6300SRichard Henderson {
372b701f195SRichard Henderson if (arg1 == 0) {
373b701f195SRichard Henderson tcg_gen_neg_i32(ret, arg2);
374951c6300SRichard Henderson } else {
37511d11d61SRichard Henderson tcg_gen_sub_i32(ret, tcg_constant_i32(arg1), arg2);
376951c6300SRichard Henderson }
377951c6300SRichard Henderson }
378951c6300SRichard Henderson
tcg_gen_subi_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)379951c6300SRichard Henderson void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
380951c6300SRichard Henderson {
3811551004eSRichard Henderson tcg_gen_addi_i32(ret, arg1, -arg2);
382951c6300SRichard Henderson }
383951c6300SRichard Henderson
tcg_gen_neg_i32(TCGv_i32 ret,TCGv_i32 arg)38409607d35SRichard Henderson void tcg_gen_neg_i32(TCGv_i32 ret, TCGv_i32 arg)
38509607d35SRichard Henderson {
38609607d35SRichard Henderson tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg);
38709607d35SRichard Henderson }
38809607d35SRichard Henderson
tcg_gen_and_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)38909607d35SRichard Henderson void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
39009607d35SRichard Henderson {
39109607d35SRichard Henderson tcg_gen_op3_i32(INDEX_op_and_i32, ret, arg1, arg2);
39209607d35SRichard Henderson }
39309607d35SRichard Henderson
tcg_gen_andi_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)394474b2e8fSRichard Henderson void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
395951c6300SRichard Henderson {
396951c6300SRichard Henderson /* Some cases can be optimized here. */
397951c6300SRichard Henderson switch (arg2) {
398951c6300SRichard Henderson case 0:
399951c6300SRichard Henderson tcg_gen_movi_i32(ret, 0);
400951c6300SRichard Henderson return;
401474b2e8fSRichard Henderson case -1:
402951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1);
403951c6300SRichard Henderson return;
404474b2e8fSRichard Henderson case 0xff:
405951c6300SRichard Henderson /* Don't recurse with tcg_gen_ext8u_i32. */
406951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8u_i32) {
407951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
408951c6300SRichard Henderson return;
409951c6300SRichard Henderson }
410951c6300SRichard Henderson break;
411474b2e8fSRichard Henderson case 0xffff:
412951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16u_i32) {
413951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
414951c6300SRichard Henderson return;
415951c6300SRichard Henderson }
416951c6300SRichard Henderson break;
417951c6300SRichard Henderson }
41811d11d61SRichard Henderson
41911d11d61SRichard Henderson tcg_gen_and_i32(ret, arg1, tcg_constant_i32(arg2));
420951c6300SRichard Henderson }
421951c6300SRichard Henderson
tcg_gen_or_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)42209607d35SRichard Henderson void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
42309607d35SRichard Henderson {
42409607d35SRichard Henderson tcg_gen_op3_i32(INDEX_op_or_i32, ret, arg1, arg2);
42509607d35SRichard Henderson }
42609607d35SRichard Henderson
tcg_gen_ori_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)427951c6300SRichard Henderson void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
428951c6300SRichard Henderson {
429951c6300SRichard Henderson /* Some cases can be optimized here. */
430951c6300SRichard Henderson if (arg2 == -1) {
431951c6300SRichard Henderson tcg_gen_movi_i32(ret, -1);
432951c6300SRichard Henderson } else if (arg2 == 0) {
433951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1);
434951c6300SRichard Henderson } else {
43511d11d61SRichard Henderson tcg_gen_or_i32(ret, arg1, tcg_constant_i32(arg2));
436951c6300SRichard Henderson }
437951c6300SRichard Henderson }
438951c6300SRichard Henderson
tcg_gen_xor_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)43909607d35SRichard Henderson void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
44009607d35SRichard Henderson {
44109607d35SRichard Henderson tcg_gen_op3_i32(INDEX_op_xor_i32, ret, arg1, arg2);
44209607d35SRichard Henderson }
44309607d35SRichard Henderson
tcg_gen_xori_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)444951c6300SRichard Henderson void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
445951c6300SRichard Henderson {
446951c6300SRichard Henderson /* Some cases can be optimized here. */
447951c6300SRichard Henderson if (arg2 == 0) {
448951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1);
449951c6300SRichard Henderson } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) {
450951c6300SRichard Henderson /* Don't recurse with tcg_gen_not_i32. */
451951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1);
452951c6300SRichard Henderson } else {
45311d11d61SRichard Henderson tcg_gen_xor_i32(ret, arg1, tcg_constant_i32(arg2));
454951c6300SRichard Henderson }
455951c6300SRichard Henderson }
456951c6300SRichard Henderson
tcg_gen_not_i32(TCGv_i32 ret,TCGv_i32 arg)45709607d35SRichard Henderson void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg)
45809607d35SRichard Henderson {
45909607d35SRichard Henderson if (TCG_TARGET_HAS_not_i32) {
46009607d35SRichard Henderson tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg);
46109607d35SRichard Henderson } else {
46209607d35SRichard Henderson tcg_gen_xori_i32(ret, arg, -1);
46309607d35SRichard Henderson }
46409607d35SRichard Henderson }
46509607d35SRichard Henderson
tcg_gen_shl_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)46609607d35SRichard Henderson void tcg_gen_shl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
46709607d35SRichard Henderson {
46809607d35SRichard Henderson tcg_gen_op3_i32(INDEX_op_shl_i32, ret, arg1, arg2);
46909607d35SRichard Henderson }
47009607d35SRichard Henderson
tcg_gen_shli_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)471474b2e8fSRichard Henderson void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
472951c6300SRichard Henderson {
473474b2e8fSRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 32);
474951c6300SRichard Henderson if (arg2 == 0) {
475951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1);
476951c6300SRichard Henderson } else {
47711d11d61SRichard Henderson tcg_gen_shl_i32(ret, arg1, tcg_constant_i32(arg2));
478951c6300SRichard Henderson }
479951c6300SRichard Henderson }
480951c6300SRichard Henderson
tcg_gen_shr_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)48109607d35SRichard Henderson void tcg_gen_shr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
48209607d35SRichard Henderson {
48309607d35SRichard Henderson tcg_gen_op3_i32(INDEX_op_shr_i32, ret, arg1, arg2);
48409607d35SRichard Henderson }
48509607d35SRichard Henderson
tcg_gen_shri_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)486474b2e8fSRichard Henderson void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
487951c6300SRichard Henderson {
488474b2e8fSRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 32);
489951c6300SRichard Henderson if (arg2 == 0) {
490951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1);
491951c6300SRichard Henderson } else {
49211d11d61SRichard Henderson tcg_gen_shr_i32(ret, arg1, tcg_constant_i32(arg2));
493951c6300SRichard Henderson }
494951c6300SRichard Henderson }
495951c6300SRichard Henderson
tcg_gen_sar_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)49609607d35SRichard Henderson void tcg_gen_sar_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
49709607d35SRichard Henderson {
49809607d35SRichard Henderson tcg_gen_op3_i32(INDEX_op_sar_i32, ret, arg1, arg2);
49909607d35SRichard Henderson }
50009607d35SRichard Henderson
tcg_gen_sari_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)501474b2e8fSRichard Henderson void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
502951c6300SRichard Henderson {
503474b2e8fSRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 32);
504951c6300SRichard Henderson if (arg2 == 0) {
505951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1);
506951c6300SRichard Henderson } else {
50711d11d61SRichard Henderson tcg_gen_sar_i32(ret, arg1, tcg_constant_i32(arg2));
508951c6300SRichard Henderson }
509951c6300SRichard Henderson }
510951c6300SRichard Henderson
tcg_gen_brcond_i32(TCGCond cond,TCGv_i32 arg1,TCGv_i32 arg2,TCGLabel * l)51142a268c2SRichard Henderson void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l)
512951c6300SRichard Henderson {
513951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) {
51442a268c2SRichard Henderson tcg_gen_br(l);
515951c6300SRichard Henderson } else if (cond != TCG_COND_NEVER) {
516*83ac625cSRichard Henderson TCGOp *op = tcg_gen_op4ii_i32(INDEX_op_brcond_i32,
517*83ac625cSRichard Henderson arg1, arg2, cond, label_arg(l));
518*83ac625cSRichard Henderson add_as_label_use(l, op);
519951c6300SRichard Henderson }
520951c6300SRichard Henderson }
521951c6300SRichard Henderson
tcg_gen_brcondi_i32(TCGCond cond,TCGv_i32 arg1,int32_t arg2,TCGLabel * l)52242a268c2SRichard Henderson void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l)
523951c6300SRichard Henderson {
52437ed3bf1SRichard Henderson if (cond == TCG_COND_ALWAYS) {
52537ed3bf1SRichard Henderson tcg_gen_br(l);
52637ed3bf1SRichard Henderson } else if (cond != TCG_COND_NEVER) {
52711d11d61SRichard Henderson tcg_gen_brcond_i32(cond, arg1, tcg_constant_i32(arg2), l);
528951c6300SRichard Henderson }
52937ed3bf1SRichard Henderson }
530951c6300SRichard Henderson
tcg_gen_setcond_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)531951c6300SRichard Henderson void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
532951c6300SRichard Henderson TCGv_i32 arg1, TCGv_i32 arg2)
533951c6300SRichard Henderson {
534951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) {
535951c6300SRichard Henderson tcg_gen_movi_i32(ret, 1);
536951c6300SRichard Henderson } else if (cond == TCG_COND_NEVER) {
537951c6300SRichard Henderson tcg_gen_movi_i32(ret, 0);
538951c6300SRichard Henderson } else {
539951c6300SRichard Henderson tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
540951c6300SRichard Henderson }
541951c6300SRichard Henderson }
542951c6300SRichard Henderson
tcg_gen_setcondi_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)543951c6300SRichard Henderson void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
544951c6300SRichard Henderson TCGv_i32 arg1, int32_t arg2)
545951c6300SRichard Henderson {
54611d11d61SRichard Henderson tcg_gen_setcond_i32(cond, ret, arg1, tcg_constant_i32(arg2));
547951c6300SRichard Henderson }
548951c6300SRichard Henderson
tcg_gen_negsetcond_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)5493635502dSRichard Henderson void tcg_gen_negsetcond_i32(TCGCond cond, TCGv_i32 ret,
5503635502dSRichard Henderson TCGv_i32 arg1, TCGv_i32 arg2)
5513635502dSRichard Henderson {
5523635502dSRichard Henderson if (cond == TCG_COND_ALWAYS) {
5533635502dSRichard Henderson tcg_gen_movi_i32(ret, -1);
5543635502dSRichard Henderson } else if (cond == TCG_COND_NEVER) {
5553635502dSRichard Henderson tcg_gen_movi_i32(ret, 0);
5563635502dSRichard Henderson } else if (TCG_TARGET_HAS_negsetcond_i32) {
5573635502dSRichard Henderson tcg_gen_op4i_i32(INDEX_op_negsetcond_i32, ret, arg1, arg2, cond);
5583635502dSRichard Henderson } else {
5593635502dSRichard Henderson tcg_gen_setcond_i32(cond, ret, arg1, arg2);
5603635502dSRichard Henderson tcg_gen_neg_i32(ret, ret);
5613635502dSRichard Henderson }
5623635502dSRichard Henderson }
5633635502dSRichard Henderson
tcg_gen_negsetcondi_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)56493c86ecdSPaolo Bonzini void tcg_gen_negsetcondi_i32(TCGCond cond, TCGv_i32 ret,
56593c86ecdSPaolo Bonzini TCGv_i32 arg1, int32_t arg2)
56693c86ecdSPaolo Bonzini {
56793c86ecdSPaolo Bonzini tcg_gen_negsetcond_i32(cond, ret, arg1, tcg_constant_i32(arg2));
56893c86ecdSPaolo Bonzini }
56993c86ecdSPaolo Bonzini
tcg_gen_mul_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)57009607d35SRichard Henderson void tcg_gen_mul_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
57109607d35SRichard Henderson {
57209607d35SRichard Henderson tcg_gen_op3_i32(INDEX_op_mul_i32, ret, arg1, arg2);
57309607d35SRichard Henderson }
57409607d35SRichard Henderson
tcg_gen_muli_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)575951c6300SRichard Henderson void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
576951c6300SRichard Henderson {
577b2e3ae94SRichard Henderson if (arg2 == 0) {
578b2e3ae94SRichard Henderson tcg_gen_movi_i32(ret, 0);
579b2e3ae94SRichard Henderson } else if (is_power_of_2(arg2)) {
580b2e3ae94SRichard Henderson tcg_gen_shli_i32(ret, arg1, ctz32(arg2));
581b2e3ae94SRichard Henderson } else {
58211d11d61SRichard Henderson tcg_gen_mul_i32(ret, arg1, tcg_constant_i32(arg2));
583951c6300SRichard Henderson }
584b2e3ae94SRichard Henderson }
585951c6300SRichard Henderson
tcg_gen_div_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)586951c6300SRichard Henderson void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
587951c6300SRichard Henderson {
588951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i32) {
589951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
590951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) {
5915dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
592951c6300SRichard Henderson tcg_gen_sari_i32(t0, arg1, 31);
593951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
594951c6300SRichard Henderson tcg_temp_free_i32(t0);
595951c6300SRichard Henderson } else {
596951c6300SRichard Henderson gen_helper_div_i32(ret, arg1, arg2);
597951c6300SRichard Henderson }
598951c6300SRichard Henderson }
599951c6300SRichard Henderson
tcg_gen_rem_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)600951c6300SRichard Henderson void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
601951c6300SRichard Henderson {
602951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i32) {
603951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
604951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i32) {
6055dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
606951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
607951c6300SRichard Henderson tcg_gen_mul_i32(t0, t0, arg2);
608951c6300SRichard Henderson tcg_gen_sub_i32(ret, arg1, t0);
609951c6300SRichard Henderson tcg_temp_free_i32(t0);
610951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) {
6115dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
612951c6300SRichard Henderson tcg_gen_sari_i32(t0, arg1, 31);
613951c6300SRichard Henderson tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
614951c6300SRichard Henderson tcg_temp_free_i32(t0);
615951c6300SRichard Henderson } else {
616951c6300SRichard Henderson gen_helper_rem_i32(ret, arg1, arg2);
617951c6300SRichard Henderson }
618951c6300SRichard Henderson }
619951c6300SRichard Henderson
tcg_gen_divu_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)620951c6300SRichard Henderson void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
621951c6300SRichard Henderson {
622951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i32) {
623951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
624951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) {
6255dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
626bfefdbeaSRichard Henderson TCGv_i32 zero = tcg_constant_i32(0);
627bfefdbeaSRichard Henderson tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, zero, arg2);
628951c6300SRichard Henderson tcg_temp_free_i32(t0);
629951c6300SRichard Henderson } else {
630951c6300SRichard Henderson gen_helper_divu_i32(ret, arg1, arg2);
631951c6300SRichard Henderson }
632951c6300SRichard Henderson }
633951c6300SRichard Henderson
tcg_gen_remu_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)634951c6300SRichard Henderson void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
635951c6300SRichard Henderson {
636951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i32) {
637951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
638951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i32) {
6395dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
640951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
641951c6300SRichard Henderson tcg_gen_mul_i32(t0, t0, arg2);
642951c6300SRichard Henderson tcg_gen_sub_i32(ret, arg1, t0);
643951c6300SRichard Henderson tcg_temp_free_i32(t0);
644951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i32) {
6455dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
646bfefdbeaSRichard Henderson TCGv_i32 zero = tcg_constant_i32(0);
647bfefdbeaSRichard Henderson tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, zero, arg2);
648951c6300SRichard Henderson tcg_temp_free_i32(t0);
649951c6300SRichard Henderson } else {
650951c6300SRichard Henderson gen_helper_remu_i32(ret, arg1, arg2);
651951c6300SRichard Henderson }
652951c6300SRichard Henderson }
653951c6300SRichard Henderson
tcg_gen_andc_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)654951c6300SRichard Henderson void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
655951c6300SRichard Henderson {
656951c6300SRichard Henderson if (TCG_TARGET_HAS_andc_i32) {
657951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
658951c6300SRichard Henderson } else {
6595dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
660951c6300SRichard Henderson tcg_gen_not_i32(t0, arg2);
661951c6300SRichard Henderson tcg_gen_and_i32(ret, arg1, t0);
662951c6300SRichard Henderson tcg_temp_free_i32(t0);
663951c6300SRichard Henderson }
664951c6300SRichard Henderson }
665951c6300SRichard Henderson
tcg_gen_eqv_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)666951c6300SRichard Henderson void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
667951c6300SRichard Henderson {
668951c6300SRichard Henderson if (TCG_TARGET_HAS_eqv_i32) {
669951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
670951c6300SRichard Henderson } else {
671951c6300SRichard Henderson tcg_gen_xor_i32(ret, arg1, arg2);
672951c6300SRichard Henderson tcg_gen_not_i32(ret, ret);
673951c6300SRichard Henderson }
674951c6300SRichard Henderson }
675951c6300SRichard Henderson
tcg_gen_nand_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)676951c6300SRichard Henderson void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
677951c6300SRichard Henderson {
678951c6300SRichard Henderson if (TCG_TARGET_HAS_nand_i32) {
679951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
680951c6300SRichard Henderson } else {
681951c6300SRichard Henderson tcg_gen_and_i32(ret, arg1, arg2);
682951c6300SRichard Henderson tcg_gen_not_i32(ret, ret);
683951c6300SRichard Henderson }
684951c6300SRichard Henderson }
685951c6300SRichard Henderson
tcg_gen_nor_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)686951c6300SRichard Henderson void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
687951c6300SRichard Henderson {
688951c6300SRichard Henderson if (TCG_TARGET_HAS_nor_i32) {
689951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
690951c6300SRichard Henderson } else {
691951c6300SRichard Henderson tcg_gen_or_i32(ret, arg1, arg2);
692951c6300SRichard Henderson tcg_gen_not_i32(ret, ret);
693951c6300SRichard Henderson }
694951c6300SRichard Henderson }
695951c6300SRichard Henderson
tcg_gen_orc_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)696951c6300SRichard Henderson void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
697951c6300SRichard Henderson {
698951c6300SRichard Henderson if (TCG_TARGET_HAS_orc_i32) {
699951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
700951c6300SRichard Henderson } else {
7015dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
702951c6300SRichard Henderson tcg_gen_not_i32(t0, arg2);
703951c6300SRichard Henderson tcg_gen_or_i32(ret, arg1, t0);
704951c6300SRichard Henderson tcg_temp_free_i32(t0);
705951c6300SRichard Henderson }
706951c6300SRichard Henderson }
707951c6300SRichard Henderson
tcg_gen_clz_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)7080e28d006SRichard Henderson void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7090e28d006SRichard Henderson {
7100e28d006SRichard Henderson if (TCG_TARGET_HAS_clz_i32) {
7110e28d006SRichard Henderson tcg_gen_op3_i32(INDEX_op_clz_i32, ret, arg1, arg2);
7120e28d006SRichard Henderson } else if (TCG_TARGET_HAS_clz_i64) {
7135dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
7145dd48602SRichard Henderson TCGv_i64 t2 = tcg_temp_ebb_new_i64();
7150e28d006SRichard Henderson tcg_gen_extu_i32_i64(t1, arg1);
7160e28d006SRichard Henderson tcg_gen_extu_i32_i64(t2, arg2);
7170e28d006SRichard Henderson tcg_gen_addi_i64(t2, t2, 32);
7180e28d006SRichard Henderson tcg_gen_clz_i64(t1, t1, t2);
7190e28d006SRichard Henderson tcg_gen_extrl_i64_i32(ret, t1);
7200e28d006SRichard Henderson tcg_temp_free_i64(t1);
7210e28d006SRichard Henderson tcg_temp_free_i64(t2);
7220e28d006SRichard Henderson tcg_gen_subi_i32(ret, ret, 32);
7230e28d006SRichard Henderson } else {
7240e28d006SRichard Henderson gen_helper_clz_i32(ret, arg1, arg2);
7250e28d006SRichard Henderson }
7260e28d006SRichard Henderson }
7270e28d006SRichard Henderson
tcg_gen_clzi_i32(TCGv_i32 ret,TCGv_i32 arg1,uint32_t arg2)7280e28d006SRichard Henderson void tcg_gen_clzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
7290e28d006SRichard Henderson {
73011d11d61SRichard Henderson tcg_gen_clz_i32(ret, arg1, tcg_constant_i32(arg2));
7310e28d006SRichard Henderson }
7320e28d006SRichard Henderson
tcg_gen_ctz_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)7330e28d006SRichard Henderson void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7340e28d006SRichard Henderson {
7350e28d006SRichard Henderson if (TCG_TARGET_HAS_ctz_i32) {
7360e28d006SRichard Henderson tcg_gen_op3_i32(INDEX_op_ctz_i32, ret, arg1, arg2);
7370e28d006SRichard Henderson } else if (TCG_TARGET_HAS_ctz_i64) {
7385dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
7395dd48602SRichard Henderson TCGv_i64 t2 = tcg_temp_ebb_new_i64();
7400e28d006SRichard Henderson tcg_gen_extu_i32_i64(t1, arg1);
7410e28d006SRichard Henderson tcg_gen_extu_i32_i64(t2, arg2);
7420e28d006SRichard Henderson tcg_gen_ctz_i64(t1, t1, t2);
7430e28d006SRichard Henderson tcg_gen_extrl_i64_i32(ret, t1);
7440e28d006SRichard Henderson tcg_temp_free_i64(t1);
7450e28d006SRichard Henderson tcg_temp_free_i64(t2);
74614e99210SRichard Henderson } else if (TCG_TARGET_HAS_ctpop_i32
74714e99210SRichard Henderson || TCG_TARGET_HAS_ctpop_i64
74814e99210SRichard Henderson || TCG_TARGET_HAS_clz_i32
74914e99210SRichard Henderson || TCG_TARGET_HAS_clz_i64) {
7505dd48602SRichard Henderson TCGv_i32 z, t = tcg_temp_ebb_new_i32();
75114e99210SRichard Henderson
75214e99210SRichard Henderson if (TCG_TARGET_HAS_ctpop_i32 || TCG_TARGET_HAS_ctpop_i64) {
75314e99210SRichard Henderson tcg_gen_subi_i32(t, arg1, 1);
75414e99210SRichard Henderson tcg_gen_andc_i32(t, t, arg1);
75514e99210SRichard Henderson tcg_gen_ctpop_i32(t, t);
75614e99210SRichard Henderson } else {
75714e99210SRichard Henderson /* Since all non-x86 hosts have clz(0) == 32, don't fight it. */
75814e99210SRichard Henderson tcg_gen_neg_i32(t, arg1);
75914e99210SRichard Henderson tcg_gen_and_i32(t, t, arg1);
76014e99210SRichard Henderson tcg_gen_clzi_i32(t, t, 32);
76114e99210SRichard Henderson tcg_gen_xori_i32(t, t, 31);
76214e99210SRichard Henderson }
76311d11d61SRichard Henderson z = tcg_constant_i32(0);
76414e99210SRichard Henderson tcg_gen_movcond_i32(TCG_COND_EQ, ret, arg1, z, arg2, t);
76514e99210SRichard Henderson tcg_temp_free_i32(t);
7660e28d006SRichard Henderson } else {
7670e28d006SRichard Henderson gen_helper_ctz_i32(ret, arg1, arg2);
7680e28d006SRichard Henderson }
7690e28d006SRichard Henderson }
7700e28d006SRichard Henderson
tcg_gen_ctzi_i32(TCGv_i32 ret,TCGv_i32 arg1,uint32_t arg2)7710e28d006SRichard Henderson void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
7720e28d006SRichard Henderson {
77314e99210SRichard Henderson if (!TCG_TARGET_HAS_ctz_i32 && TCG_TARGET_HAS_ctpop_i32 && arg2 == 32) {
77414e99210SRichard Henderson /* This equivalence has the advantage of not requiring a fixup. */
7755dd48602SRichard Henderson TCGv_i32 t = tcg_temp_ebb_new_i32();
77614e99210SRichard Henderson tcg_gen_subi_i32(t, arg1, 1);
77714e99210SRichard Henderson tcg_gen_andc_i32(t, t, arg1);
77814e99210SRichard Henderson tcg_gen_ctpop_i32(ret, t);
77914e99210SRichard Henderson tcg_temp_free_i32(t);
78014e99210SRichard Henderson } else {
78111d11d61SRichard Henderson tcg_gen_ctz_i32(ret, arg1, tcg_constant_i32(arg2));
7820e28d006SRichard Henderson }
78314e99210SRichard Henderson }
7840e28d006SRichard Henderson
tcg_gen_clrsb_i32(TCGv_i32 ret,TCGv_i32 arg)785086920c2SRichard Henderson void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg)
786086920c2SRichard Henderson {
787086920c2SRichard Henderson if (TCG_TARGET_HAS_clz_i32) {
7885dd48602SRichard Henderson TCGv_i32 t = tcg_temp_ebb_new_i32();
789086920c2SRichard Henderson tcg_gen_sari_i32(t, arg, 31);
790086920c2SRichard Henderson tcg_gen_xor_i32(t, t, arg);
791086920c2SRichard Henderson tcg_gen_clzi_i32(t, t, 32);
792086920c2SRichard Henderson tcg_gen_subi_i32(ret, t, 1);
793086920c2SRichard Henderson tcg_temp_free_i32(t);
794086920c2SRichard Henderson } else {
795086920c2SRichard Henderson gen_helper_clrsb_i32(ret, arg);
796086920c2SRichard Henderson }
797086920c2SRichard Henderson }
798086920c2SRichard Henderson
tcg_gen_ctpop_i32(TCGv_i32 ret,TCGv_i32 arg1)799a768e4e9SRichard Henderson void tcg_gen_ctpop_i32(TCGv_i32 ret, TCGv_i32 arg1)
800a768e4e9SRichard Henderson {
801a768e4e9SRichard Henderson if (TCG_TARGET_HAS_ctpop_i32) {
802a768e4e9SRichard Henderson tcg_gen_op2_i32(INDEX_op_ctpop_i32, ret, arg1);
803a768e4e9SRichard Henderson } else if (TCG_TARGET_HAS_ctpop_i64) {
8045dd48602SRichard Henderson TCGv_i64 t = tcg_temp_ebb_new_i64();
805a768e4e9SRichard Henderson tcg_gen_extu_i32_i64(t, arg1);
806a768e4e9SRichard Henderson tcg_gen_ctpop_i64(t, t);
807a768e4e9SRichard Henderson tcg_gen_extrl_i64_i32(ret, t);
808a768e4e9SRichard Henderson tcg_temp_free_i64(t);
809a768e4e9SRichard Henderson } else {
810a768e4e9SRichard Henderson gen_helper_ctpop_i32(ret, arg1);
811a768e4e9SRichard Henderson }
812a768e4e9SRichard Henderson }
813a768e4e9SRichard Henderson
tcg_gen_rotl_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)814951c6300SRichard Henderson void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
815951c6300SRichard Henderson {
816951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i32) {
817951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
818951c6300SRichard Henderson } else {
819951c6300SRichard Henderson TCGv_i32 t0, t1;
820951c6300SRichard Henderson
8215dd48602SRichard Henderson t0 = tcg_temp_ebb_new_i32();
8225dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i32();
823951c6300SRichard Henderson tcg_gen_shl_i32(t0, arg1, arg2);
824951c6300SRichard Henderson tcg_gen_subfi_i32(t1, 32, arg2);
825951c6300SRichard Henderson tcg_gen_shr_i32(t1, arg1, t1);
826951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1);
827951c6300SRichard Henderson tcg_temp_free_i32(t0);
828951c6300SRichard Henderson tcg_temp_free_i32(t1);
829951c6300SRichard Henderson }
830951c6300SRichard Henderson }
831951c6300SRichard Henderson
tcg_gen_rotli_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)83207dada03SRichard Henderson void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
833951c6300SRichard Henderson {
83407dada03SRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 32);
835951c6300SRichard Henderson /* some cases can be optimized here */
836951c6300SRichard Henderson if (arg2 == 0) {
837951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1);
838951c6300SRichard Henderson } else if (TCG_TARGET_HAS_rot_i32) {
83911d11d61SRichard Henderson tcg_gen_rotl_i32(ret, arg1, tcg_constant_i32(arg2));
840951c6300SRichard Henderson } else {
841951c6300SRichard Henderson TCGv_i32 t0, t1;
8425dd48602SRichard Henderson t0 = tcg_temp_ebb_new_i32();
8435dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i32();
844951c6300SRichard Henderson tcg_gen_shli_i32(t0, arg1, arg2);
845951c6300SRichard Henderson tcg_gen_shri_i32(t1, arg1, 32 - arg2);
846951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1);
847951c6300SRichard Henderson tcg_temp_free_i32(t0);
848951c6300SRichard Henderson tcg_temp_free_i32(t1);
849951c6300SRichard Henderson }
850951c6300SRichard Henderson }
851951c6300SRichard Henderson
tcg_gen_rotr_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)852951c6300SRichard Henderson void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
853951c6300SRichard Henderson {
854951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i32) {
855951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
856951c6300SRichard Henderson } else {
857951c6300SRichard Henderson TCGv_i32 t0, t1;
858951c6300SRichard Henderson
8595dd48602SRichard Henderson t0 = tcg_temp_ebb_new_i32();
8605dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i32();
861951c6300SRichard Henderson tcg_gen_shr_i32(t0, arg1, arg2);
862951c6300SRichard Henderson tcg_gen_subfi_i32(t1, 32, arg2);
863951c6300SRichard Henderson tcg_gen_shl_i32(t1, arg1, t1);
864951c6300SRichard Henderson tcg_gen_or_i32(ret, t0, t1);
865951c6300SRichard Henderson tcg_temp_free_i32(t0);
866951c6300SRichard Henderson tcg_temp_free_i32(t1);
867951c6300SRichard Henderson }
868951c6300SRichard Henderson }
869951c6300SRichard Henderson
tcg_gen_rotri_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)87007dada03SRichard Henderson void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
871951c6300SRichard Henderson {
87207dada03SRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 32);
873951c6300SRichard Henderson /* some cases can be optimized here */
874951c6300SRichard Henderson if (arg2 == 0) {
875951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg1);
876951c6300SRichard Henderson } else {
877951c6300SRichard Henderson tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
878951c6300SRichard Henderson }
879951c6300SRichard Henderson }
880951c6300SRichard Henderson
tcg_gen_deposit_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2,unsigned int ofs,unsigned int len)881951c6300SRichard Henderson void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
882951c6300SRichard Henderson unsigned int ofs, unsigned int len)
883951c6300SRichard Henderson {
884951c6300SRichard Henderson uint32_t mask;
885951c6300SRichard Henderson TCGv_i32 t1;
886951c6300SRichard Henderson
887951c6300SRichard Henderson tcg_debug_assert(ofs < 32);
8880d0d309dSRichard Henderson tcg_debug_assert(len > 0);
889951c6300SRichard Henderson tcg_debug_assert(len <= 32);
890951c6300SRichard Henderson tcg_debug_assert(ofs + len <= 32);
891951c6300SRichard Henderson
8920d0d309dSRichard Henderson if (len == 32) {
893951c6300SRichard Henderson tcg_gen_mov_i32(ret, arg2);
894951c6300SRichard Henderson return;
895951c6300SRichard Henderson }
896951c6300SRichard Henderson if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
897951c6300SRichard Henderson tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
898951c6300SRichard Henderson return;
899951c6300SRichard Henderson }
900951c6300SRichard Henderson
9015dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i32();
902951c6300SRichard Henderson
903b0a60567SRichard Henderson if (TCG_TARGET_HAS_extract2_i32) {
904b0a60567SRichard Henderson if (ofs + len == 32) {
905b0a60567SRichard Henderson tcg_gen_shli_i32(t1, arg1, len);
906b0a60567SRichard Henderson tcg_gen_extract2_i32(ret, t1, arg2, len);
907b0a60567SRichard Henderson goto done;
908b0a60567SRichard Henderson }
909b0a60567SRichard Henderson if (ofs == 0) {
910b0a60567SRichard Henderson tcg_gen_extract2_i32(ret, arg1, arg2, len);
911b0a60567SRichard Henderson tcg_gen_rotli_i32(ret, ret, len);
912b0a60567SRichard Henderson goto done;
913b0a60567SRichard Henderson }
914b0a60567SRichard Henderson }
915b0a60567SRichard Henderson
916b0a60567SRichard Henderson mask = (1u << len) - 1;
917951c6300SRichard Henderson if (ofs + len < 32) {
918951c6300SRichard Henderson tcg_gen_andi_i32(t1, arg2, mask);
919951c6300SRichard Henderson tcg_gen_shli_i32(t1, t1, ofs);
920951c6300SRichard Henderson } else {
921951c6300SRichard Henderson tcg_gen_shli_i32(t1, arg2, ofs);
922951c6300SRichard Henderson }
923951c6300SRichard Henderson tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
924951c6300SRichard Henderson tcg_gen_or_i32(ret, ret, t1);
925b0a60567SRichard Henderson done:
926951c6300SRichard Henderson tcg_temp_free_i32(t1);
927951c6300SRichard Henderson }
928951c6300SRichard Henderson
tcg_gen_deposit_z_i32(TCGv_i32 ret,TCGv_i32 arg,unsigned int ofs,unsigned int len)92907cc68d5SRichard Henderson void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
93007cc68d5SRichard Henderson unsigned int ofs, unsigned int len)
93107cc68d5SRichard Henderson {
93207cc68d5SRichard Henderson tcg_debug_assert(ofs < 32);
93307cc68d5SRichard Henderson tcg_debug_assert(len > 0);
93407cc68d5SRichard Henderson tcg_debug_assert(len <= 32);
93507cc68d5SRichard Henderson tcg_debug_assert(ofs + len <= 32);
93607cc68d5SRichard Henderson
93707cc68d5SRichard Henderson if (ofs + len == 32) {
93807cc68d5SRichard Henderson tcg_gen_shli_i32(ret, arg, ofs);
93907cc68d5SRichard Henderson } else if (ofs == 0) {
94007cc68d5SRichard Henderson tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
94107cc68d5SRichard Henderson } else if (TCG_TARGET_HAS_deposit_i32
94207cc68d5SRichard Henderson && TCG_TARGET_deposit_i32_valid(ofs, len)) {
94311d11d61SRichard Henderson TCGv_i32 zero = tcg_constant_i32(0);
94407cc68d5SRichard Henderson tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len);
94507cc68d5SRichard Henderson } else {
94607cc68d5SRichard Henderson /* To help two-operand hosts we prefer to zero-extend first,
94707cc68d5SRichard Henderson which allows ARG to stay live. */
94807cc68d5SRichard Henderson switch (len) {
94907cc68d5SRichard Henderson case 16:
95007cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext16u_i32) {
95107cc68d5SRichard Henderson tcg_gen_ext16u_i32(ret, arg);
95207cc68d5SRichard Henderson tcg_gen_shli_i32(ret, ret, ofs);
95307cc68d5SRichard Henderson return;
95407cc68d5SRichard Henderson }
95507cc68d5SRichard Henderson break;
95607cc68d5SRichard Henderson case 8:
95707cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext8u_i32) {
95807cc68d5SRichard Henderson tcg_gen_ext8u_i32(ret, arg);
95907cc68d5SRichard Henderson tcg_gen_shli_i32(ret, ret, ofs);
96007cc68d5SRichard Henderson return;
96107cc68d5SRichard Henderson }
96207cc68d5SRichard Henderson break;
96307cc68d5SRichard Henderson }
96407cc68d5SRichard Henderson /* Otherwise prefer zero-extension over AND for code size. */
96507cc68d5SRichard Henderson switch (ofs + len) {
96607cc68d5SRichard Henderson case 16:
96707cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext16u_i32) {
96807cc68d5SRichard Henderson tcg_gen_shli_i32(ret, arg, ofs);
96907cc68d5SRichard Henderson tcg_gen_ext16u_i32(ret, ret);
97007cc68d5SRichard Henderson return;
97107cc68d5SRichard Henderson }
97207cc68d5SRichard Henderson break;
97307cc68d5SRichard Henderson case 8:
97407cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext8u_i32) {
97507cc68d5SRichard Henderson tcg_gen_shli_i32(ret, arg, ofs);
97607cc68d5SRichard Henderson tcg_gen_ext8u_i32(ret, ret);
97707cc68d5SRichard Henderson return;
97807cc68d5SRichard Henderson }
97907cc68d5SRichard Henderson break;
98007cc68d5SRichard Henderson }
98107cc68d5SRichard Henderson tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
98207cc68d5SRichard Henderson tcg_gen_shli_i32(ret, ret, ofs);
98307cc68d5SRichard Henderson }
98407cc68d5SRichard Henderson }
98507cc68d5SRichard Henderson
tcg_gen_extract_i32(TCGv_i32 ret,TCGv_i32 arg,unsigned int ofs,unsigned int len)9867ec8bab3SRichard Henderson void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
9877ec8bab3SRichard Henderson unsigned int ofs, unsigned int len)
9887ec8bab3SRichard Henderson {
9897ec8bab3SRichard Henderson tcg_debug_assert(ofs < 32);
9907ec8bab3SRichard Henderson tcg_debug_assert(len > 0);
9917ec8bab3SRichard Henderson tcg_debug_assert(len <= 32);
9927ec8bab3SRichard Henderson tcg_debug_assert(ofs + len <= 32);
9937ec8bab3SRichard Henderson
9947ec8bab3SRichard Henderson /* Canonicalize certain special cases, even if extract is supported. */
9957ec8bab3SRichard Henderson if (ofs + len == 32) {
9967ec8bab3SRichard Henderson tcg_gen_shri_i32(ret, arg, 32 - len);
9977ec8bab3SRichard Henderson return;
9987ec8bab3SRichard Henderson }
9997ec8bab3SRichard Henderson if (ofs == 0) {
10007ec8bab3SRichard Henderson tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
10017ec8bab3SRichard Henderson return;
10027ec8bab3SRichard Henderson }
10037ec8bab3SRichard Henderson
10047ec8bab3SRichard Henderson if (TCG_TARGET_HAS_extract_i32
10057ec8bab3SRichard Henderson && TCG_TARGET_extract_i32_valid(ofs, len)) {
10067ec8bab3SRichard Henderson tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, ofs, len);
10077ec8bab3SRichard Henderson return;
10087ec8bab3SRichard Henderson }
10097ec8bab3SRichard Henderson
10107ec8bab3SRichard Henderson /* Assume that zero-extension, if available, is cheaper than a shift. */
10117ec8bab3SRichard Henderson switch (ofs + len) {
10127ec8bab3SRichard Henderson case 16:
10137ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext16u_i32) {
10147ec8bab3SRichard Henderson tcg_gen_ext16u_i32(ret, arg);
10157ec8bab3SRichard Henderson tcg_gen_shri_i32(ret, ret, ofs);
10167ec8bab3SRichard Henderson return;
10177ec8bab3SRichard Henderson }
10187ec8bab3SRichard Henderson break;
10197ec8bab3SRichard Henderson case 8:
10207ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext8u_i32) {
10217ec8bab3SRichard Henderson tcg_gen_ext8u_i32(ret, arg);
10227ec8bab3SRichard Henderson tcg_gen_shri_i32(ret, ret, ofs);
10237ec8bab3SRichard Henderson return;
10247ec8bab3SRichard Henderson }
10257ec8bab3SRichard Henderson break;
10267ec8bab3SRichard Henderson }
10277ec8bab3SRichard Henderson
10287ec8bab3SRichard Henderson /* ??? Ideally we'd know what values are available for immediate AND.
10297ec8bab3SRichard Henderson Assume that 8 bits are available, plus the special case of 16,
10307ec8bab3SRichard Henderson so that we get ext8u, ext16u. */
10317ec8bab3SRichard Henderson switch (len) {
10327ec8bab3SRichard Henderson case 1 ... 8: case 16:
10337ec8bab3SRichard Henderson tcg_gen_shri_i32(ret, arg, ofs);
10347ec8bab3SRichard Henderson tcg_gen_andi_i32(ret, ret, (1u << len) - 1);
10357ec8bab3SRichard Henderson break;
10367ec8bab3SRichard Henderson default:
10377ec8bab3SRichard Henderson tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
10387ec8bab3SRichard Henderson tcg_gen_shri_i32(ret, ret, 32 - len);
10397ec8bab3SRichard Henderson break;
10407ec8bab3SRichard Henderson }
10417ec8bab3SRichard Henderson }
10427ec8bab3SRichard Henderson
tcg_gen_sextract_i32(TCGv_i32 ret,TCGv_i32 arg,unsigned int ofs,unsigned int len)10437ec8bab3SRichard Henderson void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
10447ec8bab3SRichard Henderson unsigned int ofs, unsigned int len)
10457ec8bab3SRichard Henderson {
10467ec8bab3SRichard Henderson tcg_debug_assert(ofs < 32);
10477ec8bab3SRichard Henderson tcg_debug_assert(len > 0);
10487ec8bab3SRichard Henderson tcg_debug_assert(len <= 32);
10497ec8bab3SRichard Henderson tcg_debug_assert(ofs + len <= 32);
10507ec8bab3SRichard Henderson
10517ec8bab3SRichard Henderson /* Canonicalize certain special cases, even if extract is supported. */
10527ec8bab3SRichard Henderson if (ofs + len == 32) {
10537ec8bab3SRichard Henderson tcg_gen_sari_i32(ret, arg, 32 - len);
10547ec8bab3SRichard Henderson return;
10557ec8bab3SRichard Henderson }
10567ec8bab3SRichard Henderson if (ofs == 0) {
10577ec8bab3SRichard Henderson switch (len) {
10587ec8bab3SRichard Henderson case 16:
10597ec8bab3SRichard Henderson tcg_gen_ext16s_i32(ret, arg);
10607ec8bab3SRichard Henderson return;
10617ec8bab3SRichard Henderson case 8:
10627ec8bab3SRichard Henderson tcg_gen_ext8s_i32(ret, arg);
10637ec8bab3SRichard Henderson return;
10647ec8bab3SRichard Henderson }
10657ec8bab3SRichard Henderson }
10667ec8bab3SRichard Henderson
10677ec8bab3SRichard Henderson if (TCG_TARGET_HAS_sextract_i32
10687ec8bab3SRichard Henderson && TCG_TARGET_extract_i32_valid(ofs, len)) {
10697ec8bab3SRichard Henderson tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len);
10707ec8bab3SRichard Henderson return;
10717ec8bab3SRichard Henderson }
10727ec8bab3SRichard Henderson
10737ec8bab3SRichard Henderson /* Assume that sign-extension, if available, is cheaper than a shift. */
10747ec8bab3SRichard Henderson switch (ofs + len) {
10757ec8bab3SRichard Henderson case 16:
10767ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext16s_i32) {
10777ec8bab3SRichard Henderson tcg_gen_ext16s_i32(ret, arg);
10787ec8bab3SRichard Henderson tcg_gen_sari_i32(ret, ret, ofs);
10797ec8bab3SRichard Henderson return;
10807ec8bab3SRichard Henderson }
10817ec8bab3SRichard Henderson break;
10827ec8bab3SRichard Henderson case 8:
10837ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext8s_i32) {
10847ec8bab3SRichard Henderson tcg_gen_ext8s_i32(ret, arg);
10857ec8bab3SRichard Henderson tcg_gen_sari_i32(ret, ret, ofs);
10867ec8bab3SRichard Henderson return;
10877ec8bab3SRichard Henderson }
10887ec8bab3SRichard Henderson break;
10897ec8bab3SRichard Henderson }
10907ec8bab3SRichard Henderson switch (len) {
10917ec8bab3SRichard Henderson case 16:
10927ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext16s_i32) {
10937ec8bab3SRichard Henderson tcg_gen_shri_i32(ret, arg, ofs);
10947ec8bab3SRichard Henderson tcg_gen_ext16s_i32(ret, ret);
10957ec8bab3SRichard Henderson return;
10967ec8bab3SRichard Henderson }
10977ec8bab3SRichard Henderson break;
10987ec8bab3SRichard Henderson case 8:
10997ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext8s_i32) {
11007ec8bab3SRichard Henderson tcg_gen_shri_i32(ret, arg, ofs);
11017ec8bab3SRichard Henderson tcg_gen_ext8s_i32(ret, ret);
11027ec8bab3SRichard Henderson return;
11037ec8bab3SRichard Henderson }
11047ec8bab3SRichard Henderson break;
11057ec8bab3SRichard Henderson }
11067ec8bab3SRichard Henderson
11077ec8bab3SRichard Henderson tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
11087ec8bab3SRichard Henderson tcg_gen_sari_i32(ret, ret, 32 - len);
11097ec8bab3SRichard Henderson }
11107ec8bab3SRichard Henderson
11112089fcc9SDavid Hildenbrand /*
11122089fcc9SDavid Hildenbrand * Extract 32-bits from a 64-bit input, ah:al, starting from ofs.
11132089fcc9SDavid Hildenbrand * Unlike tcg_gen_extract_i32 above, len is fixed at 32.
11142089fcc9SDavid Hildenbrand */
tcg_gen_extract2_i32(TCGv_i32 ret,TCGv_i32 al,TCGv_i32 ah,unsigned int ofs)11152089fcc9SDavid Hildenbrand void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
11162089fcc9SDavid Hildenbrand unsigned int ofs)
11172089fcc9SDavid Hildenbrand {
11182089fcc9SDavid Hildenbrand tcg_debug_assert(ofs <= 32);
11192089fcc9SDavid Hildenbrand if (ofs == 0) {
11202089fcc9SDavid Hildenbrand tcg_gen_mov_i32(ret, al);
11212089fcc9SDavid Hildenbrand } else if (ofs == 32) {
11222089fcc9SDavid Hildenbrand tcg_gen_mov_i32(ret, ah);
11232089fcc9SDavid Hildenbrand } else if (al == ah) {
11242089fcc9SDavid Hildenbrand tcg_gen_rotri_i32(ret, al, ofs);
1125fce1296fSRichard Henderson } else if (TCG_TARGET_HAS_extract2_i32) {
1126fce1296fSRichard Henderson tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
11272089fcc9SDavid Hildenbrand } else {
11285dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
11292089fcc9SDavid Hildenbrand tcg_gen_shri_i32(t0, al, ofs);
11302089fcc9SDavid Hildenbrand tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs);
11312089fcc9SDavid Hildenbrand tcg_temp_free_i32(t0);
11322089fcc9SDavid Hildenbrand }
11332089fcc9SDavid Hildenbrand }
11342089fcc9SDavid Hildenbrand
tcg_gen_movcond_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 c1,TCGv_i32 c2,TCGv_i32 v1,TCGv_i32 v2)1135951c6300SRichard Henderson void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
1136951c6300SRichard Henderson TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2)
1137951c6300SRichard Henderson {
113837ed3bf1SRichard Henderson if (cond == TCG_COND_ALWAYS) {
113937ed3bf1SRichard Henderson tcg_gen_mov_i32(ret, v1);
114037ed3bf1SRichard Henderson } else if (cond == TCG_COND_NEVER) {
114137ed3bf1SRichard Henderson tcg_gen_mov_i32(ret, v2);
1142951c6300SRichard Henderson } else {
11433871be75SRichard Henderson tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
1144951c6300SRichard Henderson }
1145951c6300SRichard Henderson }
1146951c6300SRichard Henderson
tcg_gen_add2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 al,TCGv_i32 ah,TCGv_i32 bl,TCGv_i32 bh)1147951c6300SRichard Henderson void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
1148951c6300SRichard Henderson TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
1149951c6300SRichard Henderson {
1150951c6300SRichard Henderson if (TCG_TARGET_HAS_add2_i32) {
1151951c6300SRichard Henderson tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
1152951c6300SRichard Henderson } else {
11535dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
11545dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1155951c6300SRichard Henderson tcg_gen_concat_i32_i64(t0, al, ah);
1156951c6300SRichard Henderson tcg_gen_concat_i32_i64(t1, bl, bh);
1157951c6300SRichard Henderson tcg_gen_add_i64(t0, t0, t1);
1158951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0);
1159951c6300SRichard Henderson tcg_temp_free_i64(t0);
1160951c6300SRichard Henderson tcg_temp_free_i64(t1);
1161951c6300SRichard Henderson }
1162951c6300SRichard Henderson }
1163951c6300SRichard Henderson
tcg_gen_sub2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 al,TCGv_i32 ah,TCGv_i32 bl,TCGv_i32 bh)1164951c6300SRichard Henderson void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
1165951c6300SRichard Henderson TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
1166951c6300SRichard Henderson {
1167951c6300SRichard Henderson if (TCG_TARGET_HAS_sub2_i32) {
1168951c6300SRichard Henderson tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
1169951c6300SRichard Henderson } else {
11705dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
11715dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1172951c6300SRichard Henderson tcg_gen_concat_i32_i64(t0, al, ah);
1173951c6300SRichard Henderson tcg_gen_concat_i32_i64(t1, bl, bh);
1174951c6300SRichard Henderson tcg_gen_sub_i64(t0, t0, t1);
1175951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0);
1176951c6300SRichard Henderson tcg_temp_free_i64(t0);
1177951c6300SRichard Henderson tcg_temp_free_i64(t1);
1178951c6300SRichard Henderson }
1179951c6300SRichard Henderson }
1180951c6300SRichard Henderson
tcg_gen_mulu2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 arg1,TCGv_i32 arg2)1181951c6300SRichard Henderson void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
1182951c6300SRichard Henderson {
1183951c6300SRichard Henderson if (TCG_TARGET_HAS_mulu2_i32) {
1184951c6300SRichard Henderson tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
1185951c6300SRichard Henderson } else if (TCG_TARGET_HAS_muluh_i32) {
11865dd48602SRichard Henderson TCGv_i32 t = tcg_temp_ebb_new_i32();
1187951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
1188951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
1189951c6300SRichard Henderson tcg_gen_mov_i32(rl, t);
1190951c6300SRichard Henderson tcg_temp_free_i32(t);
11919fd86b51SRichard Henderson } else if (TCG_TARGET_REG_BITS == 64) {
11925dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
11935dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1194951c6300SRichard Henderson tcg_gen_extu_i32_i64(t0, arg1);
1195951c6300SRichard Henderson tcg_gen_extu_i32_i64(t1, arg2);
1196951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, t1);
1197951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0);
1198951c6300SRichard Henderson tcg_temp_free_i64(t0);
1199951c6300SRichard Henderson tcg_temp_free_i64(t1);
12009fd86b51SRichard Henderson } else {
12019fd86b51SRichard Henderson qemu_build_not_reached();
1202951c6300SRichard Henderson }
1203951c6300SRichard Henderson }
1204951c6300SRichard Henderson
tcg_gen_muls2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 arg1,TCGv_i32 arg2)1205951c6300SRichard Henderson void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
1206951c6300SRichard Henderson {
1207951c6300SRichard Henderson if (TCG_TARGET_HAS_muls2_i32) {
1208951c6300SRichard Henderson tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
1209951c6300SRichard Henderson } else if (TCG_TARGET_HAS_mulsh_i32) {
12105dd48602SRichard Henderson TCGv_i32 t = tcg_temp_ebb_new_i32();
1211951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
1212951c6300SRichard Henderson tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
1213951c6300SRichard Henderson tcg_gen_mov_i32(rl, t);
1214951c6300SRichard Henderson tcg_temp_free_i32(t);
1215951c6300SRichard Henderson } else if (TCG_TARGET_REG_BITS == 32) {
12165dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
12175dd48602SRichard Henderson TCGv_i32 t1 = tcg_temp_ebb_new_i32();
12185dd48602SRichard Henderson TCGv_i32 t2 = tcg_temp_ebb_new_i32();
12195dd48602SRichard Henderson TCGv_i32 t3 = tcg_temp_ebb_new_i32();
1220951c6300SRichard Henderson tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
1221951c6300SRichard Henderson /* Adjust for negative inputs. */
1222951c6300SRichard Henderson tcg_gen_sari_i32(t2, arg1, 31);
1223951c6300SRichard Henderson tcg_gen_sari_i32(t3, arg2, 31);
1224951c6300SRichard Henderson tcg_gen_and_i32(t2, t2, arg2);
1225951c6300SRichard Henderson tcg_gen_and_i32(t3, t3, arg1);
1226951c6300SRichard Henderson tcg_gen_sub_i32(rh, t1, t2);
1227951c6300SRichard Henderson tcg_gen_sub_i32(rh, rh, t3);
1228951c6300SRichard Henderson tcg_gen_mov_i32(rl, t0);
1229951c6300SRichard Henderson tcg_temp_free_i32(t0);
1230951c6300SRichard Henderson tcg_temp_free_i32(t1);
1231951c6300SRichard Henderson tcg_temp_free_i32(t2);
1232951c6300SRichard Henderson tcg_temp_free_i32(t3);
1233951c6300SRichard Henderson } else {
12345dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
12355dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1236951c6300SRichard Henderson tcg_gen_ext_i32_i64(t0, arg1);
1237951c6300SRichard Henderson tcg_gen_ext_i32_i64(t1, arg2);
1238951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, t1);
1239951c6300SRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0);
1240951c6300SRichard Henderson tcg_temp_free_i64(t0);
1241951c6300SRichard Henderson tcg_temp_free_i64(t1);
1242951c6300SRichard Henderson }
1243951c6300SRichard Henderson }
1244951c6300SRichard Henderson
tcg_gen_mulsu2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 arg1,TCGv_i32 arg2)12455087abfbSRichard Henderson void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
12465087abfbSRichard Henderson {
12475087abfbSRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
12485dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
12495dd48602SRichard Henderson TCGv_i32 t1 = tcg_temp_ebb_new_i32();
12505dd48602SRichard Henderson TCGv_i32 t2 = tcg_temp_ebb_new_i32();
12515087abfbSRichard Henderson tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
12525087abfbSRichard Henderson /* Adjust for negative input for the signed arg1. */
12535087abfbSRichard Henderson tcg_gen_sari_i32(t2, arg1, 31);
12545087abfbSRichard Henderson tcg_gen_and_i32(t2, t2, arg2);
12555087abfbSRichard Henderson tcg_gen_sub_i32(rh, t1, t2);
12565087abfbSRichard Henderson tcg_gen_mov_i32(rl, t0);
12575087abfbSRichard Henderson tcg_temp_free_i32(t0);
12585087abfbSRichard Henderson tcg_temp_free_i32(t1);
12595087abfbSRichard Henderson tcg_temp_free_i32(t2);
12605087abfbSRichard Henderson } else {
12615dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
12625dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
12635087abfbSRichard Henderson tcg_gen_ext_i32_i64(t0, arg1);
12645087abfbSRichard Henderson tcg_gen_extu_i32_i64(t1, arg2);
12655087abfbSRichard Henderson tcg_gen_mul_i64(t0, t0, t1);
12665087abfbSRichard Henderson tcg_gen_extr_i64_i32(rl, rh, t0);
12675087abfbSRichard Henderson tcg_temp_free_i64(t0);
12685087abfbSRichard Henderson tcg_temp_free_i64(t1);
12695087abfbSRichard Henderson }
12705087abfbSRichard Henderson }
12715087abfbSRichard Henderson
tcg_gen_ext8s_i32(TCGv_i32 ret,TCGv_i32 arg)1272951c6300SRichard Henderson void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
1273951c6300SRichard Henderson {
1274951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8s_i32) {
1275951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
1276951c6300SRichard Henderson } else {
1277951c6300SRichard Henderson tcg_gen_shli_i32(ret, arg, 24);
1278951c6300SRichard Henderson tcg_gen_sari_i32(ret, ret, 24);
1279951c6300SRichard Henderson }
1280951c6300SRichard Henderson }
1281951c6300SRichard Henderson
tcg_gen_ext16s_i32(TCGv_i32 ret,TCGv_i32 arg)1282951c6300SRichard Henderson void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
1283951c6300SRichard Henderson {
1284951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16s_i32) {
1285951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
1286951c6300SRichard Henderson } else {
1287951c6300SRichard Henderson tcg_gen_shli_i32(ret, arg, 16);
1288951c6300SRichard Henderson tcg_gen_sari_i32(ret, ret, 16);
1289951c6300SRichard Henderson }
1290951c6300SRichard Henderson }
1291951c6300SRichard Henderson
tcg_gen_ext8u_i32(TCGv_i32 ret,TCGv_i32 arg)1292951c6300SRichard Henderson void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
1293951c6300SRichard Henderson {
1294951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8u_i32) {
1295951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
1296951c6300SRichard Henderson } else {
1297951c6300SRichard Henderson tcg_gen_andi_i32(ret, arg, 0xffu);
1298951c6300SRichard Henderson }
1299951c6300SRichard Henderson }
1300951c6300SRichard Henderson
tcg_gen_ext16u_i32(TCGv_i32 ret,TCGv_i32 arg)1301951c6300SRichard Henderson void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
1302951c6300SRichard Henderson {
1303951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16u_i32) {
1304951c6300SRichard Henderson tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
1305951c6300SRichard Henderson } else {
1306951c6300SRichard Henderson tcg_gen_andi_i32(ret, arg, 0xffffu);
1307951c6300SRichard Henderson }
1308951c6300SRichard Henderson }
1309951c6300SRichard Henderson
13104de5a76aSPhilippe Mathieu-Daudé /*
13114de5a76aSPhilippe Mathieu-Daudé * bswap16_i32: 16-bit byte swap on the low bits of a 32-bit value.
13124de5a76aSPhilippe Mathieu-Daudé *
13134de5a76aSPhilippe Mathieu-Daudé * Byte pattern: xxab -> yyba
13144de5a76aSPhilippe Mathieu-Daudé *
13154de5a76aSPhilippe Mathieu-Daudé * With TCG_BSWAP_IZ, x == zero, else undefined.
13164de5a76aSPhilippe Mathieu-Daudé * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
13174de5a76aSPhilippe Mathieu-Daudé */
tcg_gen_bswap16_i32(TCGv_i32 ret,TCGv_i32 arg,int flags)13182b836c2aSRichard Henderson void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags)
1319951c6300SRichard Henderson {
13202b836c2aSRichard Henderson /* Only one extension flag may be present. */
13212b836c2aSRichard Henderson tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
13222b836c2aSRichard Henderson
1323951c6300SRichard Henderson if (TCG_TARGET_HAS_bswap16_i32) {
13242b836c2aSRichard Henderson tcg_gen_op3i_i32(INDEX_op_bswap16_i32, ret, arg, flags);
1325951c6300SRichard Henderson } else {
13265dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
13275dd48602SRichard Henderson TCGv_i32 t1 = tcg_temp_ebb_new_i32();
1328951c6300SRichard Henderson
13294de5a76aSPhilippe Mathieu-Daudé /* arg = ..ab (IZ) xxab (!IZ) */
13304de5a76aSPhilippe Mathieu-Daudé tcg_gen_shri_i32(t0, arg, 8); /* t0 = ...a (IZ) .xxa (!IZ) */
13312b836c2aSRichard Henderson if (!(flags & TCG_BSWAP_IZ)) {
13324de5a76aSPhilippe Mathieu-Daudé tcg_gen_ext8u_i32(t0, t0); /* t0 = ...a */
13332b836c2aSRichard Henderson }
13342b836c2aSRichard Henderson
13352b836c2aSRichard Henderson if (flags & TCG_BSWAP_OS) {
13364de5a76aSPhilippe Mathieu-Daudé tcg_gen_shli_i32(t1, arg, 24); /* t1 = b... */
13374de5a76aSPhilippe Mathieu-Daudé tcg_gen_sari_i32(t1, t1, 16); /* t1 = ssb. */
13382b836c2aSRichard Henderson } else if (flags & TCG_BSWAP_OZ) {
13394de5a76aSPhilippe Mathieu-Daudé tcg_gen_ext8u_i32(t1, arg); /* t1 = ...b */
13404de5a76aSPhilippe Mathieu-Daudé tcg_gen_shli_i32(t1, t1, 8); /* t1 = ..b. */
13412b836c2aSRichard Henderson } else {
13424de5a76aSPhilippe Mathieu-Daudé tcg_gen_shli_i32(t1, arg, 8); /* t1 = xab. */
13432b836c2aSRichard Henderson }
13442b836c2aSRichard Henderson
13454de5a76aSPhilippe Mathieu-Daudé tcg_gen_or_i32(ret, t0, t1); /* ret = ..ba (OZ) */
13464de5a76aSPhilippe Mathieu-Daudé /* = ssba (OS) */
13474de5a76aSPhilippe Mathieu-Daudé /* = xaba (no flag) */
1348951c6300SRichard Henderson tcg_temp_free_i32(t0);
13492b836c2aSRichard Henderson tcg_temp_free_i32(t1);
1350951c6300SRichard Henderson }
1351951c6300SRichard Henderson }
1352951c6300SRichard Henderson
135392964556SPhilippe Mathieu-Daudé /*
135492964556SPhilippe Mathieu-Daudé * bswap32_i32: 32-bit byte swap on a 32-bit value.
135592964556SPhilippe Mathieu-Daudé *
135692964556SPhilippe Mathieu-Daudé * Byte pattern: abcd -> dcba
135792964556SPhilippe Mathieu-Daudé */
tcg_gen_bswap32_i32(TCGv_i32 ret,TCGv_i32 arg)1358951c6300SRichard Henderson void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
1359951c6300SRichard Henderson {
1360951c6300SRichard Henderson if (TCG_TARGET_HAS_bswap32_i32) {
1361587195bdSRichard Henderson tcg_gen_op3i_i32(INDEX_op_bswap32_i32, ret, arg, 0);
1362951c6300SRichard Henderson } else {
13635dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
13645dd48602SRichard Henderson TCGv_i32 t1 = tcg_temp_ebb_new_i32();
136511d11d61SRichard Henderson TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff);
1366951c6300SRichard Henderson
1367a686dc71SRichard Henderson /* arg = abcd */
1368a686dc71SRichard Henderson tcg_gen_shri_i32(t0, arg, 8); /* t0 = .abc */
1369a686dc71SRichard Henderson tcg_gen_and_i32(t1, arg, t2); /* t1 = .b.d */
1370a686dc71SRichard Henderson tcg_gen_and_i32(t0, t0, t2); /* t0 = .a.c */
1371a686dc71SRichard Henderson tcg_gen_shli_i32(t1, t1, 8); /* t1 = b.d. */
1372a686dc71SRichard Henderson tcg_gen_or_i32(ret, t0, t1); /* ret = badc */
1373951c6300SRichard Henderson
1374a686dc71SRichard Henderson tcg_gen_shri_i32(t0, ret, 16); /* t0 = ..ba */
1375a686dc71SRichard Henderson tcg_gen_shli_i32(t1, ret, 16); /* t1 = dc.. */
1376a686dc71SRichard Henderson tcg_gen_or_i32(ret, t0, t1); /* ret = dcba */
1377951c6300SRichard Henderson
1378951c6300SRichard Henderson tcg_temp_free_i32(t0);
1379951c6300SRichard Henderson tcg_temp_free_i32(t1);
1380951c6300SRichard Henderson }
1381951c6300SRichard Henderson }
1382951c6300SRichard Henderson
1383b8976aa5SPhilippe Mathieu-Daudé /*
1384b8976aa5SPhilippe Mathieu-Daudé * hswap_i32: Swap 16-bit halfwords within a 32-bit value.
1385b8976aa5SPhilippe Mathieu-Daudé *
1386b8976aa5SPhilippe Mathieu-Daudé * Byte pattern: abcd -> cdab
1387b8976aa5SPhilippe Mathieu-Daudé */
tcg_gen_hswap_i32(TCGv_i32 ret,TCGv_i32 arg)138846be8425SRichard Henderson void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg)
138946be8425SRichard Henderson {
139046be8425SRichard Henderson /* Swapping 2 16-bit elements is a rotate. */
139146be8425SRichard Henderson tcg_gen_rotli_i32(ret, arg, 16);
139246be8425SRichard Henderson }
139346be8425SRichard Henderson
tcg_gen_smin_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1394b87fb8cdSRichard Henderson void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1395b87fb8cdSRichard Henderson {
1396b87fb8cdSRichard Henderson tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b);
1397b87fb8cdSRichard Henderson }
1398b87fb8cdSRichard Henderson
tcg_gen_umin_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1399b87fb8cdSRichard Henderson void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1400b87fb8cdSRichard Henderson {
1401b87fb8cdSRichard Henderson tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b);
1402b87fb8cdSRichard Henderson }
1403b87fb8cdSRichard Henderson
tcg_gen_smax_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1404b87fb8cdSRichard Henderson void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1405b87fb8cdSRichard Henderson {
1406b87fb8cdSRichard Henderson tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a);
1407b87fb8cdSRichard Henderson }
1408b87fb8cdSRichard Henderson
tcg_gen_umax_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1409b87fb8cdSRichard Henderson void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1410b87fb8cdSRichard Henderson {
1411b87fb8cdSRichard Henderson tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a);
1412b87fb8cdSRichard Henderson }
1413b87fb8cdSRichard Henderson
tcg_gen_abs_i32(TCGv_i32 ret,TCGv_i32 a)1414ff1f11f7SRichard Henderson void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a)
1415ff1f11f7SRichard Henderson {
14165dd48602SRichard Henderson TCGv_i32 t = tcg_temp_ebb_new_i32();
1417ff1f11f7SRichard Henderson
1418ff1f11f7SRichard Henderson tcg_gen_sari_i32(t, a, 31);
1419ff1f11f7SRichard Henderson tcg_gen_xor_i32(ret, a, t);
1420ff1f11f7SRichard Henderson tcg_gen_sub_i32(ret, ret, t);
1421ff1f11f7SRichard Henderson tcg_temp_free_i32(t);
1422ff1f11f7SRichard Henderson }
1423ff1f11f7SRichard Henderson
tcg_gen_ld8u_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)142409607d35SRichard Henderson void tcg_gen_ld8u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
142509607d35SRichard Henderson {
142609607d35SRichard Henderson tcg_gen_ldst_op_i32(INDEX_op_ld8u_i32, ret, arg2, offset);
142709607d35SRichard Henderson }
142809607d35SRichard Henderson
tcg_gen_ld8s_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)142909607d35SRichard Henderson void tcg_gen_ld8s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
143009607d35SRichard Henderson {
143109607d35SRichard Henderson tcg_gen_ldst_op_i32(INDEX_op_ld8s_i32, ret, arg2, offset);
143209607d35SRichard Henderson }
143309607d35SRichard Henderson
tcg_gen_ld16u_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)143409607d35SRichard Henderson void tcg_gen_ld16u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
143509607d35SRichard Henderson {
143609607d35SRichard Henderson tcg_gen_ldst_op_i32(INDEX_op_ld16u_i32, ret, arg2, offset);
143709607d35SRichard Henderson }
143809607d35SRichard Henderson
tcg_gen_ld16s_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)143909607d35SRichard Henderson void tcg_gen_ld16s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
144009607d35SRichard Henderson {
144109607d35SRichard Henderson tcg_gen_ldst_op_i32(INDEX_op_ld16s_i32, ret, arg2, offset);
144209607d35SRichard Henderson }
144309607d35SRichard Henderson
tcg_gen_ld_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)144409607d35SRichard Henderson void tcg_gen_ld_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
144509607d35SRichard Henderson {
144609607d35SRichard Henderson tcg_gen_ldst_op_i32(INDEX_op_ld_i32, ret, arg2, offset);
144709607d35SRichard Henderson }
144809607d35SRichard Henderson
tcg_gen_st8_i32(TCGv_i32 arg1,TCGv_ptr arg2,tcg_target_long offset)144909607d35SRichard Henderson void tcg_gen_st8_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
145009607d35SRichard Henderson {
145109607d35SRichard Henderson tcg_gen_ldst_op_i32(INDEX_op_st8_i32, arg1, arg2, offset);
145209607d35SRichard Henderson }
145309607d35SRichard Henderson
tcg_gen_st16_i32(TCGv_i32 arg1,TCGv_ptr arg2,tcg_target_long offset)145409607d35SRichard Henderson void tcg_gen_st16_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
145509607d35SRichard Henderson {
145609607d35SRichard Henderson tcg_gen_ldst_op_i32(INDEX_op_st16_i32, arg1, arg2, offset);
145709607d35SRichard Henderson }
145809607d35SRichard Henderson
tcg_gen_st_i32(TCGv_i32 arg1,TCGv_ptr arg2,tcg_target_long offset)145909607d35SRichard Henderson void tcg_gen_st_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
146009607d35SRichard Henderson {
146109607d35SRichard Henderson tcg_gen_ldst_op_i32(INDEX_op_st_i32, arg1, arg2, offset);
146209607d35SRichard Henderson }
146309607d35SRichard Henderson
146409607d35SRichard Henderson
1465951c6300SRichard Henderson /* 64-bit ops */
1466951c6300SRichard Henderson
tcg_gen_discard_i64(TCGv_i64 arg)1467951c6300SRichard Henderson void tcg_gen_discard_i64(TCGv_i64 arg)
1468951c6300SRichard Henderson {
1469e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1470e0de2f55SRichard Henderson tcg_gen_op1_i64(INDEX_op_discard, arg);
1471e0de2f55SRichard Henderson } else {
1472951c6300SRichard Henderson tcg_gen_discard_i32(TCGV_LOW(arg));
1473951c6300SRichard Henderson tcg_gen_discard_i32(TCGV_HIGH(arg));
1474951c6300SRichard Henderson }
1475e0de2f55SRichard Henderson }
1476951c6300SRichard Henderson
tcg_gen_mov_i64(TCGv_i64 ret,TCGv_i64 arg)1477951c6300SRichard Henderson void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
1478951c6300SRichard Henderson {
1479e0de2f55SRichard Henderson if (ret == arg) {
1480e0de2f55SRichard Henderson return;
1481e0de2f55SRichard Henderson }
1482e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1483e0de2f55SRichard Henderson tcg_gen_op2_i64(INDEX_op_mov_i64, ret, arg);
1484e0de2f55SRichard Henderson } else {
148511d11d61SRichard Henderson TCGTemp *ts = tcgv_i64_temp(arg);
148611d11d61SRichard Henderson
148711d11d61SRichard Henderson /* Canonicalize TCGv_i64 TEMP_CONST into TCGv_i32 TEMP_CONST. */
148811d11d61SRichard Henderson if (ts->kind == TEMP_CONST) {
148911d11d61SRichard Henderson tcg_gen_movi_i64(ret, ts->val);
149011d11d61SRichard Henderson } else {
1491951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1492951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
1493951c6300SRichard Henderson }
149411d11d61SRichard Henderson }
1495e0de2f55SRichard Henderson }
1496951c6300SRichard Henderson
tcg_gen_movi_i64(TCGv_i64 ret,int64_t arg)1497951c6300SRichard Henderson void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
1498951c6300SRichard Henderson {
1499e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1500e0de2f55SRichard Henderson tcg_gen_mov_i64(ret, tcg_constant_i64(arg));
1501e0de2f55SRichard Henderson } else {
1502951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_LOW(ret), arg);
1503951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
1504951c6300SRichard Henderson }
1505e0de2f55SRichard Henderson }
1506951c6300SRichard Henderson
tcg_gen_ld8u_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1507951c6300SRichard Henderson void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1508951c6300SRichard Henderson {
1509e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1510e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_ld8u_i64, ret, arg2, offset);
1511e0de2f55SRichard Henderson } else {
1512951c6300SRichard Henderson tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset);
1513951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1514951c6300SRichard Henderson }
1515e0de2f55SRichard Henderson }
1516951c6300SRichard Henderson
tcg_gen_ld8s_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1517951c6300SRichard Henderson void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1518951c6300SRichard Henderson {
1519e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1520e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_ld8s_i64, ret, arg2, offset);
1521e0de2f55SRichard Henderson } else {
1522951c6300SRichard Henderson tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
15233ff91d7eSJoseph Myers tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1524951c6300SRichard Henderson }
1525e0de2f55SRichard Henderson }
1526951c6300SRichard Henderson
tcg_gen_ld16u_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1527951c6300SRichard Henderson void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1528951c6300SRichard Henderson {
1529e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1530e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_ld16u_i64, ret, arg2, offset);
1531e0de2f55SRichard Henderson } else {
1532951c6300SRichard Henderson tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset);
1533951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1534951c6300SRichard Henderson }
1535e0de2f55SRichard Henderson }
1536951c6300SRichard Henderson
tcg_gen_ld16s_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1537951c6300SRichard Henderson void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1538951c6300SRichard Henderson {
1539e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1540e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_ld16s_i64, ret, arg2, offset);
1541e0de2f55SRichard Henderson } else {
1542951c6300SRichard Henderson tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset);
1543951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1544951c6300SRichard Henderson }
1545e0de2f55SRichard Henderson }
1546951c6300SRichard Henderson
tcg_gen_ld32u_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1547951c6300SRichard Henderson void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1548951c6300SRichard Henderson {
1549e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1550e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_ld32u_i64, ret, arg2, offset);
1551e0de2f55SRichard Henderson } else {
1552951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1553951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1554951c6300SRichard Henderson }
1555e0de2f55SRichard Henderson }
1556951c6300SRichard Henderson
tcg_gen_ld32s_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1557951c6300SRichard Henderson void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1558951c6300SRichard Henderson {
1559e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1560e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_ld32s_i64, ret, arg2, offset);
1561e0de2f55SRichard Henderson } else {
1562951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1563951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1564951c6300SRichard Henderson }
1565e0de2f55SRichard Henderson }
1566951c6300SRichard Henderson
tcg_gen_ld_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1567951c6300SRichard Henderson void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1568951c6300SRichard Henderson {
1569e0de2f55SRichard Henderson /*
1570e0de2f55SRichard Henderson * For 32-bit host, since arg2 and ret have different types,
1571e0de2f55SRichard Henderson * they cannot be the same temporary -- no chance of overlap.
1572e0de2f55SRichard Henderson */
1573e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1574e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_ld_i64, ret, arg2, offset);
1575e0de2f55SRichard Henderson } else if (HOST_BIG_ENDIAN) {
1576951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
1577951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
1578e0de2f55SRichard Henderson } else {
1579951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1580951c6300SRichard Henderson tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
1581e0de2f55SRichard Henderson }
1582951c6300SRichard Henderson }
1583951c6300SRichard Henderson
tcg_gen_st8_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1584d56fea79SRichard Henderson void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1585d56fea79SRichard Henderson {
1586e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1587e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_st8_i64, arg1, arg2, offset);
1588e0de2f55SRichard Henderson } else {
1589d56fea79SRichard Henderson tcg_gen_st8_i32(TCGV_LOW(arg1), arg2, offset);
1590d56fea79SRichard Henderson }
1591e0de2f55SRichard Henderson }
1592d56fea79SRichard Henderson
tcg_gen_st16_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1593d56fea79SRichard Henderson void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1594d56fea79SRichard Henderson {
1595e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1596e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_st16_i64, arg1, arg2, offset);
1597e0de2f55SRichard Henderson } else {
1598d56fea79SRichard Henderson tcg_gen_st16_i32(TCGV_LOW(arg1), arg2, offset);
1599d56fea79SRichard Henderson }
1600e0de2f55SRichard Henderson }
1601d56fea79SRichard Henderson
tcg_gen_st32_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1602d56fea79SRichard Henderson void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1603d56fea79SRichard Henderson {
1604e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1605e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_st32_i64, arg1, arg2, offset);
1606e0de2f55SRichard Henderson } else {
1607d56fea79SRichard Henderson tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
1608d56fea79SRichard Henderson }
1609e0de2f55SRichard Henderson }
1610d56fea79SRichard Henderson
tcg_gen_st_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1611951c6300SRichard Henderson void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1612951c6300SRichard Henderson {
1613e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1614e0de2f55SRichard Henderson tcg_gen_ldst_op_i64(INDEX_op_st_i64, arg1, arg2, offset);
1615e0de2f55SRichard Henderson } else if (HOST_BIG_ENDIAN) {
1616951c6300SRichard Henderson tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
1617951c6300SRichard Henderson tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
1618e0de2f55SRichard Henderson } else {
1619951c6300SRichard Henderson tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
1620951c6300SRichard Henderson tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
1621e0de2f55SRichard Henderson }
1622951c6300SRichard Henderson }
1623951c6300SRichard Henderson
tcg_gen_add_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1624d56fea79SRichard Henderson void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1625d56fea79SRichard Henderson {
1626e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1627e0de2f55SRichard Henderson tcg_gen_op3_i64(INDEX_op_add_i64, ret, arg1, arg2);
1628e0de2f55SRichard Henderson } else {
1629d56fea79SRichard Henderson tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1),
1630d56fea79SRichard Henderson TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2));
1631d56fea79SRichard Henderson }
1632e0de2f55SRichard Henderson }
1633d56fea79SRichard Henderson
tcg_gen_sub_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1634d56fea79SRichard Henderson void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1635d56fea79SRichard Henderson {
1636e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1637e0de2f55SRichard Henderson tcg_gen_op3_i64(INDEX_op_sub_i64, ret, arg1, arg2);
1638e0de2f55SRichard Henderson } else {
1639d56fea79SRichard Henderson tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1),
1640d56fea79SRichard Henderson TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2));
1641d56fea79SRichard Henderson }
1642e0de2f55SRichard Henderson }
1643d56fea79SRichard Henderson
tcg_gen_and_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1644951c6300SRichard Henderson void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1645951c6300SRichard Henderson {
1646e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1647e0de2f55SRichard Henderson tcg_gen_op3_i64(INDEX_op_and_i64, ret, arg1, arg2);
1648e0de2f55SRichard Henderson } else {
1649951c6300SRichard Henderson tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1650951c6300SRichard Henderson tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1651951c6300SRichard Henderson }
1652e0de2f55SRichard Henderson }
1653951c6300SRichard Henderson
tcg_gen_or_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1654951c6300SRichard Henderson void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1655951c6300SRichard Henderson {
1656e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1657e0de2f55SRichard Henderson tcg_gen_op3_i64(INDEX_op_or_i64, ret, arg1, arg2);
1658e0de2f55SRichard Henderson } else {
1659951c6300SRichard Henderson tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1660951c6300SRichard Henderson tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1661951c6300SRichard Henderson }
1662e0de2f55SRichard Henderson }
1663951c6300SRichard Henderson
tcg_gen_xor_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1664951c6300SRichard Henderson void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1665951c6300SRichard Henderson {
1666e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1667e0de2f55SRichard Henderson tcg_gen_op3_i64(INDEX_op_xor_i64, ret, arg1, arg2);
1668e0de2f55SRichard Henderson } else {
1669951c6300SRichard Henderson tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1670951c6300SRichard Henderson tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1671951c6300SRichard Henderson }
1672e0de2f55SRichard Henderson }
1673951c6300SRichard Henderson
tcg_gen_shl_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1674951c6300SRichard Henderson void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1675951c6300SRichard Henderson {
1676e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1677e0de2f55SRichard Henderson tcg_gen_op3_i64(INDEX_op_shl_i64, ret, arg1, arg2);
1678e0de2f55SRichard Henderson } else {
1679951c6300SRichard Henderson gen_helper_shl_i64(ret, arg1, arg2);
1680951c6300SRichard Henderson }
1681e0de2f55SRichard Henderson }
1682951c6300SRichard Henderson
tcg_gen_shr_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1683951c6300SRichard Henderson void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1684951c6300SRichard Henderson {
1685e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1686e0de2f55SRichard Henderson tcg_gen_op3_i64(INDEX_op_shr_i64, ret, arg1, arg2);
1687e0de2f55SRichard Henderson } else {
1688951c6300SRichard Henderson gen_helper_shr_i64(ret, arg1, arg2);
1689951c6300SRichard Henderson }
1690e0de2f55SRichard Henderson }
1691951c6300SRichard Henderson
tcg_gen_sar_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1692951c6300SRichard Henderson void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1693951c6300SRichard Henderson {
1694e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1695e0de2f55SRichard Henderson tcg_gen_op3_i64(INDEX_op_sar_i64, ret, arg1, arg2);
1696e0de2f55SRichard Henderson } else {
1697951c6300SRichard Henderson gen_helper_sar_i64(ret, arg1, arg2);
1698951c6300SRichard Henderson }
1699e0de2f55SRichard Henderson }
1700951c6300SRichard Henderson
tcg_gen_mul_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1701951c6300SRichard Henderson void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1702951c6300SRichard Henderson {
1703951c6300SRichard Henderson TCGv_i64 t0;
1704951c6300SRichard Henderson TCGv_i32 t1;
1705951c6300SRichard Henderson
1706e0de2f55SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1707e0de2f55SRichard Henderson tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2);
1708e0de2f55SRichard Henderson return;
1709e0de2f55SRichard Henderson }
1710e0de2f55SRichard Henderson
1711e0de2f55SRichard Henderson
17125dd48602SRichard Henderson t0 = tcg_temp_ebb_new_i64();
17135dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i32();
1714951c6300SRichard Henderson
1715951c6300SRichard Henderson tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
1716951c6300SRichard Henderson TCGV_LOW(arg1), TCGV_LOW(arg2));
1717951c6300SRichard Henderson
1718951c6300SRichard Henderson tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
1719951c6300SRichard Henderson tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1720951c6300SRichard Henderson tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2));
1721951c6300SRichard Henderson tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1722951c6300SRichard Henderson
1723951c6300SRichard Henderson tcg_gen_mov_i64(ret, t0);
1724951c6300SRichard Henderson tcg_temp_free_i64(t0);
1725951c6300SRichard Henderson tcg_temp_free_i32(t1);
1726951c6300SRichard Henderson }
172711d11d61SRichard Henderson
tcg_gen_addi_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1728951c6300SRichard Henderson void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1729951c6300SRichard Henderson {
1730951c6300SRichard Henderson /* some cases can be optimized here */
1731951c6300SRichard Henderson if (arg2 == 0) {
1732951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1);
173311d11d61SRichard Henderson } else if (TCG_TARGET_REG_BITS == 64) {
173411d11d61SRichard Henderson tcg_gen_add_i64(ret, arg1, tcg_constant_i64(arg2));
1735951c6300SRichard Henderson } else {
173611d11d61SRichard Henderson tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
173711d11d61SRichard Henderson TCGV_LOW(arg1), TCGV_HIGH(arg1),
173811d11d61SRichard Henderson tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32));
1739951c6300SRichard Henderson }
1740951c6300SRichard Henderson }
1741951c6300SRichard Henderson
tcg_gen_subfi_i64(TCGv_i64 ret,int64_t arg1,TCGv_i64 arg2)1742951c6300SRichard Henderson void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2)
1743951c6300SRichard Henderson {
1744b701f195SRichard Henderson if (arg1 == 0) {
1745b701f195SRichard Henderson tcg_gen_neg_i64(ret, arg2);
174611d11d61SRichard Henderson } else if (TCG_TARGET_REG_BITS == 64) {
174711d11d61SRichard Henderson tcg_gen_sub_i64(ret, tcg_constant_i64(arg1), arg2);
1748951c6300SRichard Henderson } else {
174911d11d61SRichard Henderson tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
175011d11d61SRichard Henderson tcg_constant_i32(arg1), tcg_constant_i32(arg1 >> 32),
175111d11d61SRichard Henderson TCGV_LOW(arg2), TCGV_HIGH(arg2));
1752951c6300SRichard Henderson }
1753951c6300SRichard Henderson }
1754951c6300SRichard Henderson
tcg_gen_subi_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1755951c6300SRichard Henderson void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1756951c6300SRichard Henderson {
17571551004eSRichard Henderson tcg_gen_addi_i64(ret, arg1, -arg2);
1758951c6300SRichard Henderson }
1759951c6300SRichard Henderson
tcg_gen_neg_i64(TCGv_i64 ret,TCGv_i64 arg)1760e0de2f55SRichard Henderson void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg)
1761e0de2f55SRichard Henderson {
1762b701f195SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
1763e0de2f55SRichard Henderson tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg);
1764e0de2f55SRichard Henderson } else {
1765b701f195SRichard Henderson TCGv_i32 zero = tcg_constant_i32(0);
1766b701f195SRichard Henderson tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
1767b701f195SRichard Henderson zero, zero, TCGV_LOW(arg), TCGV_HIGH(arg));
1768e0de2f55SRichard Henderson }
1769e0de2f55SRichard Henderson }
1770e0de2f55SRichard Henderson
tcg_gen_andi_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1771474b2e8fSRichard Henderson void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1772951c6300SRichard Henderson {
17733a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
1774951c6300SRichard Henderson tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1775951c6300SRichard Henderson tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
17763a13c3f3SRichard Henderson return;
17773a13c3f3SRichard Henderson }
17783a13c3f3SRichard Henderson
1779951c6300SRichard Henderson /* Some cases can be optimized here. */
1780951c6300SRichard Henderson switch (arg2) {
1781951c6300SRichard Henderson case 0:
1782951c6300SRichard Henderson tcg_gen_movi_i64(ret, 0);
1783951c6300SRichard Henderson return;
1784474b2e8fSRichard Henderson case -1:
1785951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1);
1786951c6300SRichard Henderson return;
1787474b2e8fSRichard Henderson case 0xff:
1788951c6300SRichard Henderson /* Don't recurse with tcg_gen_ext8u_i64. */
1789951c6300SRichard Henderson if (TCG_TARGET_HAS_ext8u_i64) {
1790951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
1791951c6300SRichard Henderson return;
1792951c6300SRichard Henderson }
1793951c6300SRichard Henderson break;
1794474b2e8fSRichard Henderson case 0xffff:
1795951c6300SRichard Henderson if (TCG_TARGET_HAS_ext16u_i64) {
1796951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
1797951c6300SRichard Henderson return;
1798951c6300SRichard Henderson }
1799951c6300SRichard Henderson break;
1800474b2e8fSRichard Henderson case 0xffffffffu:
1801951c6300SRichard Henderson if (TCG_TARGET_HAS_ext32u_i64) {
1802951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
1803951c6300SRichard Henderson return;
1804951c6300SRichard Henderson }
1805951c6300SRichard Henderson break;
1806951c6300SRichard Henderson }
180711d11d61SRichard Henderson
180811d11d61SRichard Henderson tcg_gen_and_i64(ret, arg1, tcg_constant_i64(arg2));
1809951c6300SRichard Henderson }
1810951c6300SRichard Henderson
tcg_gen_ori_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1811951c6300SRichard Henderson void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1812951c6300SRichard Henderson {
18133a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
1814951c6300SRichard Henderson tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1815951c6300SRichard Henderson tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
18163a13c3f3SRichard Henderson return;
18173a13c3f3SRichard Henderson }
1818951c6300SRichard Henderson /* Some cases can be optimized here. */
1819951c6300SRichard Henderson if (arg2 == -1) {
1820951c6300SRichard Henderson tcg_gen_movi_i64(ret, -1);
1821951c6300SRichard Henderson } else if (arg2 == 0) {
1822951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1);
1823951c6300SRichard Henderson } else {
182411d11d61SRichard Henderson tcg_gen_or_i64(ret, arg1, tcg_constant_i64(arg2));
1825951c6300SRichard Henderson }
1826951c6300SRichard Henderson }
1827951c6300SRichard Henderson
tcg_gen_xori_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1828951c6300SRichard Henderson void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1829951c6300SRichard Henderson {
18303a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
1831951c6300SRichard Henderson tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1832951c6300SRichard Henderson tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
18333a13c3f3SRichard Henderson return;
18343a13c3f3SRichard Henderson }
1835951c6300SRichard Henderson /* Some cases can be optimized here. */
1836951c6300SRichard Henderson if (arg2 == 0) {
1837951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1);
1838951c6300SRichard Henderson } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) {
1839951c6300SRichard Henderson /* Don't recurse with tcg_gen_not_i64. */
1840951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1);
1841951c6300SRichard Henderson } else {
184211d11d61SRichard Henderson tcg_gen_xor_i64(ret, arg1, tcg_constant_i64(arg2));
1843951c6300SRichard Henderson }
1844951c6300SRichard Henderson }
1845951c6300SRichard Henderson
tcg_gen_shifti_i64(TCGv_i64 ret,TCGv_i64 arg1,unsigned c,bool right,bool arith)1846951c6300SRichard Henderson static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
1847951c6300SRichard Henderson unsigned c, bool right, bool arith)
1848951c6300SRichard Henderson {
1849951c6300SRichard Henderson tcg_debug_assert(c < 64);
1850951c6300SRichard Henderson if (c == 0) {
1851951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1852951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1853951c6300SRichard Henderson } else if (c >= 32) {
1854951c6300SRichard Henderson c -= 32;
1855951c6300SRichard Henderson if (right) {
1856951c6300SRichard Henderson if (arith) {
1857951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1858951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
1859951c6300SRichard Henderson } else {
1860951c6300SRichard Henderson tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1861951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1862951c6300SRichard Henderson }
1863951c6300SRichard Henderson } else {
1864951c6300SRichard Henderson tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
1865951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_LOW(ret), 0);
1866951c6300SRichard Henderson }
186702616badSRichard Henderson } else if (right) {
186802616badSRichard Henderson if (TCG_TARGET_HAS_extract2_i32) {
186902616badSRichard Henderson tcg_gen_extract2_i32(TCGV_LOW(ret),
187002616badSRichard Henderson TCGV_LOW(arg1), TCGV_HIGH(arg1), c);
1871951c6300SRichard Henderson } else {
1872951c6300SRichard Henderson tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
187302616badSRichard Henderson tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(ret),
187402616badSRichard Henderson TCGV_HIGH(arg1), 32 - c, c);
1875951c6300SRichard Henderson }
187602616badSRichard Henderson if (arith) {
187702616badSRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
187802616badSRichard Henderson } else {
187902616badSRichard Henderson tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
188002616badSRichard Henderson }
188102616badSRichard Henderson } else {
188202616badSRichard Henderson if (TCG_TARGET_HAS_extract2_i32) {
188302616badSRichard Henderson tcg_gen_extract2_i32(TCGV_HIGH(ret),
188402616badSRichard Henderson TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
188502616badSRichard Henderson } else {
18865dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
188702616badSRichard Henderson tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
188802616badSRichard Henderson tcg_gen_deposit_i32(TCGV_HIGH(ret), t0,
188902616badSRichard Henderson TCGV_HIGH(arg1), c, 32 - c);
1890951c6300SRichard Henderson tcg_temp_free_i32(t0);
189102616badSRichard Henderson }
189202616badSRichard Henderson tcg_gen_shli_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
1893951c6300SRichard Henderson }
1894951c6300SRichard Henderson }
1895951c6300SRichard Henderson
tcg_gen_shli_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1896474b2e8fSRichard Henderson void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1897951c6300SRichard Henderson {
1898474b2e8fSRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 64);
18993a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
19003a13c3f3SRichard Henderson tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
19013a13c3f3SRichard Henderson } else if (arg2 == 0) {
1902951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1);
1903951c6300SRichard Henderson } else {
190411d11d61SRichard Henderson tcg_gen_shl_i64(ret, arg1, tcg_constant_i64(arg2));
1905951c6300SRichard Henderson }
1906951c6300SRichard Henderson }
1907951c6300SRichard Henderson
tcg_gen_shri_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1908474b2e8fSRichard Henderson void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1909951c6300SRichard Henderson {
1910474b2e8fSRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 64);
19113a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
19123a13c3f3SRichard Henderson tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
19133a13c3f3SRichard Henderson } else if (arg2 == 0) {
1914951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1);
1915951c6300SRichard Henderson } else {
191611d11d61SRichard Henderson tcg_gen_shr_i64(ret, arg1, tcg_constant_i64(arg2));
1917951c6300SRichard Henderson }
1918951c6300SRichard Henderson }
1919951c6300SRichard Henderson
tcg_gen_sari_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1920474b2e8fSRichard Henderson void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1921951c6300SRichard Henderson {
1922474b2e8fSRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 64);
19233a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
19243a13c3f3SRichard Henderson tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
19253a13c3f3SRichard Henderson } else if (arg2 == 0) {
1926951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1);
1927951c6300SRichard Henderson } else {
192811d11d61SRichard Henderson tcg_gen_sar_i64(ret, arg1, tcg_constant_i64(arg2));
1929951c6300SRichard Henderson }
1930951c6300SRichard Henderson }
1931951c6300SRichard Henderson
tcg_gen_brcond_i64(TCGCond cond,TCGv_i64 arg1,TCGv_i64 arg2,TCGLabel * l)193242a268c2SRichard Henderson void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l)
1933951c6300SRichard Henderson {
1934951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) {
193542a268c2SRichard Henderson tcg_gen_br(l);
1936951c6300SRichard Henderson } else if (cond != TCG_COND_NEVER) {
1937*83ac625cSRichard Henderson TCGOp *op;
19383a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
1939*83ac625cSRichard Henderson op = tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),
1940951c6300SRichard Henderson TCGV_HIGH(arg1), TCGV_LOW(arg2),
194142a268c2SRichard Henderson TCGV_HIGH(arg2), cond, label_arg(l));
19423a13c3f3SRichard Henderson } else {
1943*83ac625cSRichard Henderson op = tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond,
194442a268c2SRichard Henderson label_arg(l));
19453a13c3f3SRichard Henderson }
1946*83ac625cSRichard Henderson add_as_label_use(l, op);
1947951c6300SRichard Henderson }
1948951c6300SRichard Henderson }
1949951c6300SRichard Henderson
tcg_gen_brcondi_i64(TCGCond cond,TCGv_i64 arg1,int64_t arg2,TCGLabel * l)195042a268c2SRichard Henderson void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l)
1951951c6300SRichard Henderson {
195211d11d61SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
195311d11d61SRichard Henderson tcg_gen_brcond_i64(cond, arg1, tcg_constant_i64(arg2), l);
195411d11d61SRichard Henderson } else if (cond == TCG_COND_ALWAYS) {
195542a268c2SRichard Henderson tcg_gen_br(l);
1956951c6300SRichard Henderson } else if (cond != TCG_COND_NEVER) {
1957*83ac625cSRichard Henderson TCGOp *op = tcg_gen_op6ii_i32(INDEX_op_brcond2_i32,
195811d11d61SRichard Henderson TCGV_LOW(arg1), TCGV_HIGH(arg1),
195911d11d61SRichard Henderson tcg_constant_i32(arg2),
196011d11d61SRichard Henderson tcg_constant_i32(arg2 >> 32),
196111d11d61SRichard Henderson cond, label_arg(l));
1962*83ac625cSRichard Henderson add_as_label_use(l, op);
1963951c6300SRichard Henderson }
1964951c6300SRichard Henderson }
1965951c6300SRichard Henderson
tcg_gen_setcond_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1966951c6300SRichard Henderson void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
1967951c6300SRichard Henderson TCGv_i64 arg1, TCGv_i64 arg2)
1968951c6300SRichard Henderson {
1969951c6300SRichard Henderson if (cond == TCG_COND_ALWAYS) {
1970951c6300SRichard Henderson tcg_gen_movi_i64(ret, 1);
1971951c6300SRichard Henderson } else if (cond == TCG_COND_NEVER) {
1972951c6300SRichard Henderson tcg_gen_movi_i64(ret, 0);
1973951c6300SRichard Henderson } else {
19743a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
1975951c6300SRichard Henderson tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
1976951c6300SRichard Henderson TCGV_LOW(arg1), TCGV_HIGH(arg1),
1977951c6300SRichard Henderson TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
1978951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
19793a13c3f3SRichard Henderson } else {
1980951c6300SRichard Henderson tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
19813a13c3f3SRichard Henderson }
1982951c6300SRichard Henderson }
1983951c6300SRichard Henderson }
1984951c6300SRichard Henderson
tcg_gen_setcondi_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1985951c6300SRichard Henderson void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
1986951c6300SRichard Henderson TCGv_i64 arg1, int64_t arg2)
1987951c6300SRichard Henderson {
198811d11d61SRichard Henderson if (TCG_TARGET_REG_BITS == 64) {
198911d11d61SRichard Henderson tcg_gen_setcond_i64(cond, ret, arg1, tcg_constant_i64(arg2));
199011d11d61SRichard Henderson } else if (cond == TCG_COND_ALWAYS) {
199111d11d61SRichard Henderson tcg_gen_movi_i64(ret, 1);
199211d11d61SRichard Henderson } else if (cond == TCG_COND_NEVER) {
199311d11d61SRichard Henderson tcg_gen_movi_i64(ret, 0);
199411d11d61SRichard Henderson } else {
199511d11d61SRichard Henderson tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
199611d11d61SRichard Henderson TCGV_LOW(arg1), TCGV_HIGH(arg1),
199711d11d61SRichard Henderson tcg_constant_i32(arg2),
199811d11d61SRichard Henderson tcg_constant_i32(arg2 >> 32), cond);
199911d11d61SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
200011d11d61SRichard Henderson }
2001951c6300SRichard Henderson }
2002951c6300SRichard Henderson
tcg_gen_negsetcondi_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)200393c86ecdSPaolo Bonzini void tcg_gen_negsetcondi_i64(TCGCond cond, TCGv_i64 ret,
200493c86ecdSPaolo Bonzini TCGv_i64 arg1, int64_t arg2)
200593c86ecdSPaolo Bonzini {
200693c86ecdSPaolo Bonzini tcg_gen_negsetcond_i64(cond, ret, arg1, tcg_constant_i64(arg2));
200793c86ecdSPaolo Bonzini }
200893c86ecdSPaolo Bonzini
tcg_gen_negsetcond_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)20093635502dSRichard Henderson void tcg_gen_negsetcond_i64(TCGCond cond, TCGv_i64 ret,
20103635502dSRichard Henderson TCGv_i64 arg1, TCGv_i64 arg2)
20113635502dSRichard Henderson {
20123635502dSRichard Henderson if (cond == TCG_COND_ALWAYS) {
20133635502dSRichard Henderson tcg_gen_movi_i64(ret, -1);
20143635502dSRichard Henderson } else if (cond == TCG_COND_NEVER) {
20153635502dSRichard Henderson tcg_gen_movi_i64(ret, 0);
20163635502dSRichard Henderson } else if (TCG_TARGET_HAS_negsetcond_i64) {
20173635502dSRichard Henderson tcg_gen_op4i_i64(INDEX_op_negsetcond_i64, ret, arg1, arg2, cond);
20183635502dSRichard Henderson } else if (TCG_TARGET_REG_BITS == 32) {
20193635502dSRichard Henderson tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
20203635502dSRichard Henderson TCGV_LOW(arg1), TCGV_HIGH(arg1),
20213635502dSRichard Henderson TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
20223635502dSRichard Henderson tcg_gen_neg_i32(TCGV_LOW(ret), TCGV_LOW(ret));
20233635502dSRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_LOW(ret));
20243635502dSRichard Henderson } else {
20253635502dSRichard Henderson tcg_gen_setcond_i64(cond, ret, arg1, arg2);
20263635502dSRichard Henderson tcg_gen_neg_i64(ret, ret);
20273635502dSRichard Henderson }
20283635502dSRichard Henderson }
20293635502dSRichard Henderson
tcg_gen_muli_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)2030951c6300SRichard Henderson void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2031951c6300SRichard Henderson {
2032b2e3ae94SRichard Henderson if (arg2 == 0) {
2033b2e3ae94SRichard Henderson tcg_gen_movi_i64(ret, 0);
2034b2e3ae94SRichard Henderson } else if (is_power_of_2(arg2)) {
2035b2e3ae94SRichard Henderson tcg_gen_shli_i64(ret, arg1, ctz64(arg2));
2036b2e3ae94SRichard Henderson } else {
2037f04de891SRichard Henderson tcg_gen_mul_i64(ret, arg1, tcg_constant_i64(arg2));
2038951c6300SRichard Henderson }
2039b2e3ae94SRichard Henderson }
2040951c6300SRichard Henderson
tcg_gen_div_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2041951c6300SRichard Henderson void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2042951c6300SRichard Henderson {
2043951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i64) {
2044951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
2045951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) {
20465dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2047951c6300SRichard Henderson tcg_gen_sari_i64(t0, arg1, 63);
2048951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
2049951c6300SRichard Henderson tcg_temp_free_i64(t0);
2050951c6300SRichard Henderson } else {
2051951c6300SRichard Henderson gen_helper_div_i64(ret, arg1, arg2);
2052951c6300SRichard Henderson }
2053951c6300SRichard Henderson }
2054951c6300SRichard Henderson
tcg_gen_rem_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2055951c6300SRichard Henderson void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2056951c6300SRichard Henderson {
2057951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i64) {
2058951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
2059951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i64) {
20605dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2061951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
2062951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, arg2);
2063951c6300SRichard Henderson tcg_gen_sub_i64(ret, arg1, t0);
2064951c6300SRichard Henderson tcg_temp_free_i64(t0);
2065951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) {
20665dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2067951c6300SRichard Henderson tcg_gen_sari_i64(t0, arg1, 63);
2068951c6300SRichard Henderson tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
2069951c6300SRichard Henderson tcg_temp_free_i64(t0);
2070951c6300SRichard Henderson } else {
2071951c6300SRichard Henderson gen_helper_rem_i64(ret, arg1, arg2);
2072951c6300SRichard Henderson }
2073951c6300SRichard Henderson }
2074951c6300SRichard Henderson
tcg_gen_divu_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2075951c6300SRichard Henderson void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2076951c6300SRichard Henderson {
2077951c6300SRichard Henderson if (TCG_TARGET_HAS_div_i64) {
2078951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
2079951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) {
20805dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2081bfefdbeaSRichard Henderson TCGv_i64 zero = tcg_constant_i64(0);
2082bfefdbeaSRichard Henderson tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, zero, arg2);
2083951c6300SRichard Henderson tcg_temp_free_i64(t0);
2084951c6300SRichard Henderson } else {
2085951c6300SRichard Henderson gen_helper_divu_i64(ret, arg1, arg2);
2086951c6300SRichard Henderson }
2087951c6300SRichard Henderson }
2088951c6300SRichard Henderson
tcg_gen_remu_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2089951c6300SRichard Henderson void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2090951c6300SRichard Henderson {
2091951c6300SRichard Henderson if (TCG_TARGET_HAS_rem_i64) {
2092951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
2093951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div_i64) {
20945dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2095951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
2096951c6300SRichard Henderson tcg_gen_mul_i64(t0, t0, arg2);
2097951c6300SRichard Henderson tcg_gen_sub_i64(ret, arg1, t0);
2098951c6300SRichard Henderson tcg_temp_free_i64(t0);
2099951c6300SRichard Henderson } else if (TCG_TARGET_HAS_div2_i64) {
21005dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2101bfefdbeaSRichard Henderson TCGv_i64 zero = tcg_constant_i64(0);
2102bfefdbeaSRichard Henderson tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, zero, arg2);
2103951c6300SRichard Henderson tcg_temp_free_i64(t0);
2104951c6300SRichard Henderson } else {
2105951c6300SRichard Henderson gen_helper_remu_i64(ret, arg1, arg2);
2106951c6300SRichard Henderson }
2107951c6300SRichard Henderson }
2108951c6300SRichard Henderson
tcg_gen_ext8s_i64(TCGv_i64 ret,TCGv_i64 arg)2109951c6300SRichard Henderson void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
2110951c6300SRichard Henderson {
21113a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
2112951c6300SRichard Henderson tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2113951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
21143a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext8s_i64) {
2115951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
2116951c6300SRichard Henderson } else {
2117951c6300SRichard Henderson tcg_gen_shli_i64(ret, arg, 56);
2118951c6300SRichard Henderson tcg_gen_sari_i64(ret, ret, 56);
2119951c6300SRichard Henderson }
2120951c6300SRichard Henderson }
2121951c6300SRichard Henderson
tcg_gen_ext16s_i64(TCGv_i64 ret,TCGv_i64 arg)2122951c6300SRichard Henderson void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
2123951c6300SRichard Henderson {
21243a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
2125951c6300SRichard Henderson tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2126951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
21273a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext16s_i64) {
2128951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
2129951c6300SRichard Henderson } else {
2130951c6300SRichard Henderson tcg_gen_shli_i64(ret, arg, 48);
2131951c6300SRichard Henderson tcg_gen_sari_i64(ret, ret, 48);
2132951c6300SRichard Henderson }
2133951c6300SRichard Henderson }
2134951c6300SRichard Henderson
tcg_gen_ext32s_i64(TCGv_i64 ret,TCGv_i64 arg)2135951c6300SRichard Henderson void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
2136951c6300SRichard Henderson {
21373a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
2138951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2139951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
21403a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext32s_i64) {
2141951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
2142951c6300SRichard Henderson } else {
2143951c6300SRichard Henderson tcg_gen_shli_i64(ret, arg, 32);
2144951c6300SRichard Henderson tcg_gen_sari_i64(ret, ret, 32);
2145951c6300SRichard Henderson }
2146951c6300SRichard Henderson }
2147951c6300SRichard Henderson
tcg_gen_ext8u_i64(TCGv_i64 ret,TCGv_i64 arg)2148951c6300SRichard Henderson void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
2149951c6300SRichard Henderson {
21503a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
2151951c6300SRichard Henderson tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2152951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
21533a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext8u_i64) {
2154951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
2155951c6300SRichard Henderson } else {
2156951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg, 0xffu);
2157951c6300SRichard Henderson }
2158951c6300SRichard Henderson }
2159951c6300SRichard Henderson
tcg_gen_ext16u_i64(TCGv_i64 ret,TCGv_i64 arg)2160951c6300SRichard Henderson void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
2161951c6300SRichard Henderson {
21623a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
2163951c6300SRichard Henderson tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2164951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
21653a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext16u_i64) {
2166951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
2167951c6300SRichard Henderson } else {
2168951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg, 0xffffu);
2169951c6300SRichard Henderson }
2170951c6300SRichard Henderson }
2171951c6300SRichard Henderson
tcg_gen_ext32u_i64(TCGv_i64 ret,TCGv_i64 arg)2172951c6300SRichard Henderson void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
2173951c6300SRichard Henderson {
21743a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
2175951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2176951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
21773a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_ext32u_i64) {
2178951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
2179951c6300SRichard Henderson } else {
2180951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg, 0xffffffffu);
2181951c6300SRichard Henderson }
2182951c6300SRichard Henderson }
2183951c6300SRichard Henderson
21848b078800SPhilippe Mathieu-Daudé /*
21858b078800SPhilippe Mathieu-Daudé * bswap16_i64: 16-bit byte swap on the low bits of a 64-bit value.
21868b078800SPhilippe Mathieu-Daudé *
21878b078800SPhilippe Mathieu-Daudé * Byte pattern: xxxxxxxxab -> yyyyyyyyba
21888b078800SPhilippe Mathieu-Daudé *
21898b078800SPhilippe Mathieu-Daudé * With TCG_BSWAP_IZ, x == zero, else undefined.
21908b078800SPhilippe Mathieu-Daudé * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
21918b078800SPhilippe Mathieu-Daudé */
tcg_gen_bswap16_i64(TCGv_i64 ret,TCGv_i64 arg,int flags)21922b836c2aSRichard Henderson void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
2193951c6300SRichard Henderson {
21942b836c2aSRichard Henderson /* Only one extension flag may be present. */
21952b836c2aSRichard Henderson tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
21962b836c2aSRichard Henderson
21973a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
21982b836c2aSRichard Henderson tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg), flags);
21992b836c2aSRichard Henderson if (flags & TCG_BSWAP_OS) {
22002b836c2aSRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
22012b836c2aSRichard Henderson } else {
2202951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
22032b836c2aSRichard Henderson }
22043a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_bswap16_i64) {
22052b836c2aSRichard Henderson tcg_gen_op3i_i64(INDEX_op_bswap16_i64, ret, arg, flags);
2206951c6300SRichard Henderson } else {
22075dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
22085dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
2209951c6300SRichard Henderson
22108b078800SPhilippe Mathieu-Daudé /* arg = ......ab or xxxxxxab */
22118b078800SPhilippe Mathieu-Daudé tcg_gen_shri_i64(t0, arg, 8); /* t0 = .......a or .xxxxxxa */
22122b836c2aSRichard Henderson if (!(flags & TCG_BSWAP_IZ)) {
22138b078800SPhilippe Mathieu-Daudé tcg_gen_ext8u_i64(t0, t0); /* t0 = .......a */
22142b836c2aSRichard Henderson }
22152b836c2aSRichard Henderson
22162b836c2aSRichard Henderson if (flags & TCG_BSWAP_OS) {
22178b078800SPhilippe Mathieu-Daudé tcg_gen_shli_i64(t1, arg, 56); /* t1 = b....... */
22188b078800SPhilippe Mathieu-Daudé tcg_gen_sari_i64(t1, t1, 48); /* t1 = ssssssb. */
22192b836c2aSRichard Henderson } else if (flags & TCG_BSWAP_OZ) {
22208b078800SPhilippe Mathieu-Daudé tcg_gen_ext8u_i64(t1, arg); /* t1 = .......b */
22218b078800SPhilippe Mathieu-Daudé tcg_gen_shli_i64(t1, t1, 8); /* t1 = ......b. */
22222b836c2aSRichard Henderson } else {
22238b078800SPhilippe Mathieu-Daudé tcg_gen_shli_i64(t1, arg, 8); /* t1 = xxxxxab. */
22242b836c2aSRichard Henderson }
22252b836c2aSRichard Henderson
22268b078800SPhilippe Mathieu-Daudé tcg_gen_or_i64(ret, t0, t1); /* ret = ......ba (OZ) */
22278b078800SPhilippe Mathieu-Daudé /* ssssssba (OS) */
22288b078800SPhilippe Mathieu-Daudé /* xxxxxaba (no flag) */
2229951c6300SRichard Henderson tcg_temp_free_i64(t0);
22302b836c2aSRichard Henderson tcg_temp_free_i64(t1);
2231951c6300SRichard Henderson }
2232951c6300SRichard Henderson }
2233951c6300SRichard Henderson
22349c406215SPhilippe Mathieu-Daudé /*
22359c406215SPhilippe Mathieu-Daudé * bswap32_i64: 32-bit byte swap on the low bits of a 64-bit value.
22369c406215SPhilippe Mathieu-Daudé *
22379c406215SPhilippe Mathieu-Daudé * Byte pattern: xxxxabcd -> yyyydcba
22389c406215SPhilippe Mathieu-Daudé *
22399c406215SPhilippe Mathieu-Daudé * With TCG_BSWAP_IZ, x == zero, else undefined.
22409c406215SPhilippe Mathieu-Daudé * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
22419c406215SPhilippe Mathieu-Daudé */
tcg_gen_bswap32_i64(TCGv_i64 ret,TCGv_i64 arg,int flags)22422b836c2aSRichard Henderson void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
2243951c6300SRichard Henderson {
22442b836c2aSRichard Henderson /* Only one extension flag may be present. */
22452b836c2aSRichard Henderson tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
22462b836c2aSRichard Henderson
22473a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
2248951c6300SRichard Henderson tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg));
22492b836c2aSRichard Henderson if (flags & TCG_BSWAP_OS) {
22502b836c2aSRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
22512b836c2aSRichard Henderson } else {
2252951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
22532b836c2aSRichard Henderson }
22543a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_bswap32_i64) {
22552b836c2aSRichard Henderson tcg_gen_op3i_i64(INDEX_op_bswap32_i64, ret, arg, flags);
2256951c6300SRichard Henderson } else {
22575dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
22585dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
225911d11d61SRichard Henderson TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff);
2260951c6300SRichard Henderson
22612b836c2aSRichard Henderson /* arg = xxxxabcd */
22622b836c2aSRichard Henderson tcg_gen_shri_i64(t0, arg, 8); /* t0 = .xxxxabc */
2263a686dc71SRichard Henderson tcg_gen_and_i64(t1, arg, t2); /* t1 = .....b.d */
2264a686dc71SRichard Henderson tcg_gen_and_i64(t0, t0, t2); /* t0 = .....a.c */
2265a686dc71SRichard Henderson tcg_gen_shli_i64(t1, t1, 8); /* t1 = ....b.d. */
2266a686dc71SRichard Henderson tcg_gen_or_i64(ret, t0, t1); /* ret = ....badc */
2267951c6300SRichard Henderson
2268a686dc71SRichard Henderson tcg_gen_shli_i64(t1, ret, 48); /* t1 = dc...... */
2269a686dc71SRichard Henderson tcg_gen_shri_i64(t0, ret, 16); /* t0 = ......ba */
22702b836c2aSRichard Henderson if (flags & TCG_BSWAP_OS) {
22712b836c2aSRichard Henderson tcg_gen_sari_i64(t1, t1, 32); /* t1 = ssssdc.. */
22722b836c2aSRichard Henderson } else {
2273a686dc71SRichard Henderson tcg_gen_shri_i64(t1, t1, 32); /* t1 = ....dc.. */
22742b836c2aSRichard Henderson }
22759c406215SPhilippe Mathieu-Daudé tcg_gen_or_i64(ret, t0, t1); /* ret = ssssdcba (OS) */
22769c406215SPhilippe Mathieu-Daudé /* ....dcba (else) */
2277951c6300SRichard Henderson
2278951c6300SRichard Henderson tcg_temp_free_i64(t0);
2279951c6300SRichard Henderson tcg_temp_free_i64(t1);
2280951c6300SRichard Henderson }
2281951c6300SRichard Henderson }
2282951c6300SRichard Henderson
228395180e75SPhilippe Mathieu-Daudé /*
228495180e75SPhilippe Mathieu-Daudé * bswap64_i64: 64-bit byte swap on a 64-bit value.
228595180e75SPhilippe Mathieu-Daudé *
228695180e75SPhilippe Mathieu-Daudé * Byte pattern: abcdefgh -> hgfedcba
228795180e75SPhilippe Mathieu-Daudé */
tcg_gen_bswap64_i64(TCGv_i64 ret,TCGv_i64 arg)2288951c6300SRichard Henderson void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
2289951c6300SRichard Henderson {
22903a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
2291951c6300SRichard Henderson TCGv_i32 t0, t1;
22925dd48602SRichard Henderson t0 = tcg_temp_ebb_new_i32();
22935dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i32();
2294951c6300SRichard Henderson
2295951c6300SRichard Henderson tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
2296951c6300SRichard Henderson tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
2297951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), t1);
2298951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
2299951c6300SRichard Henderson tcg_temp_free_i32(t0);
2300951c6300SRichard Henderson tcg_temp_free_i32(t1);
23013a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_bswap64_i64) {
2302587195bdSRichard Henderson tcg_gen_op3i_i64(INDEX_op_bswap64_i64, ret, arg, 0);
2303951c6300SRichard Henderson } else {
23045dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
23055dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
23065dd48602SRichard Henderson TCGv_i64 t2 = tcg_temp_ebb_new_i64();
2307951c6300SRichard Henderson
23089e821eabSRichard Henderson /* arg = abcdefgh */
23099e821eabSRichard Henderson tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull);
23109e821eabSRichard Henderson tcg_gen_shri_i64(t0, arg, 8); /* t0 = .abcdefg */
23119e821eabSRichard Henderson tcg_gen_and_i64(t1, arg, t2); /* t1 = .b.d.f.h */
23129e821eabSRichard Henderson tcg_gen_and_i64(t0, t0, t2); /* t0 = .a.c.e.g */
23139e821eabSRichard Henderson tcg_gen_shli_i64(t1, t1, 8); /* t1 = b.d.f.h. */
23149e821eabSRichard Henderson tcg_gen_or_i64(ret, t0, t1); /* ret = badcfehg */
2315951c6300SRichard Henderson
23169e821eabSRichard Henderson tcg_gen_movi_i64(t2, 0x0000ffff0000ffffull);
23179e821eabSRichard Henderson tcg_gen_shri_i64(t0, ret, 16); /* t0 = ..badcfe */
23189e821eabSRichard Henderson tcg_gen_and_i64(t1, ret, t2); /* t1 = ..dc..hg */
23199e821eabSRichard Henderson tcg_gen_and_i64(t0, t0, t2); /* t0 = ..ba..fe */
23209e821eabSRichard Henderson tcg_gen_shli_i64(t1, t1, 16); /* t1 = dc..hg.. */
23219e821eabSRichard Henderson tcg_gen_or_i64(ret, t0, t1); /* ret = dcbahgfe */
2322951c6300SRichard Henderson
23239e821eabSRichard Henderson tcg_gen_shri_i64(t0, ret, 32); /* t0 = ....dcba */
23249e821eabSRichard Henderson tcg_gen_shli_i64(t1, ret, 32); /* t1 = hgfe.... */
23259e821eabSRichard Henderson tcg_gen_or_i64(ret, t0, t1); /* ret = hgfedcba */
2326951c6300SRichard Henderson
2327951c6300SRichard Henderson tcg_temp_free_i64(t0);
2328951c6300SRichard Henderson tcg_temp_free_i64(t1);
23299e821eabSRichard Henderson tcg_temp_free_i64(t2);
2330951c6300SRichard Henderson }
2331951c6300SRichard Henderson }
2332951c6300SRichard Henderson
2333b8976aa5SPhilippe Mathieu-Daudé /*
2334b8976aa5SPhilippe Mathieu-Daudé * hswap_i64: Swap 16-bit halfwords within a 64-bit value.
2335b8976aa5SPhilippe Mathieu-Daudé * See also include/qemu/bitops.h, hswap64.
2336b8976aa5SPhilippe Mathieu-Daudé *
2337b8976aa5SPhilippe Mathieu-Daudé * Byte pattern: abcdefgh -> ghefcdab
2338b8976aa5SPhilippe Mathieu-Daudé */
tcg_gen_hswap_i64(TCGv_i64 ret,TCGv_i64 arg)233946be8425SRichard Henderson void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg)
234046be8425SRichard Henderson {
234146be8425SRichard Henderson uint64_t m = 0x0000ffff0000ffffull;
23425dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
23435dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
234446be8425SRichard Henderson
2345b8976aa5SPhilippe Mathieu-Daudé /* arg = abcdefgh */
2346b8976aa5SPhilippe Mathieu-Daudé tcg_gen_rotli_i64(t1, arg, 32); /* t1 = efghabcd */
2347b8976aa5SPhilippe Mathieu-Daudé tcg_gen_andi_i64(t0, t1, m); /* t0 = ..gh..cd */
2348b8976aa5SPhilippe Mathieu-Daudé tcg_gen_shli_i64(t0, t0, 16); /* t0 = gh..cd.. */
2349b8976aa5SPhilippe Mathieu-Daudé tcg_gen_shri_i64(t1, t1, 16); /* t1 = ..efghab */
2350b8976aa5SPhilippe Mathieu-Daudé tcg_gen_andi_i64(t1, t1, m); /* t1 = ..ef..ab */
2351b8976aa5SPhilippe Mathieu-Daudé tcg_gen_or_i64(ret, t0, t1); /* ret = ghefcdab */
235246be8425SRichard Henderson
235346be8425SRichard Henderson tcg_temp_free_i64(t0);
235446be8425SRichard Henderson tcg_temp_free_i64(t1);
235546be8425SRichard Henderson }
235646be8425SRichard Henderson
2357ad262fb5SPhilippe Mathieu-Daudé /*
2358ad262fb5SPhilippe Mathieu-Daudé * wswap_i64: Swap 32-bit words within a 64-bit value.
2359ad262fb5SPhilippe Mathieu-Daudé *
2360ad262fb5SPhilippe Mathieu-Daudé * Byte pattern: abcdefgh -> efghabcd
2361ad262fb5SPhilippe Mathieu-Daudé */
tcg_gen_wswap_i64(TCGv_i64 ret,TCGv_i64 arg)236246be8425SRichard Henderson void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg)
236346be8425SRichard Henderson {
236446be8425SRichard Henderson /* Swapping 2 32-bit elements is a rotate. */
236546be8425SRichard Henderson tcg_gen_rotli_i64(ret, arg, 32);
236646be8425SRichard Henderson }
236746be8425SRichard Henderson
tcg_gen_not_i64(TCGv_i64 ret,TCGv_i64 arg)2368951c6300SRichard Henderson void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
2369951c6300SRichard Henderson {
23703a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
23713a13c3f3SRichard Henderson tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
23723a13c3f3SRichard Henderson tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
23733a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_not_i64) {
2374951c6300SRichard Henderson tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
2375951c6300SRichard Henderson } else {
2376951c6300SRichard Henderson tcg_gen_xori_i64(ret, arg, -1);
2377951c6300SRichard Henderson }
2378951c6300SRichard Henderson }
2379951c6300SRichard Henderson
tcg_gen_andc_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2380951c6300SRichard Henderson void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2381951c6300SRichard Henderson {
23823a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
23833a13c3f3SRichard Henderson tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
23843a13c3f3SRichard Henderson tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
23853a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_andc_i64) {
2386951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
2387951c6300SRichard Henderson } else {
23885dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2389951c6300SRichard Henderson tcg_gen_not_i64(t0, arg2);
2390951c6300SRichard Henderson tcg_gen_and_i64(ret, arg1, t0);
2391951c6300SRichard Henderson tcg_temp_free_i64(t0);
2392951c6300SRichard Henderson }
2393951c6300SRichard Henderson }
2394951c6300SRichard Henderson
tcg_gen_eqv_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2395951c6300SRichard Henderson void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2396951c6300SRichard Henderson {
23973a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
23983a13c3f3SRichard Henderson tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
23993a13c3f3SRichard Henderson tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
24003a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_eqv_i64) {
2401951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
2402951c6300SRichard Henderson } else {
2403951c6300SRichard Henderson tcg_gen_xor_i64(ret, arg1, arg2);
2404951c6300SRichard Henderson tcg_gen_not_i64(ret, ret);
2405951c6300SRichard Henderson }
2406951c6300SRichard Henderson }
2407951c6300SRichard Henderson
tcg_gen_nand_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2408951c6300SRichard Henderson void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2409951c6300SRichard Henderson {
24103a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
24113a13c3f3SRichard Henderson tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
24123a13c3f3SRichard Henderson tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
24133a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_nand_i64) {
2414951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
2415951c6300SRichard Henderson } else {
2416951c6300SRichard Henderson tcg_gen_and_i64(ret, arg1, arg2);
2417951c6300SRichard Henderson tcg_gen_not_i64(ret, ret);
2418951c6300SRichard Henderson }
2419951c6300SRichard Henderson }
2420951c6300SRichard Henderson
tcg_gen_nor_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2421951c6300SRichard Henderson void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2422951c6300SRichard Henderson {
24233a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
24243a13c3f3SRichard Henderson tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
24253a13c3f3SRichard Henderson tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
24263a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_nor_i64) {
2427951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
2428951c6300SRichard Henderson } else {
2429951c6300SRichard Henderson tcg_gen_or_i64(ret, arg1, arg2);
2430951c6300SRichard Henderson tcg_gen_not_i64(ret, ret);
2431951c6300SRichard Henderson }
2432951c6300SRichard Henderson }
2433951c6300SRichard Henderson
tcg_gen_orc_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2434951c6300SRichard Henderson void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2435951c6300SRichard Henderson {
24363a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
24373a13c3f3SRichard Henderson tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
24383a13c3f3SRichard Henderson tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
24393a13c3f3SRichard Henderson } else if (TCG_TARGET_HAS_orc_i64) {
2440951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
2441951c6300SRichard Henderson } else {
24425dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2443951c6300SRichard Henderson tcg_gen_not_i64(t0, arg2);
2444951c6300SRichard Henderson tcg_gen_or_i64(ret, arg1, t0);
2445951c6300SRichard Henderson tcg_temp_free_i64(t0);
2446951c6300SRichard Henderson }
2447951c6300SRichard Henderson }
2448951c6300SRichard Henderson
tcg_gen_clz_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)24490e28d006SRichard Henderson void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
24500e28d006SRichard Henderson {
24510e28d006SRichard Henderson if (TCG_TARGET_HAS_clz_i64) {
24520e28d006SRichard Henderson tcg_gen_op3_i64(INDEX_op_clz_i64, ret, arg1, arg2);
24530e28d006SRichard Henderson } else {
24540e28d006SRichard Henderson gen_helper_clz_i64(ret, arg1, arg2);
24550e28d006SRichard Henderson }
24560e28d006SRichard Henderson }
24570e28d006SRichard Henderson
tcg_gen_clzi_i64(TCGv_i64 ret,TCGv_i64 arg1,uint64_t arg2)24580e28d006SRichard Henderson void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
24590e28d006SRichard Henderson {
24600e28d006SRichard Henderson if (TCG_TARGET_REG_BITS == 32
24610e28d006SRichard Henderson && TCG_TARGET_HAS_clz_i32
24620e28d006SRichard Henderson && arg2 <= 0xffffffffu) {
24635dd48602SRichard Henderson TCGv_i32 t = tcg_temp_ebb_new_i32();
246411d11d61SRichard Henderson tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32);
24650e28d006SRichard Henderson tcg_gen_addi_i32(t, t, 32);
24660e28d006SRichard Henderson tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t);
24670e28d006SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
24680e28d006SRichard Henderson tcg_temp_free_i32(t);
24690e28d006SRichard Henderson } else {
2470f04de891SRichard Henderson tcg_gen_clz_i64(ret, arg1, tcg_constant_i64(arg2));
24710e28d006SRichard Henderson }
24720e28d006SRichard Henderson }
24730e28d006SRichard Henderson
tcg_gen_ctz_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)24740e28d006SRichard Henderson void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
24750e28d006SRichard Henderson {
24760e28d006SRichard Henderson if (TCG_TARGET_HAS_ctz_i64) {
24770e28d006SRichard Henderson tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2);
247814e99210SRichard Henderson } else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) {
24795dd48602SRichard Henderson TCGv_i64 z, t = tcg_temp_ebb_new_i64();
248014e99210SRichard Henderson
248114e99210SRichard Henderson if (TCG_TARGET_HAS_ctpop_i64) {
248214e99210SRichard Henderson tcg_gen_subi_i64(t, arg1, 1);
248314e99210SRichard Henderson tcg_gen_andc_i64(t, t, arg1);
248414e99210SRichard Henderson tcg_gen_ctpop_i64(t, t);
248514e99210SRichard Henderson } else {
248614e99210SRichard Henderson /* Since all non-x86 hosts have clz(0) == 64, don't fight it. */
248714e99210SRichard Henderson tcg_gen_neg_i64(t, arg1);
248814e99210SRichard Henderson tcg_gen_and_i64(t, t, arg1);
248914e99210SRichard Henderson tcg_gen_clzi_i64(t, t, 64);
249014e99210SRichard Henderson tcg_gen_xori_i64(t, t, 63);
249114e99210SRichard Henderson }
249211d11d61SRichard Henderson z = tcg_constant_i64(0);
249314e99210SRichard Henderson tcg_gen_movcond_i64(TCG_COND_EQ, ret, arg1, z, arg2, t);
249414e99210SRichard Henderson tcg_temp_free_i64(t);
249514e99210SRichard Henderson tcg_temp_free_i64(z);
24960e28d006SRichard Henderson } else {
24970e28d006SRichard Henderson gen_helper_ctz_i64(ret, arg1, arg2);
24980e28d006SRichard Henderson }
24990e28d006SRichard Henderson }
25000e28d006SRichard Henderson
tcg_gen_ctzi_i64(TCGv_i64 ret,TCGv_i64 arg1,uint64_t arg2)25010e28d006SRichard Henderson void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
25020e28d006SRichard Henderson {
25030e28d006SRichard Henderson if (TCG_TARGET_REG_BITS == 32
25040e28d006SRichard Henderson && TCG_TARGET_HAS_ctz_i32
25050e28d006SRichard Henderson && arg2 <= 0xffffffffu) {
25065dd48602SRichard Henderson TCGv_i32 t32 = tcg_temp_ebb_new_i32();
250711d11d61SRichard Henderson tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32);
25080e28d006SRichard Henderson tcg_gen_addi_i32(t32, t32, 32);
25090e28d006SRichard Henderson tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32);
25100e28d006SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
25110e28d006SRichard Henderson tcg_temp_free_i32(t32);
251214e99210SRichard Henderson } else if (!TCG_TARGET_HAS_ctz_i64
251314e99210SRichard Henderson && TCG_TARGET_HAS_ctpop_i64
251414e99210SRichard Henderson && arg2 == 64) {
251514e99210SRichard Henderson /* This equivalence has the advantage of not requiring a fixup. */
25165dd48602SRichard Henderson TCGv_i64 t = tcg_temp_ebb_new_i64();
251714e99210SRichard Henderson tcg_gen_subi_i64(t, arg1, 1);
251814e99210SRichard Henderson tcg_gen_andc_i64(t, t, arg1);
251914e99210SRichard Henderson tcg_gen_ctpop_i64(ret, t);
252014e99210SRichard Henderson tcg_temp_free_i64(t);
25210e28d006SRichard Henderson } else {
2522f04de891SRichard Henderson tcg_gen_ctz_i64(ret, arg1, tcg_constant_i64(arg2));
25230e28d006SRichard Henderson }
25240e28d006SRichard Henderson }
25250e28d006SRichard Henderson
tcg_gen_clrsb_i64(TCGv_i64 ret,TCGv_i64 arg)2526086920c2SRichard Henderson void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg)
2527086920c2SRichard Henderson {
2528086920c2SRichard Henderson if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) {
25295dd48602SRichard Henderson TCGv_i64 t = tcg_temp_ebb_new_i64();
2530086920c2SRichard Henderson tcg_gen_sari_i64(t, arg, 63);
2531086920c2SRichard Henderson tcg_gen_xor_i64(t, t, arg);
2532086920c2SRichard Henderson tcg_gen_clzi_i64(t, t, 64);
2533086920c2SRichard Henderson tcg_gen_subi_i64(ret, t, 1);
2534086920c2SRichard Henderson tcg_temp_free_i64(t);
2535086920c2SRichard Henderson } else {
2536086920c2SRichard Henderson gen_helper_clrsb_i64(ret, arg);
2537086920c2SRichard Henderson }
2538086920c2SRichard Henderson }
2539086920c2SRichard Henderson
tcg_gen_ctpop_i64(TCGv_i64 ret,TCGv_i64 arg1)2540a768e4e9SRichard Henderson void tcg_gen_ctpop_i64(TCGv_i64 ret, TCGv_i64 arg1)
2541a768e4e9SRichard Henderson {
2542a768e4e9SRichard Henderson if (TCG_TARGET_HAS_ctpop_i64) {
2543a768e4e9SRichard Henderson tcg_gen_op2_i64(INDEX_op_ctpop_i64, ret, arg1);
2544a768e4e9SRichard Henderson } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_ctpop_i32) {
2545a768e4e9SRichard Henderson tcg_gen_ctpop_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
2546a768e4e9SRichard Henderson tcg_gen_ctpop_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
2547a768e4e9SRichard Henderson tcg_gen_add_i32(TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret));
2548a768e4e9SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2549a768e4e9SRichard Henderson } else {
2550a768e4e9SRichard Henderson gen_helper_ctpop_i64(ret, arg1);
2551a768e4e9SRichard Henderson }
2552a768e4e9SRichard Henderson }
2553a768e4e9SRichard Henderson
tcg_gen_rotl_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2554951c6300SRichard Henderson void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2555951c6300SRichard Henderson {
2556951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i64) {
2557951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
2558951c6300SRichard Henderson } else {
2559951c6300SRichard Henderson TCGv_i64 t0, t1;
25605dd48602SRichard Henderson t0 = tcg_temp_ebb_new_i64();
25615dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i64();
2562951c6300SRichard Henderson tcg_gen_shl_i64(t0, arg1, arg2);
2563951c6300SRichard Henderson tcg_gen_subfi_i64(t1, 64, arg2);
2564951c6300SRichard Henderson tcg_gen_shr_i64(t1, arg1, t1);
2565951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1);
2566951c6300SRichard Henderson tcg_temp_free_i64(t0);
2567951c6300SRichard Henderson tcg_temp_free_i64(t1);
2568951c6300SRichard Henderson }
2569951c6300SRichard Henderson }
2570951c6300SRichard Henderson
tcg_gen_rotli_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)257107dada03SRichard Henderson void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2572951c6300SRichard Henderson {
257307dada03SRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 64);
2574951c6300SRichard Henderson /* some cases can be optimized here */
2575951c6300SRichard Henderson if (arg2 == 0) {
2576951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1);
2577951c6300SRichard Henderson } else if (TCG_TARGET_HAS_rot_i64) {
257811d11d61SRichard Henderson tcg_gen_rotl_i64(ret, arg1, tcg_constant_i64(arg2));
2579951c6300SRichard Henderson } else {
2580951c6300SRichard Henderson TCGv_i64 t0, t1;
25815dd48602SRichard Henderson t0 = tcg_temp_ebb_new_i64();
25825dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i64();
2583951c6300SRichard Henderson tcg_gen_shli_i64(t0, arg1, arg2);
2584951c6300SRichard Henderson tcg_gen_shri_i64(t1, arg1, 64 - arg2);
2585951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1);
2586951c6300SRichard Henderson tcg_temp_free_i64(t0);
2587951c6300SRichard Henderson tcg_temp_free_i64(t1);
2588951c6300SRichard Henderson }
2589951c6300SRichard Henderson }
2590951c6300SRichard Henderson
tcg_gen_rotr_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2591951c6300SRichard Henderson void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2592951c6300SRichard Henderson {
2593951c6300SRichard Henderson if (TCG_TARGET_HAS_rot_i64) {
2594951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
2595951c6300SRichard Henderson } else {
2596951c6300SRichard Henderson TCGv_i64 t0, t1;
25975dd48602SRichard Henderson t0 = tcg_temp_ebb_new_i64();
25985dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i64();
2599951c6300SRichard Henderson tcg_gen_shr_i64(t0, arg1, arg2);
2600951c6300SRichard Henderson tcg_gen_subfi_i64(t1, 64, arg2);
2601951c6300SRichard Henderson tcg_gen_shl_i64(t1, arg1, t1);
2602951c6300SRichard Henderson tcg_gen_or_i64(ret, t0, t1);
2603951c6300SRichard Henderson tcg_temp_free_i64(t0);
2604951c6300SRichard Henderson tcg_temp_free_i64(t1);
2605951c6300SRichard Henderson }
2606951c6300SRichard Henderson }
2607951c6300SRichard Henderson
tcg_gen_rotri_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)260807dada03SRichard Henderson void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2609951c6300SRichard Henderson {
261007dada03SRichard Henderson tcg_debug_assert(arg2 >= 0 && arg2 < 64);
2611951c6300SRichard Henderson /* some cases can be optimized here */
2612951c6300SRichard Henderson if (arg2 == 0) {
2613951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg1);
2614951c6300SRichard Henderson } else {
2615951c6300SRichard Henderson tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
2616951c6300SRichard Henderson }
2617951c6300SRichard Henderson }
2618951c6300SRichard Henderson
tcg_gen_deposit_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2,unsigned int ofs,unsigned int len)2619951c6300SRichard Henderson void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
2620951c6300SRichard Henderson unsigned int ofs, unsigned int len)
2621951c6300SRichard Henderson {
2622951c6300SRichard Henderson uint64_t mask;
2623951c6300SRichard Henderson TCGv_i64 t1;
2624951c6300SRichard Henderson
2625951c6300SRichard Henderson tcg_debug_assert(ofs < 64);
26260d0d309dSRichard Henderson tcg_debug_assert(len > 0);
2627951c6300SRichard Henderson tcg_debug_assert(len <= 64);
2628951c6300SRichard Henderson tcg_debug_assert(ofs + len <= 64);
2629951c6300SRichard Henderson
26300d0d309dSRichard Henderson if (len == 64) {
2631951c6300SRichard Henderson tcg_gen_mov_i64(ret, arg2);
2632951c6300SRichard Henderson return;
2633951c6300SRichard Henderson }
2634951c6300SRichard Henderson if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
2635951c6300SRichard Henderson tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
2636951c6300SRichard Henderson return;
2637951c6300SRichard Henderson }
2638951c6300SRichard Henderson
26393a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
2640951c6300SRichard Henderson if (ofs >= 32) {
2641951c6300SRichard Henderson tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1),
2642951c6300SRichard Henderson TCGV_LOW(arg2), ofs - 32, len);
2643951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
2644951c6300SRichard Henderson return;
2645951c6300SRichard Henderson }
2646951c6300SRichard Henderson if (ofs + len <= 32) {
2647951c6300SRichard Henderson tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1),
2648951c6300SRichard Henderson TCGV_LOW(arg2), ofs, len);
2649951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
2650951c6300SRichard Henderson return;
2651951c6300SRichard Henderson }
26523a13c3f3SRichard Henderson }
2653951c6300SRichard Henderson
26545dd48602SRichard Henderson t1 = tcg_temp_ebb_new_i64();
2655951c6300SRichard Henderson
2656b0a60567SRichard Henderson if (TCG_TARGET_HAS_extract2_i64) {
2657b0a60567SRichard Henderson if (ofs + len == 64) {
2658b0a60567SRichard Henderson tcg_gen_shli_i64(t1, arg1, len);
2659b0a60567SRichard Henderson tcg_gen_extract2_i64(ret, t1, arg2, len);
2660b0a60567SRichard Henderson goto done;
2661b0a60567SRichard Henderson }
2662b0a60567SRichard Henderson if (ofs == 0) {
2663b0a60567SRichard Henderson tcg_gen_extract2_i64(ret, arg1, arg2, len);
2664b0a60567SRichard Henderson tcg_gen_rotli_i64(ret, ret, len);
2665b0a60567SRichard Henderson goto done;
2666b0a60567SRichard Henderson }
2667b0a60567SRichard Henderson }
2668b0a60567SRichard Henderson
2669b0a60567SRichard Henderson mask = (1ull << len) - 1;
2670951c6300SRichard Henderson if (ofs + len < 64) {
2671951c6300SRichard Henderson tcg_gen_andi_i64(t1, arg2, mask);
2672951c6300SRichard Henderson tcg_gen_shli_i64(t1, t1, ofs);
2673951c6300SRichard Henderson } else {
2674951c6300SRichard Henderson tcg_gen_shli_i64(t1, arg2, ofs);
2675951c6300SRichard Henderson }
2676951c6300SRichard Henderson tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
2677951c6300SRichard Henderson tcg_gen_or_i64(ret, ret, t1);
2678b0a60567SRichard Henderson done:
2679951c6300SRichard Henderson tcg_temp_free_i64(t1);
2680951c6300SRichard Henderson }
2681951c6300SRichard Henderson
tcg_gen_deposit_z_i64(TCGv_i64 ret,TCGv_i64 arg,unsigned int ofs,unsigned int len)268207cc68d5SRichard Henderson void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
268307cc68d5SRichard Henderson unsigned int ofs, unsigned int len)
268407cc68d5SRichard Henderson {
268507cc68d5SRichard Henderson tcg_debug_assert(ofs < 64);
268607cc68d5SRichard Henderson tcg_debug_assert(len > 0);
268707cc68d5SRichard Henderson tcg_debug_assert(len <= 64);
268807cc68d5SRichard Henderson tcg_debug_assert(ofs + len <= 64);
268907cc68d5SRichard Henderson
269007cc68d5SRichard Henderson if (ofs + len == 64) {
269107cc68d5SRichard Henderson tcg_gen_shli_i64(ret, arg, ofs);
269207cc68d5SRichard Henderson } else if (ofs == 0) {
269307cc68d5SRichard Henderson tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
269407cc68d5SRichard Henderson } else if (TCG_TARGET_HAS_deposit_i64
269507cc68d5SRichard Henderson && TCG_TARGET_deposit_i64_valid(ofs, len)) {
269611d11d61SRichard Henderson TCGv_i64 zero = tcg_constant_i64(0);
269707cc68d5SRichard Henderson tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len);
269807cc68d5SRichard Henderson } else {
269907cc68d5SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
270007cc68d5SRichard Henderson if (ofs >= 32) {
270107cc68d5SRichard Henderson tcg_gen_deposit_z_i32(TCGV_HIGH(ret), TCGV_LOW(arg),
270207cc68d5SRichard Henderson ofs - 32, len);
270307cc68d5SRichard Henderson tcg_gen_movi_i32(TCGV_LOW(ret), 0);
270407cc68d5SRichard Henderson return;
270507cc68d5SRichard Henderson }
270607cc68d5SRichard Henderson if (ofs + len <= 32) {
270707cc68d5SRichard Henderson tcg_gen_deposit_z_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
270807cc68d5SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
270907cc68d5SRichard Henderson return;
271007cc68d5SRichard Henderson }
271107cc68d5SRichard Henderson }
271207cc68d5SRichard Henderson /* To help two-operand hosts we prefer to zero-extend first,
271307cc68d5SRichard Henderson which allows ARG to stay live. */
271407cc68d5SRichard Henderson switch (len) {
271507cc68d5SRichard Henderson case 32:
271607cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext32u_i64) {
271707cc68d5SRichard Henderson tcg_gen_ext32u_i64(ret, arg);
271807cc68d5SRichard Henderson tcg_gen_shli_i64(ret, ret, ofs);
271907cc68d5SRichard Henderson return;
272007cc68d5SRichard Henderson }
272107cc68d5SRichard Henderson break;
272207cc68d5SRichard Henderson case 16:
272307cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext16u_i64) {
272407cc68d5SRichard Henderson tcg_gen_ext16u_i64(ret, arg);
272507cc68d5SRichard Henderson tcg_gen_shli_i64(ret, ret, ofs);
272607cc68d5SRichard Henderson return;
272707cc68d5SRichard Henderson }
272807cc68d5SRichard Henderson break;
272907cc68d5SRichard Henderson case 8:
273007cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext8u_i64) {
273107cc68d5SRichard Henderson tcg_gen_ext8u_i64(ret, arg);
273207cc68d5SRichard Henderson tcg_gen_shli_i64(ret, ret, ofs);
273307cc68d5SRichard Henderson return;
273407cc68d5SRichard Henderson }
273507cc68d5SRichard Henderson break;
273607cc68d5SRichard Henderson }
273707cc68d5SRichard Henderson /* Otherwise prefer zero-extension over AND for code size. */
273807cc68d5SRichard Henderson switch (ofs + len) {
273907cc68d5SRichard Henderson case 32:
274007cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext32u_i64) {
274107cc68d5SRichard Henderson tcg_gen_shli_i64(ret, arg, ofs);
274207cc68d5SRichard Henderson tcg_gen_ext32u_i64(ret, ret);
274307cc68d5SRichard Henderson return;
274407cc68d5SRichard Henderson }
274507cc68d5SRichard Henderson break;
274607cc68d5SRichard Henderson case 16:
274707cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext16u_i64) {
274807cc68d5SRichard Henderson tcg_gen_shli_i64(ret, arg, ofs);
274907cc68d5SRichard Henderson tcg_gen_ext16u_i64(ret, ret);
275007cc68d5SRichard Henderson return;
275107cc68d5SRichard Henderson }
275207cc68d5SRichard Henderson break;
275307cc68d5SRichard Henderson case 8:
275407cc68d5SRichard Henderson if (TCG_TARGET_HAS_ext8u_i64) {
275507cc68d5SRichard Henderson tcg_gen_shli_i64(ret, arg, ofs);
275607cc68d5SRichard Henderson tcg_gen_ext8u_i64(ret, ret);
275707cc68d5SRichard Henderson return;
275807cc68d5SRichard Henderson }
275907cc68d5SRichard Henderson break;
276007cc68d5SRichard Henderson }
276107cc68d5SRichard Henderson tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
276207cc68d5SRichard Henderson tcg_gen_shli_i64(ret, ret, ofs);
276307cc68d5SRichard Henderson }
276407cc68d5SRichard Henderson }
276507cc68d5SRichard Henderson
tcg_gen_extract_i64(TCGv_i64 ret,TCGv_i64 arg,unsigned int ofs,unsigned int len)27667ec8bab3SRichard Henderson void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
27677ec8bab3SRichard Henderson unsigned int ofs, unsigned int len)
27687ec8bab3SRichard Henderson {
27697ec8bab3SRichard Henderson tcg_debug_assert(ofs < 64);
27707ec8bab3SRichard Henderson tcg_debug_assert(len > 0);
27717ec8bab3SRichard Henderson tcg_debug_assert(len <= 64);
27727ec8bab3SRichard Henderson tcg_debug_assert(ofs + len <= 64);
27737ec8bab3SRichard Henderson
27747ec8bab3SRichard Henderson /* Canonicalize certain special cases, even if extract is supported. */
27757ec8bab3SRichard Henderson if (ofs + len == 64) {
27767ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, arg, 64 - len);
27777ec8bab3SRichard Henderson return;
27787ec8bab3SRichard Henderson }
27797ec8bab3SRichard Henderson if (ofs == 0) {
27807ec8bab3SRichard Henderson tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
27817ec8bab3SRichard Henderson return;
27827ec8bab3SRichard Henderson }
27837ec8bab3SRichard Henderson
27847ec8bab3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
27857ec8bab3SRichard Henderson /* Look for a 32-bit extract within one of the two words. */
27867ec8bab3SRichard Henderson if (ofs >= 32) {
27877ec8bab3SRichard Henderson tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
27887ec8bab3SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
27897ec8bab3SRichard Henderson return;
27907ec8bab3SRichard Henderson }
27917ec8bab3SRichard Henderson if (ofs + len <= 32) {
27927ec8bab3SRichard Henderson tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
27937ec8bab3SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
27947ec8bab3SRichard Henderson return;
27957ec8bab3SRichard Henderson }
27967ec8bab3SRichard Henderson /* The field is split across two words. One double-word
27977ec8bab3SRichard Henderson shift is better than two double-word shifts. */
27987ec8bab3SRichard Henderson goto do_shift_and;
27997ec8bab3SRichard Henderson }
28007ec8bab3SRichard Henderson
28017ec8bab3SRichard Henderson if (TCG_TARGET_HAS_extract_i64
28027ec8bab3SRichard Henderson && TCG_TARGET_extract_i64_valid(ofs, len)) {
28037ec8bab3SRichard Henderson tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len);
28047ec8bab3SRichard Henderson return;
28057ec8bab3SRichard Henderson }
28067ec8bab3SRichard Henderson
28077ec8bab3SRichard Henderson /* Assume that zero-extension, if available, is cheaper than a shift. */
28087ec8bab3SRichard Henderson switch (ofs + len) {
28097ec8bab3SRichard Henderson case 32:
28107ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext32u_i64) {
28117ec8bab3SRichard Henderson tcg_gen_ext32u_i64(ret, arg);
28127ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, ret, ofs);
28137ec8bab3SRichard Henderson return;
28147ec8bab3SRichard Henderson }
28157ec8bab3SRichard Henderson break;
28167ec8bab3SRichard Henderson case 16:
28177ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext16u_i64) {
28187ec8bab3SRichard Henderson tcg_gen_ext16u_i64(ret, arg);
28197ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, ret, ofs);
28207ec8bab3SRichard Henderson return;
28217ec8bab3SRichard Henderson }
28227ec8bab3SRichard Henderson break;
28237ec8bab3SRichard Henderson case 8:
28247ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext8u_i64) {
28257ec8bab3SRichard Henderson tcg_gen_ext8u_i64(ret, arg);
28267ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, ret, ofs);
28277ec8bab3SRichard Henderson return;
28287ec8bab3SRichard Henderson }
28297ec8bab3SRichard Henderson break;
28307ec8bab3SRichard Henderson }
28317ec8bab3SRichard Henderson
28327ec8bab3SRichard Henderson /* ??? Ideally we'd know what values are available for immediate AND.
28337ec8bab3SRichard Henderson Assume that 8 bits are available, plus the special cases of 16 and 32,
28347ec8bab3SRichard Henderson so that we get ext8u, ext16u, and ext32u. */
28357ec8bab3SRichard Henderson switch (len) {
28367ec8bab3SRichard Henderson case 1 ... 8: case 16: case 32:
28377ec8bab3SRichard Henderson do_shift_and:
28387ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, arg, ofs);
28397ec8bab3SRichard Henderson tcg_gen_andi_i64(ret, ret, (1ull << len) - 1);
28407ec8bab3SRichard Henderson break;
28417ec8bab3SRichard Henderson default:
28427ec8bab3SRichard Henderson tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
28437ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, ret, 64 - len);
28447ec8bab3SRichard Henderson break;
28457ec8bab3SRichard Henderson }
28467ec8bab3SRichard Henderson }
28477ec8bab3SRichard Henderson
tcg_gen_sextract_i64(TCGv_i64 ret,TCGv_i64 arg,unsigned int ofs,unsigned int len)28487ec8bab3SRichard Henderson void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
28497ec8bab3SRichard Henderson unsigned int ofs, unsigned int len)
28507ec8bab3SRichard Henderson {
28517ec8bab3SRichard Henderson tcg_debug_assert(ofs < 64);
28527ec8bab3SRichard Henderson tcg_debug_assert(len > 0);
28537ec8bab3SRichard Henderson tcg_debug_assert(len <= 64);
28547ec8bab3SRichard Henderson tcg_debug_assert(ofs + len <= 64);
28557ec8bab3SRichard Henderson
28567ec8bab3SRichard Henderson /* Canonicalize certain special cases, even if sextract is supported. */
28577ec8bab3SRichard Henderson if (ofs + len == 64) {
28587ec8bab3SRichard Henderson tcg_gen_sari_i64(ret, arg, 64 - len);
28597ec8bab3SRichard Henderson return;
28607ec8bab3SRichard Henderson }
28617ec8bab3SRichard Henderson if (ofs == 0) {
28627ec8bab3SRichard Henderson switch (len) {
28637ec8bab3SRichard Henderson case 32:
28647ec8bab3SRichard Henderson tcg_gen_ext32s_i64(ret, arg);
28657ec8bab3SRichard Henderson return;
28667ec8bab3SRichard Henderson case 16:
28677ec8bab3SRichard Henderson tcg_gen_ext16s_i64(ret, arg);
28687ec8bab3SRichard Henderson return;
28697ec8bab3SRichard Henderson case 8:
28707ec8bab3SRichard Henderson tcg_gen_ext8s_i64(ret, arg);
28717ec8bab3SRichard Henderson return;
28727ec8bab3SRichard Henderson }
28737ec8bab3SRichard Henderson }
28747ec8bab3SRichard Henderson
28757ec8bab3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
28767ec8bab3SRichard Henderson /* Look for a 32-bit extract within one of the two words. */
28777ec8bab3SRichard Henderson if (ofs >= 32) {
28787ec8bab3SRichard Henderson tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
28797ec8bab3SRichard Henderson } else if (ofs + len <= 32) {
28807ec8bab3SRichard Henderson tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
28817ec8bab3SRichard Henderson } else if (ofs == 0) {
28827ec8bab3SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
28837ec8bab3SRichard Henderson tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32);
28847ec8bab3SRichard Henderson return;
28857ec8bab3SRichard Henderson } else if (len > 32) {
28865dd48602SRichard Henderson TCGv_i32 t = tcg_temp_ebb_new_i32();
28877ec8bab3SRichard Henderson /* Extract the bits for the high word normally. */
28887ec8bab3SRichard Henderson tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32);
28897ec8bab3SRichard Henderson /* Shift the field down for the low part. */
28907ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, arg, ofs);
28917ec8bab3SRichard Henderson /* Overwrite the shift into the high part. */
28927ec8bab3SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(ret), t);
28937ec8bab3SRichard Henderson tcg_temp_free_i32(t);
28947ec8bab3SRichard Henderson return;
28957ec8bab3SRichard Henderson } else {
28967ec8bab3SRichard Henderson /* Shift the field down for the low part, such that the
28977ec8bab3SRichard Henderson field sits at the MSB. */
28987ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, arg, ofs + len - 32);
28997ec8bab3SRichard Henderson /* Shift the field down from the MSB, sign extending. */
29007ec8bab3SRichard Henderson tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_LOW(ret), 32 - len);
29017ec8bab3SRichard Henderson }
29027ec8bab3SRichard Henderson /* Sign-extend the field from 32 bits. */
29037ec8bab3SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
29047ec8bab3SRichard Henderson return;
29057ec8bab3SRichard Henderson }
29067ec8bab3SRichard Henderson
29077ec8bab3SRichard Henderson if (TCG_TARGET_HAS_sextract_i64
29087ec8bab3SRichard Henderson && TCG_TARGET_extract_i64_valid(ofs, len)) {
29097ec8bab3SRichard Henderson tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len);
29107ec8bab3SRichard Henderson return;
29117ec8bab3SRichard Henderson }
29127ec8bab3SRichard Henderson
29137ec8bab3SRichard Henderson /* Assume that sign-extension, if available, is cheaper than a shift. */
29147ec8bab3SRichard Henderson switch (ofs + len) {
29157ec8bab3SRichard Henderson case 32:
29167ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext32s_i64) {
29177ec8bab3SRichard Henderson tcg_gen_ext32s_i64(ret, arg);
29187ec8bab3SRichard Henderson tcg_gen_sari_i64(ret, ret, ofs);
29197ec8bab3SRichard Henderson return;
29207ec8bab3SRichard Henderson }
29217ec8bab3SRichard Henderson break;
29227ec8bab3SRichard Henderson case 16:
29237ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext16s_i64) {
29247ec8bab3SRichard Henderson tcg_gen_ext16s_i64(ret, arg);
29257ec8bab3SRichard Henderson tcg_gen_sari_i64(ret, ret, ofs);
29267ec8bab3SRichard Henderson return;
29277ec8bab3SRichard Henderson }
29287ec8bab3SRichard Henderson break;
29297ec8bab3SRichard Henderson case 8:
29307ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext8s_i64) {
29317ec8bab3SRichard Henderson tcg_gen_ext8s_i64(ret, arg);
29327ec8bab3SRichard Henderson tcg_gen_sari_i64(ret, ret, ofs);
29337ec8bab3SRichard Henderson return;
29347ec8bab3SRichard Henderson }
29357ec8bab3SRichard Henderson break;
29367ec8bab3SRichard Henderson }
29377ec8bab3SRichard Henderson switch (len) {
29387ec8bab3SRichard Henderson case 32:
29397ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext32s_i64) {
29407ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, arg, ofs);
29417ec8bab3SRichard Henderson tcg_gen_ext32s_i64(ret, ret);
29427ec8bab3SRichard Henderson return;
29437ec8bab3SRichard Henderson }
29447ec8bab3SRichard Henderson break;
29457ec8bab3SRichard Henderson case 16:
29467ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext16s_i64) {
29477ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, arg, ofs);
29487ec8bab3SRichard Henderson tcg_gen_ext16s_i64(ret, ret);
29497ec8bab3SRichard Henderson return;
29507ec8bab3SRichard Henderson }
29517ec8bab3SRichard Henderson break;
29527ec8bab3SRichard Henderson case 8:
29537ec8bab3SRichard Henderson if (TCG_TARGET_HAS_ext8s_i64) {
29547ec8bab3SRichard Henderson tcg_gen_shri_i64(ret, arg, ofs);
29557ec8bab3SRichard Henderson tcg_gen_ext8s_i64(ret, ret);
29567ec8bab3SRichard Henderson return;
29577ec8bab3SRichard Henderson }
29587ec8bab3SRichard Henderson break;
29597ec8bab3SRichard Henderson }
29607ec8bab3SRichard Henderson tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
29617ec8bab3SRichard Henderson tcg_gen_sari_i64(ret, ret, 64 - len);
29627ec8bab3SRichard Henderson }
29637ec8bab3SRichard Henderson
29642089fcc9SDavid Hildenbrand /*
29652089fcc9SDavid Hildenbrand * Extract 64 bits from a 128-bit input, ah:al, starting from ofs.
29662089fcc9SDavid Hildenbrand * Unlike tcg_gen_extract_i64 above, len is fixed at 64.
29672089fcc9SDavid Hildenbrand */
tcg_gen_extract2_i64(TCGv_i64 ret,TCGv_i64 al,TCGv_i64 ah,unsigned int ofs)29682089fcc9SDavid Hildenbrand void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
29692089fcc9SDavid Hildenbrand unsigned int ofs)
29702089fcc9SDavid Hildenbrand {
29712089fcc9SDavid Hildenbrand tcg_debug_assert(ofs <= 64);
29722089fcc9SDavid Hildenbrand if (ofs == 0) {
29732089fcc9SDavid Hildenbrand tcg_gen_mov_i64(ret, al);
29742089fcc9SDavid Hildenbrand } else if (ofs == 64) {
29752089fcc9SDavid Hildenbrand tcg_gen_mov_i64(ret, ah);
29762089fcc9SDavid Hildenbrand } else if (al == ah) {
29772089fcc9SDavid Hildenbrand tcg_gen_rotri_i64(ret, al, ofs);
2978fce1296fSRichard Henderson } else if (TCG_TARGET_HAS_extract2_i64) {
2979fce1296fSRichard Henderson tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
29802089fcc9SDavid Hildenbrand } else {
29815dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
29822089fcc9SDavid Hildenbrand tcg_gen_shri_i64(t0, al, ofs);
29832089fcc9SDavid Hildenbrand tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs);
29842089fcc9SDavid Hildenbrand tcg_temp_free_i64(t0);
29852089fcc9SDavid Hildenbrand }
29862089fcc9SDavid Hildenbrand }
29872089fcc9SDavid Hildenbrand
tcg_gen_movcond_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 c1,TCGv_i64 c2,TCGv_i64 v1,TCGv_i64 v2)2988951c6300SRichard Henderson void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
2989951c6300SRichard Henderson TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2)
2990951c6300SRichard Henderson {
299137ed3bf1SRichard Henderson if (cond == TCG_COND_ALWAYS) {
299237ed3bf1SRichard Henderson tcg_gen_mov_i64(ret, v1);
299337ed3bf1SRichard Henderson } else if (cond == TCG_COND_NEVER) {
299437ed3bf1SRichard Henderson tcg_gen_mov_i64(ret, v2);
29953871be75SRichard Henderson } else if (TCG_TARGET_REG_BITS == 64) {
29963871be75SRichard Henderson tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
29973871be75SRichard Henderson } else {
29985dd48602SRichard Henderson TCGv_i32 t0 = tcg_temp_ebb_new_i32();
29993871be75SRichard Henderson TCGv_i32 zero = tcg_constant_i32(0);
30003871be75SRichard Henderson
3001951c6300SRichard Henderson tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
3002951c6300SRichard Henderson TCGV_LOW(c1), TCGV_HIGH(c1),
3003951c6300SRichard Henderson TCGV_LOW(c2), TCGV_HIGH(c2), cond);
3004951c6300SRichard Henderson
30053871be75SRichard Henderson tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, zero,
3006951c6300SRichard Henderson TCGV_LOW(v1), TCGV_LOW(v2));
30073871be75SRichard Henderson tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, zero,
3008951c6300SRichard Henderson TCGV_HIGH(v1), TCGV_HIGH(v2));
3009951c6300SRichard Henderson
3010951c6300SRichard Henderson tcg_temp_free_i32(t0);
3011951c6300SRichard Henderson }
3012951c6300SRichard Henderson }
3013951c6300SRichard Henderson
tcg_gen_add2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 al,TCGv_i64 ah,TCGv_i64 bl,TCGv_i64 bh)3014951c6300SRichard Henderson void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
3015951c6300SRichard Henderson TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
3016951c6300SRichard Henderson {
3017951c6300SRichard Henderson if (TCG_TARGET_HAS_add2_i64) {
3018951c6300SRichard Henderson tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
3019951c6300SRichard Henderson } else {
30205dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
30215dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
3022951c6300SRichard Henderson tcg_gen_add_i64(t0, al, bl);
3023951c6300SRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
3024951c6300SRichard Henderson tcg_gen_add_i64(rh, ah, bh);
3025951c6300SRichard Henderson tcg_gen_add_i64(rh, rh, t1);
3026951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0);
3027951c6300SRichard Henderson tcg_temp_free_i64(t0);
3028951c6300SRichard Henderson tcg_temp_free_i64(t1);
3029951c6300SRichard Henderson }
3030951c6300SRichard Henderson }
3031951c6300SRichard Henderson
tcg_gen_sub2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 al,TCGv_i64 ah,TCGv_i64 bl,TCGv_i64 bh)3032951c6300SRichard Henderson void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
3033951c6300SRichard Henderson TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
3034951c6300SRichard Henderson {
3035951c6300SRichard Henderson if (TCG_TARGET_HAS_sub2_i64) {
3036951c6300SRichard Henderson tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
3037951c6300SRichard Henderson } else {
30385dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
30395dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
3040951c6300SRichard Henderson tcg_gen_sub_i64(t0, al, bl);
3041951c6300SRichard Henderson tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
3042951c6300SRichard Henderson tcg_gen_sub_i64(rh, ah, bh);
3043951c6300SRichard Henderson tcg_gen_sub_i64(rh, rh, t1);
3044951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0);
3045951c6300SRichard Henderson tcg_temp_free_i64(t0);
3046951c6300SRichard Henderson tcg_temp_free_i64(t1);
3047951c6300SRichard Henderson }
3048951c6300SRichard Henderson }
3049951c6300SRichard Henderson
tcg_gen_mulu2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 arg1,TCGv_i64 arg2)3050951c6300SRichard Henderson void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
3051951c6300SRichard Henderson {
3052951c6300SRichard Henderson if (TCG_TARGET_HAS_mulu2_i64) {
3053951c6300SRichard Henderson tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
3054951c6300SRichard Henderson } else if (TCG_TARGET_HAS_muluh_i64) {
30555dd48602SRichard Henderson TCGv_i64 t = tcg_temp_ebb_new_i64();
3056951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
3057951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
3058951c6300SRichard Henderson tcg_gen_mov_i64(rl, t);
3059951c6300SRichard Henderson tcg_temp_free_i64(t);
3060951c6300SRichard Henderson } else {
30615dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3062951c6300SRichard Henderson tcg_gen_mul_i64(t0, arg1, arg2);
3063951c6300SRichard Henderson gen_helper_muluh_i64(rh, arg1, arg2);
3064951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0);
3065951c6300SRichard Henderson tcg_temp_free_i64(t0);
3066951c6300SRichard Henderson }
3067951c6300SRichard Henderson }
3068951c6300SRichard Henderson
tcg_gen_muls2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 arg1,TCGv_i64 arg2)3069951c6300SRichard Henderson void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
3070951c6300SRichard Henderson {
3071951c6300SRichard Henderson if (TCG_TARGET_HAS_muls2_i64) {
3072951c6300SRichard Henderson tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
3073951c6300SRichard Henderson } else if (TCG_TARGET_HAS_mulsh_i64) {
30745dd48602SRichard Henderson TCGv_i64 t = tcg_temp_ebb_new_i64();
3075951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
3076951c6300SRichard Henderson tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
3077951c6300SRichard Henderson tcg_gen_mov_i64(rl, t);
3078951c6300SRichard Henderson tcg_temp_free_i64(t);
3079951c6300SRichard Henderson } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
30805dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
30815dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
30825dd48602SRichard Henderson TCGv_i64 t2 = tcg_temp_ebb_new_i64();
30835dd48602SRichard Henderson TCGv_i64 t3 = tcg_temp_ebb_new_i64();
3084951c6300SRichard Henderson tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
3085951c6300SRichard Henderson /* Adjust for negative inputs. */
3086951c6300SRichard Henderson tcg_gen_sari_i64(t2, arg1, 63);
3087951c6300SRichard Henderson tcg_gen_sari_i64(t3, arg2, 63);
3088951c6300SRichard Henderson tcg_gen_and_i64(t2, t2, arg2);
3089951c6300SRichard Henderson tcg_gen_and_i64(t3, t3, arg1);
3090951c6300SRichard Henderson tcg_gen_sub_i64(rh, t1, t2);
3091951c6300SRichard Henderson tcg_gen_sub_i64(rh, rh, t3);
3092951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0);
3093951c6300SRichard Henderson tcg_temp_free_i64(t0);
3094951c6300SRichard Henderson tcg_temp_free_i64(t1);
3095951c6300SRichard Henderson tcg_temp_free_i64(t2);
3096951c6300SRichard Henderson tcg_temp_free_i64(t3);
3097951c6300SRichard Henderson } else {
30985dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3099951c6300SRichard Henderson tcg_gen_mul_i64(t0, arg1, arg2);
3100951c6300SRichard Henderson gen_helper_mulsh_i64(rh, arg1, arg2);
3101951c6300SRichard Henderson tcg_gen_mov_i64(rl, t0);
3102951c6300SRichard Henderson tcg_temp_free_i64(t0);
3103951c6300SRichard Henderson }
3104951c6300SRichard Henderson }
3105951c6300SRichard Henderson
tcg_gen_mulsu2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 arg1,TCGv_i64 arg2)31065087abfbSRichard Henderson void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
31075087abfbSRichard Henderson {
31085dd48602SRichard Henderson TCGv_i64 t0 = tcg_temp_ebb_new_i64();
31095dd48602SRichard Henderson TCGv_i64 t1 = tcg_temp_ebb_new_i64();
31105dd48602SRichard Henderson TCGv_i64 t2 = tcg_temp_ebb_new_i64();
31115087abfbSRichard Henderson tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
31125087abfbSRichard Henderson /* Adjust for negative input for the signed arg1. */
31135087abfbSRichard Henderson tcg_gen_sari_i64(t2, arg1, 63);
31145087abfbSRichard Henderson tcg_gen_and_i64(t2, t2, arg2);
31155087abfbSRichard Henderson tcg_gen_sub_i64(rh, t1, t2);
31165087abfbSRichard Henderson tcg_gen_mov_i64(rl, t0);
31175087abfbSRichard Henderson tcg_temp_free_i64(t0);
31185087abfbSRichard Henderson tcg_temp_free_i64(t1);
31195087abfbSRichard Henderson tcg_temp_free_i64(t2);
31205087abfbSRichard Henderson }
31215087abfbSRichard Henderson
tcg_gen_smin_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3122b87fb8cdSRichard Henderson void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3123b87fb8cdSRichard Henderson {
3124b87fb8cdSRichard Henderson tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b);
3125b87fb8cdSRichard Henderson }
3126b87fb8cdSRichard Henderson
tcg_gen_umin_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3127b87fb8cdSRichard Henderson void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3128b87fb8cdSRichard Henderson {
3129b87fb8cdSRichard Henderson tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b);
3130b87fb8cdSRichard Henderson }
3131b87fb8cdSRichard Henderson
tcg_gen_smax_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3132b87fb8cdSRichard Henderson void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3133b87fb8cdSRichard Henderson {
3134b87fb8cdSRichard Henderson tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a);
3135b87fb8cdSRichard Henderson }
3136b87fb8cdSRichard Henderson
tcg_gen_umax_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3137b87fb8cdSRichard Henderson void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3138b87fb8cdSRichard Henderson {
3139b87fb8cdSRichard Henderson tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a);
3140b87fb8cdSRichard Henderson }
3141b87fb8cdSRichard Henderson
tcg_gen_abs_i64(TCGv_i64 ret,TCGv_i64 a)3142ff1f11f7SRichard Henderson void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a)
3143ff1f11f7SRichard Henderson {
31445dd48602SRichard Henderson TCGv_i64 t = tcg_temp_ebb_new_i64();
3145ff1f11f7SRichard Henderson
3146ff1f11f7SRichard Henderson tcg_gen_sari_i64(t, a, 63);
3147ff1f11f7SRichard Henderson tcg_gen_xor_i64(ret, a, t);
3148ff1f11f7SRichard Henderson tcg_gen_sub_i64(ret, ret, t);
3149ff1f11f7SRichard Henderson tcg_temp_free_i64(t);
3150ff1f11f7SRichard Henderson }
3151ff1f11f7SRichard Henderson
3152951c6300SRichard Henderson /* Size changing operations. */
3153951c6300SRichard Henderson
tcg_gen_extrl_i64_i32(TCGv_i32 ret,TCGv_i64 arg)3154609ad705SRichard Henderson void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
3155951c6300SRichard Henderson {
31563a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
3157951c6300SRichard Henderson tcg_gen_mov_i32(ret, TCGV_LOW(arg));
315813d885b0SRichard Henderson } else if (TCG_TARGET_HAS_extr_i64_i32) {
3159b7e8b17aSRichard Henderson tcg_gen_op2(INDEX_op_extrl_i64_i32,
3160ae8b75dcSRichard Henderson tcgv_i32_arg(ret), tcgv_i64_arg(arg));
3161951c6300SRichard Henderson } else {
3162dc41aa7dSRichard Henderson tcg_gen_mov_i32(ret, (TCGv_i32)arg);
3163609ad705SRichard Henderson }
3164609ad705SRichard Henderson }
3165609ad705SRichard Henderson
tcg_gen_extrh_i64_i32(TCGv_i32 ret,TCGv_i64 arg)3166609ad705SRichard Henderson void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
3167609ad705SRichard Henderson {
3168609ad705SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
3169609ad705SRichard Henderson tcg_gen_mov_i32(ret, TCGV_HIGH(arg));
317013d885b0SRichard Henderson } else if (TCG_TARGET_HAS_extr_i64_i32) {
3171b7e8b17aSRichard Henderson tcg_gen_op2(INDEX_op_extrh_i64_i32,
3172ae8b75dcSRichard Henderson tcgv_i32_arg(ret), tcgv_i64_arg(arg));
3173951c6300SRichard Henderson } else {
31745dd48602SRichard Henderson TCGv_i64 t = tcg_temp_ebb_new_i64();
3175609ad705SRichard Henderson tcg_gen_shri_i64(t, arg, 32);
3176dc41aa7dSRichard Henderson tcg_gen_mov_i32(ret, (TCGv_i32)t);
3177951c6300SRichard Henderson tcg_temp_free_i64(t);
3178951c6300SRichard Henderson }
3179951c6300SRichard Henderson }
3180951c6300SRichard Henderson
tcg_gen_extu_i32_i64(TCGv_i64 ret,TCGv_i32 arg)3181951c6300SRichard Henderson void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
3182951c6300SRichard Henderson {
31833a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
3184951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), arg);
3185951c6300SRichard Henderson tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
31863a13c3f3SRichard Henderson } else {
3187b7e8b17aSRichard Henderson tcg_gen_op2(INDEX_op_extu_i32_i64,
3188ae8b75dcSRichard Henderson tcgv_i64_arg(ret), tcgv_i32_arg(arg));
31893a13c3f3SRichard Henderson }
3190951c6300SRichard Henderson }
3191951c6300SRichard Henderson
tcg_gen_ext_i32_i64(TCGv_i64 ret,TCGv_i32 arg)3192951c6300SRichard Henderson void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
3193951c6300SRichard Henderson {
31943a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
3195951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(ret), arg);
3196951c6300SRichard Henderson tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
31973a13c3f3SRichard Henderson } else {
3198b7e8b17aSRichard Henderson tcg_gen_op2(INDEX_op_ext_i32_i64,
3199ae8b75dcSRichard Henderson tcgv_i64_arg(ret), tcgv_i32_arg(arg));
32003a13c3f3SRichard Henderson }
3201951c6300SRichard Henderson }
3202951c6300SRichard Henderson
tcg_gen_concat_i32_i64(TCGv_i64 dest,TCGv_i32 low,TCGv_i32 high)3203951c6300SRichard Henderson void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
3204951c6300SRichard Henderson {
32053a13c3f3SRichard Henderson TCGv_i64 tmp;
32063a13c3f3SRichard Henderson
32073a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
3208951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_LOW(dest), low);
3209951c6300SRichard Henderson tcg_gen_mov_i32(TCGV_HIGH(dest), high);
32103a13c3f3SRichard Henderson return;
32113a13c3f3SRichard Henderson }
32123a13c3f3SRichard Henderson
32135dd48602SRichard Henderson tmp = tcg_temp_ebb_new_i64();
3214951c6300SRichard Henderson /* These extensions are only needed for type correctness.
3215951c6300SRichard Henderson We may be able to do better given target specific information. */
3216951c6300SRichard Henderson tcg_gen_extu_i32_i64(tmp, high);
3217951c6300SRichard Henderson tcg_gen_extu_i32_i64(dest, low);
3218951c6300SRichard Henderson /* If deposit is available, use it. Otherwise use the extra
3219951c6300SRichard Henderson knowledge that we have of the zero-extensions above. */
3220951c6300SRichard Henderson if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
3221951c6300SRichard Henderson tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
3222951c6300SRichard Henderson } else {
3223951c6300SRichard Henderson tcg_gen_shli_i64(tmp, tmp, 32);
3224951c6300SRichard Henderson tcg_gen_or_i64(dest, dest, tmp);
3225951c6300SRichard Henderson }
3226951c6300SRichard Henderson tcg_temp_free_i64(tmp);
3227951c6300SRichard Henderson }
3228951c6300SRichard Henderson
tcg_gen_extr_i64_i32(TCGv_i32 lo,TCGv_i32 hi,TCGv_i64 arg)3229951c6300SRichard Henderson void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
3230951c6300SRichard Henderson {
32313a13c3f3SRichard Henderson if (TCG_TARGET_REG_BITS == 32) {
3232951c6300SRichard Henderson tcg_gen_mov_i32(lo, TCGV_LOW(arg));
3233951c6300SRichard Henderson tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
32343a13c3f3SRichard Henderson } else {
3235609ad705SRichard Henderson tcg_gen_extrl_i64_i32(lo, arg);
3236609ad705SRichard Henderson tcg_gen_extrh_i64_i32(hi, arg);
32373a13c3f3SRichard Henderson }
3238951c6300SRichard Henderson }
3239951c6300SRichard Henderson
tcg_gen_extr32_i64(TCGv_i64 lo,TCGv_i64 hi,TCGv_i64 arg)3240951c6300SRichard Henderson void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
3241951c6300SRichard Henderson {
3242951c6300SRichard Henderson tcg_gen_ext32u_i64(lo, arg);
3243951c6300SRichard Henderson tcg_gen_shri_i64(hi, arg, 32);
3244951c6300SRichard Henderson }
3245951c6300SRichard Henderson
tcg_gen_concat32_i64(TCGv_i64 ret,TCGv_i64 lo,TCGv_i64 hi)3246e0de2f55SRichard Henderson void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 hi)
3247e0de2f55SRichard Henderson {
3248e0de2f55SRichard Henderson tcg_gen_deposit_i64(ret, lo, hi, 32, 32);
3249e0de2f55SRichard Henderson }
3250e0de2f55SRichard Henderson
tcg_gen_extr_i128_i64(TCGv_i64 lo,TCGv_i64 hi,TCGv_i128 arg)32514771e71cSRichard Henderson void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg)
32524771e71cSRichard Henderson {
32534771e71cSRichard Henderson tcg_gen_mov_i64(lo, TCGV128_LOW(arg));
32544771e71cSRichard Henderson tcg_gen_mov_i64(hi, TCGV128_HIGH(arg));
32554771e71cSRichard Henderson }
32564771e71cSRichard Henderson
tcg_gen_concat_i64_i128(TCGv_i128 ret,TCGv_i64 lo,TCGv_i64 hi)32574771e71cSRichard Henderson void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi)
32584771e71cSRichard Henderson {
32594771e71cSRichard Henderson tcg_gen_mov_i64(TCGV128_LOW(ret), lo);
32604771e71cSRichard Henderson tcg_gen_mov_i64(TCGV128_HIGH(ret), hi);
32614771e71cSRichard Henderson }
32624771e71cSRichard Henderson
tcg_gen_mov_i128(TCGv_i128 dst,TCGv_i128 src)32634771e71cSRichard Henderson void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src)
32644771e71cSRichard Henderson {
32654771e71cSRichard Henderson if (dst != src) {
32664771e71cSRichard Henderson tcg_gen_mov_i64(TCGV128_LOW(dst), TCGV128_LOW(src));
32674771e71cSRichard Henderson tcg_gen_mov_i64(TCGV128_HIGH(dst), TCGV128_HIGH(src));
32684771e71cSRichard Henderson }
32694771e71cSRichard Henderson }
32704771e71cSRichard Henderson
tcg_gen_ld_i128(TCGv_i128 ret,TCGv_ptr base,tcg_target_long offset)3271a01d9792SRichard Henderson void tcg_gen_ld_i128(TCGv_i128 ret, TCGv_ptr base, tcg_target_long offset)
3272a01d9792SRichard Henderson {
3273a01d9792SRichard Henderson if (HOST_BIG_ENDIAN) {
3274a01d9792SRichard Henderson tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset);
3275a01d9792SRichard Henderson tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset + 8);
3276a01d9792SRichard Henderson } else {
3277a01d9792SRichard Henderson tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset);
3278a01d9792SRichard Henderson tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset + 8);
3279a01d9792SRichard Henderson }
3280a01d9792SRichard Henderson }
3281a01d9792SRichard Henderson
tcg_gen_st_i128(TCGv_i128 val,TCGv_ptr base,tcg_target_long offset)3282a01d9792SRichard Henderson void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, tcg_target_long offset)
3283a01d9792SRichard Henderson {
3284a01d9792SRichard Henderson if (HOST_BIG_ENDIAN) {
3285a01d9792SRichard Henderson tcg_gen_st_i64(TCGV128_HIGH(val), base, offset);
3286a01d9792SRichard Henderson tcg_gen_st_i64(TCGV128_LOW(val), base, offset + 8);
3287a01d9792SRichard Henderson } else {
3288a01d9792SRichard Henderson tcg_gen_st_i64(TCGV128_LOW(val), base, offset);
3289a01d9792SRichard Henderson tcg_gen_st_i64(TCGV128_HIGH(val), base, offset + 8);
3290a01d9792SRichard Henderson }
3291a01d9792SRichard Henderson }
3292a01d9792SRichard Henderson
3293951c6300SRichard Henderson /* QEMU specific operations. */
3294951c6300SRichard Henderson
tcg_gen_exit_tb(const TranslationBlock * tb,unsigned idx)3295d9971435SRichard Henderson void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
329607ea28b4SRichard Henderson {
3297eba40358SRichard Henderson /*
3298eba40358SRichard Henderson * Let the jit code return the read-only version of the
3299eba40358SRichard Henderson * TranslationBlock, so that we minimize the pc-relative
3300eba40358SRichard Henderson * distance of the address of the exit_tb code to TB.
3301eba40358SRichard Henderson * This will improve utilization of pc-relative address loads.
3302eba40358SRichard Henderson *
3303eba40358SRichard Henderson * TODO: Move this to translator_loop, so that all const
3304eba40358SRichard Henderson * TranslationBlock pointers refer to read-only memory.
3305eba40358SRichard Henderson * This requires coordination with targets that do not use
3306eba40358SRichard Henderson * the translator_loop.
3307eba40358SRichard Henderson */
3308eba40358SRichard Henderson uintptr_t val = (uintptr_t)tcg_splitwx_to_rx((void *)tb) + idx;
330907ea28b4SRichard Henderson
331007ea28b4SRichard Henderson if (tb == NULL) {
331107ea28b4SRichard Henderson tcg_debug_assert(idx == 0);
331207ea28b4SRichard Henderson } else if (idx <= TB_EXIT_IDXMAX) {
331307ea28b4SRichard Henderson #ifdef CONFIG_DEBUG_TCG
331407ea28b4SRichard Henderson /* This is an exit following a goto_tb. Verify that we have
331507ea28b4SRichard Henderson seen this numbered exit before, via tcg_gen_goto_tb. */
331607ea28b4SRichard Henderson tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx));
331707ea28b4SRichard Henderson #endif
331807ea28b4SRichard Henderson } else {
331907ea28b4SRichard Henderson /* This is an exit via the exitreq label. */
332007ea28b4SRichard Henderson tcg_debug_assert(idx == TB_EXIT_REQUESTED);
332107ea28b4SRichard Henderson }
332207ea28b4SRichard Henderson
332307ea28b4SRichard Henderson tcg_gen_op1i(INDEX_op_exit_tb, val);
332407ea28b4SRichard Henderson }
332507ea28b4SRichard Henderson
tcg_gen_goto_tb(unsigned idx)3326951c6300SRichard Henderson void tcg_gen_goto_tb(unsigned idx)
3327951c6300SRichard Henderson {
332884f15616SRichard Henderson /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */
3329b7e4afbdSRichard Henderson tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB));
3330951c6300SRichard Henderson /* We only support two chained exits. */
333107ea28b4SRichard Henderson tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
3332951c6300SRichard Henderson #ifdef CONFIG_DEBUG_TCG
3333a4761232SPhilippe Mathieu-Daudé /* Verify that we haven't seen this numbered exit before. */
3334b1311c4aSEmilio G. Cota tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
3335b1311c4aSEmilio G. Cota tcg_ctx->goto_tb_issue_mask |= 1 << idx;
3336951c6300SRichard Henderson #endif
3337e6d86bedSEmilio G. Cota plugin_gen_disable_mem_helpers();
3338951c6300SRichard Henderson tcg_gen_op1i(INDEX_op_goto_tb, idx);
3339951c6300SRichard Henderson }
3340951c6300SRichard Henderson
tcg_gen_lookup_and_goto_ptr(void)33417f11636dSEmilio G. Cota void tcg_gen_lookup_and_goto_ptr(void)
3342cedbcb01SEmilio G. Cota {
3343e6d86bedSEmilio G. Cota TCGv_ptr ptr;
3344e6d86bedSEmilio G. Cota
3345b7e4afbdSRichard Henderson if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) {
334684f15616SRichard Henderson tcg_gen_exit_tb(NULL, 0);
334784f15616SRichard Henderson return;
334884f15616SRichard Henderson }
334984f15616SRichard Henderson
3350e6d86bedSEmilio G. Cota plugin_gen_disable_mem_helpers();
33515dd48602SRichard Henderson ptr = tcg_temp_ebb_new_ptr();
3352ad75a51eSRichard Henderson gen_helper_lookup_tb_ptr(ptr, tcg_env);
3353ae8b75dcSRichard Henderson tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr));
3354cedbcb01SEmilio G. Cota tcg_temp_free_ptr(ptr);
3355cedbcb01SEmilio G. Cota }
3356