blob: 5590dc512af026d596e05c1c62490b1b4ec703b7 [file] [log] [blame]
bellardc896fe22008-02-01 10:05:41 +00001/*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
Richard Hendersone58eb532013-08-27 13:13:44 -070024
25#ifndef TCG_H
26#define TCG_H
27
aurel32f8393942009-04-13 18:45:38 +000028#include "qemu-common.h"
Paolo Bonzini33c11872016-03-15 16:58:45 +010029#include "cpu.h"
Paolo Bonzini00f6da62016-03-15 13:16:36 +010030#include "exec/tb-context.h"
Richard Henderson0ec9eab2013-09-19 12:16:45 -070031#include "qemu/bitops.h"
Richard Henderson15fa08f2017-11-02 15:19:14 +010032#include "qemu/queue.h"
Alex Bennée20937142017-02-23 18:29:07 +000033#include "tcg-mo.h"
Richard Henderson78cd7b82013-08-20 14:41:29 -070034#include "tcg-target.h"
Richard Hendersone6cd4bb2018-08-15 16:31:47 -070035#include "qemu/int128.h"
Richard Henderson78cd7b82013-08-20 14:41:29 -070036
Paolo Bonzini00f6da62016-03-15 13:16:36 +010037/* XXX: make safe guess about sizes */
38#define MAX_OP_PER_INSTR 266
39
40#if HOST_LONG_BITS == 32
41#define MAX_OPC_PARAM_PER_ARG 2
42#else
43#define MAX_OPC_PARAM_PER_ARG 1
44#endif
Richard Henderson1df3caa2017-12-13 16:52:57 -060045#define MAX_OPC_PARAM_IARGS 6
Paolo Bonzini00f6da62016-03-15 13:16:36 +010046#define MAX_OPC_PARAM_OARGS 1
47#define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS)
48
49/* A Call op needs up to 4 + 2N parameters on 32-bit archs,
50 * and up to 4 + N parameters on 64-bit archs
51 * (N = number of input arguments + output arguments). */
52#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
Paolo Bonzini00f6da62016-03-15 13:16:36 +010053
Peter Crosthwaite6e0b0732015-05-30 23:11:34 -070054#define CPU_TEMP_BUF_NLONGS 128
55
Richard Henderson78cd7b82013-08-20 14:41:29 -070056/* Default target word size to pointer size. */
57#ifndef TCG_TARGET_REG_BITS
58# if UINTPTR_MAX == UINT32_MAX
59# define TCG_TARGET_REG_BITS 32
60# elif UINTPTR_MAX == UINT64_MAX
61# define TCG_TARGET_REG_BITS 64
62# else
63# error Unknown pointer size for tcg target
64# endif
Stefan Weil817b8382011-09-17 22:00:27 +020065#endif
66
bellardc896fe22008-02-01 10:05:41 +000067#if TCG_TARGET_REG_BITS == 32
68typedef int32_t tcg_target_long;
69typedef uint32_t tcg_target_ulong;
70#define TCG_PRIlx PRIx32
71#define TCG_PRIld PRId32
72#elif TCG_TARGET_REG_BITS == 64
73typedef int64_t tcg_target_long;
74typedef uint64_t tcg_target_ulong;
75#define TCG_PRIlx PRIx64
76#define TCG_PRIld PRId64
77#else
78#error unsupported
79#endif
80
KONRAD Frederic8d4e9142017-02-23 18:29:08 +000081/* Oversized TCG guests make things like MTTCG hard
82 * as we can't use atomics for cputlb updates.
83 */
84#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
85#define TCG_OVERSIZED_GUEST 1
86#else
87#define TCG_OVERSIZED_GUEST 0
88#endif
89
bellardc896fe22008-02-01 10:05:41 +000090#if TCG_TARGET_NB_REGS <= 32
91typedef uint32_t TCGRegSet;
92#elif TCG_TARGET_NB_REGS <= 64
93typedef uint64_t TCGRegSet;
94#else
95#error unsupported
96#endif
97
Richard Henderson25c4d9c2011-08-17 14:11:46 -070098#if TCG_TARGET_REG_BITS == 32
Richard Hendersone6a72732013-02-19 23:51:49 -080099/* Turn some undef macros into false macros. */
Richard Henderson609ad702015-07-24 07:16:00 -0700100#define TCG_TARGET_HAS_extrl_i64_i32 0
101#define TCG_TARGET_HAS_extrh_i64_i32 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700102#define TCG_TARGET_HAS_div_i64 0
Richard Hendersonca675f42013-03-11 22:41:47 -0700103#define TCG_TARGET_HAS_rem_i64 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700104#define TCG_TARGET_HAS_div2_i64 0
105#define TCG_TARGET_HAS_rot_i64 0
106#define TCG_TARGET_HAS_ext8s_i64 0
107#define TCG_TARGET_HAS_ext16s_i64 0
108#define TCG_TARGET_HAS_ext32s_i64 0
109#define TCG_TARGET_HAS_ext8u_i64 0
110#define TCG_TARGET_HAS_ext16u_i64 0
111#define TCG_TARGET_HAS_ext32u_i64 0
112#define TCG_TARGET_HAS_bswap16_i64 0
113#define TCG_TARGET_HAS_bswap32_i64 0
114#define TCG_TARGET_HAS_bswap64_i64 0
115#define TCG_TARGET_HAS_neg_i64 0
116#define TCG_TARGET_HAS_not_i64 0
117#define TCG_TARGET_HAS_andc_i64 0
118#define TCG_TARGET_HAS_orc_i64 0
119#define TCG_TARGET_HAS_eqv_i64 0
120#define TCG_TARGET_HAS_nand_i64 0
121#define TCG_TARGET_HAS_nor_i64 0
Richard Henderson0e28d002016-11-16 09:23:28 +0100122#define TCG_TARGET_HAS_clz_i64 0
123#define TCG_TARGET_HAS_ctz_i64 0
Richard Hendersona768e4e2016-11-21 11:13:39 +0100124#define TCG_TARGET_HAS_ctpop_i64 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700125#define TCG_TARGET_HAS_deposit_i64 0
Richard Henderson7ec8bab2016-10-14 12:04:32 -0500126#define TCG_TARGET_HAS_extract_i64 0
127#define TCG_TARGET_HAS_sextract_i64 0
Richard Hendersonffc5ea02012-09-21 10:13:34 -0700128#define TCG_TARGET_HAS_movcond_i64 0
Richard Hendersond7156f72013-02-19 23:51:52 -0800129#define TCG_TARGET_HAS_add2_i64 0
130#define TCG_TARGET_HAS_sub2_i64 0
131#define TCG_TARGET_HAS_mulu2_i64 0
Richard Henderson4d3203f2013-02-19 23:51:53 -0800132#define TCG_TARGET_HAS_muls2_i64 0
Richard Henderson03271522013-08-14 14:35:56 -0700133#define TCG_TARGET_HAS_muluh_i64 0
134#define TCG_TARGET_HAS_mulsh_i64 0
Richard Hendersone6a72732013-02-19 23:51:49 -0800135/* Turn some undef macros into true macros. */
136#define TCG_TARGET_HAS_add2_i32 1
137#define TCG_TARGET_HAS_sub2_i32 1
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700138#endif
139
Jan Kiszkaa4773322011-09-29 18:52:11 +0200140#ifndef TCG_TARGET_deposit_i32_valid
141#define TCG_TARGET_deposit_i32_valid(ofs, len) 1
142#endif
143#ifndef TCG_TARGET_deposit_i64_valid
144#define TCG_TARGET_deposit_i64_valid(ofs, len) 1
145#endif
Richard Henderson7ec8bab2016-10-14 12:04:32 -0500146#ifndef TCG_TARGET_extract_i32_valid
147#define TCG_TARGET_extract_i32_valid(ofs, len) 1
148#endif
149#ifndef TCG_TARGET_extract_i64_valid
150#define TCG_TARGET_extract_i64_valid(ofs, len) 1
151#endif
Jan Kiszkaa4773322011-09-29 18:52:11 +0200152
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700153/* Only one of DIV or DIV2 should be defined. */
154#if defined(TCG_TARGET_HAS_div_i32)
155#define TCG_TARGET_HAS_div2_i32 0
156#elif defined(TCG_TARGET_HAS_div2_i32)
157#define TCG_TARGET_HAS_div_i32 0
Richard Hendersonca675f42013-03-11 22:41:47 -0700158#define TCG_TARGET_HAS_rem_i32 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700159#endif
160#if defined(TCG_TARGET_HAS_div_i64)
161#define TCG_TARGET_HAS_div2_i64 0
162#elif defined(TCG_TARGET_HAS_div2_i64)
163#define TCG_TARGET_HAS_div_i64 0
Richard Hendersonca675f42013-03-11 22:41:47 -0700164#define TCG_TARGET_HAS_rem_i64 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700165#endif
166
Richard Hendersondf9ebea2014-03-26 10:59:14 -0700167/* For 32-bit targets, some sort of unsigned widening multiply is required. */
168#if TCG_TARGET_REG_BITS == 32 \
169 && !(defined(TCG_TARGET_HAS_mulu2_i32) \
170 || defined(TCG_TARGET_HAS_muluh_i32))
171# error "Missing unsigned widening multiply"
172#endif
173
Richard Hendersond2fd7452017-09-14 13:53:46 -0700174#if !defined(TCG_TARGET_HAS_v64) \
175 && !defined(TCG_TARGET_HAS_v128) \
176 && !defined(TCG_TARGET_HAS_v256)
177#define TCG_TARGET_MAYBE_vec 0
178#define TCG_TARGET_HAS_neg_vec 0
179#define TCG_TARGET_HAS_not_vec 0
180#define TCG_TARGET_HAS_andc_vec 0
181#define TCG_TARGET_HAS_orc_vec 0
Richard Hendersond0ec9792017-11-17 14:35:11 +0100182#define TCG_TARGET_HAS_shi_vec 0
183#define TCG_TARGET_HAS_shs_vec 0
184#define TCG_TARGET_HAS_shv_vec 0
Richard Henderson37740302017-11-21 10:11:14 +0100185#define TCG_TARGET_HAS_mul_vec 0
Richard Henderson8afaf052018-12-17 18:01:47 -0800186#define TCG_TARGET_HAS_sat_vec 0
Richard Hendersond2fd7452017-09-14 13:53:46 -0700187#else
188#define TCG_TARGET_MAYBE_vec 1
189#endif
190#ifndef TCG_TARGET_HAS_v64
191#define TCG_TARGET_HAS_v64 0
192#endif
193#ifndef TCG_TARGET_HAS_v128
194#define TCG_TARGET_HAS_v128 0
195#endif
196#ifndef TCG_TARGET_HAS_v256
197#define TCG_TARGET_HAS_v256 0
198#endif
199
Richard Henderson9aef40e2015-08-30 09:21:33 -0700200#ifndef TARGET_INSN_START_EXTRA_WORDS
201# define TARGET_INSN_START_WORDS 1
202#else
203# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS)
204#endif
205
Richard Hendersona9751602010-03-19 11:12:29 -0700206typedef enum TCGOpcode {
Aurelien Jarnoc61aaf72010-06-03 19:40:04 +0200207#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
bellardc896fe22008-02-01 10:05:41 +0000208#include "tcg-opc.h"
209#undef DEF
210 NB_OPS,
Richard Hendersona9751602010-03-19 11:12:29 -0700211} TCGOpcode;
bellardc896fe22008-02-01 10:05:41 +0000212
Richard Henderson80a8b9a2017-09-11 12:50:42 -0700213#define tcg_regset_set_reg(d, r) ((d) |= (TCGRegSet)1 << (r))
214#define tcg_regset_reset_reg(d, r) ((d) &= ~((TCGRegSet)1 << (r)))
215#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
bellardc896fe22008-02-01 10:05:41 +0000216
Richard Henderson1813e172014-03-28 12:56:22 -0700217#ifndef TCG_TARGET_INSN_UNIT_SIZE
Richard Henderson50533612014-04-28 12:01:23 -0700218# error "Missing TCG_TARGET_INSN_UNIT_SIZE"
219#elif TCG_TARGET_INSN_UNIT_SIZE == 1
Richard Henderson1813e172014-03-28 12:56:22 -0700220typedef uint8_t tcg_insn_unit;
221#elif TCG_TARGET_INSN_UNIT_SIZE == 2
222typedef uint16_t tcg_insn_unit;
223#elif TCG_TARGET_INSN_UNIT_SIZE == 4
224typedef uint32_t tcg_insn_unit;
225#elif TCG_TARGET_INSN_UNIT_SIZE == 8
226typedef uint64_t tcg_insn_unit;
227#else
228/* The port better have done this. */
229#endif
230
231
Paolo Bonzini8bff06a2016-07-15 18:27:40 +0200232#if defined CONFIG_DEBUG_TCG || defined QEMU_STATIC_ANALYSIS
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300233# define tcg_debug_assert(X) do { assert(X); } while (0)
Thomas Huth6fa2cef2018-12-03 13:48:19 +0100234#else
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300235# define tcg_debug_assert(X) \
236 do { if (!(X)) { __builtin_unreachable(); } } while (0)
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300237#endif
238
bellardc896fe22008-02-01 10:05:41 +0000239typedef struct TCGRelocation {
240 struct TCGRelocation *next;
241 int type;
Richard Henderson1813e172014-03-28 12:56:22 -0700242 tcg_insn_unit *ptr;
Richard Henderson2ba7fae22013-08-20 15:30:10 -0700243 intptr_t addend;
bellardc896fe22008-02-01 10:05:41 +0000244} TCGRelocation;
245
246typedef struct TCGLabel {
Richard Henderson51e39722015-02-13 18:51:05 -0800247 unsigned has_value : 1;
Richard Hendersond88a1172018-11-26 12:47:28 -0800248 unsigned id : 15;
249 unsigned refs : 16;
bellardc896fe22008-02-01 10:05:41 +0000250 union {
Richard Henderson2ba7fae22013-08-20 15:30:10 -0700251 uintptr_t value;
Richard Henderson1813e172014-03-28 12:56:22 -0700252 tcg_insn_unit *value_ptr;
bellardc896fe22008-02-01 10:05:41 +0000253 TCGRelocation *first_reloc;
254 } u;
255} TCGLabel;
256
257typedef struct TCGPool {
258 struct TCGPool *next;
blueswir1c44f9452008-05-19 16:32:18 +0000259 int size;
260 uint8_t data[0] __attribute__ ((aligned));
bellardc896fe22008-02-01 10:05:41 +0000261} TCGPool;
262
263#define TCG_POOL_CHUNK_SIZE 32768
264
blueswir1c4071c92008-03-16 19:21:07 +0000265#define TCG_MAX_TEMPS 512
Richard Henderson190ce7f2015-08-31 14:34:41 -0700266#define TCG_MAX_INSNS 512
bellardc896fe22008-02-01 10:05:41 +0000267
bellardb03cce82008-05-10 10:52:05 +0000268/* when the size of the arguments of a called function is smaller than
269 this value, they are statically allocated in the TB stack frame */
270#define TCG_STATIC_CALL_ARGS_SIZE 128
271
Richard Hendersonc02244a2010-03-19 11:36:30 -0700272typedef enum TCGType {
273 TCG_TYPE_I32,
274 TCG_TYPE_I64,
Richard Hendersond2fd7452017-09-14 13:53:46 -0700275
276 TCG_TYPE_V64,
277 TCG_TYPE_V128,
278 TCG_TYPE_V256,
279
Richard Hendersonc02244a2010-03-19 11:36:30 -0700280 TCG_TYPE_COUNT, /* number of different types */
bellardc896fe22008-02-01 10:05:41 +0000281
Richard Henderson3b6dac32010-06-02 17:26:55 -0700282 /* An alias for the size of the host register. */
bellardc896fe22008-02-01 10:05:41 +0000283#if TCG_TARGET_REG_BITS == 32
Richard Henderson3b6dac32010-06-02 17:26:55 -0700284 TCG_TYPE_REG = TCG_TYPE_I32,
bellardc896fe22008-02-01 10:05:41 +0000285#else
Richard Henderson3b6dac32010-06-02 17:26:55 -0700286 TCG_TYPE_REG = TCG_TYPE_I64,
bellardc896fe22008-02-01 10:05:41 +0000287#endif
Richard Henderson3b6dac32010-06-02 17:26:55 -0700288
Richard Hendersond2898372013-08-20 14:48:46 -0700289 /* An alias for the size of the native pointer. */
290#if UINTPTR_MAX == UINT32_MAX
291 TCG_TYPE_PTR = TCG_TYPE_I32,
292#else
293 TCG_TYPE_PTR = TCG_TYPE_I64,
294#endif
Richard Henderson3b6dac32010-06-02 17:26:55 -0700295
296 /* An alias for the size of the target "long", aka register. */
Richard Hendersonc02244a2010-03-19 11:36:30 -0700297#if TARGET_LONG_BITS == 64
298 TCG_TYPE_TL = TCG_TYPE_I64,
299#else
300 TCG_TYPE_TL = TCG_TYPE_I32,
301#endif
302} TCGType;
bellardc896fe22008-02-01 10:05:41 +0000303
Richard Henderson6c5f4ea2013-09-03 13:52:19 -0700304/* Constants for qemu_ld and qemu_st for the Memory Operation field. */
305typedef enum TCGMemOp {
306 MO_8 = 0,
307 MO_16 = 1,
308 MO_32 = 2,
309 MO_64 = 3,
310 MO_SIZE = 3, /* Mask for the above. */
311
312 MO_SIGN = 4, /* Sign-extended, otherwise zero-extended. */
313
314 MO_BSWAP = 8, /* Host reverse endian. */
315#ifdef HOST_WORDS_BIGENDIAN
316 MO_LE = MO_BSWAP,
317 MO_BE = 0,
318#else
319 MO_LE = 0,
320 MO_BE = MO_BSWAP,
321#endif
322#ifdef TARGET_WORDS_BIGENDIAN
323 MO_TE = MO_BE,
324#else
325 MO_TE = MO_LE,
326#endif
327
Richard Hendersondfb36302015-05-13 11:25:20 -0700328 /* MO_UNALN accesses are never checked for alignment.
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300329 * MO_ALIGN accesses will result in a call to the CPU's
330 * do_unaligned_access hook if the guest address is not aligned.
331 * The default depends on whether the target CPU defines ALIGNED_ONLY.
Richard Henderson85aa8082016-07-14 12:43:06 -0700332 *
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300333 * Some architectures (e.g. ARMv8) need the address which is aligned
334 * to a size more than the size of the memory access.
Richard Henderson85aa8082016-07-14 12:43:06 -0700335 * Some architectures (e.g. SPARCv9) need an address which is aligned,
336 * but less strictly than the natural alignment.
337 *
338 * MO_ALIGN supposes the alignment size is the size of a memory access.
339 *
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300340 * There are three options:
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300341 * - unaligned access permitted (MO_UNALN).
Richard Henderson85aa8082016-07-14 12:43:06 -0700342 * - an alignment to the size of an access (MO_ALIGN);
343 * - an alignment to a specified size, which may be more or less than
344 * the access size (MO_ALIGN_x where 'x' is a size in bytes);
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300345 */
346 MO_ASHIFT = 4,
347 MO_AMASK = 7 << MO_ASHIFT,
Richard Hendersondfb36302015-05-13 11:25:20 -0700348#ifdef ALIGNED_ONLY
349 MO_ALIGN = 0,
350 MO_UNALN = MO_AMASK,
351#else
352 MO_ALIGN = MO_AMASK,
353 MO_UNALN = 0,
354#endif
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300355 MO_ALIGN_2 = 1 << MO_ASHIFT,
356 MO_ALIGN_4 = 2 << MO_ASHIFT,
357 MO_ALIGN_8 = 3 << MO_ASHIFT,
358 MO_ALIGN_16 = 4 << MO_ASHIFT,
359 MO_ALIGN_32 = 5 << MO_ASHIFT,
360 MO_ALIGN_64 = 6 << MO_ASHIFT,
Richard Hendersondfb36302015-05-13 11:25:20 -0700361
Richard Henderson6c5f4ea2013-09-03 13:52:19 -0700362 /* Combinations of the above, for ease of use. */
363 MO_UB = MO_8,
364 MO_UW = MO_16,
365 MO_UL = MO_32,
366 MO_SB = MO_SIGN | MO_8,
367 MO_SW = MO_SIGN | MO_16,
368 MO_SL = MO_SIGN | MO_32,
369 MO_Q = MO_64,
370
371 MO_LEUW = MO_LE | MO_UW,
372 MO_LEUL = MO_LE | MO_UL,
373 MO_LESW = MO_LE | MO_SW,
374 MO_LESL = MO_LE | MO_SL,
375 MO_LEQ = MO_LE | MO_Q,
376
377 MO_BEUW = MO_BE | MO_UW,
378 MO_BEUL = MO_BE | MO_UL,
379 MO_BESW = MO_BE | MO_SW,
380 MO_BESL = MO_BE | MO_SL,
381 MO_BEQ = MO_BE | MO_Q,
382
383 MO_TEUW = MO_TE | MO_UW,
384 MO_TEUL = MO_TE | MO_UL,
385 MO_TESW = MO_TE | MO_SW,
386 MO_TESL = MO_TE | MO_SL,
387 MO_TEQ = MO_TE | MO_Q,
388
389 MO_SSIZE = MO_SIZE | MO_SIGN,
390} TCGMemOp;
391
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300392/**
393 * get_alignment_bits
394 * @memop: TCGMemOp value
395 *
396 * Extract the alignment size from the memop.
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300397 */
Richard Henderson85aa8082016-07-14 12:43:06 -0700398static inline unsigned get_alignment_bits(TCGMemOp memop)
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300399{
Richard Henderson85aa8082016-07-14 12:43:06 -0700400 unsigned a = memop & MO_AMASK;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300401
402 if (a == MO_UNALN) {
Richard Henderson85aa8082016-07-14 12:43:06 -0700403 /* No alignment required. */
404 a = 0;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300405 } else if (a == MO_ALIGN) {
Richard Henderson85aa8082016-07-14 12:43:06 -0700406 /* A natural alignment requirement. */
407 a = memop & MO_SIZE;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300408 } else {
Richard Henderson85aa8082016-07-14 12:43:06 -0700409 /* A specific alignment requirement. */
410 a = a >> MO_ASHIFT;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300411 }
412#if defined(CONFIG_SOFTMMU)
413 /* The requested alignment cannot overlap the TLB flags. */
Richard Henderson85aa8082016-07-14 12:43:06 -0700414 tcg_debug_assert((TLB_FLAGS_MASK & ((1 << a) - 1)) == 0);
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300415#endif
Richard Henderson85aa8082016-07-14 12:43:06 -0700416 return a;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300417}
418
bellardc896fe22008-02-01 10:05:41 +0000419typedef tcg_target_ulong TCGArg;
420
Peter Maydella40d4702016-10-21 17:38:42 +0100421/* Define type and accessor macros for TCG variables.
422
423 TCG variables are the inputs and outputs of TCG ops, as described
424 in tcg/README. Target CPU front-end code uses these types to deal
425 with TCG variables as it emits TCG code via the tcg_gen_* functions.
426 They come in several flavours:
427 * TCGv_i32 : 32 bit integer type
428 * TCGv_i64 : 64 bit integer type
429 * TCGv_ptr : a host pointer type
Richard Hendersond2fd7452017-09-14 13:53:46 -0700430 * TCGv_vec : a host vector type; the exact size is not exposed
431 to the CPU front-end code.
Peter Maydella40d4702016-10-21 17:38:42 +0100432 * TCGv : an integer type the same size as target_ulong
433 (an alias for either TCGv_i32 or TCGv_i64)
434 The compiler's type checking will complain if you mix them
435 up and pass the wrong sized TCGv to a function.
436
437 Users of tcg_gen_* don't need to know about any of the internal
438 details of these, and should treat them as opaque types.
439 You won't be able to look inside them in a debugger either.
440
441 Internal implementation details follow:
442
443 Note that there is no definition of the structs TCGv_i32_d etc anywhere.
444 This is deliberate, because the values we store in variables of type
445 TCGv_i32 are not really pointers-to-structures. They're just small
446 integers, but keeping them in pointer types like this means that the
447 compiler will complain if you accidentally pass a TCGv_i32 to a
448 function which takes a TCGv_i64, and so on. Only the internals of
Richard Hendersondc41aa72017-10-20 00:30:24 -0700449 TCG need to care about the actual contents of the types. */
pbrookac56dd42008-02-03 19:56:33 +0000450
Richard Hendersonb6c73a62014-09-16 09:51:46 -0700451typedef struct TCGv_i32_d *TCGv_i32;
452typedef struct TCGv_i64_d *TCGv_i64;
453typedef struct TCGv_ptr_d *TCGv_ptr;
Richard Hendersond2fd7452017-09-14 13:53:46 -0700454typedef struct TCGv_vec_d *TCGv_vec;
LluĂ­s Vilanova1bcea732016-02-25 17:43:15 +0100455typedef TCGv_ptr TCGv_env;
LluĂ­s Vilanova5d4e1a12016-02-25 17:43:21 +0100456#if TARGET_LONG_BITS == 32
457#define TCGv TCGv_i32
458#elif TARGET_LONG_BITS == 64
459#define TCGv TCGv_i64
460#else
461#error Unhandled TARGET_LONG_BITS value
462#endif
pbrookac56dd42008-02-03 19:56:33 +0000463
bellardc896fe22008-02-01 10:05:41 +0000464/* call flags */
Aurelien Jarno78505272012-10-09 21:53:08 +0200465/* Helper does not read globals (either directly or through an exception). It
466 implies TCG_CALL_NO_WRITE_GLOBALS. */
Richard Henderson3b503522018-11-26 10:37:34 -0800467#define TCG_CALL_NO_READ_GLOBALS 0x0001
Aurelien Jarno78505272012-10-09 21:53:08 +0200468/* Helper does not write globals */
Richard Henderson3b503522018-11-26 10:37:34 -0800469#define TCG_CALL_NO_WRITE_GLOBALS 0x0002
Aurelien Jarno78505272012-10-09 21:53:08 +0200470/* Helper can be safely suppressed if the return value is not used. */
Richard Henderson3b503522018-11-26 10:37:34 -0800471#define TCG_CALL_NO_SIDE_EFFECTS 0x0004
Richard Henderson15d74092018-11-26 11:32:38 -0800472/* Helper is QEMU_NORETURN. */
473#define TCG_CALL_NO_RETURN 0x0008
Aurelien Jarno78505272012-10-09 21:53:08 +0200474
475/* convenience version of most used call flags */
476#define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS
477#define TCG_CALL_NO_WG TCG_CALL_NO_WRITE_GLOBALS
478#define TCG_CALL_NO_SE TCG_CALL_NO_SIDE_EFFECTS
479#define TCG_CALL_NO_RWG_SE (TCG_CALL_NO_RWG | TCG_CALL_NO_SE)
480#define TCG_CALL_NO_WG_SE (TCG_CALL_NO_WG | TCG_CALL_NO_SE)
481
Richard Hendersone89b28a2017-10-20 12:08:19 -0700482/* Used to align parameters. See the comment before tcgv_i32_temp. */
483#define TCG_CALL_DUMMY_ARG ((TCGArg)0)
bellard39cf05d2008-05-22 14:59:57 +0000484
Stefan Weila93cf9d2012-11-02 08:29:53 +0100485/* Conditions. Note that these are laid out for easy manipulation by
486 the functions below:
Richard Henderson0aed2572012-09-24 14:21:40 -0700487 bit 0 is used for inverting;
488 bit 1 is signed,
489 bit 2 is unsigned,
490 bit 3 is used with bit 0 for swapping signed/unsigned. */
bellardc896fe22008-02-01 10:05:41 +0000491typedef enum {
Richard Henderson0aed2572012-09-24 14:21:40 -0700492 /* non-signed */
493 TCG_COND_NEVER = 0 | 0 | 0 | 0,
494 TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
495 TCG_COND_EQ = 8 | 0 | 0 | 0,
496 TCG_COND_NE = 8 | 0 | 0 | 1,
497 /* signed */
498 TCG_COND_LT = 0 | 0 | 2 | 0,
499 TCG_COND_GE = 0 | 0 | 2 | 1,
500 TCG_COND_LE = 8 | 0 | 2 | 0,
501 TCG_COND_GT = 8 | 0 | 2 | 1,
bellardc896fe22008-02-01 10:05:41 +0000502 /* unsigned */
Richard Henderson0aed2572012-09-24 14:21:40 -0700503 TCG_COND_LTU = 0 | 4 | 0 | 0,
504 TCG_COND_GEU = 0 | 4 | 0 | 1,
505 TCG_COND_LEU = 8 | 4 | 0 | 0,
506 TCG_COND_GTU = 8 | 4 | 0 | 1,
bellardc896fe22008-02-01 10:05:41 +0000507} TCGCond;
508
Richard Henderson1c086222010-02-09 12:33:09 -0800509/* Invert the sense of the comparison. */
Richard Henderson401d4662010-01-07 10:15:20 -0800510static inline TCGCond tcg_invert_cond(TCGCond c)
511{
512 return (TCGCond)(c ^ 1);
513}
514
Richard Henderson1c086222010-02-09 12:33:09 -0800515/* Swap the operands in a comparison. */
516static inline TCGCond tcg_swap_cond(TCGCond c)
517{
Richard Henderson0aed2572012-09-24 14:21:40 -0700518 return c & 6 ? (TCGCond)(c ^ 9) : c;
Richard Henderson1c086222010-02-09 12:33:09 -0800519}
520
Richard Hendersond1e321b2012-09-24 14:21:41 -0700521/* Create an "unsigned" version of a "signed" comparison. */
Richard Hendersonff44c2f2009-12-27 09:09:41 +0000522static inline TCGCond tcg_unsigned_cond(TCGCond c)
523{
Richard Henderson0aed2572012-09-24 14:21:40 -0700524 return c & 2 ? (TCGCond)(c ^ 6) : c;
Richard Hendersonff44c2f2009-12-27 09:09:41 +0000525}
526
Richard Henderson923ed172017-11-20 14:47:02 +0100527/* Create a "signed" version of an "unsigned" comparison. */
528static inline TCGCond tcg_signed_cond(TCGCond c)
529{
530 return c & 4 ? (TCGCond)(c ^ 6) : c;
531}
532
Richard Hendersond1e321b2012-09-24 14:21:41 -0700533/* Must a comparison be considered unsigned? */
Richard Hendersonbcc66562012-09-24 14:21:39 -0700534static inline bool is_unsigned_cond(TCGCond c)
535{
Richard Henderson0aed2572012-09-24 14:21:40 -0700536 return (c & 4) != 0;
Richard Hendersonbcc66562012-09-24 14:21:39 -0700537}
538
Richard Hendersond1e321b2012-09-24 14:21:41 -0700539/* Create a "high" version of a double-word comparison.
540 This removes equality from a LTE or GTE comparison. */
541static inline TCGCond tcg_high_cond(TCGCond c)
542{
543 switch (c) {
544 case TCG_COND_GE:
545 case TCG_COND_LE:
546 case TCG_COND_GEU:
547 case TCG_COND_LEU:
548 return (TCGCond)(c ^ 8);
549 default:
550 return c;
551 }
552}
553
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400554typedef enum TCGTempVal {
555 TEMP_VAL_DEAD,
556 TEMP_VAL_REG,
557 TEMP_VAL_MEM,
558 TEMP_VAL_CONST,
559} TCGTempVal;
bellardc896fe22008-02-01 10:05:41 +0000560
bellardc896fe22008-02-01 10:05:41 +0000561typedef struct TCGTemp {
Richard Hendersonb6638662013-09-18 14:54:45 -0700562 TCGReg reg:8;
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400563 TCGTempVal val_type:8;
564 TCGType base_type:8;
565 TCGType type:8;
bellardc896fe22008-02-01 10:05:41 +0000566 unsigned int fixed_reg:1;
Richard Hendersonb3915db2013-09-19 10:36:18 -0700567 unsigned int indirect_reg:1;
568 unsigned int indirect_base:1;
bellardc896fe22008-02-01 10:05:41 +0000569 unsigned int mem_coherent:1;
570 unsigned int mem_allocated:1;
Richard Hendersonfa477d22016-11-02 11:20:15 -0600571 /* If true, the temp is saved across both basic blocks and
572 translation blocks. */
573 unsigned int temp_global:1;
574 /* If true, the temp is saved across basic blocks but dead
575 at the end of translation blocks. If false, the temp is
576 dead at the end of basic blocks. */
577 unsigned int temp_local:1;
578 unsigned int temp_allocated:1;
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400579
580 tcg_target_long val;
Richard Hendersonb3a62932013-09-18 14:12:53 -0700581 struct TCGTemp *mem_base;
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400582 intptr_t mem_offset;
bellardc896fe22008-02-01 10:05:41 +0000583 const char *name;
Richard Hendersonb83eabe2016-11-01 15:56:04 -0600584
585 /* Pass-specific information that can be stored for a temporary.
586 One word worth of integer data, and one pointer to data
587 allocated separately. */
588 uintptr_t state;
589 void *state_ptr;
bellardc896fe22008-02-01 10:05:41 +0000590} TCGTemp;
591
bellardc896fe22008-02-01 10:05:41 +0000592typedef struct TCGContext TCGContext;
593
Richard Henderson0ec9eab2013-09-19 12:16:45 -0700594typedef struct TCGTempSet {
595 unsigned long l[BITS_TO_LONGS(TCG_MAX_TEMPS)];
596} TCGTempSet;
597
Richard Hendersona1b3c482016-06-22 15:46:09 -0700598/* While we limit helpers to 6 arguments, for 32-bit hosts, with padding,
599 this imples a max of 6*2 (64-bit in) + 2 (64-bit out) = 14 operands.
600 There are never more than 2 outputs, which means that we can store all
601 dead + sync data within 16 bits. */
602#define DEAD_ARG 4
603#define SYNC_ARG 1
604typedef uint16_t TCGLifeData;
605
Richard Henderson75e8b9b2016-12-08 10:52:57 -0800606/* The layout here is designed to avoid a bitfield crossing of
607 a 32-bit boundary, which would cause GCC to add extra padding. */
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700608typedef struct TCGOp {
Richard Hendersonbee158c2016-06-22 20:43:29 -0700609 TCGOpcode opc : 8; /* 8 */
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700610
Richard Hendersoncd9090a2017-11-14 13:02:51 +0100611 /* Parameters for this opcode. See below. */
612 unsigned param1 : 4; /* 12 */
613 unsigned param2 : 4; /* 16 */
Richard Hendersonbee158c2016-06-22 20:43:29 -0700614
Richard Hendersonbee158c2016-06-22 20:43:29 -0700615 /* Lifetime data of the operands. */
Richard Henderson15fa08f2017-11-02 15:19:14 +0100616 unsigned life : 16; /* 32 */
617
618 /* Next and previous opcodes. */
619 QTAILQ_ENTRY(TCGOp) link;
Richard Henderson75e8b9b2016-12-08 10:52:57 -0800620
621 /* Arguments for the opcode. */
622 TCGArg args[MAX_OPC_PARAM];
Richard Henderson69e37062018-11-27 07:44:51 -0800623
624 /* Register preferences for the output(s). */
625 TCGRegSet output_pref[2];
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700626} TCGOp;
627
Richard Hendersoncd9090a2017-11-14 13:02:51 +0100628#define TCGOP_CALLI(X) (X)->param1
629#define TCGOP_CALLO(X) (X)->param2
630
Richard Hendersond2fd7452017-09-14 13:53:46 -0700631#define TCGOP_VECL(X) (X)->param1
632#define TCGOP_VECE(X) (X)->param2
633
Richard Hendersondcb8e752016-06-22 19:42:31 -0700634/* Make sure operands fit in the bitfields above. */
635QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8));
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700636
Emilio G. Cotac3fac112017-07-05 19:35:06 -0400637typedef struct TCGProfile {
Emilio G. Cota72fd2ef2018-10-10 10:48:53 -0400638 int64_t cpu_exec_time;
Emilio G. Cotac3fac112017-07-05 19:35:06 -0400639 int64_t tb_count1;
640 int64_t tb_count;
641 int64_t op_count; /* total insn count */
642 int op_count_max; /* max insn per TB */
Emilio G. Cotac3fac112017-07-05 19:35:06 -0400643 int temp_count_max;
Emilio G. Cotadd1d7da2018-10-10 10:48:52 -0400644 int64_t temp_count;
Emilio G. Cotac3fac112017-07-05 19:35:06 -0400645 int64_t del_op_count;
646 int64_t code_in_len;
647 int64_t code_out_len;
648 int64_t search_out_len;
649 int64_t interm_time;
650 int64_t code_time;
651 int64_t la_time;
652 int64_t opt_time;
653 int64_t restore_count;
654 int64_t restore_time;
655 int64_t table_op_count[NB_OPS];
656} TCGProfile;
657
bellardc896fe22008-02-01 10:05:41 +0000658struct TCGContext {
659 uint8_t *pool_cur, *pool_end;
Kirill Batuzov40552992012-03-02 13:22:17 +0400660 TCGPool *pool_first, *pool_current, *pool_first_large;
bellardc896fe22008-02-01 10:05:41 +0000661 int nb_labels;
bellardc896fe22008-02-01 10:05:41 +0000662 int nb_globals;
663 int nb_temps;
Richard Henderson5a184072016-06-23 20:34:33 -0700664 int nb_indirects;
Richard Hendersonabebf922018-05-08 19:18:59 +0000665 int nb_ops;
bellardc896fe22008-02-01 10:05:41 +0000666
667 /* goto_tb support */
Richard Henderson1813e172014-03-28 12:56:22 -0700668 tcg_insn_unit *code_buf;
Sergey Fedorovf3091012016-04-10 23:35:45 +0300669 uint16_t *tb_jmp_reset_offset; /* tb->jmp_reset_offset */
Richard Hendersona8583392017-07-31 22:02:31 -0700670 uintptr_t *tb_jmp_insn_offset; /* tb->jmp_target_arg if direct_jump */
671 uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_arg if !direct_jump */
bellardc896fe22008-02-01 10:05:41 +0000672
bellardc896fe22008-02-01 10:05:41 +0000673 TCGRegSet reserved_regs;
Emilio G. Cotae82d5a22017-07-16 15:13:52 -0400674 uint32_t tb_cflags; /* cflags of the current TB */
Richard Hendersone2c6d1b2013-08-20 15:12:31 -0700675 intptr_t current_frame_offset;
676 intptr_t frame_start;
677 intptr_t frame_end;
Richard Hendersonb3a62932013-09-18 14:12:53 -0700678 TCGTemp *frame_temp;
bellardc896fe22008-02-01 10:05:41 +0000679
Richard Henderson1813e172014-03-28 12:56:22 -0700680 tcg_insn_unit *code_ptr;
bellardc896fe22008-02-01 10:05:41 +0000681
bellarda23a9ec2008-05-23 09:52:20 +0000682#ifdef CONFIG_PROFILER
Emilio G. Cotac3fac112017-07-05 19:35:06 -0400683 TCGProfile prof;
bellarda23a9ec2008-05-23 09:52:20 +0000684#endif
Peter Maydell27bfd832011-03-06 21:39:53 +0000685
686#ifdef CONFIG_DEBUG_TCG
687 int temps_in_use;
Richard Henderson0a209d42012-09-21 17:18:16 -0700688 int goto_tb_issue_mask;
Peter Maydell27bfd832011-03-06 21:39:53 +0000689#endif
Yeongkyoon Leeb76f0d82012-10-31 16:04:25 +0900690
Richard Henderson1813e172014-03-28 12:56:22 -0700691 /* Code generation. Note that we specifically do not use tcg_insn_unit
692 here, because there's too much arithmetic throughout that relies
693 on addition and subtraction working on bytes. Rely on the GCC
694 extension that allows arithmetic on void*. */
Richard Henderson1813e172014-03-28 12:56:22 -0700695 void *code_gen_prologue;
Emilio G. Cotacedbcb02017-04-26 23:29:14 -0400696 void *code_gen_epilogue;
Richard Henderson1813e172014-03-28 12:56:22 -0700697 void *code_gen_buffer;
Evgeny Voevodin0b0d3322013-02-01 01:47:22 +0700698 size_t code_gen_buffer_size;
Richard Henderson1813e172014-03-28 12:56:22 -0700699 void *code_gen_ptr;
Richard Henderson57a26942017-07-30 13:13:21 -0700700 void *data_gen_ptr;
Evgeny Voevodin0b0d3322013-02-01 01:47:22 +0700701
Richard Hendersonb125f9d2015-09-22 13:01:15 -0700702 /* Threshold to flush the translated code buffer. */
703 void *code_gen_highwater;
704
Emilio G. Cota128ed222017-08-01 15:11:12 -0400705 size_t tb_phys_invalidate_count;
706
LluĂ­s Vilanova7c255042016-06-09 19:31:41 +0200707 /* Track which vCPU triggers events */
708 CPUState *cpu; /* *_trans */
LluĂ­s Vilanova7c255042016-06-09 19:31:41 +0200709
Richard Henderson659ef5c2017-07-30 12:30:41 -0700710 /* These structures are private to tcg-target.inc.c. */
711#ifdef TCG_TARGET_NEED_LDST_LABELS
Paolo Bonzinib58deb32018-12-06 11:58:10 +0100712 QSIMPLEQ_HEAD(, TCGLabelQemuLdst) ldst_labels;
Richard Henderson659ef5c2017-07-30 12:30:41 -0700713#endif
Richard Henderson57a26942017-07-30 13:13:21 -0700714#ifdef TCG_TARGET_NEED_POOL_LABELS
715 struct TCGLabelPoolData *pool_labels;
716#endif
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700717
Emilio G. Cota26689782017-07-04 13:54:21 -0400718 TCGLabel *exitreq_label;
719
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700720 TCGTempSet free_temps[TCG_TYPE_COUNT * 2];
721 TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
722
Paolo Bonzinieae3eb32018-12-06 13:10:34 +0100723 QTAILQ_HEAD(, TCGOp) ops, free_ops;
Richard Henderson15fa08f2017-11-02 15:19:14 +0100724
Richard Hendersonf8b2f202013-09-18 15:21:56 -0700725 /* Tells which temporary holds a given register.
726 It does not take into account fixed registers */
727 TCGTemp *reg_to_temp[TCG_TARGET_NB_REGS];
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700728
Richard Hendersonfca8a502015-09-01 19:11:45 -0700729 uint16_t gen_insn_end_off[TCG_MAX_INSNS];
730 target_ulong gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
bellardc896fe22008-02-01 10:05:41 +0000731};
732
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400733extern TCGContext tcg_init_ctx;
Emilio G. Cota3468b592017-07-19 18:57:58 -0400734extern __thread TCGContext *tcg_ctx;
Richard Henderson1c2adb92017-10-10 14:34:37 -0700735extern TCGv_env cpu_env;
bellardc896fe22008-02-01 10:05:41 +0000736
Richard Henderson1807f4c2017-06-20 12:24:57 -0700737static inline size_t temp_idx(TCGTemp *ts)
738{
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400739 ptrdiff_t n = ts - tcg_ctx->temps;
740 tcg_debug_assert(n >= 0 && n < tcg_ctx->nb_temps);
Richard Henderson1807f4c2017-06-20 12:24:57 -0700741 return n;
742}
743
744static inline TCGArg temp_arg(TCGTemp *ts)
745{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700746 return (uintptr_t)ts;
Richard Henderson1807f4c2017-06-20 12:24:57 -0700747}
748
Richard Henderson43439132017-06-19 23:18:10 -0700749static inline TCGTemp *arg_temp(TCGArg a)
750{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700751 return (TCGTemp *)(uintptr_t)a;
Richard Henderson43439132017-06-19 23:18:10 -0700752}
753
Richard Hendersone89b28a2017-10-20 12:08:19 -0700754/* Using the offset of a temporary, relative to TCGContext, rather than
755 its index means that we don't use 0. That leaves offset 0 free for
756 a NULL representation without having to leave index 0 unused. */
757static inline TCGTemp *tcgv_i32_temp(TCGv_i32 v)
Richard Henderson63490392017-06-20 13:43:15 -0700758{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700759 uintptr_t o = (uintptr_t)v;
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400760 TCGTemp *t = (void *)tcg_ctx + o;
Richard Hendersone89b28a2017-10-20 12:08:19 -0700761 tcg_debug_assert(offsetof(TCGContext, temps[temp_idx(t)]) == o);
762 return t;
Richard Henderson63490392017-06-20 13:43:15 -0700763}
764
Richard Hendersone89b28a2017-10-20 12:08:19 -0700765static inline TCGTemp *tcgv_i64_temp(TCGv_i64 v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700766{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700767 return tcgv_i32_temp((TCGv_i32)v);
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700768}
769
Richard Hendersone89b28a2017-10-20 12:08:19 -0700770static inline TCGTemp *tcgv_ptr_temp(TCGv_ptr v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700771{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700772 return tcgv_i32_temp((TCGv_i32)v);
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700773}
774
Richard Hendersond2fd7452017-09-14 13:53:46 -0700775static inline TCGTemp *tcgv_vec_temp(TCGv_vec v)
776{
777 return tcgv_i32_temp((TCGv_i32)v);
778}
779
Richard Hendersone89b28a2017-10-20 12:08:19 -0700780static inline TCGArg tcgv_i32_arg(TCGv_i32 v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700781{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700782 return temp_arg(tcgv_i32_temp(v));
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700783}
784
Richard Hendersone89b28a2017-10-20 12:08:19 -0700785static inline TCGArg tcgv_i64_arg(TCGv_i64 v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700786{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700787 return temp_arg(tcgv_i64_temp(v));
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700788}
789
Richard Hendersone89b28a2017-10-20 12:08:19 -0700790static inline TCGArg tcgv_ptr_arg(TCGv_ptr v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700791{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700792 return temp_arg(tcgv_ptr_temp(v));
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700793}
794
Richard Hendersond2fd7452017-09-14 13:53:46 -0700795static inline TCGArg tcgv_vec_arg(TCGv_vec v)
796{
797 return temp_arg(tcgv_vec_temp(v));
798}
799
Richard Henderson085272b2017-10-20 00:05:45 -0700800static inline TCGv_i32 temp_tcgv_i32(TCGTemp *t)
801{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700802 (void)temp_idx(t); /* trigger embedded assert */
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400803 return (TCGv_i32)((void *)t - (void *)tcg_ctx);
Richard Henderson085272b2017-10-20 00:05:45 -0700804}
805
806static inline TCGv_i64 temp_tcgv_i64(TCGTemp *t)
807{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700808 return (TCGv_i64)temp_tcgv_i32(t);
Richard Henderson085272b2017-10-20 00:05:45 -0700809}
810
811static inline TCGv_ptr temp_tcgv_ptr(TCGTemp *t)
812{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700813 return (TCGv_ptr)temp_tcgv_i32(t);
Richard Henderson085272b2017-10-20 00:05:45 -0700814}
815
Richard Hendersond2fd7452017-09-14 13:53:46 -0700816static inline TCGv_vec temp_tcgv_vec(TCGTemp *t)
817{
818 return (TCGv_vec)temp_tcgv_i32(t);
819}
820
Richard Hendersondc41aa72017-10-20 00:30:24 -0700821#if TCG_TARGET_REG_BITS == 32
822static inline TCGv_i32 TCGV_LOW(TCGv_i64 t)
823{
824 return temp_tcgv_i32(tcgv_i64_temp(t));
825}
826
827static inline TCGv_i32 TCGV_HIGH(TCGv_i64 t)
828{
829 return temp_tcgv_i32(tcgv_i64_temp(t) + 1);
830}
831#endif
832
Richard Henderson15fa08f2017-11-02 15:19:14 +0100833static inline void tcg_set_insn_param(TCGOp *op, int arg, TCGArg v)
Edgar E. Iglesias1d414782016-05-12 13:22:26 +0100834{
Richard Henderson15fa08f2017-11-02 15:19:14 +0100835 op->args[arg] = v;
Edgar E. Iglesias1d414782016-05-12 13:22:26 +0100836}
837
Richard Henderson9743cd52018-04-10 13:02:26 +0100838static inline void tcg_set_insn_start_param(TCGOp *op, int arg, target_ulong v)
839{
840#if TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
841 tcg_set_insn_param(op, arg, v);
842#else
843 tcg_set_insn_param(op, arg * 2, v);
844 tcg_set_insn_param(op, arg * 2 + 1, v >> 32);
845#endif
846}
847
Richard Henderson15fa08f2017-11-02 15:19:14 +0100848/* The last op that was emitted. */
849static inline TCGOp *tcg_last_op(void)
Richard Hendersonfe700ad2014-03-30 15:36:56 -0700850{
Paolo Bonzinieae3eb32018-12-06 13:10:34 +0100851 return QTAILQ_LAST(&tcg_ctx->ops);
Richard Hendersonfe700ad2014-03-30 15:36:56 -0700852}
853
854/* Test for whether to terminate the TB for using too many opcodes. */
855static inline bool tcg_op_buf_full(void)
856{
Richard Hendersonabebf922018-05-08 19:18:59 +0000857 /* This is not a hard limit, it merely stops translation when
858 * we have produced "enough" opcodes. We want to limit TB size
859 * such that a RISC host can reasonably use a 16-bit signed
Richard Henderson9f754622018-06-14 19:57:03 -1000860 * branch within the TB. We also need to be mindful of the
861 * 16-bit unsigned offsets, TranslationBlock.jmp_reset_offset[]
862 * and TCGContext.gen_insn_end_off[].
Richard Hendersonabebf922018-05-08 19:18:59 +0000863 */
Richard Henderson9f754622018-06-14 19:57:03 -1000864 return tcg_ctx->nb_ops >= 4000;
Richard Hendersonfe700ad2014-03-30 15:36:56 -0700865}
866
bellardc896fe22008-02-01 10:05:41 +0000867/* pool based memory allocation */
868
Emilio G. Cota0ac20312017-08-04 23:46:31 -0400869/* user-mode: mmap_lock must be held for tcg_malloc_internal. */
bellardc896fe22008-02-01 10:05:41 +0000870void *tcg_malloc_internal(TCGContext *s, int size);
871void tcg_pool_reset(TCGContext *s);
Emilio G. Cota6e3b2bf2017-06-06 19:12:25 -0400872TranslationBlock *tcg_tb_alloc(TCGContext *s);
bellardc896fe22008-02-01 10:05:41 +0000873
Emilio G. Cotae8feb962017-07-07 19:24:20 -0400874void tcg_region_init(void);
875void tcg_region_reset_all(void);
876
877size_t tcg_code_size(void);
878size_t tcg_code_capacity(void);
879
Emilio G. Cotabe2cdc52017-07-26 16:58:05 -0400880void tcg_tb_insert(TranslationBlock *tb);
881void tcg_tb_remove(TranslationBlock *tb);
Emilio G. Cota128ed222017-08-01 15:11:12 -0400882size_t tcg_tb_phys_invalidate_count(void);
Emilio G. Cotabe2cdc52017-07-26 16:58:05 -0400883TranslationBlock *tcg_tb_lookup(uintptr_t tc_ptr);
884void tcg_tb_foreach(GTraverseFunc func, gpointer user_data);
885size_t tcg_nb_tbs(void);
886
Emilio G. Cota0ac20312017-08-04 23:46:31 -0400887/* user-mode: Called with mmap_lock held. */
bellardc896fe22008-02-01 10:05:41 +0000888static inline void *tcg_malloc(int size)
889{
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400890 TCGContext *s = tcg_ctx;
bellardc896fe22008-02-01 10:05:41 +0000891 uint8_t *ptr, *ptr_end;
Richard Henderson13aaef62017-08-02 14:50:04 -0700892
893 /* ??? This is a weak placeholder for minimum malloc alignment. */
894 size = QEMU_ALIGN_UP(size, 8);
895
bellardc896fe22008-02-01 10:05:41 +0000896 ptr = s->pool_cur;
897 ptr_end = ptr + size;
898 if (unlikely(ptr_end > s->pool_end)) {
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400899 return tcg_malloc_internal(tcg_ctx, size);
bellardc896fe22008-02-01 10:05:41 +0000900 } else {
901 s->pool_cur = ptr_end;
902 return ptr;
903 }
904}
905
906void tcg_context_init(TCGContext *s);
Emilio G. Cota3468b592017-07-19 18:57:58 -0400907void tcg_register_thread(void);
Richard Henderson9002ec72010-05-06 08:50:41 -0700908void tcg_prologue_init(TCGContext *s);
bellardc896fe22008-02-01 10:05:41 +0000909void tcg_func_start(TCGContext *s);
910
Alex Bennée5bd2ec32016-03-15 14:30:16 +0000911int tcg_gen_code(TCGContext *s, TranslationBlock *tb);
bellardc896fe22008-02-01 10:05:41 +0000912
Richard Hendersonb6638662013-09-18 14:54:45 -0700913void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
pbrooka7812ae2008-11-17 14:43:54 +0000914
Richard Henderson085272b2017-10-20 00:05:45 -0700915TCGTemp *tcg_global_mem_new_internal(TCGType, TCGv_ptr,
916 intptr_t, const char *);
Richard Henderson5bfa8032018-02-22 18:17:57 -0800917TCGTemp *tcg_temp_new_internal(TCGType, bool);
918void tcg_temp_free_internal(TCGTemp *);
Richard Hendersond2fd7452017-09-14 13:53:46 -0700919TCGv_vec tcg_temp_new_vec(TCGType type);
920TCGv_vec tcg_temp_new_vec_matching(TCGv_vec match);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700921
Richard Henderson5bfa8032018-02-22 18:17:57 -0800922static inline void tcg_temp_free_i32(TCGv_i32 arg)
923{
924 tcg_temp_free_internal(tcgv_i32_temp(arg));
925}
926
927static inline void tcg_temp_free_i64(TCGv_i64 arg)
928{
929 tcg_temp_free_internal(tcgv_i64_temp(arg));
930}
931
932static inline void tcg_temp_free_ptr(TCGv_ptr arg)
933{
934 tcg_temp_free_internal(tcgv_ptr_temp(arg));
935}
936
937static inline void tcg_temp_free_vec(TCGv_vec arg)
938{
939 tcg_temp_free_internal(tcgv_vec_temp(arg));
940}
Richard Hendersone1ccc052013-09-18 12:53:09 -0700941
Richard Hendersone1ccc052013-09-18 12:53:09 -0700942static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
943 const char *name)
944{
Richard Henderson085272b2017-10-20 00:05:45 -0700945 TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
946 return temp_tcgv_i32(t);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700947}
948
pbrooka7812ae2008-11-17 14:43:54 +0000949static inline TCGv_i32 tcg_temp_new_i32(void)
bellard641d5fb2008-05-25 17:24:00 +0000950{
Richard Henderson5bfa8032018-02-22 18:17:57 -0800951 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, false);
952 return temp_tcgv_i32(t);
bellard641d5fb2008-05-25 17:24:00 +0000953}
Richard Hendersone1ccc052013-09-18 12:53:09 -0700954
pbrooka7812ae2008-11-17 14:43:54 +0000955static inline TCGv_i32 tcg_temp_local_new_i32(void)
bellard641d5fb2008-05-25 17:24:00 +0000956{
Richard Henderson5bfa8032018-02-22 18:17:57 -0800957 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I32, true);
958 return temp_tcgv_i32(t);
bellard641d5fb2008-05-25 17:24:00 +0000959}
pbrooka7812ae2008-11-17 14:43:54 +0000960
Richard Hendersone1ccc052013-09-18 12:53:09 -0700961static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
962 const char *name)
963{
Richard Henderson085272b2017-10-20 00:05:45 -0700964 TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
965 return temp_tcgv_i64(t);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700966}
967
pbrooka7812ae2008-11-17 14:43:54 +0000968static inline TCGv_i64 tcg_temp_new_i64(void)
969{
Richard Henderson5bfa8032018-02-22 18:17:57 -0800970 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, false);
971 return temp_tcgv_i64(t);
pbrooka7812ae2008-11-17 14:43:54 +0000972}
Richard Hendersone1ccc052013-09-18 12:53:09 -0700973
pbrooka7812ae2008-11-17 14:43:54 +0000974static inline TCGv_i64 tcg_temp_local_new_i64(void)
975{
Richard Henderson5bfa8032018-02-22 18:17:57 -0800976 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I64, true);
977 return temp_tcgv_i64(t);
978}
979
980static inline TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t offset,
981 const char *name)
982{
983 TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_PTR, reg, offset, name);
984 return temp_tcgv_ptr(t);
985}
986
987static inline TCGv_ptr tcg_temp_new_ptr(void)
988{
989 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, false);
990 return temp_tcgv_ptr(t);
991}
992
993static inline TCGv_ptr tcg_temp_local_new_ptr(void)
994{
995 TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_PTR, true);
996 return temp_tcgv_ptr(t);
pbrooka7812ae2008-11-17 14:43:54 +0000997}
pbrooka7812ae2008-11-17 14:43:54 +0000998
Peter Maydell27bfd832011-03-06 21:39:53 +0000999#if defined(CONFIG_DEBUG_TCG)
1000/* If you call tcg_clear_temp_count() at the start of a section of
1001 * code which is not supposed to leak any TCG temporaries, then
1002 * calling tcg_check_temp_count() at the end of the section will
1003 * return 1 if the section did in fact leak a temporary.
1004 */
1005void tcg_clear_temp_count(void);
1006int tcg_check_temp_count(void);
1007#else
1008#define tcg_clear_temp_count() do { } while (0)
1009#define tcg_check_temp_count() 0
1010#endif
1011
Emilio G. Cota72fd2ef2018-10-10 10:48:53 -04001012int64_t tcg_cpu_exec_time(void);
Stefan Weil405cf9f2010-10-22 23:03:31 +02001013void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
Max Filippov246ae242014-11-02 11:04:18 +03001014void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf);
bellardc896fe22008-02-01 10:05:41 +00001015
1016#define TCG_CT_ALIAS 0x80
1017#define TCG_CT_IALIAS 0x40
Richard Henderson82790a82016-11-18 08:35:03 +01001018#define TCG_CT_NEWREG 0x20 /* output requires a new register */
bellardc896fe22008-02-01 10:05:41 +00001019#define TCG_CT_REG 0x01
1020#define TCG_CT_CONST 0x02 /* any constant of register size */
1021
1022typedef struct TCGArgConstraint {
bellard5ff9d6a2008-02-04 00:37:54 +00001023 uint16_t ct;
1024 uint8_t alias_index;
bellardc896fe22008-02-01 10:05:41 +00001025 union {
1026 TCGRegSet regs;
1027 } u;
1028} TCGArgConstraint;
1029
1030#define TCG_MAX_OP_ARGS 16
1031
Richard Henderson8399ad52011-08-17 14:11:45 -07001032/* Bits for TCGOpDef->flags, 8 bits available. */
1033enum {
Richard Hendersonae36a242018-11-27 13:45:08 -08001034 /* Instruction exits the translation block. */
1035 TCG_OPF_BB_EXIT = 0x01,
Richard Henderson8399ad52011-08-17 14:11:45 -07001036 /* Instruction defines the end of a basic block. */
Richard Hendersonae36a242018-11-27 13:45:08 -08001037 TCG_OPF_BB_END = 0x02,
Richard Henderson8399ad52011-08-17 14:11:45 -07001038 /* Instruction clobbers call registers and potentially update globals. */
Richard Hendersonae36a242018-11-27 13:45:08 -08001039 TCG_OPF_CALL_CLOBBER = 0x04,
Aurelien Jarno3d5c5f82012-10-09 21:53:08 +02001040 /* Instruction has side effects: it cannot be removed if its outputs
1041 are not used, and might trigger exceptions. */
Richard Hendersonae36a242018-11-27 13:45:08 -08001042 TCG_OPF_SIDE_EFFECTS = 0x08,
Richard Henderson8399ad52011-08-17 14:11:45 -07001043 /* Instruction operands are 64-bits (otherwise 32-bits). */
Richard Hendersonae36a242018-11-27 13:45:08 -08001044 TCG_OPF_64BIT = 0x10,
Richard Hendersonc1a61f62013-05-02 11:57:40 +01001045 /* Instruction is optional and not implemented by the host, or insn
1046 is generic and should not be implemened by the host. */
Richard Hendersonae36a242018-11-27 13:45:08 -08001047 TCG_OPF_NOT_PRESENT = 0x20,
Richard Hendersond2fd7452017-09-14 13:53:46 -07001048 /* Instruction operands are vectors. */
Richard Hendersonae36a242018-11-27 13:45:08 -08001049 TCG_OPF_VECTOR = 0x40,
Richard Henderson8399ad52011-08-17 14:11:45 -07001050};
bellardc896fe22008-02-01 10:05:41 +00001051
1052typedef struct TCGOpDef {
1053 const char *name;
1054 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
1055 uint8_t flags;
bellardc896fe22008-02-01 10:05:41 +00001056 TCGArgConstraint *args_ct;
1057 int *sorted_args;
Stefan Weilc68aaa12010-02-15 17:17:21 +01001058#if defined(CONFIG_DEBUG_TCG)
1059 int used;
1060#endif
bellardc896fe22008-02-01 10:05:41 +00001061} TCGOpDef;
Richard Henderson8399ad52011-08-17 14:11:45 -07001062
1063extern TCGOpDef tcg_op_defs[];
Stefan Weil2a243742011-09-29 18:33:21 +02001064extern const size_t tcg_op_defs_max;
1065
bellardc896fe22008-02-01 10:05:41 +00001066typedef struct TCGTargetOpDef {
Richard Hendersona9751602010-03-19 11:12:29 -07001067 TCGOpcode op;
bellardc896fe22008-02-01 10:05:41 +00001068 const char *args_ct_str[TCG_MAX_OP_ARGS];
1069} TCGTargetOpDef;
1070
bellardc896fe22008-02-01 10:05:41 +00001071#define tcg_abort() \
1072do {\
1073 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
1074 abort();\
1075} while (0)
1076
Richard Hendersonbe0f34b2017-08-17 07:43:20 -07001077bool tcg_op_supported(TCGOpcode op);
1078
Richard Hendersonae8b75d2017-10-15 13:27:56 -07001079void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
pbrooka7812ae2008-11-17 14:43:54 +00001080
Richard Henderson15fa08f2017-11-02 15:19:14 +01001081TCGOp *tcg_emit_op(TCGOpcode opc);
Richard Henderson0c627cd2014-03-30 16:51:54 -07001082void tcg_op_remove(TCGContext *s, TCGOp *op);
Emilio G. Cotaac1043f2018-12-09 14:37:19 -05001083TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, TCGOpcode opc);
1084TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc);
Richard Henderson5a184072016-06-23 20:34:33 -07001085
Richard Hendersonc45cb8b2014-09-19 13:49:15 -07001086void tcg_optimize(TCGContext *s);
Kirill Batuzov8f2e8c02011-07-07 16:37:12 +04001087
pbrooka7812ae2008-11-17 14:43:54 +00001088TCGv_i32 tcg_const_i32(int32_t val);
1089TCGv_i64 tcg_const_i64(int64_t val);
1090TCGv_i32 tcg_const_local_i32(int32_t val);
1091TCGv_i64 tcg_const_local_i64(int64_t val);
Richard Hendersond2fd7452017-09-14 13:53:46 -07001092TCGv_vec tcg_const_zeros_vec(TCGType);
1093TCGv_vec tcg_const_ones_vec(TCGType);
1094TCGv_vec tcg_const_zeros_vec_matching(TCGv_vec);
1095TCGv_vec tcg_const_ones_vec_matching(TCGv_vec);
pbrooka7812ae2008-11-17 14:43:54 +00001096
Richard Henderson5bfa8032018-02-22 18:17:57 -08001097#if UINTPTR_MAX == UINT32_MAX
1098# define tcg_const_ptr(x) ((TCGv_ptr)tcg_const_i32((intptr_t)(x)))
1099# define tcg_const_local_ptr(x) ((TCGv_ptr)tcg_const_local_i32((intptr_t)(x)))
1100#else
1101# define tcg_const_ptr(x) ((TCGv_ptr)tcg_const_i64((intptr_t)(x)))
1102# define tcg_const_local_ptr(x) ((TCGv_ptr)tcg_const_local_i64((intptr_t)(x)))
1103#endif
1104
Richard Henderson42a268c2015-02-13 12:51:55 -08001105TCGLabel *gen_new_label(void);
1106
1107/**
1108 * label_arg
1109 * @l: label
1110 *
1111 * Encode a label for storage in the TCG opcode stream.
1112 */
1113
1114static inline TCGArg label_arg(TCGLabel *l)
1115{
Richard Henderson51e39722015-02-13 18:51:05 -08001116 return (uintptr_t)l;
Richard Henderson42a268c2015-02-13 12:51:55 -08001117}
1118
1119/**
1120 * arg_label
1121 * @i: value
1122 *
1123 * The opposite of label_arg. Retrieve a label from the
1124 * encoding of the TCG opcode stream.
1125 */
1126
Richard Henderson51e39722015-02-13 18:51:05 -08001127static inline TCGLabel *arg_label(TCGArg i)
Richard Henderson42a268c2015-02-13 12:51:55 -08001128{
Richard Henderson51e39722015-02-13 18:51:05 -08001129 return (TCGLabel *)(uintptr_t)i;
Richard Henderson42a268c2015-02-13 12:51:55 -08001130}
1131
Peter Maydell09800112013-02-22 18:10:00 +00001132/**
Richard Henderson52a1f642014-03-31 14:27:27 -07001133 * tcg_ptr_byte_diff
1134 * @a, @b: addresses to be differenced
1135 *
1136 * There are many places within the TCG backends where we need a byte
1137 * difference between two pointers. While this can be accomplished
1138 * with local casting, it's easy to get wrong -- especially if one is
1139 * concerned with the signedness of the result.
1140 *
1141 * This version relies on GCC's void pointer arithmetic to get the
1142 * correct result.
1143 */
1144
1145static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
1146{
1147 return a - b;
1148}
1149
1150/**
1151 * tcg_pcrel_diff
1152 * @s: the tcg context
1153 * @target: address of the target
1154 *
1155 * Produce a pc-relative difference, from the current code_ptr
1156 * to the destination address.
1157 */
1158
1159static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
1160{
1161 return tcg_ptr_byte_diff(target, s->code_ptr);
1162}
1163
1164/**
1165 * tcg_current_code_size
1166 * @s: the tcg context
1167 *
1168 * Compute the current code size within the translation block.
1169 * This is used to fill in qemu's data structures for goto_tb.
1170 */
1171
1172static inline size_t tcg_current_code_size(TCGContext *s)
1173{
1174 return tcg_ptr_byte_diff(s->code_ptr, s->code_buf);
1175}
1176
Richard Henderson59227d52015-05-12 11:51:44 -07001177/* Combine the TCGMemOp and mmu_idx parameters into a single value. */
1178typedef uint32_t TCGMemOpIdx;
1179
1180/**
1181 * make_memop_idx
1182 * @op: memory operation
1183 * @idx: mmu index
1184 *
1185 * Encode these values into a single parameter.
1186 */
1187static inline TCGMemOpIdx make_memop_idx(TCGMemOp op, unsigned idx)
1188{
1189 tcg_debug_assert(idx <= 15);
1190 return (op << 4) | idx;
1191}
1192
1193/**
1194 * get_memop
1195 * @oi: combined op/idx parameter
1196 *
1197 * Extract the memory operation from the combined value.
1198 */
1199static inline TCGMemOp get_memop(TCGMemOpIdx oi)
1200{
1201 return oi >> 4;
1202}
1203
1204/**
1205 * get_mmuidx
1206 * @oi: combined op/idx parameter
1207 *
1208 * Extract the mmu index from the combined value.
1209 */
1210static inline unsigned get_mmuidx(TCGMemOpIdx oi)
1211{
1212 return oi & 15;
1213}
1214
Richard Henderson52a1f642014-03-31 14:27:27 -07001215/**
Peter Maydell09800112013-02-22 18:10:00 +00001216 * tcg_qemu_tb_exec:
Sergey Fedorov819af242016-04-21 15:58:23 +03001217 * @env: pointer to CPUArchState for the CPU
Peter Maydell09800112013-02-22 18:10:00 +00001218 * @tb_ptr: address of generated code for the TB to execute
1219 *
1220 * Start executing code from a given translation block.
1221 * Where translation blocks have been linked, execution
1222 * may proceed from the given TB into successive ones.
1223 * Control eventually returns only when some action is needed
1224 * from the top-level loop: either control must pass to a TB
1225 * which has not yet been directly linked, or an asynchronous
1226 * event such as an interrupt needs handling.
1227 *
Sergey Fedorov819af242016-04-21 15:58:23 +03001228 * Return: The return value is the value passed to the corresponding
1229 * tcg_gen_exit_tb() at translation time of the last TB attempted to execute.
1230 * The value is either zero or a 4-byte aligned pointer to that TB combined
1231 * with additional information in its two least significant bits. The
1232 * additional information is encoded as follows:
Peter Maydell09800112013-02-22 18:10:00 +00001233 * 0, 1: the link between this TB and the next is via the specified
1234 * TB index (0 or 1). That is, we left the TB via (the equivalent
1235 * of) "goto_tb <index>". The main loop uses this to determine
1236 * how to link the TB just executed to the next.
1237 * 2: we are using instruction counting code generation, and we
1238 * did not start executing this TB because the instruction counter
Sergey Fedorov819af242016-04-21 15:58:23 +03001239 * would hit zero midway through it. In this case the pointer
Peter Maydell09800112013-02-22 18:10:00 +00001240 * returned is the TB we were about to execute, and the caller must
1241 * arrange to execute the remaining count of instructions.
Peter Maydell378df4b2013-02-22 18:10:03 +00001242 * 3: we stopped because the CPU's exit_request flag was set
1243 * (usually meaning that there is an interrupt that needs to be
Sergey Fedorov819af242016-04-21 15:58:23 +03001244 * handled). The pointer returned is the TB we were about to execute
1245 * when we noticed the pending exit request.
Peter Maydell09800112013-02-22 18:10:00 +00001246 *
1247 * If the bottom two bits indicate an exit-via-index then the CPU
1248 * state is correctly synchronised and ready for execution of the next
1249 * TB (and in particular the guest PC is the address to execute next).
1250 * Otherwise, we gave up on execution of this TB before it started, and
Peter Crosthwaitefee068e2015-04-29 00:52:21 -07001251 * the caller must fix up the CPU state by calling the CPU's
Sergey Fedorov819af242016-04-21 15:58:23 +03001252 * synchronize_from_tb() method with the TB pointer we return (falling
Peter Crosthwaitefee068e2015-04-29 00:52:21 -07001253 * back to calling the CPU's set_pc method with tb->pb if no
1254 * synchronize_from_tb() method exists).
Peter Maydell09800112013-02-22 18:10:00 +00001255 *
1256 * Note that TCG targets may use a different definition of tcg_qemu_tb_exec
1257 * to this default (which just calls the prologue.code emitted by
1258 * tcg_target_qemu_prologue()).
1259 */
Richard Henderson07ea28b2018-05-30 18:06:23 -07001260#define TB_EXIT_MASK 3
1261#define TB_EXIT_IDX0 0
1262#define TB_EXIT_IDX1 1
1263#define TB_EXIT_IDXMAX 1
Peter Maydell378df4b2013-02-22 18:10:03 +00001264#define TB_EXIT_REQUESTED 3
Peter Maydell09800112013-02-22 18:10:00 +00001265
Paolo Bonzini5a58e882015-05-19 09:59:34 +02001266#ifdef HAVE_TCG_QEMU_TB_EXEC
1267uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
1268#else
Stefan Weilce285b12011-09-30 21:23:06 +02001269# define tcg_qemu_tb_exec(env, tb_ptr) \
Emilio G. Cotab1311c42017-07-12 17:15:52 -04001270 ((uintptr_t (*)(void *, void *))tcg_ctx->code_gen_prologue)(env, tb_ptr)
bellard932a6902008-05-30 20:56:52 +00001271#endif
Richard Henderson813da622012-03-19 12:25:11 -07001272
1273void tcg_register_jit(void *buf, size_t buf_size);
Yeongkyoon Leeb76f0d82012-10-31 16:04:25 +09001274
Richard Hendersondb432672017-09-15 14:11:45 -07001275#if TCG_TARGET_MAYBE_vec
1276/* Return zero if the tuple (opc, type, vece) is unsupportable;
1277 return > 0 if it is directly supportable;
1278 return < 0 if we must call tcg_expand_vec_op. */
1279int tcg_can_emit_vec_op(TCGOpcode, TCGType, unsigned);
1280#else
1281static inline int tcg_can_emit_vec_op(TCGOpcode o, TCGType t, unsigned ve)
1282{
1283 return 0;
1284}
1285#endif
1286
1287/* Expand the tuple (opc, type, vece) on the given arguments. */
1288void tcg_expand_vec_op(TCGOpcode, TCGType, unsigned, TCGArg, ...);
1289
1290/* Replicate a constant C accoring to the log2 of the element size. */
1291uint64_t dup_const(unsigned vece, uint64_t c);
1292
1293#define dup_const(VECE, C) \
1294 (__builtin_constant_p(VECE) \
1295 ? ( (VECE) == MO_8 ? 0x0101010101010101ull * (uint8_t)(C) \
1296 : (VECE) == MO_16 ? 0x0001000100010001ull * (uint16_t)(C) \
1297 : (VECE) == MO_32 ? 0x0000000100000001ull * (uint32_t)(C) \
1298 : dup_const(VECE, C)) \
1299 : dup_const(VECE, C))
1300
1301
Richard Hendersone58eb532013-08-27 13:13:44 -07001302/*
1303 * Memory helpers that will be used by TCG generated code.
1304 */
1305#ifdef CONFIG_SOFTMMU
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001306/* Value zero-extended to tcg register size. */
1307tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001308 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001309tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001310 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001311tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001312 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001313uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001314 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001315tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001316 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001317tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001318 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001319uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001320 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Hendersone58eb532013-08-27 13:13:44 -07001321
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001322/* Value sign-extended to tcg register size. */
1323tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001324 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001325tcg_target_ulong helper_le_ldsw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001326 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001327tcg_target_ulong helper_le_ldsl_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001328 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001329tcg_target_ulong helper_be_ldsw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001330 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001331tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001332 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001333
Richard Hendersone58eb532013-08-27 13:13:44 -07001334void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001335 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001336void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001337 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001338void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001339 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001340void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001341 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001342void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001343 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001344void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001345 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001346void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001347 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001348
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001349uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
1350 TCGMemOpIdx oi, uintptr_t retaddr);
1351uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
1352 TCGMemOpIdx oi, uintptr_t retaddr);
1353uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
1354 TCGMemOpIdx oi, uintptr_t retaddr);
1355uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
1356 TCGMemOpIdx oi, uintptr_t retaddr);
1357uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
1358 TCGMemOpIdx oi, uintptr_t retaddr);
1359uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
1360 TCGMemOpIdx oi, uintptr_t retaddr);
1361uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
1362 TCGMemOpIdx oi, uintptr_t retaddr);
1363
Richard Henderson867b3202013-09-04 11:45:20 -07001364/* Temporary aliases until backends are converted. */
1365#ifdef TARGET_WORDS_BIGENDIAN
1366# define helper_ret_ldsw_mmu helper_be_ldsw_mmu
1367# define helper_ret_lduw_mmu helper_be_lduw_mmu
1368# define helper_ret_ldsl_mmu helper_be_ldsl_mmu
1369# define helper_ret_ldul_mmu helper_be_ldul_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001370# define helper_ret_ldl_mmu helper_be_ldul_mmu
Richard Henderson867b3202013-09-04 11:45:20 -07001371# define helper_ret_ldq_mmu helper_be_ldq_mmu
1372# define helper_ret_stw_mmu helper_be_stw_mmu
1373# define helper_ret_stl_mmu helper_be_stl_mmu
1374# define helper_ret_stq_mmu helper_be_stq_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001375# define helper_ret_ldw_cmmu helper_be_ldw_cmmu
1376# define helper_ret_ldl_cmmu helper_be_ldl_cmmu
1377# define helper_ret_ldq_cmmu helper_be_ldq_cmmu
Richard Henderson867b3202013-09-04 11:45:20 -07001378#else
1379# define helper_ret_ldsw_mmu helper_le_ldsw_mmu
1380# define helper_ret_lduw_mmu helper_le_lduw_mmu
1381# define helper_ret_ldsl_mmu helper_le_ldsl_mmu
1382# define helper_ret_ldul_mmu helper_le_ldul_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001383# define helper_ret_ldl_mmu helper_le_ldul_mmu
Richard Henderson867b3202013-09-04 11:45:20 -07001384# define helper_ret_ldq_mmu helper_le_ldq_mmu
1385# define helper_ret_stw_mmu helper_le_stw_mmu
1386# define helper_ret_stl_mmu helper_le_stl_mmu
1387# define helper_ret_stq_mmu helper_le_stq_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001388# define helper_ret_ldw_cmmu helper_le_ldw_cmmu
1389# define helper_ret_ldl_cmmu helper_le_ldl_cmmu
1390# define helper_ret_ldq_cmmu helper_le_ldq_cmmu
Richard Henderson867b3202013-09-04 11:45:20 -07001391#endif
Richard Hendersone58eb532013-08-27 13:13:44 -07001392
Richard Hendersonc482cb12016-06-28 11:37:27 -07001393uint32_t helper_atomic_cmpxchgb_mmu(CPUArchState *env, target_ulong addr,
1394 uint32_t cmpv, uint32_t newv,
1395 TCGMemOpIdx oi, uintptr_t retaddr);
1396uint32_t helper_atomic_cmpxchgw_le_mmu(CPUArchState *env, target_ulong addr,
1397 uint32_t cmpv, uint32_t newv,
1398 TCGMemOpIdx oi, uintptr_t retaddr);
1399uint32_t helper_atomic_cmpxchgl_le_mmu(CPUArchState *env, target_ulong addr,
1400 uint32_t cmpv, uint32_t newv,
1401 TCGMemOpIdx oi, uintptr_t retaddr);
1402uint64_t helper_atomic_cmpxchgq_le_mmu(CPUArchState *env, target_ulong addr,
1403 uint64_t cmpv, uint64_t newv,
1404 TCGMemOpIdx oi, uintptr_t retaddr);
1405uint32_t helper_atomic_cmpxchgw_be_mmu(CPUArchState *env, target_ulong addr,
1406 uint32_t cmpv, uint32_t newv,
1407 TCGMemOpIdx oi, uintptr_t retaddr);
1408uint32_t helper_atomic_cmpxchgl_be_mmu(CPUArchState *env, target_ulong addr,
1409 uint32_t cmpv, uint32_t newv,
1410 TCGMemOpIdx oi, uintptr_t retaddr);
1411uint64_t helper_atomic_cmpxchgq_be_mmu(CPUArchState *env, target_ulong addr,
1412 uint64_t cmpv, uint64_t newv,
1413 TCGMemOpIdx oi, uintptr_t retaddr);
1414
1415#define GEN_ATOMIC_HELPER(NAME, TYPE, SUFFIX) \
1416TYPE helper_atomic_ ## NAME ## SUFFIX ## _mmu \
1417 (CPUArchState *env, target_ulong addr, TYPE val, \
1418 TCGMemOpIdx oi, uintptr_t retaddr);
1419
Richard Hendersondf79b992016-09-02 12:23:57 -07001420#ifdef CONFIG_ATOMIC64
Richard Hendersonc482cb12016-06-28 11:37:27 -07001421#define GEN_ATOMIC_HELPER_ALL(NAME) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001422 GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001423 GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001424 GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001425 GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001426 GEN_ATOMIC_HELPER(NAME, uint32_t, l_be) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001427 GEN_ATOMIC_HELPER(NAME, uint64_t, q_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001428 GEN_ATOMIC_HELPER(NAME, uint64_t, q_be)
Richard Hendersondf79b992016-09-02 12:23:57 -07001429#else
1430#define GEN_ATOMIC_HELPER_ALL(NAME) \
1431 GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
1432 GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
1433 GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
1434 GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
1435 GEN_ATOMIC_HELPER(NAME, uint32_t, l_be)
1436#endif
Richard Hendersonc482cb12016-06-28 11:37:27 -07001437
1438GEN_ATOMIC_HELPER_ALL(fetch_add)
1439GEN_ATOMIC_HELPER_ALL(fetch_sub)
1440GEN_ATOMIC_HELPER_ALL(fetch_and)
1441GEN_ATOMIC_HELPER_ALL(fetch_or)
1442GEN_ATOMIC_HELPER_ALL(fetch_xor)
Richard Henderson5507c2b2018-05-10 18:10:57 +01001443GEN_ATOMIC_HELPER_ALL(fetch_smin)
1444GEN_ATOMIC_HELPER_ALL(fetch_umin)
1445GEN_ATOMIC_HELPER_ALL(fetch_smax)
1446GEN_ATOMIC_HELPER_ALL(fetch_umax)
Richard Hendersonc482cb12016-06-28 11:37:27 -07001447
1448GEN_ATOMIC_HELPER_ALL(add_fetch)
1449GEN_ATOMIC_HELPER_ALL(sub_fetch)
1450GEN_ATOMIC_HELPER_ALL(and_fetch)
1451GEN_ATOMIC_HELPER_ALL(or_fetch)
1452GEN_ATOMIC_HELPER_ALL(xor_fetch)
Richard Henderson5507c2b2018-05-10 18:10:57 +01001453GEN_ATOMIC_HELPER_ALL(smin_fetch)
1454GEN_ATOMIC_HELPER_ALL(umin_fetch)
1455GEN_ATOMIC_HELPER_ALL(smax_fetch)
1456GEN_ATOMIC_HELPER_ALL(umax_fetch)
Richard Hendersonc482cb12016-06-28 11:37:27 -07001457
1458GEN_ATOMIC_HELPER_ALL(xchg)
1459
1460#undef GEN_ATOMIC_HELPER_ALL
1461#undef GEN_ATOMIC_HELPER
Richard Hendersone58eb532013-08-27 13:13:44 -07001462#endif /* CONFIG_SOFTMMU */
1463
Richard Hendersone6cd4bb2018-08-15 16:31:47 -07001464/*
1465 * These aren't really a "proper" helpers because TCG cannot manage Int128.
1466 * However, use the same format as the others, for use by the backends.
1467 *
1468 * The cmpxchg functions are only defined if HAVE_CMPXCHG128;
1469 * the ld/st functions are only defined if HAVE_ATOMIC128,
1470 * as defined by <qemu/atomic128.h>.
1471 */
Richard Henderson7ebee432016-06-29 21:10:59 -07001472Int128 helper_atomic_cmpxchgo_le_mmu(CPUArchState *env, target_ulong addr,
1473 Int128 cmpv, Int128 newv,
1474 TCGMemOpIdx oi, uintptr_t retaddr);
1475Int128 helper_atomic_cmpxchgo_be_mmu(CPUArchState *env, target_ulong addr,
1476 Int128 cmpv, Int128 newv,
1477 TCGMemOpIdx oi, uintptr_t retaddr);
1478
1479Int128 helper_atomic_ldo_le_mmu(CPUArchState *env, target_ulong addr,
1480 TCGMemOpIdx oi, uintptr_t retaddr);
1481Int128 helper_atomic_ldo_be_mmu(CPUArchState *env, target_ulong addr,
1482 TCGMemOpIdx oi, uintptr_t retaddr);
1483void helper_atomic_sto_le_mmu(CPUArchState *env, target_ulong addr, Int128 val,
1484 TCGMemOpIdx oi, uintptr_t retaddr);
1485void helper_atomic_sto_be_mmu(CPUArchState *env, target_ulong addr, Int128 val,
1486 TCGMemOpIdx oi, uintptr_t retaddr);
1487
Richard Hendersone58eb532013-08-27 13:13:44 -07001488#endif /* TCG_H */