blob: 6c216bb73fe0bd347367af25b2b6db7221104966 [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
54#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
55
Peter Crosthwaite6e0b0732015-05-30 23:11:34 -070056#define CPU_TEMP_BUF_NLONGS 128
57
Richard Henderson78cd7b82013-08-20 14:41:29 -070058/* Default target word size to pointer size. */
59#ifndef TCG_TARGET_REG_BITS
60# if UINTPTR_MAX == UINT32_MAX
61# define TCG_TARGET_REG_BITS 32
62# elif UINTPTR_MAX == UINT64_MAX
63# define TCG_TARGET_REG_BITS 64
64# else
65# error Unknown pointer size for tcg target
66# endif
Stefan Weil817b8382011-09-17 22:00:27 +020067#endif
68
bellardc896fe22008-02-01 10:05:41 +000069#if TCG_TARGET_REG_BITS == 32
70typedef int32_t tcg_target_long;
71typedef uint32_t tcg_target_ulong;
72#define TCG_PRIlx PRIx32
73#define TCG_PRIld PRId32
74#elif TCG_TARGET_REG_BITS == 64
75typedef int64_t tcg_target_long;
76typedef uint64_t tcg_target_ulong;
77#define TCG_PRIlx PRIx64
78#define TCG_PRIld PRId64
79#else
80#error unsupported
81#endif
82
KONRAD Frederic8d4e9142017-02-23 18:29:08 +000083/* Oversized TCG guests make things like MTTCG hard
84 * as we can't use atomics for cputlb updates.
85 */
86#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
87#define TCG_OVERSIZED_GUEST 1
88#else
89#define TCG_OVERSIZED_GUEST 0
90#endif
91
bellardc896fe22008-02-01 10:05:41 +000092#if TCG_TARGET_NB_REGS <= 32
93typedef uint32_t TCGRegSet;
94#elif TCG_TARGET_NB_REGS <= 64
95typedef uint64_t TCGRegSet;
96#else
97#error unsupported
98#endif
99
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700100#if TCG_TARGET_REG_BITS == 32
Richard Hendersone6a72732013-02-19 23:51:49 -0800101/* Turn some undef macros into false macros. */
Richard Henderson609ad702015-07-24 07:16:00 -0700102#define TCG_TARGET_HAS_extrl_i64_i32 0
103#define TCG_TARGET_HAS_extrh_i64_i32 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700104#define TCG_TARGET_HAS_div_i64 0
Richard Hendersonca675f42013-03-11 22:41:47 -0700105#define TCG_TARGET_HAS_rem_i64 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700106#define TCG_TARGET_HAS_div2_i64 0
107#define TCG_TARGET_HAS_rot_i64 0
108#define TCG_TARGET_HAS_ext8s_i64 0
109#define TCG_TARGET_HAS_ext16s_i64 0
110#define TCG_TARGET_HAS_ext32s_i64 0
111#define TCG_TARGET_HAS_ext8u_i64 0
112#define TCG_TARGET_HAS_ext16u_i64 0
113#define TCG_TARGET_HAS_ext32u_i64 0
114#define TCG_TARGET_HAS_bswap16_i64 0
115#define TCG_TARGET_HAS_bswap32_i64 0
116#define TCG_TARGET_HAS_bswap64_i64 0
117#define TCG_TARGET_HAS_neg_i64 0
118#define TCG_TARGET_HAS_not_i64 0
119#define TCG_TARGET_HAS_andc_i64 0
120#define TCG_TARGET_HAS_orc_i64 0
121#define TCG_TARGET_HAS_eqv_i64 0
122#define TCG_TARGET_HAS_nand_i64 0
123#define TCG_TARGET_HAS_nor_i64 0
Richard Henderson0e28d002016-11-16 09:23:28 +0100124#define TCG_TARGET_HAS_clz_i64 0
125#define TCG_TARGET_HAS_ctz_i64 0
Richard Hendersona768e4e2016-11-21 11:13:39 +0100126#define TCG_TARGET_HAS_ctpop_i64 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700127#define TCG_TARGET_HAS_deposit_i64 0
Richard Henderson7ec8bab2016-10-14 12:04:32 -0500128#define TCG_TARGET_HAS_extract_i64 0
129#define TCG_TARGET_HAS_sextract_i64 0
Richard Hendersonffc5ea02012-09-21 10:13:34 -0700130#define TCG_TARGET_HAS_movcond_i64 0
Richard Hendersond7156f72013-02-19 23:51:52 -0800131#define TCG_TARGET_HAS_add2_i64 0
132#define TCG_TARGET_HAS_sub2_i64 0
133#define TCG_TARGET_HAS_mulu2_i64 0
Richard Henderson4d3203f2013-02-19 23:51:53 -0800134#define TCG_TARGET_HAS_muls2_i64 0
Richard Henderson03271522013-08-14 14:35:56 -0700135#define TCG_TARGET_HAS_muluh_i64 0
136#define TCG_TARGET_HAS_mulsh_i64 0
Richard Hendersone6a72732013-02-19 23:51:49 -0800137/* Turn some undef macros into true macros. */
138#define TCG_TARGET_HAS_add2_i32 1
139#define TCG_TARGET_HAS_sub2_i32 1
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700140#endif
141
Jan Kiszkaa4773322011-09-29 18:52:11 +0200142#ifndef TCG_TARGET_deposit_i32_valid
143#define TCG_TARGET_deposit_i32_valid(ofs, len) 1
144#endif
145#ifndef TCG_TARGET_deposit_i64_valid
146#define TCG_TARGET_deposit_i64_valid(ofs, len) 1
147#endif
Richard Henderson7ec8bab2016-10-14 12:04:32 -0500148#ifndef TCG_TARGET_extract_i32_valid
149#define TCG_TARGET_extract_i32_valid(ofs, len) 1
150#endif
151#ifndef TCG_TARGET_extract_i64_valid
152#define TCG_TARGET_extract_i64_valid(ofs, len) 1
153#endif
Jan Kiszkaa4773322011-09-29 18:52:11 +0200154
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700155/* Only one of DIV or DIV2 should be defined. */
156#if defined(TCG_TARGET_HAS_div_i32)
157#define TCG_TARGET_HAS_div2_i32 0
158#elif defined(TCG_TARGET_HAS_div2_i32)
159#define TCG_TARGET_HAS_div_i32 0
Richard Hendersonca675f42013-03-11 22:41:47 -0700160#define TCG_TARGET_HAS_rem_i32 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700161#endif
162#if defined(TCG_TARGET_HAS_div_i64)
163#define TCG_TARGET_HAS_div2_i64 0
164#elif defined(TCG_TARGET_HAS_div2_i64)
165#define TCG_TARGET_HAS_div_i64 0
Richard Hendersonca675f42013-03-11 22:41:47 -0700166#define TCG_TARGET_HAS_rem_i64 0
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700167#endif
168
Richard Hendersondf9ebea2014-03-26 10:59:14 -0700169/* For 32-bit targets, some sort of unsigned widening multiply is required. */
170#if TCG_TARGET_REG_BITS == 32 \
171 && !(defined(TCG_TARGET_HAS_mulu2_i32) \
172 || defined(TCG_TARGET_HAS_muluh_i32))
173# error "Missing unsigned widening multiply"
174#endif
175
Richard Henderson9aef40e2015-08-30 09:21:33 -0700176#ifndef TARGET_INSN_START_EXTRA_WORDS
177# define TARGET_INSN_START_WORDS 1
178#else
179# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS)
180#endif
181
Richard Hendersona9751602010-03-19 11:12:29 -0700182typedef enum TCGOpcode {
Aurelien Jarnoc61aaf72010-06-03 19:40:04 +0200183#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
bellardc896fe22008-02-01 10:05:41 +0000184#include "tcg-opc.h"
185#undef DEF
186 NB_OPS,
Richard Hendersona9751602010-03-19 11:12:29 -0700187} TCGOpcode;
bellardc896fe22008-02-01 10:05:41 +0000188
189#define tcg_regset_clear(d) (d) = 0
190#define tcg_regset_set(d, s) (d) = (s)
191#define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg)
Aurelien Jarno7d301752009-10-28 22:44:34 +0100192#define tcg_regset_set_reg(d, r) (d) |= 1L << (r)
193#define tcg_regset_reset_reg(d, r) (d) &= ~(1L << (r))
bellardc896fe22008-02-01 10:05:41 +0000194#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
195#define tcg_regset_or(d, a, b) (d) = (a) | (b)
196#define tcg_regset_and(d, a, b) (d) = (a) & (b)
197#define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b)
198#define tcg_regset_not(d, a) (d) = ~(a)
199
Richard Henderson1813e172014-03-28 12:56:22 -0700200#ifndef TCG_TARGET_INSN_UNIT_SIZE
Richard Henderson50533612014-04-28 12:01:23 -0700201# error "Missing TCG_TARGET_INSN_UNIT_SIZE"
202#elif TCG_TARGET_INSN_UNIT_SIZE == 1
Richard Henderson1813e172014-03-28 12:56:22 -0700203typedef uint8_t tcg_insn_unit;
204#elif TCG_TARGET_INSN_UNIT_SIZE == 2
205typedef uint16_t tcg_insn_unit;
206#elif TCG_TARGET_INSN_UNIT_SIZE == 4
207typedef uint32_t tcg_insn_unit;
208#elif TCG_TARGET_INSN_UNIT_SIZE == 8
209typedef uint64_t tcg_insn_unit;
210#else
211/* The port better have done this. */
212#endif
213
214
Paolo Bonzini8bff06a2016-07-15 18:27:40 +0200215#if defined CONFIG_DEBUG_TCG || defined QEMU_STATIC_ANALYSIS
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300216# define tcg_debug_assert(X) do { assert(X); } while (0)
217#elif QEMU_GNUC_PREREQ(4, 5)
218# define tcg_debug_assert(X) \
219 do { if (!(X)) { __builtin_unreachable(); } } while (0)
220#else
221# define tcg_debug_assert(X) do { (void)(X); } while (0)
222#endif
223
bellardc896fe22008-02-01 10:05:41 +0000224typedef struct TCGRelocation {
225 struct TCGRelocation *next;
226 int type;
Richard Henderson1813e172014-03-28 12:56:22 -0700227 tcg_insn_unit *ptr;
Richard Henderson2ba7fae22013-08-20 15:30:10 -0700228 intptr_t addend;
bellardc896fe22008-02-01 10:05:41 +0000229} TCGRelocation;
230
231typedef struct TCGLabel {
Richard Henderson51e39722015-02-13 18:51:05 -0800232 unsigned has_value : 1;
233 unsigned id : 31;
bellardc896fe22008-02-01 10:05:41 +0000234 union {
Richard Henderson2ba7fae22013-08-20 15:30:10 -0700235 uintptr_t value;
Richard Henderson1813e172014-03-28 12:56:22 -0700236 tcg_insn_unit *value_ptr;
bellardc896fe22008-02-01 10:05:41 +0000237 TCGRelocation *first_reloc;
238 } u;
239} TCGLabel;
240
241typedef struct TCGPool {
242 struct TCGPool *next;
blueswir1c44f9452008-05-19 16:32:18 +0000243 int size;
244 uint8_t data[0] __attribute__ ((aligned));
bellardc896fe22008-02-01 10:05:41 +0000245} TCGPool;
246
247#define TCG_POOL_CHUNK_SIZE 32768
248
blueswir1c4071c92008-03-16 19:21:07 +0000249#define TCG_MAX_TEMPS 512
Richard Henderson190ce7f2015-08-31 14:34:41 -0700250#define TCG_MAX_INSNS 512
bellardc896fe22008-02-01 10:05:41 +0000251
bellardb03cce82008-05-10 10:52:05 +0000252/* when the size of the arguments of a called function is smaller than
253 this value, they are statically allocated in the TB stack frame */
254#define TCG_STATIC_CALL_ARGS_SIZE 128
255
Richard Hendersonc02244a2010-03-19 11:36:30 -0700256typedef enum TCGType {
257 TCG_TYPE_I32,
258 TCG_TYPE_I64,
259 TCG_TYPE_COUNT, /* number of different types */
bellardc896fe22008-02-01 10:05:41 +0000260
Richard Henderson3b6dac32010-06-02 17:26:55 -0700261 /* An alias for the size of the host register. */
bellardc896fe22008-02-01 10:05:41 +0000262#if TCG_TARGET_REG_BITS == 32
Richard Henderson3b6dac32010-06-02 17:26:55 -0700263 TCG_TYPE_REG = TCG_TYPE_I32,
bellardc896fe22008-02-01 10:05:41 +0000264#else
Richard Henderson3b6dac32010-06-02 17:26:55 -0700265 TCG_TYPE_REG = TCG_TYPE_I64,
bellardc896fe22008-02-01 10:05:41 +0000266#endif
Richard Henderson3b6dac32010-06-02 17:26:55 -0700267
Richard Hendersond2898372013-08-20 14:48:46 -0700268 /* An alias for the size of the native pointer. */
269#if UINTPTR_MAX == UINT32_MAX
270 TCG_TYPE_PTR = TCG_TYPE_I32,
271#else
272 TCG_TYPE_PTR = TCG_TYPE_I64,
273#endif
Richard Henderson3b6dac32010-06-02 17:26:55 -0700274
275 /* An alias for the size of the target "long", aka register. */
Richard Hendersonc02244a2010-03-19 11:36:30 -0700276#if TARGET_LONG_BITS == 64
277 TCG_TYPE_TL = TCG_TYPE_I64,
278#else
279 TCG_TYPE_TL = TCG_TYPE_I32,
280#endif
281} TCGType;
bellardc896fe22008-02-01 10:05:41 +0000282
Richard Henderson6c5f4ea2013-09-03 13:52:19 -0700283/* Constants for qemu_ld and qemu_st for the Memory Operation field. */
284typedef enum TCGMemOp {
285 MO_8 = 0,
286 MO_16 = 1,
287 MO_32 = 2,
288 MO_64 = 3,
289 MO_SIZE = 3, /* Mask for the above. */
290
291 MO_SIGN = 4, /* Sign-extended, otherwise zero-extended. */
292
293 MO_BSWAP = 8, /* Host reverse endian. */
294#ifdef HOST_WORDS_BIGENDIAN
295 MO_LE = MO_BSWAP,
296 MO_BE = 0,
297#else
298 MO_LE = 0,
299 MO_BE = MO_BSWAP,
300#endif
301#ifdef TARGET_WORDS_BIGENDIAN
302 MO_TE = MO_BE,
303#else
304 MO_TE = MO_LE,
305#endif
306
Richard Hendersondfb36302015-05-13 11:25:20 -0700307 /* MO_UNALN accesses are never checked for alignment.
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300308 * MO_ALIGN accesses will result in a call to the CPU's
309 * do_unaligned_access hook if the guest address is not aligned.
310 * The default depends on whether the target CPU defines ALIGNED_ONLY.
Richard Henderson85aa8082016-07-14 12:43:06 -0700311 *
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300312 * Some architectures (e.g. ARMv8) need the address which is aligned
313 * to a size more than the size of the memory access.
Richard Henderson85aa8082016-07-14 12:43:06 -0700314 * Some architectures (e.g. SPARCv9) need an address which is aligned,
315 * but less strictly than the natural alignment.
316 *
317 * MO_ALIGN supposes the alignment size is the size of a memory access.
318 *
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300319 * There are three options:
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300320 * - unaligned access permitted (MO_UNALN).
Richard Henderson85aa8082016-07-14 12:43:06 -0700321 * - an alignment to the size of an access (MO_ALIGN);
322 * - an alignment to a specified size, which may be more or less than
323 * the access size (MO_ALIGN_x where 'x' is a size in bytes);
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300324 */
325 MO_ASHIFT = 4,
326 MO_AMASK = 7 << MO_ASHIFT,
Richard Hendersondfb36302015-05-13 11:25:20 -0700327#ifdef ALIGNED_ONLY
328 MO_ALIGN = 0,
329 MO_UNALN = MO_AMASK,
330#else
331 MO_ALIGN = MO_AMASK,
332 MO_UNALN = 0,
333#endif
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300334 MO_ALIGN_2 = 1 << MO_ASHIFT,
335 MO_ALIGN_4 = 2 << MO_ASHIFT,
336 MO_ALIGN_8 = 3 << MO_ASHIFT,
337 MO_ALIGN_16 = 4 << MO_ASHIFT,
338 MO_ALIGN_32 = 5 << MO_ASHIFT,
339 MO_ALIGN_64 = 6 << MO_ASHIFT,
Richard Hendersondfb36302015-05-13 11:25:20 -0700340
Richard Henderson6c5f4ea2013-09-03 13:52:19 -0700341 /* Combinations of the above, for ease of use. */
342 MO_UB = MO_8,
343 MO_UW = MO_16,
344 MO_UL = MO_32,
345 MO_SB = MO_SIGN | MO_8,
346 MO_SW = MO_SIGN | MO_16,
347 MO_SL = MO_SIGN | MO_32,
348 MO_Q = MO_64,
349
350 MO_LEUW = MO_LE | MO_UW,
351 MO_LEUL = MO_LE | MO_UL,
352 MO_LESW = MO_LE | MO_SW,
353 MO_LESL = MO_LE | MO_SL,
354 MO_LEQ = MO_LE | MO_Q,
355
356 MO_BEUW = MO_BE | MO_UW,
357 MO_BEUL = MO_BE | MO_UL,
358 MO_BESW = MO_BE | MO_SW,
359 MO_BESL = MO_BE | MO_SL,
360 MO_BEQ = MO_BE | MO_Q,
361
362 MO_TEUW = MO_TE | MO_UW,
363 MO_TEUL = MO_TE | MO_UL,
364 MO_TESW = MO_TE | MO_SW,
365 MO_TESL = MO_TE | MO_SL,
366 MO_TEQ = MO_TE | MO_Q,
367
368 MO_SSIZE = MO_SIZE | MO_SIGN,
369} TCGMemOp;
370
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300371/**
372 * get_alignment_bits
373 * @memop: TCGMemOp value
374 *
375 * Extract the alignment size from the memop.
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300376 */
Richard Henderson85aa8082016-07-14 12:43:06 -0700377static inline unsigned get_alignment_bits(TCGMemOp memop)
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300378{
Richard Henderson85aa8082016-07-14 12:43:06 -0700379 unsigned a = memop & MO_AMASK;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300380
381 if (a == MO_UNALN) {
Richard Henderson85aa8082016-07-14 12:43:06 -0700382 /* No alignment required. */
383 a = 0;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300384 } else if (a == MO_ALIGN) {
Richard Henderson85aa8082016-07-14 12:43:06 -0700385 /* A natural alignment requirement. */
386 a = memop & MO_SIZE;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300387 } else {
Richard Henderson85aa8082016-07-14 12:43:06 -0700388 /* A specific alignment requirement. */
389 a = a >> MO_ASHIFT;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300390 }
391#if defined(CONFIG_SOFTMMU)
392 /* The requested alignment cannot overlap the TLB flags. */
Richard Henderson85aa8082016-07-14 12:43:06 -0700393 tcg_debug_assert((TLB_FLAGS_MASK & ((1 << a) - 1)) == 0);
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300394#endif
Richard Henderson85aa8082016-07-14 12:43:06 -0700395 return a;
Sergey Sorokin1f00b272016-06-23 21:16:46 +0300396}
397
bellardc896fe22008-02-01 10:05:41 +0000398typedef tcg_target_ulong TCGArg;
399
Peter Maydella40d4702016-10-21 17:38:42 +0100400/* Define type and accessor macros for TCG variables.
401
402 TCG variables are the inputs and outputs of TCG ops, as described
403 in tcg/README. Target CPU front-end code uses these types to deal
404 with TCG variables as it emits TCG code via the tcg_gen_* functions.
405 They come in several flavours:
406 * TCGv_i32 : 32 bit integer type
407 * TCGv_i64 : 64 bit integer type
408 * TCGv_ptr : a host pointer type
409 * TCGv : an integer type the same size as target_ulong
410 (an alias for either TCGv_i32 or TCGv_i64)
411 The compiler's type checking will complain if you mix them
412 up and pass the wrong sized TCGv to a function.
413
414 Users of tcg_gen_* don't need to know about any of the internal
415 details of these, and should treat them as opaque types.
416 You won't be able to look inside them in a debugger either.
417
418 Internal implementation details follow:
419
420 Note that there is no definition of the structs TCGv_i32_d etc anywhere.
421 This is deliberate, because the values we store in variables of type
422 TCGv_i32 are not really pointers-to-structures. They're just small
423 integers, but keeping them in pointer types like this means that the
424 compiler will complain if you accidentally pass a TCGv_i32 to a
425 function which takes a TCGv_i64, and so on. Only the internals of
426 TCG need to care about the actual contents of the types, and they always
427 box and unbox via the MAKE_TCGV_* and GET_TCGV_* functions.
428 Converting to and from intptr_t rather than int reduces the number
429 of sign-extension instructions that get implied on 64-bit hosts. */
pbrookac56dd42008-02-03 19:56:33 +0000430
Richard Hendersonb6c73a62014-09-16 09:51:46 -0700431typedef struct TCGv_i32_d *TCGv_i32;
432typedef struct TCGv_i64_d *TCGv_i64;
433typedef struct TCGv_ptr_d *TCGv_ptr;
LluĂ­s Vilanova1bcea732016-02-25 17:43:15 +0100434typedef TCGv_ptr TCGv_env;
LluĂ­s Vilanova5d4e1a12016-02-25 17:43:21 +0100435#if TARGET_LONG_BITS == 32
436#define TCGv TCGv_i32
437#elif TARGET_LONG_BITS == 64
438#define TCGv TCGv_i64
439#else
440#error Unhandled TARGET_LONG_BITS value
441#endif
pbrookac56dd42008-02-03 19:56:33 +0000442
Richard Hendersonb6c73a62014-09-16 09:51:46 -0700443static inline TCGv_i32 QEMU_ARTIFICIAL MAKE_TCGV_I32(intptr_t i)
pbrookac56dd42008-02-03 19:56:33 +0000444{
Richard Hendersonb6c73a62014-09-16 09:51:46 -0700445 return (TCGv_i32)i;
446}
pbrookac56dd42008-02-03 19:56:33 +0000447
Richard Hendersonb6c73a62014-09-16 09:51:46 -0700448static inline TCGv_i64 QEMU_ARTIFICIAL MAKE_TCGV_I64(intptr_t i)
pbrooka7812ae2008-11-17 14:43:54 +0000449{
Richard Hendersonb6c73a62014-09-16 09:51:46 -0700450 return (TCGv_i64)i;
451}
pbrooka7812ae2008-11-17 14:43:54 +0000452
Richard Hendersonb6c73a62014-09-16 09:51:46 -0700453static inline TCGv_ptr QEMU_ARTIFICIAL MAKE_TCGV_PTR(intptr_t i)
454{
455 return (TCGv_ptr)i;
456}
Peter Maydellebecf362011-05-27 13:12:13 +0100457
Richard Hendersonb6c73a62014-09-16 09:51:46 -0700458static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_I32(TCGv_i32 t)
459{
460 return (intptr_t)t;
461}
462
463static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_I64(TCGv_i64 t)
464{
465 return (intptr_t)t;
466}
467
468static inline intptr_t QEMU_ARTIFICIAL GET_TCGV_PTR(TCGv_ptr t)
469{
470 return (intptr_t)t;
471}
472
pbrookac56dd42008-02-03 19:56:33 +0000473#if TCG_TARGET_REG_BITS == 32
pbrooka7812ae2008-11-17 14:43:54 +0000474#define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
475#define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
pbrookac56dd42008-02-03 19:56:33 +0000476#endif
477
aurel3243e860e2009-03-10 10:29:45 +0000478#define TCGV_EQUAL_I32(a, b) (GET_TCGV_I32(a) == GET_TCGV_I32(b))
479#define TCGV_EQUAL_I64(a, b) (GET_TCGV_I64(a) == GET_TCGV_I64(b))
Peter Maydellc1de7882014-02-08 14:46:55 +0000480#define TCGV_EQUAL_PTR(a, b) (GET_TCGV_PTR(a) == GET_TCGV_PTR(b))
aurel3243e860e2009-03-10 10:29:45 +0000481
pbrooka50f5b92008-06-29 15:25:29 +0000482/* Dummy definition to avoid compiler warnings. */
pbrooka7812ae2008-11-17 14:43:54 +0000483#define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1)
484#define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1)
Peter Maydellc1de7882014-02-08 14:46:55 +0000485#define TCGV_UNUSED_PTR(x) x = MAKE_TCGV_PTR(-1)
pbrooka50f5b92008-06-29 15:25:29 +0000486
Richard Hendersonafcb92b2012-12-07 15:07:17 -0600487#define TCGV_IS_UNUSED_I32(x) (GET_TCGV_I32(x) == -1)
488#define TCGV_IS_UNUSED_I64(x) (GET_TCGV_I64(x) == -1)
Peter Maydellc1de7882014-02-08 14:46:55 +0000489#define TCGV_IS_UNUSED_PTR(x) (GET_TCGV_PTR(x) == -1)
Richard Hendersonafcb92b2012-12-07 15:07:17 -0600490
bellardc896fe22008-02-01 10:05:41 +0000491/* call flags */
Aurelien Jarno78505272012-10-09 21:53:08 +0200492/* Helper does not read globals (either directly or through an exception). It
493 implies TCG_CALL_NO_WRITE_GLOBALS. */
494#define TCG_CALL_NO_READ_GLOBALS 0x0010
495/* Helper does not write globals */
496#define TCG_CALL_NO_WRITE_GLOBALS 0x0020
497/* Helper can be safely suppressed if the return value is not used. */
498#define TCG_CALL_NO_SIDE_EFFECTS 0x0040
499
500/* convenience version of most used call flags */
501#define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS
502#define TCG_CALL_NO_WG TCG_CALL_NO_WRITE_GLOBALS
503#define TCG_CALL_NO_SE TCG_CALL_NO_SIDE_EFFECTS
504#define TCG_CALL_NO_RWG_SE (TCG_CALL_NO_RWG | TCG_CALL_NO_SE)
505#define TCG_CALL_NO_WG_SE (TCG_CALL_NO_WG | TCG_CALL_NO_SE)
506
bellard39cf05d2008-05-22 14:59:57 +0000507/* used to align parameters */
pbrooka7812ae2008-11-17 14:43:54 +0000508#define TCG_CALL_DUMMY_TCGV MAKE_TCGV_I32(-1)
bellard39cf05d2008-05-22 14:59:57 +0000509#define TCG_CALL_DUMMY_ARG ((TCGArg)(-1))
510
Stefan Weila93cf9d2012-11-02 08:29:53 +0100511/* Conditions. Note that these are laid out for easy manipulation by
512 the functions below:
Richard Henderson0aed2572012-09-24 14:21:40 -0700513 bit 0 is used for inverting;
514 bit 1 is signed,
515 bit 2 is unsigned,
516 bit 3 is used with bit 0 for swapping signed/unsigned. */
bellardc896fe22008-02-01 10:05:41 +0000517typedef enum {
Richard Henderson0aed2572012-09-24 14:21:40 -0700518 /* non-signed */
519 TCG_COND_NEVER = 0 | 0 | 0 | 0,
520 TCG_COND_ALWAYS = 0 | 0 | 0 | 1,
521 TCG_COND_EQ = 8 | 0 | 0 | 0,
522 TCG_COND_NE = 8 | 0 | 0 | 1,
523 /* signed */
524 TCG_COND_LT = 0 | 0 | 2 | 0,
525 TCG_COND_GE = 0 | 0 | 2 | 1,
526 TCG_COND_LE = 8 | 0 | 2 | 0,
527 TCG_COND_GT = 8 | 0 | 2 | 1,
bellardc896fe22008-02-01 10:05:41 +0000528 /* unsigned */
Richard Henderson0aed2572012-09-24 14:21:40 -0700529 TCG_COND_LTU = 0 | 4 | 0 | 0,
530 TCG_COND_GEU = 0 | 4 | 0 | 1,
531 TCG_COND_LEU = 8 | 4 | 0 | 0,
532 TCG_COND_GTU = 8 | 4 | 0 | 1,
bellardc896fe22008-02-01 10:05:41 +0000533} TCGCond;
534
Richard Henderson1c086222010-02-09 12:33:09 -0800535/* Invert the sense of the comparison. */
Richard Henderson401d4662010-01-07 10:15:20 -0800536static inline TCGCond tcg_invert_cond(TCGCond c)
537{
538 return (TCGCond)(c ^ 1);
539}
540
Richard Henderson1c086222010-02-09 12:33:09 -0800541/* Swap the operands in a comparison. */
542static inline TCGCond tcg_swap_cond(TCGCond c)
543{
Richard Henderson0aed2572012-09-24 14:21:40 -0700544 return c & 6 ? (TCGCond)(c ^ 9) : c;
Richard Henderson1c086222010-02-09 12:33:09 -0800545}
546
Richard Hendersond1e321b2012-09-24 14:21:41 -0700547/* Create an "unsigned" version of a "signed" comparison. */
Richard Hendersonff44c2f2009-12-27 09:09:41 +0000548static inline TCGCond tcg_unsigned_cond(TCGCond c)
549{
Richard Henderson0aed2572012-09-24 14:21:40 -0700550 return c & 2 ? (TCGCond)(c ^ 6) : c;
Richard Hendersonff44c2f2009-12-27 09:09:41 +0000551}
552
Richard Hendersond1e321b2012-09-24 14:21:41 -0700553/* Must a comparison be considered unsigned? */
Richard Hendersonbcc66562012-09-24 14:21:39 -0700554static inline bool is_unsigned_cond(TCGCond c)
555{
Richard Henderson0aed2572012-09-24 14:21:40 -0700556 return (c & 4) != 0;
Richard Hendersonbcc66562012-09-24 14:21:39 -0700557}
558
Richard Hendersond1e321b2012-09-24 14:21:41 -0700559/* Create a "high" version of a double-word comparison.
560 This removes equality from a LTE or GTE comparison. */
561static inline TCGCond tcg_high_cond(TCGCond c)
562{
563 switch (c) {
564 case TCG_COND_GE:
565 case TCG_COND_LE:
566 case TCG_COND_GEU:
567 case TCG_COND_LEU:
568 return (TCGCond)(c ^ 8);
569 default:
570 return c;
571 }
572}
573
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400574typedef enum TCGTempVal {
575 TEMP_VAL_DEAD,
576 TEMP_VAL_REG,
577 TEMP_VAL_MEM,
578 TEMP_VAL_CONST,
579} TCGTempVal;
bellardc896fe22008-02-01 10:05:41 +0000580
bellardc896fe22008-02-01 10:05:41 +0000581typedef struct TCGTemp {
Richard Hendersonb6638662013-09-18 14:54:45 -0700582 TCGReg reg:8;
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400583 TCGTempVal val_type:8;
584 TCGType base_type:8;
585 TCGType type:8;
bellardc896fe22008-02-01 10:05:41 +0000586 unsigned int fixed_reg:1;
Richard Hendersonb3915db2013-09-19 10:36:18 -0700587 unsigned int indirect_reg:1;
588 unsigned int indirect_base:1;
bellardc896fe22008-02-01 10:05:41 +0000589 unsigned int mem_coherent:1;
590 unsigned int mem_allocated:1;
Stefan Weil5225d662011-04-28 17:20:26 +0200591 unsigned int temp_local:1; /* If true, the temp is saved across
bellard641d5fb2008-05-25 17:24:00 +0000592 basic blocks. Otherwise, it is not
Stefan Weil5225d662011-04-28 17:20:26 +0200593 preserved across basic blocks. */
bellarde8996ee2008-05-23 17:33:39 +0000594 unsigned int temp_allocated:1; /* never used for code gen */
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400595
596 tcg_target_long val;
Richard Hendersonb3a62932013-09-18 14:12:53 -0700597 struct TCGTemp *mem_base;
Emilio G. Cota00c8fa92015-04-02 20:07:53 -0400598 intptr_t mem_offset;
bellardc896fe22008-02-01 10:05:41 +0000599 const char *name;
600} TCGTemp;
601
bellardc896fe22008-02-01 10:05:41 +0000602typedef struct TCGContext TCGContext;
603
Richard Henderson0ec9eab2013-09-19 12:16:45 -0700604typedef struct TCGTempSet {
605 unsigned long l[BITS_TO_LONGS(TCG_MAX_TEMPS)];
606} TCGTempSet;
607
Richard Hendersona1b3c482016-06-22 15:46:09 -0700608/* While we limit helpers to 6 arguments, for 32-bit hosts, with padding,
609 this imples a max of 6*2 (64-bit in) + 2 (64-bit out) = 14 operands.
610 There are never more than 2 outputs, which means that we can store all
611 dead + sync data within 16 bits. */
612#define DEAD_ARG 4
613#define SYNC_ARG 1
614typedef uint16_t TCGLifeData;
615
Richard Hendersonbee158c2016-06-22 20:43:29 -0700616/* The layout here is designed to avoid crossing of a 32-bit boundary.
617 If we do so, gcc adds padding, expanding the size to 12. */
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700618typedef struct TCGOp {
Richard Hendersonbee158c2016-06-22 20:43:29 -0700619 TCGOpcode opc : 8; /* 8 */
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700620
Richard Hendersondcb8e752016-06-22 19:42:31 -0700621 /* Index of the prev/next op, or 0 for the end of the list. */
Richard Hendersonbee158c2016-06-22 20:43:29 -0700622 unsigned prev : 10; /* 18 */
623 unsigned next : 10; /* 28 */
624
625 /* The number of out and in parameter for a call. */
626 unsigned calli : 4; /* 32 */
627 unsigned callo : 2; /* 34 */
628
629 /* Index of the arguments for this op, or 0 for zero-operand ops. */
630 unsigned args : 14; /* 48 */
631
632 /* Lifetime data of the operands. */
633 unsigned life : 16; /* 64 */
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700634} TCGOp;
635
Richard Hendersondcb8e752016-06-22 19:42:31 -0700636/* Make sure operands fit in the bitfields above. */
637QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8));
Richard Hendersonbee158c2016-06-22 20:43:29 -0700638QEMU_BUILD_BUG_ON(OPC_BUF_SIZE > (1 << 10));
639QEMU_BUILD_BUG_ON(OPPARAM_BUF_SIZE > (1 << 14));
Richard Hendersondcb8e752016-06-22 19:42:31 -0700640
641/* Make sure that we don't overflow 64 bits without noticing. */
642QEMU_BUILD_BUG_ON(sizeof(TCGOp) > 8);
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700643
bellardc896fe22008-02-01 10:05:41 +0000644struct TCGContext {
645 uint8_t *pool_cur, *pool_end;
Kirill Batuzov40552992012-03-02 13:22:17 +0400646 TCGPool *pool_first, *pool_current, *pool_first_large;
bellardc896fe22008-02-01 10:05:41 +0000647 int nb_labels;
bellardc896fe22008-02-01 10:05:41 +0000648 int nb_globals;
649 int nb_temps;
Richard Henderson5a184072016-06-23 20:34:33 -0700650 int nb_indirects;
bellardc896fe22008-02-01 10:05:41 +0000651
652 /* goto_tb support */
Richard Henderson1813e172014-03-28 12:56:22 -0700653 tcg_insn_unit *code_buf;
Sergey Fedorovf3091012016-04-10 23:35:45 +0300654 uint16_t *tb_jmp_reset_offset; /* tb->jmp_reset_offset */
655 uint16_t *tb_jmp_insn_offset; /* tb->jmp_insn_offset if USE_DIRECT_JUMP */
656 uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_addr if !USE_DIRECT_JUMP */
bellardc896fe22008-02-01 10:05:41 +0000657
bellardc896fe22008-02-01 10:05:41 +0000658 TCGRegSet reserved_regs;
Richard Hendersone2c6d1b2013-08-20 15:12:31 -0700659 intptr_t current_frame_offset;
660 intptr_t frame_start;
661 intptr_t frame_end;
Richard Hendersonb3a62932013-09-18 14:12:53 -0700662 TCGTemp *frame_temp;
bellardc896fe22008-02-01 10:05:41 +0000663
Richard Henderson1813e172014-03-28 12:56:22 -0700664 tcg_insn_unit *code_ptr;
bellardc896fe22008-02-01 10:05:41 +0000665
Richard Henderson6e085f72013-09-14 14:37:06 -0700666 GHashTable *helpers;
bellarda23a9ec2008-05-23 09:52:20 +0000667
668#ifdef CONFIG_PROFILER
669 /* profiling info */
670 int64_t tb_count1;
671 int64_t tb_count;
672 int64_t op_count; /* total insn count */
673 int op_count_max; /* max insn per TB */
674 int64_t temp_count;
675 int temp_count_max;
bellarda23a9ec2008-05-23 09:52:20 +0000676 int64_t del_op_count;
677 int64_t code_in_len;
678 int64_t code_out_len;
Richard Hendersonfca8a502015-09-01 19:11:45 -0700679 int64_t search_out_len;
bellarda23a9ec2008-05-23 09:52:20 +0000680 int64_t interm_time;
681 int64_t code_time;
682 int64_t la_time;
Aurelien Jarnoc5cc28f2012-09-06 16:47:13 +0200683 int64_t opt_time;
bellarda23a9ec2008-05-23 09:52:20 +0000684 int64_t restore_count;
685 int64_t restore_time;
686#endif
Peter Maydell27bfd832011-03-06 21:39:53 +0000687
688#ifdef CONFIG_DEBUG_TCG
689 int temps_in_use;
Richard Henderson0a209d42012-09-21 17:18:16 -0700690 int goto_tb_issue_mask;
Peter Maydell27bfd832011-03-06 21:39:53 +0000691#endif
Yeongkyoon Leeb76f0d82012-10-31 16:04:25 +0900692
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700693 int gen_next_op_idx;
694 int gen_next_parm_idx;
Evgeny Voevodin8232a462012-11-12 13:27:44 +0400695
Richard Henderson1813e172014-03-28 12:56:22 -0700696 /* Code generation. Note that we specifically do not use tcg_insn_unit
697 here, because there's too much arithmetic throughout that relies
698 on addition and subtraction working on bytes. Rely on the GCC
699 extension that allows arithmetic on void*. */
Evgeny Voevodin0b0d3322013-02-01 01:47:22 +0700700 int code_gen_max_blocks;
Richard Henderson1813e172014-03-28 12:56:22 -0700701 void *code_gen_prologue;
702 void *code_gen_buffer;
Evgeny Voevodin0b0d3322013-02-01 01:47:22 +0700703 size_t code_gen_buffer_size;
Richard Henderson1813e172014-03-28 12:56:22 -0700704 void *code_gen_ptr;
Evgeny Voevodin0b0d3322013-02-01 01:47:22 +0700705
Richard Hendersonb125f9d2015-09-22 13:01:15 -0700706 /* Threshold to flush the translated code buffer. */
707 void *code_gen_highwater;
708
Evgeny Voevodin5e5f07e2013-02-01 01:47:23 +0700709 TBContext tb_ctx;
710
LluĂ­s Vilanova7c255042016-06-09 19:31:41 +0200711 /* Track which vCPU triggers events */
712 CPUState *cpu; /* *_trans */
713 TCGv_env tcg_env; /* *_exec */
714
Peter Maydellce151102016-02-23 14:49:41 +0000715 /* The TCGBackendData structure is private to tcg-target.inc.c. */
Richard Henderson9ecefc82013-10-03 14:51:24 -0500716 struct TCGBackendData *be;
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700717
718 TCGTempSet free_temps[TCG_TYPE_COUNT * 2];
719 TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
720
Richard Hendersonf8b2f202013-09-18 15:21:56 -0700721 /* Tells which temporary holds a given register.
722 It does not take into account fixed registers */
723 TCGTemp *reg_to_temp[TCG_TARGET_NB_REGS];
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700724
725 TCGOp gen_op_buf[OPC_BUF_SIZE];
726 TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
727
Richard Hendersonfca8a502015-09-01 19:11:45 -0700728 uint16_t gen_insn_end_off[TCG_MAX_INSNS];
729 target_ulong gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
bellardc896fe22008-02-01 10:05:41 +0000730};
731
732extern TCGContext tcg_ctx;
Richard Hendersonfdbc2b52016-06-29 22:12:55 -0700733extern bool parallel_cpus;
bellardc896fe22008-02-01 10:05:41 +0000734
Edgar E. Iglesias1d414782016-05-12 13:22:26 +0100735static inline void tcg_set_insn_param(int op_idx, int arg, TCGArg v)
736{
737 int op_argi = tcg_ctx.gen_op_buf[op_idx].args;
738 tcg_ctx.gen_opparam_buf[op_argi + arg] = v;
739}
740
Richard Hendersonfe700ad2014-03-30 15:36:56 -0700741/* The number of opcodes emitted so far. */
742static inline int tcg_op_buf_count(void)
743{
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700744 return tcg_ctx.gen_next_op_idx;
Richard Hendersonfe700ad2014-03-30 15:36:56 -0700745}
746
747/* Test for whether to terminate the TB for using too many opcodes. */
748static inline bool tcg_op_buf_full(void)
749{
750 return tcg_op_buf_count() >= OPC_MAX_SIZE;
751}
752
bellardc896fe22008-02-01 10:05:41 +0000753/* pool based memory allocation */
754
Paolo Bonzini7d7500d2016-10-27 16:10:03 +0100755/* tb_lock must be held for tcg_malloc_internal. */
bellardc896fe22008-02-01 10:05:41 +0000756void *tcg_malloc_internal(TCGContext *s, int size);
757void tcg_pool_reset(TCGContext *s);
bellardc896fe22008-02-01 10:05:41 +0000758
KONRAD Frederic677ef622015-08-10 17:27:02 +0200759void tb_lock(void);
760void tb_unlock(void);
761void tb_lock_reset(void);
762
Paolo Bonzini7d7500d2016-10-27 16:10:03 +0100763/* Called with tb_lock held. */
bellardc896fe22008-02-01 10:05:41 +0000764static inline void *tcg_malloc(int size)
765{
766 TCGContext *s = &tcg_ctx;
767 uint8_t *ptr, *ptr_end;
768 size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
769 ptr = s->pool_cur;
770 ptr_end = ptr + size;
771 if (unlikely(ptr_end > s->pool_end)) {
772 return tcg_malloc_internal(&tcg_ctx, size);
773 } else {
774 s->pool_cur = ptr_end;
775 return ptr;
776 }
777}
778
779void tcg_context_init(TCGContext *s);
Richard Henderson9002ec72010-05-06 08:50:41 -0700780void tcg_prologue_init(TCGContext *s);
bellardc896fe22008-02-01 10:05:41 +0000781void tcg_func_start(TCGContext *s);
782
Alex Bennée5bd2ec32016-03-15 14:30:16 +0000783int tcg_gen_code(TCGContext *s, TranslationBlock *tb);
bellardc896fe22008-02-01 10:05:41 +0000784
Richard Hendersonb6638662013-09-18 14:54:45 -0700785void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
pbrooka7812ae2008-11-17 14:43:54 +0000786
Richard Hendersone1ccc052013-09-18 12:53:09 -0700787int tcg_global_mem_new_internal(TCGType, TCGv_ptr, intptr_t, const char *);
788
Richard Hendersonb6638662013-09-18 14:54:45 -0700789TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name);
790TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700791
pbrooka7812ae2008-11-17 14:43:54 +0000792TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700793TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
794
795void tcg_temp_free_i32(TCGv_i32 arg);
796void tcg_temp_free_i64(TCGv_i64 arg);
797
Richard Hendersone1ccc052013-09-18 12:53:09 -0700798static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
799 const char *name)
800{
801 int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
802 return MAKE_TCGV_I32(idx);
803}
804
pbrooka7812ae2008-11-17 14:43:54 +0000805static inline TCGv_i32 tcg_temp_new_i32(void)
bellard641d5fb2008-05-25 17:24:00 +0000806{
pbrooka7812ae2008-11-17 14:43:54 +0000807 return tcg_temp_new_internal_i32(0);
bellard641d5fb2008-05-25 17:24:00 +0000808}
Richard Hendersone1ccc052013-09-18 12:53:09 -0700809
pbrooka7812ae2008-11-17 14:43:54 +0000810static inline TCGv_i32 tcg_temp_local_new_i32(void)
bellard641d5fb2008-05-25 17:24:00 +0000811{
pbrooka7812ae2008-11-17 14:43:54 +0000812 return tcg_temp_new_internal_i32(1);
bellard641d5fb2008-05-25 17:24:00 +0000813}
pbrooka7812ae2008-11-17 14:43:54 +0000814
Richard Hendersone1ccc052013-09-18 12:53:09 -0700815static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
816 const char *name)
817{
818 int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
819 return MAKE_TCGV_I64(idx);
820}
821
pbrooka7812ae2008-11-17 14:43:54 +0000822static inline TCGv_i64 tcg_temp_new_i64(void)
823{
824 return tcg_temp_new_internal_i64(0);
825}
Richard Hendersone1ccc052013-09-18 12:53:09 -0700826
pbrooka7812ae2008-11-17 14:43:54 +0000827static inline TCGv_i64 tcg_temp_local_new_i64(void)
828{
829 return tcg_temp_new_internal_i64(1);
830}
pbrooka7812ae2008-11-17 14:43:54 +0000831
Peter Maydell27bfd832011-03-06 21:39:53 +0000832#if defined(CONFIG_DEBUG_TCG)
833/* If you call tcg_clear_temp_count() at the start of a section of
834 * code which is not supposed to leak any TCG temporaries, then
835 * calling tcg_check_temp_count() at the end of the section will
836 * return 1 if the section did in fact leak a temporary.
837 */
838void tcg_clear_temp_count(void);
839int tcg_check_temp_count(void);
840#else
841#define tcg_clear_temp_count() do { } while (0)
842#define tcg_check_temp_count() 0
843#endif
844
Stefan Weil405cf9f2010-10-22 23:03:31 +0200845void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
Max Filippov246ae242014-11-02 11:04:18 +0300846void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf);
bellardc896fe22008-02-01 10:05:41 +0000847
848#define TCG_CT_ALIAS 0x80
849#define TCG_CT_IALIAS 0x40
Richard Henderson82790a82016-11-18 08:35:03 +0100850#define TCG_CT_NEWREG 0x20 /* output requires a new register */
bellardc896fe22008-02-01 10:05:41 +0000851#define TCG_CT_REG 0x01
852#define TCG_CT_CONST 0x02 /* any constant of register size */
853
854typedef struct TCGArgConstraint {
bellard5ff9d6a2008-02-04 00:37:54 +0000855 uint16_t ct;
856 uint8_t alias_index;
bellardc896fe22008-02-01 10:05:41 +0000857 union {
858 TCGRegSet regs;
859 } u;
860} TCGArgConstraint;
861
862#define TCG_MAX_OP_ARGS 16
863
Richard Henderson8399ad52011-08-17 14:11:45 -0700864/* Bits for TCGOpDef->flags, 8 bits available. */
865enum {
866 /* Instruction defines the end of a basic block. */
867 TCG_OPF_BB_END = 0x01,
868 /* Instruction clobbers call registers and potentially update globals. */
869 TCG_OPF_CALL_CLOBBER = 0x02,
Aurelien Jarno3d5c5f82012-10-09 21:53:08 +0200870 /* Instruction has side effects: it cannot be removed if its outputs
871 are not used, and might trigger exceptions. */
Richard Henderson8399ad52011-08-17 14:11:45 -0700872 TCG_OPF_SIDE_EFFECTS = 0x04,
873 /* Instruction operands are 64-bits (otherwise 32-bits). */
874 TCG_OPF_64BIT = 0x08,
Richard Hendersonc1a61f62013-05-02 11:57:40 +0100875 /* Instruction is optional and not implemented by the host, or insn
876 is generic and should not be implemened by the host. */
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700877 TCG_OPF_NOT_PRESENT = 0x10,
Richard Henderson8399ad52011-08-17 14:11:45 -0700878};
bellardc896fe22008-02-01 10:05:41 +0000879
880typedef struct TCGOpDef {
881 const char *name;
882 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
883 uint8_t flags;
bellardc896fe22008-02-01 10:05:41 +0000884 TCGArgConstraint *args_ct;
885 int *sorted_args;
Stefan Weilc68aaa12010-02-15 17:17:21 +0100886#if defined(CONFIG_DEBUG_TCG)
887 int used;
888#endif
bellardc896fe22008-02-01 10:05:41 +0000889} TCGOpDef;
Richard Henderson8399ad52011-08-17 14:11:45 -0700890
891extern TCGOpDef tcg_op_defs[];
Stefan Weil2a243742011-09-29 18:33:21 +0200892extern const size_t tcg_op_defs_max;
893
bellardc896fe22008-02-01 10:05:41 +0000894typedef struct TCGTargetOpDef {
Richard Hendersona9751602010-03-19 11:12:29 -0700895 TCGOpcode op;
bellardc896fe22008-02-01 10:05:41 +0000896 const char *args_ct_str[TCG_MAX_OP_ARGS];
897} TCGTargetOpDef;
898
bellardc896fe22008-02-01 10:05:41 +0000899#define tcg_abort() \
900do {\
901 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
902 abort();\
903} while (0)
904
Richard Henderson8b73d492013-08-20 15:07:08 -0700905#if UINTPTR_MAX == UINT32_MAX
Peter Maydellebecf362011-05-27 13:12:13 +0100906#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n))
907#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n))
908
Richard Henderson8b73d492013-08-20 15:07:08 -0700909#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((intptr_t)(V)))
Peter Maydellebecf362011-05-27 13:12:13 +0100910#define tcg_global_reg_new_ptr(R, N) \
911 TCGV_NAT_TO_PTR(tcg_global_reg_new_i32((R), (N)))
912#define tcg_global_mem_new_ptr(R, O, N) \
913 TCGV_NAT_TO_PTR(tcg_global_mem_new_i32((R), (O), (N)))
914#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i32())
915#define tcg_temp_free_ptr(T) tcg_temp_free_i32(TCGV_PTR_TO_NAT(T))
bellardc896fe22008-02-01 10:05:41 +0000916#else
Peter Maydellebecf362011-05-27 13:12:13 +0100917#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I64(n))
918#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I64(GET_TCGV_PTR(n))
919
Richard Henderson8b73d492013-08-20 15:07:08 -0700920#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((intptr_t)(V)))
Peter Maydellebecf362011-05-27 13:12:13 +0100921#define tcg_global_reg_new_ptr(R, N) \
922 TCGV_NAT_TO_PTR(tcg_global_reg_new_i64((R), (N)))
923#define tcg_global_mem_new_ptr(R, O, N) \
924 TCGV_NAT_TO_PTR(tcg_global_mem_new_i64((R), (O), (N)))
925#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i64())
926#define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T))
bellardc896fe22008-02-01 10:05:41 +0000927#endif
928
Richard Hendersonbbb8a1b2014-04-08 08:39:43 -0700929void tcg_gen_callN(TCGContext *s, void *func,
930 TCGArg ret, int nargs, TCGArg *args);
pbrooka7812ae2008-11-17 14:43:54 +0000931
Richard Henderson0c627cd2014-03-30 16:51:54 -0700932void tcg_op_remove(TCGContext *s, TCGOp *op);
Richard Henderson5a184072016-06-23 20:34:33 -0700933TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
934TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
935
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700936void tcg_optimize(TCGContext *s);
Kirill Batuzov8f2e8c02011-07-07 16:37:12 +0400937
pbrooka7812ae2008-11-17 14:43:54 +0000938/* only used for debugging purposes */
Blue Swirleeacee42012-06-03 16:35:32 +0000939void tcg_dump_ops(TCGContext *s);
pbrooka7812ae2008-11-17 14:43:54 +0000940
pbrooka7812ae2008-11-17 14:43:54 +0000941TCGv_i32 tcg_const_i32(int32_t val);
942TCGv_i64 tcg_const_i64(int64_t val);
943TCGv_i32 tcg_const_local_i32(int32_t val);
944TCGv_i64 tcg_const_local_i64(int64_t val);
945
Richard Henderson42a268c2015-02-13 12:51:55 -0800946TCGLabel *gen_new_label(void);
947
948/**
949 * label_arg
950 * @l: label
951 *
952 * Encode a label for storage in the TCG opcode stream.
953 */
954
955static inline TCGArg label_arg(TCGLabel *l)
956{
Richard Henderson51e39722015-02-13 18:51:05 -0800957 return (uintptr_t)l;
Richard Henderson42a268c2015-02-13 12:51:55 -0800958}
959
960/**
961 * arg_label
962 * @i: value
963 *
964 * The opposite of label_arg. Retrieve a label from the
965 * encoding of the TCG opcode stream.
966 */
967
Richard Henderson51e39722015-02-13 18:51:05 -0800968static inline TCGLabel *arg_label(TCGArg i)
Richard Henderson42a268c2015-02-13 12:51:55 -0800969{
Richard Henderson51e39722015-02-13 18:51:05 -0800970 return (TCGLabel *)(uintptr_t)i;
Richard Henderson42a268c2015-02-13 12:51:55 -0800971}
972
Peter Maydell09800112013-02-22 18:10:00 +0000973/**
Richard Henderson52a1f642014-03-31 14:27:27 -0700974 * tcg_ptr_byte_diff
975 * @a, @b: addresses to be differenced
976 *
977 * There are many places within the TCG backends where we need a byte
978 * difference between two pointers. While this can be accomplished
979 * with local casting, it's easy to get wrong -- especially if one is
980 * concerned with the signedness of the result.
981 *
982 * This version relies on GCC's void pointer arithmetic to get the
983 * correct result.
984 */
985
986static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
987{
988 return a - b;
989}
990
991/**
992 * tcg_pcrel_diff
993 * @s: the tcg context
994 * @target: address of the target
995 *
996 * Produce a pc-relative difference, from the current code_ptr
997 * to the destination address.
998 */
999
1000static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
1001{
1002 return tcg_ptr_byte_diff(target, s->code_ptr);
1003}
1004
1005/**
1006 * tcg_current_code_size
1007 * @s: the tcg context
1008 *
1009 * Compute the current code size within the translation block.
1010 * This is used to fill in qemu's data structures for goto_tb.
1011 */
1012
1013static inline size_t tcg_current_code_size(TCGContext *s)
1014{
1015 return tcg_ptr_byte_diff(s->code_ptr, s->code_buf);
1016}
1017
Richard Henderson59227d52015-05-12 11:51:44 -07001018/* Combine the TCGMemOp and mmu_idx parameters into a single value. */
1019typedef uint32_t TCGMemOpIdx;
1020
1021/**
1022 * make_memop_idx
1023 * @op: memory operation
1024 * @idx: mmu index
1025 *
1026 * Encode these values into a single parameter.
1027 */
1028static inline TCGMemOpIdx make_memop_idx(TCGMemOp op, unsigned idx)
1029{
1030 tcg_debug_assert(idx <= 15);
1031 return (op << 4) | idx;
1032}
1033
1034/**
1035 * get_memop
1036 * @oi: combined op/idx parameter
1037 *
1038 * Extract the memory operation from the combined value.
1039 */
1040static inline TCGMemOp get_memop(TCGMemOpIdx oi)
1041{
1042 return oi >> 4;
1043}
1044
1045/**
1046 * get_mmuidx
1047 * @oi: combined op/idx parameter
1048 *
1049 * Extract the mmu index from the combined value.
1050 */
1051static inline unsigned get_mmuidx(TCGMemOpIdx oi)
1052{
1053 return oi & 15;
1054}
1055
Richard Henderson52a1f642014-03-31 14:27:27 -07001056/**
Peter Maydell09800112013-02-22 18:10:00 +00001057 * tcg_qemu_tb_exec:
Sergey Fedorov819af242016-04-21 15:58:23 +03001058 * @env: pointer to CPUArchState for the CPU
Peter Maydell09800112013-02-22 18:10:00 +00001059 * @tb_ptr: address of generated code for the TB to execute
1060 *
1061 * Start executing code from a given translation block.
1062 * Where translation blocks have been linked, execution
1063 * may proceed from the given TB into successive ones.
1064 * Control eventually returns only when some action is needed
1065 * from the top-level loop: either control must pass to a TB
1066 * which has not yet been directly linked, or an asynchronous
1067 * event such as an interrupt needs handling.
1068 *
Sergey Fedorov819af242016-04-21 15:58:23 +03001069 * Return: The return value is the value passed to the corresponding
1070 * tcg_gen_exit_tb() at translation time of the last TB attempted to execute.
1071 * The value is either zero or a 4-byte aligned pointer to that TB combined
1072 * with additional information in its two least significant bits. The
1073 * additional information is encoded as follows:
Peter Maydell09800112013-02-22 18:10:00 +00001074 * 0, 1: the link between this TB and the next is via the specified
1075 * TB index (0 or 1). That is, we left the TB via (the equivalent
1076 * of) "goto_tb <index>". The main loop uses this to determine
1077 * how to link the TB just executed to the next.
1078 * 2: we are using instruction counting code generation, and we
1079 * did not start executing this TB because the instruction counter
Sergey Fedorov819af242016-04-21 15:58:23 +03001080 * would hit zero midway through it. In this case the pointer
Peter Maydell09800112013-02-22 18:10:00 +00001081 * returned is the TB we were about to execute, and the caller must
1082 * arrange to execute the remaining count of instructions.
Peter Maydell378df4b2013-02-22 18:10:03 +00001083 * 3: we stopped because the CPU's exit_request flag was set
1084 * (usually meaning that there is an interrupt that needs to be
Sergey Fedorov819af242016-04-21 15:58:23 +03001085 * handled). The pointer returned is the TB we were about to execute
1086 * when we noticed the pending exit request.
Peter Maydell09800112013-02-22 18:10:00 +00001087 *
1088 * If the bottom two bits indicate an exit-via-index then the CPU
1089 * state is correctly synchronised and ready for execution of the next
1090 * TB (and in particular the guest PC is the address to execute next).
1091 * Otherwise, we gave up on execution of this TB before it started, and
Peter Crosthwaitefee068e2015-04-29 00:52:21 -07001092 * the caller must fix up the CPU state by calling the CPU's
Sergey Fedorov819af242016-04-21 15:58:23 +03001093 * synchronize_from_tb() method with the TB pointer we return (falling
Peter Crosthwaitefee068e2015-04-29 00:52:21 -07001094 * back to calling the CPU's set_pc method with tb->pb if no
1095 * synchronize_from_tb() method exists).
Peter Maydell09800112013-02-22 18:10:00 +00001096 *
1097 * Note that TCG targets may use a different definition of tcg_qemu_tb_exec
1098 * to this default (which just calls the prologue.code emitted by
1099 * tcg_target_qemu_prologue()).
1100 */
1101#define TB_EXIT_MASK 3
1102#define TB_EXIT_IDX0 0
1103#define TB_EXIT_IDX1 1
Peter Maydell378df4b2013-02-22 18:10:03 +00001104#define TB_EXIT_REQUESTED 3
Peter Maydell09800112013-02-22 18:10:00 +00001105
Paolo Bonzini5a58e882015-05-19 09:59:34 +02001106#ifdef HAVE_TCG_QEMU_TB_EXEC
1107uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
1108#else
Stefan Weilce285b12011-09-30 21:23:06 +02001109# define tcg_qemu_tb_exec(env, tb_ptr) \
Richard Henderson04d5a1d2013-08-20 14:35:34 -07001110 ((uintptr_t (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr)
bellard932a6902008-05-30 20:56:52 +00001111#endif
Richard Henderson813da622012-03-19 12:25:11 -07001112
1113void tcg_register_jit(void *buf, size_t buf_size);
Yeongkyoon Leeb76f0d82012-10-31 16:04:25 +09001114
Richard Hendersone58eb532013-08-27 13:13:44 -07001115/*
1116 * Memory helpers that will be used by TCG generated code.
1117 */
1118#ifdef CONFIG_SOFTMMU
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001119/* Value zero-extended to tcg register size. */
1120tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001121 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001122tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001123 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001124tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001125 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001126uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001127 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001128tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001129 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001130tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001131 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001132uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001133 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Hendersone58eb532013-08-27 13:13:44 -07001134
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001135/* Value sign-extended to tcg register size. */
1136tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001137 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001138tcg_target_ulong helper_le_ldsw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001139 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001140tcg_target_ulong helper_le_ldsl_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001141 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001142tcg_target_ulong helper_be_ldsw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001143 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001144tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001145 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001146
Richard Hendersone58eb532013-08-27 13:13:44 -07001147void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001148 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001149void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001150 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001151void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001152 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001153void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001154 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001155void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001156 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001157void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001158 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001159void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001160 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001161
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001162uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
1163 TCGMemOpIdx oi, uintptr_t retaddr);
1164uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
1165 TCGMemOpIdx oi, uintptr_t retaddr);
1166uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
1167 TCGMemOpIdx oi, uintptr_t retaddr);
1168uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
1169 TCGMemOpIdx oi, uintptr_t retaddr);
1170uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
1171 TCGMemOpIdx oi, uintptr_t retaddr);
1172uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
1173 TCGMemOpIdx oi, uintptr_t retaddr);
1174uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
1175 TCGMemOpIdx oi, uintptr_t retaddr);
1176
Richard Henderson867b3202013-09-04 11:45:20 -07001177/* Temporary aliases until backends are converted. */
1178#ifdef TARGET_WORDS_BIGENDIAN
1179# define helper_ret_ldsw_mmu helper_be_ldsw_mmu
1180# define helper_ret_lduw_mmu helper_be_lduw_mmu
1181# define helper_ret_ldsl_mmu helper_be_ldsl_mmu
1182# define helper_ret_ldul_mmu helper_be_ldul_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001183# define helper_ret_ldl_mmu helper_be_ldul_mmu
Richard Henderson867b3202013-09-04 11:45:20 -07001184# define helper_ret_ldq_mmu helper_be_ldq_mmu
1185# define helper_ret_stw_mmu helper_be_stw_mmu
1186# define helper_ret_stl_mmu helper_be_stl_mmu
1187# define helper_ret_stq_mmu helper_be_stq_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001188# define helper_ret_ldw_cmmu helper_be_ldw_cmmu
1189# define helper_ret_ldl_cmmu helper_be_ldl_cmmu
1190# define helper_ret_ldq_cmmu helper_be_ldq_cmmu
Richard Henderson867b3202013-09-04 11:45:20 -07001191#else
1192# define helper_ret_ldsw_mmu helper_le_ldsw_mmu
1193# define helper_ret_lduw_mmu helper_le_lduw_mmu
1194# define helper_ret_ldsl_mmu helper_le_ldsl_mmu
1195# define helper_ret_ldul_mmu helper_le_ldul_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001196# define helper_ret_ldl_mmu helper_le_ldul_mmu
Richard Henderson867b3202013-09-04 11:45:20 -07001197# define helper_ret_ldq_mmu helper_le_ldq_mmu
1198# define helper_ret_stw_mmu helper_le_stw_mmu
1199# define helper_ret_stl_mmu helper_le_stl_mmu
1200# define helper_ret_stq_mmu helper_le_stq_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001201# define helper_ret_ldw_cmmu helper_le_ldw_cmmu
1202# define helper_ret_ldl_cmmu helper_le_ldl_cmmu
1203# define helper_ret_ldq_cmmu helper_le_ldq_cmmu
Richard Henderson867b3202013-09-04 11:45:20 -07001204#endif
Richard Hendersone58eb532013-08-27 13:13:44 -07001205
Richard Hendersonc482cb12016-06-28 11:37:27 -07001206uint32_t helper_atomic_cmpxchgb_mmu(CPUArchState *env, target_ulong addr,
1207 uint32_t cmpv, uint32_t newv,
1208 TCGMemOpIdx oi, uintptr_t retaddr);
1209uint32_t helper_atomic_cmpxchgw_le_mmu(CPUArchState *env, target_ulong addr,
1210 uint32_t cmpv, uint32_t newv,
1211 TCGMemOpIdx oi, uintptr_t retaddr);
1212uint32_t helper_atomic_cmpxchgl_le_mmu(CPUArchState *env, target_ulong addr,
1213 uint32_t cmpv, uint32_t newv,
1214 TCGMemOpIdx oi, uintptr_t retaddr);
1215uint64_t helper_atomic_cmpxchgq_le_mmu(CPUArchState *env, target_ulong addr,
1216 uint64_t cmpv, uint64_t newv,
1217 TCGMemOpIdx oi, uintptr_t retaddr);
1218uint32_t helper_atomic_cmpxchgw_be_mmu(CPUArchState *env, target_ulong addr,
1219 uint32_t cmpv, uint32_t newv,
1220 TCGMemOpIdx oi, uintptr_t retaddr);
1221uint32_t helper_atomic_cmpxchgl_be_mmu(CPUArchState *env, target_ulong addr,
1222 uint32_t cmpv, uint32_t newv,
1223 TCGMemOpIdx oi, uintptr_t retaddr);
1224uint64_t helper_atomic_cmpxchgq_be_mmu(CPUArchState *env, target_ulong addr,
1225 uint64_t cmpv, uint64_t newv,
1226 TCGMemOpIdx oi, uintptr_t retaddr);
1227
1228#define GEN_ATOMIC_HELPER(NAME, TYPE, SUFFIX) \
1229TYPE helper_atomic_ ## NAME ## SUFFIX ## _mmu \
1230 (CPUArchState *env, target_ulong addr, TYPE val, \
1231 TCGMemOpIdx oi, uintptr_t retaddr);
1232
Richard Hendersondf79b992016-09-02 12:23:57 -07001233#ifdef CONFIG_ATOMIC64
Richard Hendersonc482cb12016-06-28 11:37:27 -07001234#define GEN_ATOMIC_HELPER_ALL(NAME) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001235 GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001236 GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001237 GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001238 GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001239 GEN_ATOMIC_HELPER(NAME, uint32_t, l_be) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001240 GEN_ATOMIC_HELPER(NAME, uint64_t, q_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001241 GEN_ATOMIC_HELPER(NAME, uint64_t, q_be)
Richard Hendersondf79b992016-09-02 12:23:57 -07001242#else
1243#define GEN_ATOMIC_HELPER_ALL(NAME) \
1244 GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
1245 GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
1246 GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
1247 GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
1248 GEN_ATOMIC_HELPER(NAME, uint32_t, l_be)
1249#endif
Richard Hendersonc482cb12016-06-28 11:37:27 -07001250
1251GEN_ATOMIC_HELPER_ALL(fetch_add)
1252GEN_ATOMIC_HELPER_ALL(fetch_sub)
1253GEN_ATOMIC_HELPER_ALL(fetch_and)
1254GEN_ATOMIC_HELPER_ALL(fetch_or)
1255GEN_ATOMIC_HELPER_ALL(fetch_xor)
1256
1257GEN_ATOMIC_HELPER_ALL(add_fetch)
1258GEN_ATOMIC_HELPER_ALL(sub_fetch)
1259GEN_ATOMIC_HELPER_ALL(and_fetch)
1260GEN_ATOMIC_HELPER_ALL(or_fetch)
1261GEN_ATOMIC_HELPER_ALL(xor_fetch)
1262
1263GEN_ATOMIC_HELPER_ALL(xchg)
1264
1265#undef GEN_ATOMIC_HELPER_ALL
1266#undef GEN_ATOMIC_HELPER
Richard Hendersone58eb532013-08-27 13:13:44 -07001267#endif /* CONFIG_SOFTMMU */
1268
Richard Henderson7ebee432016-06-29 21:10:59 -07001269#ifdef CONFIG_ATOMIC128
1270#include "qemu/int128.h"
1271
1272/* These aren't really a "proper" helpers because TCG cannot manage Int128.
1273 However, use the same format as the others, for use by the backends. */
1274Int128 helper_atomic_cmpxchgo_le_mmu(CPUArchState *env, target_ulong addr,
1275 Int128 cmpv, Int128 newv,
1276 TCGMemOpIdx oi, uintptr_t retaddr);
1277Int128 helper_atomic_cmpxchgo_be_mmu(CPUArchState *env, target_ulong addr,
1278 Int128 cmpv, Int128 newv,
1279 TCGMemOpIdx oi, uintptr_t retaddr);
1280
1281Int128 helper_atomic_ldo_le_mmu(CPUArchState *env, target_ulong addr,
1282 TCGMemOpIdx oi, uintptr_t retaddr);
1283Int128 helper_atomic_ldo_be_mmu(CPUArchState *env, target_ulong addr,
1284 TCGMemOpIdx oi, uintptr_t retaddr);
1285void helper_atomic_sto_le_mmu(CPUArchState *env, target_ulong addr, Int128 val,
1286 TCGMemOpIdx oi, uintptr_t retaddr);
1287void helper_atomic_sto_be_mmu(CPUArchState *env, target_ulong addr, Int128 val,
1288 TCGMemOpIdx oi, uintptr_t retaddr);
1289
1290#endif /* CONFIG_ATOMIC128 */
1291
Richard Hendersone58eb532013-08-27 13:13:44 -07001292#endif /* TCG_H */