blob: cb7b329876851f6e8536f1be03553437e0d367f7 [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"
Alex Bennée20937142017-02-23 18:29:07 +000032#include "tcg-mo.h"
Richard Henderson78cd7b82013-08-20 14:41:29 -070033#include "tcg-target.h"
34
Paolo Bonzini00f6da62016-03-15 13:16:36 +010035/* XXX: make safe guess about sizes */
36#define MAX_OP_PER_INSTR 266
37
38#if HOST_LONG_BITS == 32
39#define MAX_OPC_PARAM_PER_ARG 2
40#else
41#define MAX_OPC_PARAM_PER_ARG 1
42#endif
43#define MAX_OPC_PARAM_IARGS 5
44#define MAX_OPC_PARAM_OARGS 1
45#define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS)
46
47/* A Call op needs up to 4 + 2N parameters on 32-bit archs,
48 * and up to 4 + N parameters on 64-bit archs
49 * (N = number of input arguments + output arguments). */
50#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
51#define OPC_BUF_SIZE 640
52#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
53
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 Henderson9aef40e2015-08-30 09:21:33 -0700174#ifndef TARGET_INSN_START_EXTRA_WORDS
175# define TARGET_INSN_START_WORDS 1
176#else
177# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS)
178#endif
179
Richard Hendersona9751602010-03-19 11:12:29 -0700180typedef enum TCGOpcode {
Aurelien Jarnoc61aaf72010-06-03 19:40:04 +0200181#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
bellardc896fe22008-02-01 10:05:41 +0000182#include "tcg-opc.h"
183#undef DEF
184 NB_OPS,
Richard Hendersona9751602010-03-19 11:12:29 -0700185} TCGOpcode;
bellardc896fe22008-02-01 10:05:41 +0000186
Richard Henderson80a8b9a2017-09-11 12:50:42 -0700187#define tcg_regset_set_reg(d, r) ((d) |= (TCGRegSet)1 << (r))
188#define tcg_regset_reset_reg(d, r) ((d) &= ~((TCGRegSet)1 << (r)))
189#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
bellardc896fe22008-02-01 10:05:41 +0000190
Richard Henderson1813e172014-03-28 12:56:22 -0700191#ifndef TCG_TARGET_INSN_UNIT_SIZE
Richard Henderson50533612014-04-28 12:01:23 -0700192# error "Missing TCG_TARGET_INSN_UNIT_SIZE"
193#elif TCG_TARGET_INSN_UNIT_SIZE == 1
Richard Henderson1813e172014-03-28 12:56:22 -0700194typedef uint8_t tcg_insn_unit;
195#elif TCG_TARGET_INSN_UNIT_SIZE == 2
196typedef uint16_t tcg_insn_unit;
197#elif TCG_TARGET_INSN_UNIT_SIZE == 4
198typedef uint32_t tcg_insn_unit;
199#elif TCG_TARGET_INSN_UNIT_SIZE == 8
200typedef uint64_t tcg_insn_unit;
201#else
202/* The port better have done this. */
203#endif
204
205
Paolo Bonzini8bff06a2016-07-15 18:27:40 +0200206#if defined CONFIG_DEBUG_TCG || defined QEMU_STATIC_ANALYSIS
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300207# define tcg_debug_assert(X) do { assert(X); } while (0)
208#elif QEMU_GNUC_PREREQ(4, 5)
209# define tcg_debug_assert(X) \
210 do { if (!(X)) { __builtin_unreachable(); } } while (0)
211#else
212# define tcg_debug_assert(X) do { (void)(X); } while (0)
213#endif
214
bellardc896fe22008-02-01 10:05:41 +0000215typedef struct TCGRelocation {
216 struct TCGRelocation *next;
217 int type;
Richard Henderson1813e172014-03-28 12:56:22 -0700218 tcg_insn_unit *ptr;
Richard Henderson2ba7fae22013-08-20 15:30:10 -0700219 intptr_t addend;
bellardc896fe22008-02-01 10:05:41 +0000220} TCGRelocation;
221
222typedef struct TCGLabel {
Richard Henderson51e39722015-02-13 18:51:05 -0800223 unsigned has_value : 1;
224 unsigned id : 31;
bellardc896fe22008-02-01 10:05:41 +0000225 union {
Richard Henderson2ba7fae22013-08-20 15:30:10 -0700226 uintptr_t value;
Richard Henderson1813e172014-03-28 12:56:22 -0700227 tcg_insn_unit *value_ptr;
bellardc896fe22008-02-01 10:05:41 +0000228 TCGRelocation *first_reloc;
229 } u;
230} TCGLabel;
231
232typedef struct TCGPool {
233 struct TCGPool *next;
blueswir1c44f9452008-05-19 16:32:18 +0000234 int size;
235 uint8_t data[0] __attribute__ ((aligned));
bellardc896fe22008-02-01 10:05:41 +0000236} TCGPool;
237
238#define TCG_POOL_CHUNK_SIZE 32768
239
blueswir1c4071c92008-03-16 19:21:07 +0000240#define TCG_MAX_TEMPS 512
Richard Henderson190ce7f2015-08-31 14:34:41 -0700241#define TCG_MAX_INSNS 512
bellardc896fe22008-02-01 10:05:41 +0000242
bellardb03cce82008-05-10 10:52:05 +0000243/* when the size of the arguments of a called function is smaller than
244 this value, they are statically allocated in the TB stack frame */
245#define TCG_STATIC_CALL_ARGS_SIZE 128
246
Richard Hendersonc02244a2010-03-19 11:36:30 -0700247typedef enum TCGType {
248 TCG_TYPE_I32,
249 TCG_TYPE_I64,
250 TCG_TYPE_COUNT, /* number of different types */
bellardc896fe22008-02-01 10:05:41 +0000251
Richard Henderson3b6dac32010-06-02 17:26:55 -0700252 /* An alias for the size of the host register. */
bellardc896fe22008-02-01 10:05:41 +0000253#if TCG_TARGET_REG_BITS == 32
Richard Henderson3b6dac32010-06-02 17:26:55 -0700254 TCG_TYPE_REG = TCG_TYPE_I32,
bellardc896fe22008-02-01 10:05:41 +0000255#else
Richard Henderson3b6dac32010-06-02 17:26:55 -0700256 TCG_TYPE_REG = TCG_TYPE_I64,
bellardc896fe22008-02-01 10:05:41 +0000257#endif
Richard Henderson3b6dac32010-06-02 17:26:55 -0700258
Richard Hendersond2898372013-08-20 14:48:46 -0700259 /* An alias for the size of the native pointer. */
260#if UINTPTR_MAX == UINT32_MAX
261 TCG_TYPE_PTR = TCG_TYPE_I32,
262#else
263 TCG_TYPE_PTR = TCG_TYPE_I64,
264#endif
Richard Henderson3b6dac32010-06-02 17:26:55 -0700265
266 /* An alias for the size of the target "long", aka register. */
Richard Hendersonc02244a2010-03-19 11:36:30 -0700267#if TARGET_LONG_BITS == 64
268 TCG_TYPE_TL = TCG_TYPE_I64,
269#else
270 TCG_TYPE_TL = TCG_TYPE_I32,
271#endif
272} TCGType;
bellardc896fe22008-02-01 10:05:41 +0000273
Richard Henderson6c5f4ea2013-09-03 13:52:19 -0700274/* Constants for qemu_ld and qemu_st for the Memory Operation field. */
275typedef enum TCGMemOp {
276 MO_8 = 0,
277 MO_16 = 1,
278 MO_32 = 2,
279 MO_64 = 3,
280 MO_SIZE = 3, /* Mask for the above. */
281
282 MO_SIGN = 4, /* Sign-extended, otherwise zero-extended. */
283
284 MO_BSWAP = 8, /* Host reverse endian. */
285#ifdef HOST_WORDS_BIGENDIAN
286 MO_LE = MO_BSWAP,
287 MO_BE = 0,
288#else
289 MO_LE = 0,
290 MO_BE = MO_BSWAP,
291#endif
292#ifdef TARGET_WORDS_BIGENDIAN
293 MO_TE = MO_BE,
294#else
295 MO_TE = MO_LE,
296#endif
297
Richard Hendersondfb36302015-05-13 11:25:20 -0700298 /* MO_UNALN accesses are never checked for alignment.
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300299 * MO_ALIGN accesses will result in a call to the CPU's
300 * do_unaligned_access hook if the guest address is not aligned.
301 * The default depends on whether the target CPU defines ALIGNED_ONLY.
Richard Henderson85aa8082016-07-14 12:43:06 -0700302 *
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300303 * Some architectures (e.g. ARMv8) need the address which is aligned
304 * to a size more than the size of the memory access.
Richard Henderson85aa8082016-07-14 12:43:06 -0700305 * Some architectures (e.g. SPARCv9) need an address which is aligned,
306 * but less strictly than the natural alignment.
307 *
308 * MO_ALIGN supposes the alignment size is the size of a memory access.
309 *
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300310 * There are three options:
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300311 * - unaligned access permitted (MO_UNALN).
Richard Henderson85aa8082016-07-14 12:43:06 -0700312 * - an alignment to the size of an access (MO_ALIGN);
313 * - an alignment to a specified size, which may be more or less than
314 * the access size (MO_ALIGN_x where 'x' is a size in bytes);
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300315 */
316 MO_ASHIFT = 4,
317 MO_AMASK = 7 << MO_ASHIFT,
Richard Hendersondfb36302015-05-13 11:25:20 -0700318#ifdef ALIGNED_ONLY
319 MO_ALIGN = 0,
320 MO_UNALN = MO_AMASK,
321#else
322 MO_ALIGN = MO_AMASK,
323 MO_UNALN = 0,
324#endif
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300325 MO_ALIGN_2 = 1 << MO_ASHIFT,
326 MO_ALIGN_4 = 2 << MO_ASHIFT,
327 MO_ALIGN_8 = 3 << MO_ASHIFT,
328 MO_ALIGN_16 = 4 << MO_ASHIFT,
329 MO_ALIGN_32 = 5 << MO_ASHIFT,
330 MO_ALIGN_64 = 6 << MO_ASHIFT,
Richard Hendersondfb36302015-05-13 11:25:20 -0700331
Richard Henderson6c5f4ea2013-09-03 13:52:19 -0700332 /* Combinations of the above, for ease of use. */
333 MO_UB = MO_8,
334 MO_UW = MO_16,
335 MO_UL = MO_32,
336 MO_SB = MO_SIGN | MO_8,
337 MO_SW = MO_SIGN | MO_16,
338 MO_SL = MO_SIGN | MO_32,
339 MO_Q = MO_64,
340
341 MO_LEUW = MO_LE | MO_UW,
342 MO_LEUL = MO_LE | MO_UL,
343 MO_LESW = MO_LE | MO_SW,
344 MO_LESL = MO_LE | MO_SL,
345 MO_LEQ = MO_LE | MO_Q,
346
347 MO_BEUW = MO_BE | MO_UW,
348 MO_BEUL = MO_BE | MO_UL,
349 MO_BESW = MO_BE | MO_SW,
350 MO_BESL = MO_BE | MO_SL,
351 MO_BEQ = MO_BE | MO_Q,
352
353 MO_TEUW = MO_TE | MO_UW,
354 MO_TEUL = MO_TE | MO_UL,
355 MO_TESW = MO_TE | MO_SW,
356 MO_TESL = MO_TE | MO_SL,
357 MO_TEQ = MO_TE | MO_Q,
358
359 MO_SSIZE = MO_SIZE | MO_SIGN,
360} TCGMemOp;
361
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300362/**
363 * get_alignment_bits
364 * @memop: TCGMemOp value
365 *
366 * Extract the alignment size from the memop.
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300367 */
Richard Henderson85aa8082016-07-14 12:43:06 -0700368static inline unsigned get_alignment_bits(TCGMemOp memop)
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300369{
Richard Henderson85aa8082016-07-14 12:43:06 -0700370 unsigned a = memop & MO_AMASK;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300371
372 if (a == MO_UNALN) {
Richard Henderson85aa8082016-07-14 12:43:06 -0700373 /* No alignment required. */
374 a = 0;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300375 } else if (a == MO_ALIGN) {
Richard Henderson85aa8082016-07-14 12:43:06 -0700376 /* A natural alignment requirement. */
377 a = memop & MO_SIZE;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300378 } else {
Richard Henderson85aa8082016-07-14 12:43:06 -0700379 /* A specific alignment requirement. */
380 a = a >> MO_ASHIFT;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300381 }
382#if defined(CONFIG_SOFTMMU)
383 /* The requested alignment cannot overlap the TLB flags. */
Richard Henderson85aa8082016-07-14 12:43:06 -0700384 tcg_debug_assert((TLB_FLAGS_MASK & ((1 << a) - 1)) == 0);
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300385#endif
Richard Henderson85aa8082016-07-14 12:43:06 -0700386 return a;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300387}
388
bellardc896fe22008-02-01 10:05:41 +0000389typedef tcg_target_ulong TCGArg;
390
Peter Maydella40d4702016-10-21 17:38:42 +0100391/* Define type and accessor macros for TCG variables.
392
393 TCG variables are the inputs and outputs of TCG ops, as described
394 in tcg/README. Target CPU front-end code uses these types to deal
395 with TCG variables as it emits TCG code via the tcg_gen_* functions.
396 They come in several flavours:
397 * TCGv_i32 : 32 bit integer type
398 * TCGv_i64 : 64 bit integer type
399 * TCGv_ptr : a host pointer type
400 * TCGv : an integer type the same size as target_ulong
401 (an alias for either TCGv_i32 or TCGv_i64)
402 The compiler's type checking will complain if you mix them
403 up and pass the wrong sized TCGv to a function.
404
405 Users of tcg_gen_* don't need to know about any of the internal
406 details of these, and should treat them as opaque types.
407 You won't be able to look inside them in a debugger either.
408
409 Internal implementation details follow:
410
411 Note that there is no definition of the structs TCGv_i32_d etc anywhere.
412 This is deliberate, because the values we store in variables of type
413 TCGv_i32 are not really pointers-to-structures. They're just small
414 integers, but keeping them in pointer types like this means that the
415 compiler will complain if you accidentally pass a TCGv_i32 to a
416 function which takes a TCGv_i64, and so on. Only the internals of
Richard Hendersondc41aa72017-10-20 00:30:24 -0700417 TCG need to care about the actual contents of the types. */
pbrookac56dd42008-02-03 19:56:33 +0000418
Richard Hendersonb6c73a62014-09-16 09:51:46 -0700419typedef struct TCGv_i32_d *TCGv_i32;
420typedef struct TCGv_i64_d *TCGv_i64;
421typedef struct TCGv_ptr_d *TCGv_ptr;
LluĂ­s Vilanova1bcea732016-02-25 17:43:15 +0100422typedef TCGv_ptr TCGv_env;
LluĂ­s Vilanova5d4e1a12016-02-25 17:43:21 +0100423#if TARGET_LONG_BITS == 32
424#define TCGv TCGv_i32
425#elif TARGET_LONG_BITS == 64
426#define TCGv TCGv_i64
427#else
428#error Unhandled TARGET_LONG_BITS value
429#endif
pbrookac56dd42008-02-03 19:56:33 +0000430
Richard Hendersone89b28a2017-10-20 12:08:19 -0700431/* See the comment before tcgv_i32_temp. */
432#define TCGV_UNUSED_I32(x) (x = (TCGv_i32)NULL)
433#define TCGV_UNUSED_I64(x) (x = (TCGv_i64)NULL)
434#define TCGV_UNUSED_PTR(x) (x = (TCGv_ptr)NULL)
pbrooka50f5b92008-06-29 15:25:29 +0000435
Richard Hendersone89b28a2017-10-20 12:08:19 -0700436#define TCGV_IS_UNUSED_I32(x) ((x) == (TCGv_i32)NULL)
437#define TCGV_IS_UNUSED_I64(x) ((x) == (TCGv_i64)NULL)
438#define TCGV_IS_UNUSED_PTR(x) ((x) == (TCGv_ptr)NULL)
Richard Hendersonafcb92b2012-12-07 15:07:17 -0600439
bellardc896fe22008-02-01 10:05:41 +0000440/* call flags */
Aurelien Jarno78505272012-10-09 21:53:08 +0200441/* Helper does not read globals (either directly or through an exception). It
442 implies TCG_CALL_NO_WRITE_GLOBALS. */
443#define TCG_CALL_NO_READ_GLOBALS 0x0010
444/* Helper does not write globals */
445#define TCG_CALL_NO_WRITE_GLOBALS 0x0020
446/* Helper can be safely suppressed if the return value is not used. */
447#define TCG_CALL_NO_SIDE_EFFECTS 0x0040
448
449/* convenience version of most used call flags */
450#define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS
451#define TCG_CALL_NO_WG TCG_CALL_NO_WRITE_GLOBALS
452#define TCG_CALL_NO_SE TCG_CALL_NO_SIDE_EFFECTS
453#define TCG_CALL_NO_RWG_SE (TCG_CALL_NO_RWG | TCG_CALL_NO_SE)
454#define TCG_CALL_NO_WG_SE (TCG_CALL_NO_WG | TCG_CALL_NO_SE)
455
Richard Hendersone89b28a2017-10-20 12:08:19 -0700456/* Used to align parameters. See the comment before tcgv_i32_temp. */
457#define TCG_CALL_DUMMY_ARG ((TCGArg)0)
bellard39cf05d2008-05-22 14:59:57 +0000458
Stefan Weila93cf9d2012-11-02 08:29:53 +0100459/* Conditions. Note that these are laid out for easy manipulation by
460 the functions below:
Richard Henderson0aed2572012-09-24 14:21:40 -0700461 bit 0 is used for inverting;
462 bit 1 is signed,
463 bit 2 is unsigned,
464 bit 3 is used with bit 0 for swapping signed/unsigned. */
bellardc896fe22008-02-01 10:05:41 +0000465typedef enum {
Richard Henderson0aed2572012-09-24 14:21:40 -0700466 /* non-signed */
467 TCG_COND_NEVER = 0 | 0 | 0 | 0,
468 TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
469 TCG_COND_EQ = 8 | 0 | 0 | 0,
470 TCG_COND_NE = 8 | 0 | 0 | 1,
471 /* signed */
472 TCG_COND_LT = 0 | 0 | 2 | 0,
473 TCG_COND_GE = 0 | 0 | 2 | 1,
474 TCG_COND_LE = 8 | 0 | 2 | 0,
475 TCG_COND_GT = 8 | 0 | 2 | 1,
bellardc896fe22008-02-01 10:05:41 +0000476 /* unsigned */
Richard Henderson0aed2572012-09-24 14:21:40 -0700477 TCG_COND_LTU = 0 | 4 | 0 | 0,
478 TCG_COND_GEU = 0 | 4 | 0 | 1,
479 TCG_COND_LEU = 8 | 4 | 0 | 0,
480 TCG_COND_GTU = 8 | 4 | 0 | 1,
bellardc896fe22008-02-01 10:05:41 +0000481} TCGCond;
482
Richard Henderson1c086222010-02-09 12:33:09 -0800483/* Invert the sense of the comparison. */
Richard Henderson401d4662010-01-07 10:15:20 -0800484static inline TCGCond tcg_invert_cond(TCGCond c)
485{
486 return (TCGCond)(c ^ 1);
487}
488
Richard Henderson1c086222010-02-09 12:33:09 -0800489/* Swap the operands in a comparison. */
490static inline TCGCond tcg_swap_cond(TCGCond c)
491{
Richard Henderson0aed2572012-09-24 14:21:40 -0700492 return c & 6 ? (TCGCond)(c ^ 9) : c;
Richard Henderson1c086222010-02-09 12:33:09 -0800493}
494
Richard Hendersond1e321b2012-09-24 14:21:41 -0700495/* Create an "unsigned" version of a "signed" comparison. */
Richard Hendersonff44c2f2009-12-27 09:09:41 +0000496static inline TCGCond tcg_unsigned_cond(TCGCond c)
497{
Richard Henderson0aed2572012-09-24 14:21:40 -0700498 return c & 2 ? (TCGCond)(c ^ 6) : c;
Richard Hendersonff44c2f2009-12-27 09:09:41 +0000499}
500
Richard Hendersond1e321b2012-09-24 14:21:41 -0700501/* Must a comparison be considered unsigned? */
Richard Hendersonbcc66562012-09-24 14:21:39 -0700502static inline bool is_unsigned_cond(TCGCond c)
503{
Richard Henderson0aed2572012-09-24 14:21:40 -0700504 return (c & 4) != 0;
Richard Hendersonbcc66562012-09-24 14:21:39 -0700505}
506
Richard Hendersond1e321b2012-09-24 14:21:41 -0700507/* Create a "high" version of a double-word comparison.
508 This removes equality from a LTE or GTE comparison. */
509static inline TCGCond tcg_high_cond(TCGCond c)
510{
511 switch (c) {
512 case TCG_COND_GE:
513 case TCG_COND_LE:
514 case TCG_COND_GEU:
515 case TCG_COND_LEU:
516 return (TCGCond)(c ^ 8);
517 default:
518 return c;
519 }
520}
521
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400522typedef enum TCGTempVal {
523 TEMP_VAL_DEAD,
524 TEMP_VAL_REG,
525 TEMP_VAL_MEM,
526 TEMP_VAL_CONST,
527} TCGTempVal;
bellardc896fe22008-02-01 10:05:41 +0000528
bellardc896fe22008-02-01 10:05:41 +0000529typedef struct TCGTemp {
Richard Hendersonb6638662013-09-18 14:54:45 -0700530 TCGReg reg:8;
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400531 TCGTempVal val_type:8;
532 TCGType base_type:8;
533 TCGType type:8;
bellardc896fe22008-02-01 10:05:41 +0000534 unsigned int fixed_reg:1;
Richard Hendersonb3915db2013-09-19 10:36:18 -0700535 unsigned int indirect_reg:1;
536 unsigned int indirect_base:1;
bellardc896fe22008-02-01 10:05:41 +0000537 unsigned int mem_coherent:1;
538 unsigned int mem_allocated:1;
Richard Hendersonfa477d22016-11-02 11:20:15 -0600539 /* If true, the temp is saved across both basic blocks and
540 translation blocks. */
541 unsigned int temp_global:1;
542 /* If true, the temp is saved across basic blocks but dead
543 at the end of translation blocks. If false, the temp is
544 dead at the end of basic blocks. */
545 unsigned int temp_local:1;
546 unsigned int temp_allocated:1;
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400547
548 tcg_target_long val;
Richard Hendersonb3a62932013-09-18 14:12:53 -0700549 struct TCGTemp *mem_base;
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400550 intptr_t mem_offset;
bellardc896fe22008-02-01 10:05:41 +0000551 const char *name;
Richard Hendersonb83eabe2016-11-01 15:56:04 -0600552
553 /* Pass-specific information that can be stored for a temporary.
554 One word worth of integer data, and one pointer to data
555 allocated separately. */
556 uintptr_t state;
557 void *state_ptr;
bellardc896fe22008-02-01 10:05:41 +0000558} TCGTemp;
559
bellardc896fe22008-02-01 10:05:41 +0000560typedef struct TCGContext TCGContext;
561
Richard Henderson0ec9eab2013-09-19 12:16:45 -0700562typedef struct TCGTempSet {
563 unsigned long l[BITS_TO_LONGS(TCG_MAX_TEMPS)];
564} TCGTempSet;
565
Richard Hendersona1b3c482016-06-22 15:46:09 -0700566/* While we limit helpers to 6 arguments, for 32-bit hosts, with padding,
567 this imples a max of 6*2 (64-bit in) + 2 (64-bit out) = 14 operands.
568 There are never more than 2 outputs, which means that we can store all
569 dead + sync data within 16 bits. */
570#define DEAD_ARG 4
571#define SYNC_ARG 1
572typedef uint16_t TCGLifeData;
573
Richard Henderson75e8b9b2016-12-08 10:52:57 -0800574/* The layout here is designed to avoid a bitfield crossing of
575 a 32-bit boundary, which would cause GCC to add extra padding. */
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700576typedef struct TCGOp {
Richard Hendersonbee158c2016-06-22 20:43:29 -0700577 TCGOpcode opc : 8; /* 8 */
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700578
Richard Hendersonbee158c2016-06-22 20:43:29 -0700579 /* The number of out and in parameter for a call. */
Richard Henderson75e8b9b2016-12-08 10:52:57 -0800580 unsigned calli : 4; /* 12 */
581 unsigned callo : 2; /* 14 */
582 unsigned : 2; /* 16 */
Richard Hendersonbee158c2016-06-22 20:43:29 -0700583
Richard Henderson75e8b9b2016-12-08 10:52:57 -0800584 /* Index of the prev/next op, or 0 for the end of the list. */
585 unsigned prev : 16; /* 32 */
586 unsigned next : 16; /* 48 */
Richard Hendersonbee158c2016-06-22 20:43:29 -0700587
588 /* Lifetime data of the operands. */
589 unsigned life : 16; /* 64 */
Richard Henderson75e8b9b2016-12-08 10:52:57 -0800590
591 /* Arguments for the opcode. */
592 TCGArg args[MAX_OPC_PARAM];
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700593} TCGOp;
594
Richard Henderson75e8b9b2016-12-08 10:52:57 -0800595/* Make sure that we don't expand the structure without noticing. */
596QEMU_BUILD_BUG_ON(sizeof(TCGOp) != 8 + sizeof(TCGArg) * MAX_OPC_PARAM);
597
Richard Hendersondcb8e752016-06-22 19:42:31 -0700598/* Make sure operands fit in the bitfields above. */
599QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8));
Richard Henderson75e8b9b2016-12-08 10:52:57 -0800600QEMU_BUILD_BUG_ON(OPC_BUF_SIZE > (1 << 16));
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700601
Emilio G. Cotac3fac112017-07-05 19:35:06 -0400602typedef struct TCGProfile {
603 int64_t tb_count1;
604 int64_t tb_count;
605 int64_t op_count; /* total insn count */
606 int op_count_max; /* max insn per TB */
607 int64_t temp_count;
608 int temp_count_max;
609 int64_t del_op_count;
610 int64_t code_in_len;
611 int64_t code_out_len;
612 int64_t search_out_len;
613 int64_t interm_time;
614 int64_t code_time;
615 int64_t la_time;
616 int64_t opt_time;
617 int64_t restore_count;
618 int64_t restore_time;
619 int64_t table_op_count[NB_OPS];
620} TCGProfile;
621
bellardc896fe22008-02-01 10:05:41 +0000622struct TCGContext {
623 uint8_t *pool_cur, *pool_end;
Kirill Batuzov40552992012-03-02 13:22:17 +0400624 TCGPool *pool_first, *pool_current, *pool_first_large;
bellardc896fe22008-02-01 10:05:41 +0000625 int nb_labels;
bellardc896fe22008-02-01 10:05:41 +0000626 int nb_globals;
627 int nb_temps;
Richard Henderson5a184072016-06-23 20:34:33 -0700628 int nb_indirects;
bellardc896fe22008-02-01 10:05:41 +0000629
630 /* goto_tb support */
Richard Henderson1813e172014-03-28 12:56:22 -0700631 tcg_insn_unit *code_buf;
Sergey Fedorovf3091012016-04-10 23:35:45 +0300632 uint16_t *tb_jmp_reset_offset; /* tb->jmp_reset_offset */
Richard Hendersona8583392017-07-31 22:02:31 -0700633 uintptr_t *tb_jmp_insn_offset; /* tb->jmp_target_arg if direct_jump */
634 uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_arg if !direct_jump */
bellardc896fe22008-02-01 10:05:41 +0000635
bellardc896fe22008-02-01 10:05:41 +0000636 TCGRegSet reserved_regs;
Emilio G. Cotae82d5a22017-07-16 15:13:52 -0400637 uint32_t tb_cflags; /* cflags of the current TB */
Richard Hendersone2c6d1b2013-08-20 15:12:31 -0700638 intptr_t current_frame_offset;
639 intptr_t frame_start;
640 intptr_t frame_end;
Richard Hendersonb3a62932013-09-18 14:12:53 -0700641 TCGTemp *frame_temp;
bellardc896fe22008-02-01 10:05:41 +0000642
Richard Henderson1813e172014-03-28 12:56:22 -0700643 tcg_insn_unit *code_ptr;
bellardc896fe22008-02-01 10:05:41 +0000644
bellarda23a9ec2008-05-23 09:52:20 +0000645#ifdef CONFIG_PROFILER
Emilio G. Cotac3fac112017-07-05 19:35:06 -0400646 TCGProfile prof;
bellarda23a9ec2008-05-23 09:52:20 +0000647#endif
Peter Maydell27bfd832011-03-06 21:39:53 +0000648
649#ifdef CONFIG_DEBUG_TCG
650 int temps_in_use;
Richard Henderson0a209d42012-09-21 17:18:16 -0700651 int goto_tb_issue_mask;
Peter Maydell27bfd832011-03-06 21:39:53 +0000652#endif
Yeongkyoon Leeb76f0d82012-10-31 16:04:25 +0900653
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700654 int gen_next_op_idx;
Evgeny Voevodin8232a462012-11-12 13:27:44 +0400655
Richard Henderson1813e172014-03-28 12:56:22 -0700656 /* Code generation. Note that we specifically do not use tcg_insn_unit
657 here, because there's too much arithmetic throughout that relies
658 on addition and subtraction working on bytes. Rely on the GCC
659 extension that allows arithmetic on void*. */
Richard Henderson1813e172014-03-28 12:56:22 -0700660 void *code_gen_prologue;
Emilio G. Cotacedbcb02017-04-26 23:29:14 -0400661 void *code_gen_epilogue;
Richard Henderson1813e172014-03-28 12:56:22 -0700662 void *code_gen_buffer;
Evgeny Voevodin0b0d3322013-02-01 01:47:22 +0700663 size_t code_gen_buffer_size;
Richard Henderson1813e172014-03-28 12:56:22 -0700664 void *code_gen_ptr;
Richard Henderson57a26942017-07-30 13:13:21 -0700665 void *data_gen_ptr;
Evgeny Voevodin0b0d3322013-02-01 01:47:22 +0700666
Richard Hendersonb125f9d2015-09-22 13:01:15 -0700667 /* Threshold to flush the translated code buffer. */
668 void *code_gen_highwater;
669
LluĂ­s Vilanova7c255042016-06-09 19:31:41 +0200670 /* Track which vCPU triggers events */
671 CPUState *cpu; /* *_trans */
LluĂ­s Vilanova7c255042016-06-09 19:31:41 +0200672
Richard Henderson659ef5c2017-07-30 12:30:41 -0700673 /* These structures are private to tcg-target.inc.c. */
674#ifdef TCG_TARGET_NEED_LDST_LABELS
675 struct TCGLabelQemuLdst *ldst_labels;
676#endif
Richard Henderson57a26942017-07-30 13:13:21 -0700677#ifdef TCG_TARGET_NEED_POOL_LABELS
678 struct TCGLabelPoolData *pool_labels;
679#endif
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700680
Emilio G. Cota26689782017-07-04 13:54:21 -0400681 TCGLabel *exitreq_label;
682
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700683 TCGTempSet free_temps[TCG_TYPE_COUNT * 2];
684 TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
685
Richard Hendersonf8b2f202013-09-18 15:21:56 -0700686 /* Tells which temporary holds a given register.
687 It does not take into account fixed registers */
688 TCGTemp *reg_to_temp[TCG_TARGET_NB_REGS];
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700689
690 TCGOp gen_op_buf[OPC_BUF_SIZE];
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700691
Richard Hendersonfca8a502015-09-01 19:11:45 -0700692 uint16_t gen_insn_end_off[TCG_MAX_INSNS];
693 target_ulong gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
bellardc896fe22008-02-01 10:05:41 +0000694};
695
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400696extern TCGContext tcg_init_ctx;
Emilio G. Cota3468b592017-07-19 18:57:58 -0400697extern __thread TCGContext *tcg_ctx;
Richard Henderson1c2adb92017-10-10 14:34:37 -0700698extern TCGv_env cpu_env;
bellardc896fe22008-02-01 10:05:41 +0000699
Richard Henderson1807f4c2017-06-20 12:24:57 -0700700static inline size_t temp_idx(TCGTemp *ts)
701{
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400702 ptrdiff_t n = ts - tcg_ctx->temps;
703 tcg_debug_assert(n >= 0 && n < tcg_ctx->nb_temps);
Richard Henderson1807f4c2017-06-20 12:24:57 -0700704 return n;
705}
706
707static inline TCGArg temp_arg(TCGTemp *ts)
708{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700709 return (uintptr_t)ts;
Richard Henderson1807f4c2017-06-20 12:24:57 -0700710}
711
Richard Henderson43439132017-06-19 23:18:10 -0700712static inline TCGTemp *arg_temp(TCGArg a)
713{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700714 return (TCGTemp *)(uintptr_t)a;
Richard Henderson43439132017-06-19 23:18:10 -0700715}
716
Richard Hendersone89b28a2017-10-20 12:08:19 -0700717/* Using the offset of a temporary, relative to TCGContext, rather than
718 its index means that we don't use 0. That leaves offset 0 free for
719 a NULL representation without having to leave index 0 unused. */
720static inline TCGTemp *tcgv_i32_temp(TCGv_i32 v)
Richard Henderson63490392017-06-20 13:43:15 -0700721{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700722 uintptr_t o = (uintptr_t)v;
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400723 TCGTemp *t = (void *)tcg_ctx + o;
Richard Hendersone89b28a2017-10-20 12:08:19 -0700724 tcg_debug_assert(offsetof(TCGContext, temps[temp_idx(t)]) == o);
725 return t;
Richard Henderson63490392017-06-20 13:43:15 -0700726}
727
Richard Hendersone89b28a2017-10-20 12:08:19 -0700728static inline TCGTemp *tcgv_i64_temp(TCGv_i64 v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700729{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700730 return tcgv_i32_temp((TCGv_i32)v);
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700731}
732
Richard Hendersone89b28a2017-10-20 12:08:19 -0700733static inline TCGTemp *tcgv_ptr_temp(TCGv_ptr v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700734{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700735 return tcgv_i32_temp((TCGv_i32)v);
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700736}
737
Richard Hendersone89b28a2017-10-20 12:08:19 -0700738static inline TCGArg tcgv_i32_arg(TCGv_i32 v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700739{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700740 return temp_arg(tcgv_i32_temp(v));
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700741}
742
Richard Hendersone89b28a2017-10-20 12:08:19 -0700743static inline TCGArg tcgv_i64_arg(TCGv_i64 v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700744{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700745 return temp_arg(tcgv_i64_temp(v));
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700746}
747
Richard Hendersone89b28a2017-10-20 12:08:19 -0700748static inline TCGArg tcgv_ptr_arg(TCGv_ptr v)
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700749{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700750 return temp_arg(tcgv_ptr_temp(v));
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700751}
752
Richard Henderson085272b2017-10-20 00:05:45 -0700753static inline TCGv_i32 temp_tcgv_i32(TCGTemp *t)
754{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700755 (void)temp_idx(t); /* trigger embedded assert */
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400756 return (TCGv_i32)((void *)t - (void *)tcg_ctx);
Richard Henderson085272b2017-10-20 00:05:45 -0700757}
758
759static inline TCGv_i64 temp_tcgv_i64(TCGTemp *t)
760{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700761 return (TCGv_i64)temp_tcgv_i32(t);
Richard Henderson085272b2017-10-20 00:05:45 -0700762}
763
764static inline TCGv_ptr temp_tcgv_ptr(TCGTemp *t)
765{
Richard Hendersone89b28a2017-10-20 12:08:19 -0700766 return (TCGv_ptr)temp_tcgv_i32(t);
Richard Henderson085272b2017-10-20 00:05:45 -0700767}
768
Richard Hendersondc41aa72017-10-20 00:30:24 -0700769#if TCG_TARGET_REG_BITS == 32
770static inline TCGv_i32 TCGV_LOW(TCGv_i64 t)
771{
772 return temp_tcgv_i32(tcgv_i64_temp(t));
773}
774
775static inline TCGv_i32 TCGV_HIGH(TCGv_i64 t)
776{
777 return temp_tcgv_i32(tcgv_i64_temp(t) + 1);
778}
779#endif
780
Edgar E. Iglesias1d414782016-05-12 13:22:26 +0100781static inline void tcg_set_insn_param(int op_idx, int arg, TCGArg v)
782{
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400783 tcg_ctx->gen_op_buf[op_idx].args[arg] = v;
Edgar E. Iglesias1d414782016-05-12 13:22:26 +0100784}
785
Richard Hendersonfe700ad2014-03-30 15:36:56 -0700786/* The number of opcodes emitted so far. */
787static inline int tcg_op_buf_count(void)
788{
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400789 return tcg_ctx->gen_next_op_idx;
Richard Hendersonfe700ad2014-03-30 15:36:56 -0700790}
791
792/* Test for whether to terminate the TB for using too many opcodes. */
793static inline bool tcg_op_buf_full(void)
794{
795 return tcg_op_buf_count() >= OPC_MAX_SIZE;
796}
797
bellardc896fe22008-02-01 10:05:41 +0000798/* pool based memory allocation */
799
Emilio G. Cota3468b592017-07-19 18:57:58 -0400800/* user-mode: tb_lock must be held for tcg_malloc_internal. */
bellardc896fe22008-02-01 10:05:41 +0000801void *tcg_malloc_internal(TCGContext *s, int size);
802void tcg_pool_reset(TCGContext *s);
Emilio G. Cota6e3b2bf2017-06-06 19:12:25 -0400803TranslationBlock *tcg_tb_alloc(TCGContext *s);
bellardc896fe22008-02-01 10:05:41 +0000804
Emilio G. Cotae8feb962017-07-07 19:24:20 -0400805void tcg_region_init(void);
806void tcg_region_reset_all(void);
807
808size_t tcg_code_size(void);
809size_t tcg_code_capacity(void);
810
Emilio G. Cota3468b592017-07-19 18:57:58 -0400811/* user-mode: Called with tb_lock held. */
bellardc896fe22008-02-01 10:05:41 +0000812static inline void *tcg_malloc(int size)
813{
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400814 TCGContext *s = tcg_ctx;
bellardc896fe22008-02-01 10:05:41 +0000815 uint8_t *ptr, *ptr_end;
Richard Henderson13aaef62017-08-02 14:50:04 -0700816
817 /* ??? This is a weak placeholder for minimum malloc alignment. */
818 size = QEMU_ALIGN_UP(size, 8);
819
bellardc896fe22008-02-01 10:05:41 +0000820 ptr = s->pool_cur;
821 ptr_end = ptr + size;
822 if (unlikely(ptr_end > s->pool_end)) {
Emilio G. Cotab1311c42017-07-12 17:15:52 -0400823 return tcg_malloc_internal(tcg_ctx, size);
bellardc896fe22008-02-01 10:05:41 +0000824 } else {
825 s->pool_cur = ptr_end;
826 return ptr;
827 }
828}
829
830void tcg_context_init(TCGContext *s);
Emilio G. Cota3468b592017-07-19 18:57:58 -0400831void tcg_register_thread(void);
Richard Henderson9002ec72010-05-06 08:50:41 -0700832void tcg_prologue_init(TCGContext *s);
bellardc896fe22008-02-01 10:05:41 +0000833void tcg_func_start(TCGContext *s);
834
Alex Bennée5bd2ec32016-03-15 14:30:16 +0000835int tcg_gen_code(TCGContext *s, TranslationBlock *tb);
bellardc896fe22008-02-01 10:05:41 +0000836
Richard Hendersonb6638662013-09-18 14:54:45 -0700837void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
pbrooka7812ae2008-11-17 14:43:54 +0000838
Richard Henderson085272b2017-10-20 00:05:45 -0700839TCGTemp *tcg_global_mem_new_internal(TCGType, TCGv_ptr,
840 intptr_t, const char *);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700841
pbrooka7812ae2008-11-17 14:43:54 +0000842TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700843TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
844
845void tcg_temp_free_i32(TCGv_i32 arg);
846void tcg_temp_free_i64(TCGv_i64 arg);
847
Richard Hendersone1ccc052013-09-18 12:53:09 -0700848static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
849 const char *name)
850{
Richard Henderson085272b2017-10-20 00:05:45 -0700851 TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
852 return temp_tcgv_i32(t);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700853}
854
pbrooka7812ae2008-11-17 14:43:54 +0000855static inline TCGv_i32 tcg_temp_new_i32(void)
bellard641d5fb2008-05-25 17:24:00 +0000856{
pbrooka7812ae2008-11-17 14:43:54 +0000857 return tcg_temp_new_internal_i32(0);
bellard641d5fb2008-05-25 17:24:00 +0000858}
Richard Hendersone1ccc052013-09-18 12:53:09 -0700859
pbrooka7812ae2008-11-17 14:43:54 +0000860static inline TCGv_i32 tcg_temp_local_new_i32(void)
bellard641d5fb2008-05-25 17:24:00 +0000861{
pbrooka7812ae2008-11-17 14:43:54 +0000862 return tcg_temp_new_internal_i32(1);
bellard641d5fb2008-05-25 17:24:00 +0000863}
pbrooka7812ae2008-11-17 14:43:54 +0000864
Richard Hendersone1ccc052013-09-18 12:53:09 -0700865static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
866 const char *name)
867{
Richard Henderson085272b2017-10-20 00:05:45 -0700868 TCGTemp *t = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
869 return temp_tcgv_i64(t);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700870}
871
pbrooka7812ae2008-11-17 14:43:54 +0000872static inline TCGv_i64 tcg_temp_new_i64(void)
873{
874 return tcg_temp_new_internal_i64(0);
875}
Richard Hendersone1ccc052013-09-18 12:53:09 -0700876
pbrooka7812ae2008-11-17 14:43:54 +0000877static inline TCGv_i64 tcg_temp_local_new_i64(void)
878{
879 return tcg_temp_new_internal_i64(1);
880}
pbrooka7812ae2008-11-17 14:43:54 +0000881
Peter Maydell27bfd832011-03-06 21:39:53 +0000882#if defined(CONFIG_DEBUG_TCG)
883/* If you call tcg_clear_temp_count() at the start of a section of
884 * code which is not supposed to leak any TCG temporaries, then
885 * calling tcg_check_temp_count() at the end of the section will
886 * return 1 if the section did in fact leak a temporary.
887 */
888void tcg_clear_temp_count(void);
889int tcg_check_temp_count(void);
890#else
891#define tcg_clear_temp_count() do { } while (0)
892#define tcg_check_temp_count() 0
893#endif
894
Stefan Weil405cf9f2010-10-22 23:03:31 +0200895void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
Max Filippov246ae242014-11-02 11:04:18 +0300896void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf);
bellardc896fe22008-02-01 10:05:41 +0000897
898#define TCG_CT_ALIAS 0x80
899#define TCG_CT_IALIAS 0x40
Richard Henderson82790a82016-11-18 08:35:03 +0100900#define TCG_CT_NEWREG 0x20 /* output requires a new register */
bellardc896fe22008-02-01 10:05:41 +0000901#define TCG_CT_REG 0x01
902#define TCG_CT_CONST 0x02 /* any constant of register size */
903
904typedef struct TCGArgConstraint {
bellard5ff9d6a2008-02-04 00:37:54 +0000905 uint16_t ct;
906 uint8_t alias_index;
bellardc896fe22008-02-01 10:05:41 +0000907 union {
908 TCGRegSet regs;
909 } u;
910} TCGArgConstraint;
911
912#define TCG_MAX_OP_ARGS 16
913
Richard Henderson8399ad52011-08-17 14:11:45 -0700914/* Bits for TCGOpDef->flags, 8 bits available. */
915enum {
916 /* Instruction defines the end of a basic block. */
917 TCG_OPF_BB_END = 0x01,
918 /* Instruction clobbers call registers and potentially update globals. */
919 TCG_OPF_CALL_CLOBBER = 0x02,
Aurelien Jarno3d5c5f82012-10-09 21:53:08 +0200920 /* Instruction has side effects: it cannot be removed if its outputs
921 are not used, and might trigger exceptions. */
Richard Henderson8399ad52011-08-17 14:11:45 -0700922 TCG_OPF_SIDE_EFFECTS = 0x04,
923 /* Instruction operands are 64-bits (otherwise 32-bits). */
924 TCG_OPF_64BIT = 0x08,
Richard Hendersonc1a61f62013-05-02 11:57:40 +0100925 /* Instruction is optional and not implemented by the host, or insn
926 is generic and should not be implemened by the host. */
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700927 TCG_OPF_NOT_PRESENT = 0x10,
Richard Henderson8399ad52011-08-17 14:11:45 -0700928};
bellardc896fe22008-02-01 10:05:41 +0000929
930typedef struct TCGOpDef {
931 const char *name;
932 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
933 uint8_t flags;
bellardc896fe22008-02-01 10:05:41 +0000934 TCGArgConstraint *args_ct;
935 int *sorted_args;
Stefan Weilc68aaa12010-02-15 17:17:21 +0100936#if defined(CONFIG_DEBUG_TCG)
937 int used;
938#endif
bellardc896fe22008-02-01 10:05:41 +0000939} TCGOpDef;
Richard Henderson8399ad52011-08-17 14:11:45 -0700940
941extern TCGOpDef tcg_op_defs[];
Stefan Weil2a243742011-09-29 18:33:21 +0200942extern const size_t tcg_op_defs_max;
943
bellardc896fe22008-02-01 10:05:41 +0000944typedef struct TCGTargetOpDef {
Richard Hendersona9751602010-03-19 11:12:29 -0700945 TCGOpcode op;
bellardc896fe22008-02-01 10:05:41 +0000946 const char *args_ct_str[TCG_MAX_OP_ARGS];
947} TCGTargetOpDef;
948
bellardc896fe22008-02-01 10:05:41 +0000949#define tcg_abort() \
950do {\
951 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
952 abort();\
953} while (0)
954
Richard Henderson8b73d492013-08-20 15:07:08 -0700955#if UINTPTR_MAX == UINT32_MAX
Richard Hendersondc41aa72017-10-20 00:30:24 -0700956static inline TCGv_ptr TCGV_NAT_TO_PTR(TCGv_i32 n) { return (TCGv_ptr)n; }
957static inline TCGv_i32 TCGV_PTR_TO_NAT(TCGv_ptr n) { return (TCGv_i32)n; }
Peter Maydellebecf362011-05-27 13:12:13 +0100958
Richard Henderson8b73d492013-08-20 15:07:08 -0700959#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((intptr_t)(V)))
Peter Maydellebecf362011-05-27 13:12:13 +0100960#define tcg_global_mem_new_ptr(R, O, N) \
961 TCGV_NAT_TO_PTR(tcg_global_mem_new_i32((R), (O), (N)))
962#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i32())
963#define tcg_temp_free_ptr(T) tcg_temp_free_i32(TCGV_PTR_TO_NAT(T))
bellardc896fe22008-02-01 10:05:41 +0000964#else
Richard Hendersondc41aa72017-10-20 00:30:24 -0700965static inline TCGv_ptr TCGV_NAT_TO_PTR(TCGv_i64 n) { return (TCGv_ptr)n; }
966static inline TCGv_i64 TCGV_PTR_TO_NAT(TCGv_ptr n) { return (TCGv_i64)n; }
Peter Maydellebecf362011-05-27 13:12:13 +0100967
Richard Henderson8b73d492013-08-20 15:07:08 -0700968#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((intptr_t)(V)))
Peter Maydellebecf362011-05-27 13:12:13 +0100969#define tcg_global_mem_new_ptr(R, O, N) \
970 TCGV_NAT_TO_PTR(tcg_global_mem_new_i64((R), (O), (N)))
971#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i64())
972#define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T))
bellardc896fe22008-02-01 10:05:41 +0000973#endif
974
Richard Hendersonbe0f34b2017-08-17 07:43:20 -0700975bool tcg_op_supported(TCGOpcode op);
976
Richard Hendersonae8b75d2017-10-15 13:27:56 -0700977void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
pbrooka7812ae2008-11-17 14:43:54 +0000978
Richard Henderson0c627cd2014-03-30 16:51:54 -0700979void tcg_op_remove(TCGContext *s, TCGOp *op);
Richard Henderson5a184072016-06-23 20:34:33 -0700980TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
981TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
982
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700983void tcg_optimize(TCGContext *s);
Kirill Batuzov8f2e8c02011-07-07 16:37:12 +0400984
pbrooka7812ae2008-11-17 14:43:54 +0000985/* only used for debugging purposes */
Blue Swirleeacee42012-06-03 16:35:32 +0000986void tcg_dump_ops(TCGContext *s);
pbrooka7812ae2008-11-17 14:43:54 +0000987
pbrooka7812ae2008-11-17 14:43:54 +0000988TCGv_i32 tcg_const_i32(int32_t val);
989TCGv_i64 tcg_const_i64(int64_t val);
990TCGv_i32 tcg_const_local_i32(int32_t val);
991TCGv_i64 tcg_const_local_i64(int64_t val);
992
Richard Henderson42a268c2015-02-13 12:51:55 -0800993TCGLabel *gen_new_label(void);
994
995/**
996 * label_arg
997 * @l: label
998 *
999 * Encode a label for storage in the TCG opcode stream.
1000 */
1001
1002static inline TCGArg label_arg(TCGLabel *l)
1003{
Richard Henderson51e39722015-02-13 18:51:05 -08001004 return (uintptr_t)l;
Richard Henderson42a268c2015-02-13 12:51:55 -08001005}
1006
1007/**
1008 * arg_label
1009 * @i: value
1010 *
1011 * The opposite of label_arg. Retrieve a label from the
1012 * encoding of the TCG opcode stream.
1013 */
1014
Richard Henderson51e39722015-02-13 18:51:05 -08001015static inline TCGLabel *arg_label(TCGArg i)
Richard Henderson42a268c2015-02-13 12:51:55 -08001016{
Richard Henderson51e39722015-02-13 18:51:05 -08001017 return (TCGLabel *)(uintptr_t)i;
Richard Henderson42a268c2015-02-13 12:51:55 -08001018}
1019
Peter Maydell09800112013-02-22 18:10:00 +00001020/**
Richard Henderson52a1f642014-03-31 14:27:27 -07001021 * tcg_ptr_byte_diff
1022 * @a, @b: addresses to be differenced
1023 *
1024 * There are many places within the TCG backends where we need a byte
1025 * difference between two pointers. While this can be accomplished
1026 * with local casting, it's easy to get wrong -- especially if one is
1027 * concerned with the signedness of the result.
1028 *
1029 * This version relies on GCC's void pointer arithmetic to get the
1030 * correct result.
1031 */
1032
1033static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
1034{
1035 return a - b;
1036}
1037
1038/**
1039 * tcg_pcrel_diff
1040 * @s: the tcg context
1041 * @target: address of the target
1042 *
1043 * Produce a pc-relative difference, from the current code_ptr
1044 * to the destination address.
1045 */
1046
1047static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
1048{
1049 return tcg_ptr_byte_diff(target, s->code_ptr);
1050}
1051
1052/**
1053 * tcg_current_code_size
1054 * @s: the tcg context
1055 *
1056 * Compute the current code size within the translation block.
1057 * This is used to fill in qemu's data structures for goto_tb.
1058 */
1059
1060static inline size_t tcg_current_code_size(TCGContext *s)
1061{
1062 return tcg_ptr_byte_diff(s->code_ptr, s->code_buf);
1063}
1064
Richard Henderson59227d52015-05-12 11:51:44 -07001065/* Combine the TCGMemOp and mmu_idx parameters into a single value. */
1066typedef uint32_t TCGMemOpIdx;
1067
1068/**
1069 * make_memop_idx
1070 * @op: memory operation
1071 * @idx: mmu index
1072 *
1073 * Encode these values into a single parameter.
1074 */
1075static inline TCGMemOpIdx make_memop_idx(TCGMemOp op, unsigned idx)
1076{
1077 tcg_debug_assert(idx <= 15);
1078 return (op << 4) | idx;
1079}
1080
1081/**
1082 * get_memop
1083 * @oi: combined op/idx parameter
1084 *
1085 * Extract the memory operation from the combined value.
1086 */
1087static inline TCGMemOp get_memop(TCGMemOpIdx oi)
1088{
1089 return oi >> 4;
1090}
1091
1092/**
1093 * get_mmuidx
1094 * @oi: combined op/idx parameter
1095 *
1096 * Extract the mmu index from the combined value.
1097 */
1098static inline unsigned get_mmuidx(TCGMemOpIdx oi)
1099{
1100 return oi & 15;
1101}
1102
Richard Henderson52a1f642014-03-31 14:27:27 -07001103/**
Peter Maydell09800112013-02-22 18:10:00 +00001104 * tcg_qemu_tb_exec:
Sergey Fedorov819af242016-04-21 15:58:23 +03001105 * @env: pointer to CPUArchState for the CPU
Peter Maydell09800112013-02-22 18:10:00 +00001106 * @tb_ptr: address of generated code for the TB to execute
1107 *
1108 * Start executing code from a given translation block.
1109 * Where translation blocks have been linked, execution
1110 * may proceed from the given TB into successive ones.
1111 * Control eventually returns only when some action is needed
1112 * from the top-level loop: either control must pass to a TB
1113 * which has not yet been directly linked, or an asynchronous
1114 * event such as an interrupt needs handling.
1115 *
Sergey Fedorov819af242016-04-21 15:58:23 +03001116 * Return: The return value is the value passed to the corresponding
1117 * tcg_gen_exit_tb() at translation time of the last TB attempted to execute.
1118 * The value is either zero or a 4-byte aligned pointer to that TB combined
1119 * with additional information in its two least significant bits. The
1120 * additional information is encoded as follows:
Peter Maydell09800112013-02-22 18:10:00 +00001121 * 0, 1: the link between this TB and the next is via the specified
1122 * TB index (0 or 1). That is, we left the TB via (the equivalent
1123 * of) "goto_tb <index>". The main loop uses this to determine
1124 * how to link the TB just executed to the next.
1125 * 2: we are using instruction counting code generation, and we
1126 * did not start executing this TB because the instruction counter
Sergey Fedorov819af242016-04-21 15:58:23 +03001127 * would hit zero midway through it. In this case the pointer
Peter Maydell09800112013-02-22 18:10:00 +00001128 * returned is the TB we were about to execute, and the caller must
1129 * arrange to execute the remaining count of instructions.
Peter Maydell378df4b2013-02-22 18:10:03 +00001130 * 3: we stopped because the CPU's exit_request flag was set
1131 * (usually meaning that there is an interrupt that needs to be
Sergey Fedorov819af242016-04-21 15:58:23 +03001132 * handled). The pointer returned is the TB we were about to execute
1133 * when we noticed the pending exit request.
Peter Maydell09800112013-02-22 18:10:00 +00001134 *
1135 * If the bottom two bits indicate an exit-via-index then the CPU
1136 * state is correctly synchronised and ready for execution of the next
1137 * TB (and in particular the guest PC is the address to execute next).
1138 * Otherwise, we gave up on execution of this TB before it started, and
Peter Crosthwaitefee068e2015-04-29 00:52:21 -07001139 * the caller must fix up the CPU state by calling the CPU's
Sergey Fedorov819af242016-04-21 15:58:23 +03001140 * synchronize_from_tb() method with the TB pointer we return (falling
Peter Crosthwaitefee068e2015-04-29 00:52:21 -07001141 * back to calling the CPU's set_pc method with tb->pb if no
1142 * synchronize_from_tb() method exists).
Peter Maydell09800112013-02-22 18:10:00 +00001143 *
1144 * Note that TCG targets may use a different definition of tcg_qemu_tb_exec
1145 * to this default (which just calls the prologue.code emitted by
1146 * tcg_target_qemu_prologue()).
1147 */
1148#define TB_EXIT_MASK 3
1149#define TB_EXIT_IDX0 0
1150#define TB_EXIT_IDX1 1
Peter Maydell378df4b2013-02-22 18:10:03 +00001151#define TB_EXIT_REQUESTED 3
Peter Maydell09800112013-02-22 18:10:00 +00001152
Paolo Bonzini5a58e882015-05-19 09:59:34 +02001153#ifdef HAVE_TCG_QEMU_TB_EXEC
1154uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
1155#else
Stefan Weilce285b12011-09-30 21:23:06 +02001156# define tcg_qemu_tb_exec(env, tb_ptr) \
Emilio G. Cotab1311c42017-07-12 17:15:52 -04001157 ((uintptr_t (*)(void *, void *))tcg_ctx->code_gen_prologue)(env, tb_ptr)
bellard932a6902008-05-30 20:56:52 +00001158#endif
Richard Henderson813da622012-03-19 12:25:11 -07001159
1160void tcg_register_jit(void *buf, size_t buf_size);
Yeongkyoon Leeb76f0d82012-10-31 16:04:25 +09001161
Richard Hendersone58eb532013-08-27 13:13:44 -07001162/*
1163 * Memory helpers that will be used by TCG generated code.
1164 */
1165#ifdef CONFIG_SOFTMMU
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001166/* Value zero-extended to tcg register size. */
1167tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001168 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001169tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001170 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001171tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001172 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001173uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001174 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001175tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001176 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001177tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001178 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001179uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001180 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Hendersone58eb532013-08-27 13:13:44 -07001181
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001182/* Value sign-extended to tcg register size. */
1183tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001184 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001185tcg_target_ulong helper_le_ldsw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001186 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001187tcg_target_ulong helper_le_ldsl_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001188 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001189tcg_target_ulong helper_be_ldsw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001190 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001191tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001192 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001193
Richard Hendersone58eb532013-08-27 13:13:44 -07001194void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001195 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001196void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001197 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001198void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001199 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001200void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001201 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001202void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001203 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001204void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001205 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001206void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001207 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001208
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001209uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
1210 TCGMemOpIdx oi, uintptr_t retaddr);
1211uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
1212 TCGMemOpIdx oi, uintptr_t retaddr);
1213uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
1214 TCGMemOpIdx oi, uintptr_t retaddr);
1215uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
1216 TCGMemOpIdx oi, uintptr_t retaddr);
1217uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
1218 TCGMemOpIdx oi, uintptr_t retaddr);
1219uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
1220 TCGMemOpIdx oi, uintptr_t retaddr);
1221uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
1222 TCGMemOpIdx oi, uintptr_t retaddr);
1223
Richard Henderson867b3202013-09-04 11:45:20 -07001224/* Temporary aliases until backends are converted. */
1225#ifdef TARGET_WORDS_BIGENDIAN
1226# define helper_ret_ldsw_mmu helper_be_ldsw_mmu
1227# define helper_ret_lduw_mmu helper_be_lduw_mmu
1228# define helper_ret_ldsl_mmu helper_be_ldsl_mmu
1229# define helper_ret_ldul_mmu helper_be_ldul_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001230# define helper_ret_ldl_mmu helper_be_ldul_mmu
Richard Henderson867b3202013-09-04 11:45:20 -07001231# define helper_ret_ldq_mmu helper_be_ldq_mmu
1232# define helper_ret_stw_mmu helper_be_stw_mmu
1233# define helper_ret_stl_mmu helper_be_stl_mmu
1234# define helper_ret_stq_mmu helper_be_stq_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001235# define helper_ret_ldw_cmmu helper_be_ldw_cmmu
1236# define helper_ret_ldl_cmmu helper_be_ldl_cmmu
1237# define helper_ret_ldq_cmmu helper_be_ldq_cmmu
Richard Henderson867b3202013-09-04 11:45:20 -07001238#else
1239# define helper_ret_ldsw_mmu helper_le_ldsw_mmu
1240# define helper_ret_lduw_mmu helper_le_lduw_mmu
1241# define helper_ret_ldsl_mmu helper_le_ldsl_mmu
1242# define helper_ret_ldul_mmu helper_le_ldul_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001243# define helper_ret_ldl_mmu helper_le_ldul_mmu
Richard Henderson867b3202013-09-04 11:45:20 -07001244# define helper_ret_ldq_mmu helper_le_ldq_mmu
1245# define helper_ret_stw_mmu helper_le_stw_mmu
1246# define helper_ret_stl_mmu helper_le_stl_mmu
1247# define helper_ret_stq_mmu helper_le_stq_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001248# define helper_ret_ldw_cmmu helper_le_ldw_cmmu
1249# define helper_ret_ldl_cmmu helper_le_ldl_cmmu
1250# define helper_ret_ldq_cmmu helper_le_ldq_cmmu
Richard Henderson867b3202013-09-04 11:45:20 -07001251#endif
Richard Hendersone58eb532013-08-27 13:13:44 -07001252
Richard Hendersonc482cb12016-06-28 11:37:27 -07001253uint32_t helper_atomic_cmpxchgb_mmu(CPUArchState *env, target_ulong addr,
1254 uint32_t cmpv, uint32_t newv,
1255 TCGMemOpIdx oi, uintptr_t retaddr);
1256uint32_t helper_atomic_cmpxchgw_le_mmu(CPUArchState *env, target_ulong addr,
1257 uint32_t cmpv, uint32_t newv,
1258 TCGMemOpIdx oi, uintptr_t retaddr);
1259uint32_t helper_atomic_cmpxchgl_le_mmu(CPUArchState *env, target_ulong addr,
1260 uint32_t cmpv, uint32_t newv,
1261 TCGMemOpIdx oi, uintptr_t retaddr);
1262uint64_t helper_atomic_cmpxchgq_le_mmu(CPUArchState *env, target_ulong addr,
1263 uint64_t cmpv, uint64_t newv,
1264 TCGMemOpIdx oi, uintptr_t retaddr);
1265uint32_t helper_atomic_cmpxchgw_be_mmu(CPUArchState *env, target_ulong addr,
1266 uint32_t cmpv, uint32_t newv,
1267 TCGMemOpIdx oi, uintptr_t retaddr);
1268uint32_t helper_atomic_cmpxchgl_be_mmu(CPUArchState *env, target_ulong addr,
1269 uint32_t cmpv, uint32_t newv,
1270 TCGMemOpIdx oi, uintptr_t retaddr);
1271uint64_t helper_atomic_cmpxchgq_be_mmu(CPUArchState *env, target_ulong addr,
1272 uint64_t cmpv, uint64_t newv,
1273 TCGMemOpIdx oi, uintptr_t retaddr);
1274
1275#define GEN_ATOMIC_HELPER(NAME, TYPE, SUFFIX) \
1276TYPE helper_atomic_ ## NAME ## SUFFIX ## _mmu \
1277 (CPUArchState *env, target_ulong addr, TYPE val, \
1278 TCGMemOpIdx oi, uintptr_t retaddr);
1279
Richard Hendersondf79b992016-09-02 12:23:57 -07001280#ifdef CONFIG_ATOMIC64
Richard Hendersonc482cb12016-06-28 11:37:27 -07001281#define GEN_ATOMIC_HELPER_ALL(NAME) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001282 GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001283 GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001284 GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001285 GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001286 GEN_ATOMIC_HELPER(NAME, uint32_t, l_be) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001287 GEN_ATOMIC_HELPER(NAME, uint64_t, q_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001288 GEN_ATOMIC_HELPER(NAME, uint64_t, q_be)
Richard Hendersondf79b992016-09-02 12:23:57 -07001289#else
1290#define GEN_ATOMIC_HELPER_ALL(NAME) \
1291 GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
1292 GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
1293 GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
1294 GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
1295 GEN_ATOMIC_HELPER(NAME, uint32_t, l_be)
1296#endif
Richard Hendersonc482cb12016-06-28 11:37:27 -07001297
1298GEN_ATOMIC_HELPER_ALL(fetch_add)
1299GEN_ATOMIC_HELPER_ALL(fetch_sub)
1300GEN_ATOMIC_HELPER_ALL(fetch_and)
1301GEN_ATOMIC_HELPER_ALL(fetch_or)
1302GEN_ATOMIC_HELPER_ALL(fetch_xor)
1303
1304GEN_ATOMIC_HELPER_ALL(add_fetch)
1305GEN_ATOMIC_HELPER_ALL(sub_fetch)
1306GEN_ATOMIC_HELPER_ALL(and_fetch)
1307GEN_ATOMIC_HELPER_ALL(or_fetch)
1308GEN_ATOMIC_HELPER_ALL(xor_fetch)
1309
1310GEN_ATOMIC_HELPER_ALL(xchg)
1311
1312#undef GEN_ATOMIC_HELPER_ALL
1313#undef GEN_ATOMIC_HELPER
Richard Hendersone58eb532013-08-27 13:13:44 -07001314#endif /* CONFIG_SOFTMMU */
1315
Richard Henderson7ebee432016-06-29 21:10:59 -07001316#ifdef CONFIG_ATOMIC128
1317#include "qemu/int128.h"
1318
1319/* These aren't really a "proper" helpers because TCG cannot manage Int128.
1320 However, use the same format as the others, for use by the backends. */
1321Int128 helper_atomic_cmpxchgo_le_mmu(CPUArchState *env, target_ulong addr,
1322 Int128 cmpv, Int128 newv,
1323 TCGMemOpIdx oi, uintptr_t retaddr);
1324Int128 helper_atomic_cmpxchgo_be_mmu(CPUArchState *env, target_ulong addr,
1325 Int128 cmpv, Int128 newv,
1326 TCGMemOpIdx oi, uintptr_t retaddr);
1327
1328Int128 helper_atomic_ldo_le_mmu(CPUArchState *env, target_ulong addr,
1329 TCGMemOpIdx oi, uintptr_t retaddr);
1330Int128 helper_atomic_ldo_be_mmu(CPUArchState *env, target_ulong addr,
1331 TCGMemOpIdx oi, uintptr_t retaddr);
1332void helper_atomic_sto_le_mmu(CPUArchState *env, target_ulong addr, Int128 val,
1333 TCGMemOpIdx oi, uintptr_t retaddr);
1334void helper_atomic_sto_be_mmu(CPUArchState *env, target_ulong addr, Int128 val,
1335 TCGMemOpIdx oi, uintptr_t retaddr);
1336
1337#endif /* CONFIG_ATOMIC128 */
1338
Richard Hendersone58eb532013-08-27 13:13:44 -07001339#endif /* TCG_H */