blob: 9e37722799a604a8b07e4430f2bc9d5dec49d9f2 [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*. */
Richard Henderson1813e172014-03-28 12:56:22 -0700700 void *code_gen_prologue;
Emilio G. Cotacedbcb02017-04-26 23:29:14 -0400701 void *code_gen_epilogue;
Richard Henderson1813e172014-03-28 12:56:22 -0700702 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);
Emilio G. Cota6e3b2bf2017-06-06 19:12:25 -0400758TranslationBlock *tcg_tb_alloc(TCGContext *s);
bellardc896fe22008-02-01 10:05:41 +0000759
KONRAD Frederic677ef622015-08-10 17:27:02 +0200760void tb_lock(void);
761void tb_unlock(void);
762void tb_lock_reset(void);
763
Paolo Bonzini7d7500d2016-10-27 16:10:03 +0100764/* Called with tb_lock held. */
bellardc896fe22008-02-01 10:05:41 +0000765static inline void *tcg_malloc(int size)
766{
767 TCGContext *s = &tcg_ctx;
768 uint8_t *ptr, *ptr_end;
769 size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
770 ptr = s->pool_cur;
771 ptr_end = ptr + size;
772 if (unlikely(ptr_end > s->pool_end)) {
773 return tcg_malloc_internal(&tcg_ctx, size);
774 } else {
775 s->pool_cur = ptr_end;
776 return ptr;
777 }
778}
779
780void tcg_context_init(TCGContext *s);
Richard Henderson9002ec72010-05-06 08:50:41 -0700781void tcg_prologue_init(TCGContext *s);
bellardc896fe22008-02-01 10:05:41 +0000782void tcg_func_start(TCGContext *s);
783
Alex Bennée5bd2ec32016-03-15 14:30:16 +0000784int tcg_gen_code(TCGContext *s, TranslationBlock *tb);
bellardc896fe22008-02-01 10:05:41 +0000785
Richard Hendersonb6638662013-09-18 14:54:45 -0700786void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
pbrooka7812ae2008-11-17 14:43:54 +0000787
Richard Hendersone1ccc052013-09-18 12:53:09 -0700788int tcg_global_mem_new_internal(TCGType, TCGv_ptr, intptr_t, const char *);
789
Richard Hendersonb6638662013-09-18 14:54:45 -0700790TCGv_i32 tcg_global_reg_new_i32(TCGReg reg, const char *name);
791TCGv_i64 tcg_global_reg_new_i64(TCGReg reg, const char *name);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700792
pbrooka7812ae2008-11-17 14:43:54 +0000793TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
Richard Hendersone1ccc052013-09-18 12:53:09 -0700794TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
795
796void tcg_temp_free_i32(TCGv_i32 arg);
797void tcg_temp_free_i64(TCGv_i64 arg);
798
Richard Hendersone1ccc052013-09-18 12:53:09 -0700799static inline TCGv_i32 tcg_global_mem_new_i32(TCGv_ptr reg, intptr_t offset,
800 const char *name)
801{
802 int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
803 return MAKE_TCGV_I32(idx);
804}
805
pbrooka7812ae2008-11-17 14:43:54 +0000806static inline TCGv_i32 tcg_temp_new_i32(void)
bellard641d5fb2008-05-25 17:24:00 +0000807{
pbrooka7812ae2008-11-17 14:43:54 +0000808 return tcg_temp_new_internal_i32(0);
bellard641d5fb2008-05-25 17:24:00 +0000809}
Richard Hendersone1ccc052013-09-18 12:53:09 -0700810
pbrooka7812ae2008-11-17 14:43:54 +0000811static inline TCGv_i32 tcg_temp_local_new_i32(void)
bellard641d5fb2008-05-25 17:24:00 +0000812{
pbrooka7812ae2008-11-17 14:43:54 +0000813 return tcg_temp_new_internal_i32(1);
bellard641d5fb2008-05-25 17:24:00 +0000814}
pbrooka7812ae2008-11-17 14:43:54 +0000815
Richard Hendersone1ccc052013-09-18 12:53:09 -0700816static inline TCGv_i64 tcg_global_mem_new_i64(TCGv_ptr reg, intptr_t offset,
817 const char *name)
818{
819 int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
820 return MAKE_TCGV_I64(idx);
821}
822
pbrooka7812ae2008-11-17 14:43:54 +0000823static inline TCGv_i64 tcg_temp_new_i64(void)
824{
825 return tcg_temp_new_internal_i64(0);
826}
Richard Hendersone1ccc052013-09-18 12:53:09 -0700827
pbrooka7812ae2008-11-17 14:43:54 +0000828static inline TCGv_i64 tcg_temp_local_new_i64(void)
829{
830 return tcg_temp_new_internal_i64(1);
831}
pbrooka7812ae2008-11-17 14:43:54 +0000832
Peter Maydell27bfd832011-03-06 21:39:53 +0000833#if defined(CONFIG_DEBUG_TCG)
834/* If you call tcg_clear_temp_count() at the start of a section of
835 * code which is not supposed to leak any TCG temporaries, then
836 * calling tcg_check_temp_count() at the end of the section will
837 * return 1 if the section did in fact leak a temporary.
838 */
839void tcg_clear_temp_count(void);
840int tcg_check_temp_count(void);
841#else
842#define tcg_clear_temp_count() do { } while (0)
843#define tcg_check_temp_count() 0
844#endif
845
Stefan Weil405cf9f2010-10-22 23:03:31 +0200846void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
Max Filippov246ae242014-11-02 11:04:18 +0300847void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf);
bellardc896fe22008-02-01 10:05:41 +0000848
849#define TCG_CT_ALIAS 0x80
850#define TCG_CT_IALIAS 0x40
Richard Henderson82790a82016-11-18 08:35:03 +0100851#define TCG_CT_NEWREG 0x20 /* output requires a new register */
bellardc896fe22008-02-01 10:05:41 +0000852#define TCG_CT_REG 0x01
853#define TCG_CT_CONST 0x02 /* any constant of register size */
854
855typedef struct TCGArgConstraint {
bellard5ff9d6a2008-02-04 00:37:54 +0000856 uint16_t ct;
857 uint8_t alias_index;
bellardc896fe22008-02-01 10:05:41 +0000858 union {
859 TCGRegSet regs;
860 } u;
861} TCGArgConstraint;
862
863#define TCG_MAX_OP_ARGS 16
864
Richard Henderson8399ad52011-08-17 14:11:45 -0700865/* Bits for TCGOpDef->flags, 8 bits available. */
866enum {
867 /* Instruction defines the end of a basic block. */
868 TCG_OPF_BB_END = 0x01,
869 /* Instruction clobbers call registers and potentially update globals. */
870 TCG_OPF_CALL_CLOBBER = 0x02,
Aurelien Jarno3d5c5f82012-10-09 21:53:08 +0200871 /* Instruction has side effects: it cannot be removed if its outputs
872 are not used, and might trigger exceptions. */
Richard Henderson8399ad52011-08-17 14:11:45 -0700873 TCG_OPF_SIDE_EFFECTS = 0x04,
874 /* Instruction operands are 64-bits (otherwise 32-bits). */
875 TCG_OPF_64BIT = 0x08,
Richard Hendersonc1a61f62013-05-02 11:57:40 +0100876 /* Instruction is optional and not implemented by the host, or insn
877 is generic and should not be implemened by the host. */
Richard Henderson25c4d9c2011-08-17 14:11:46 -0700878 TCG_OPF_NOT_PRESENT = 0x10,
Richard Henderson8399ad52011-08-17 14:11:45 -0700879};
bellardc896fe22008-02-01 10:05:41 +0000880
881typedef struct TCGOpDef {
882 const char *name;
883 uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
884 uint8_t flags;
bellardc896fe22008-02-01 10:05:41 +0000885 TCGArgConstraint *args_ct;
886 int *sorted_args;
Stefan Weilc68aaa12010-02-15 17:17:21 +0100887#if defined(CONFIG_DEBUG_TCG)
888 int used;
889#endif
bellardc896fe22008-02-01 10:05:41 +0000890} TCGOpDef;
Richard Henderson8399ad52011-08-17 14:11:45 -0700891
892extern TCGOpDef tcg_op_defs[];
Stefan Weil2a243742011-09-29 18:33:21 +0200893extern const size_t tcg_op_defs_max;
894
bellardc896fe22008-02-01 10:05:41 +0000895typedef struct TCGTargetOpDef {
Richard Hendersona9751602010-03-19 11:12:29 -0700896 TCGOpcode op;
bellardc896fe22008-02-01 10:05:41 +0000897 const char *args_ct_str[TCG_MAX_OP_ARGS];
898} TCGTargetOpDef;
899
bellardc896fe22008-02-01 10:05:41 +0000900#define tcg_abort() \
901do {\
902 fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
903 abort();\
904} while (0)
905
Richard Henderson8b73d492013-08-20 15:07:08 -0700906#if UINTPTR_MAX == UINT32_MAX
Peter Maydellebecf362011-05-27 13:12:13 +0100907#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n))
908#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n))
909
Richard Henderson8b73d492013-08-20 15:07:08 -0700910#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((intptr_t)(V)))
Peter Maydellebecf362011-05-27 13:12:13 +0100911#define tcg_global_reg_new_ptr(R, N) \
912 TCGV_NAT_TO_PTR(tcg_global_reg_new_i32((R), (N)))
913#define tcg_global_mem_new_ptr(R, O, N) \
914 TCGV_NAT_TO_PTR(tcg_global_mem_new_i32((R), (O), (N)))
915#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i32())
916#define tcg_temp_free_ptr(T) tcg_temp_free_i32(TCGV_PTR_TO_NAT(T))
bellardc896fe22008-02-01 10:05:41 +0000917#else
Peter Maydellebecf362011-05-27 13:12:13 +0100918#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I64(n))
919#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I64(GET_TCGV_PTR(n))
920
Richard Henderson8b73d492013-08-20 15:07:08 -0700921#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((intptr_t)(V)))
Peter Maydellebecf362011-05-27 13:12:13 +0100922#define tcg_global_reg_new_ptr(R, N) \
923 TCGV_NAT_TO_PTR(tcg_global_reg_new_i64((R), (N)))
924#define tcg_global_mem_new_ptr(R, O, N) \
925 TCGV_NAT_TO_PTR(tcg_global_mem_new_i64((R), (O), (N)))
926#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i64())
927#define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T))
bellardc896fe22008-02-01 10:05:41 +0000928#endif
929
Richard Hendersonbbb8a1b2014-04-08 08:39:43 -0700930void tcg_gen_callN(TCGContext *s, void *func,
931 TCGArg ret, int nargs, TCGArg *args);
pbrooka7812ae2008-11-17 14:43:54 +0000932
Richard Henderson0c627cd2014-03-30 16:51:54 -0700933void tcg_op_remove(TCGContext *s, TCGOp *op);
Richard Henderson5a184072016-06-23 20:34:33 -0700934TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
935TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
936
Richard Hendersonc45cb8b2014-09-19 13:49:15 -0700937void tcg_optimize(TCGContext *s);
Kirill Batuzov8f2e8c02011-07-07 16:37:12 +0400938
pbrooka7812ae2008-11-17 14:43:54 +0000939/* only used for debugging purposes */
Blue Swirleeacee42012-06-03 16:35:32 +0000940void tcg_dump_ops(TCGContext *s);
pbrooka7812ae2008-11-17 14:43:54 +0000941
pbrooka7812ae2008-11-17 14:43:54 +0000942TCGv_i32 tcg_const_i32(int32_t val);
943TCGv_i64 tcg_const_i64(int64_t val);
944TCGv_i32 tcg_const_local_i32(int32_t val);
945TCGv_i64 tcg_const_local_i64(int64_t val);
946
Richard Henderson42a268c2015-02-13 12:51:55 -0800947TCGLabel *gen_new_label(void);
948
949/**
950 * label_arg
951 * @l: label
952 *
953 * Encode a label for storage in the TCG opcode stream.
954 */
955
956static inline TCGArg label_arg(TCGLabel *l)
957{
Richard Henderson51e39722015-02-13 18:51:05 -0800958 return (uintptr_t)l;
Richard Henderson42a268c2015-02-13 12:51:55 -0800959}
960
961/**
962 * arg_label
963 * @i: value
964 *
965 * The opposite of label_arg. Retrieve a label from the
966 * encoding of the TCG opcode stream.
967 */
968
Richard Henderson51e39722015-02-13 18:51:05 -0800969static inline TCGLabel *arg_label(TCGArg i)
Richard Henderson42a268c2015-02-13 12:51:55 -0800970{
Richard Henderson51e39722015-02-13 18:51:05 -0800971 return (TCGLabel *)(uintptr_t)i;
Richard Henderson42a268c2015-02-13 12:51:55 -0800972}
973
Peter Maydell09800112013-02-22 18:10:00 +0000974/**
Richard Henderson52a1f642014-03-31 14:27:27 -0700975 * tcg_ptr_byte_diff
976 * @a, @b: addresses to be differenced
977 *
978 * There are many places within the TCG backends where we need a byte
979 * difference between two pointers. While this can be accomplished
980 * with local casting, it's easy to get wrong -- especially if one is
981 * concerned with the signedness of the result.
982 *
983 * This version relies on GCC's void pointer arithmetic to get the
984 * correct result.
985 */
986
987static inline ptrdiff_t tcg_ptr_byte_diff(void *a, void *b)
988{
989 return a - b;
990}
991
992/**
993 * tcg_pcrel_diff
994 * @s: the tcg context
995 * @target: address of the target
996 *
997 * Produce a pc-relative difference, from the current code_ptr
998 * to the destination address.
999 */
1000
1001static inline ptrdiff_t tcg_pcrel_diff(TCGContext *s, void *target)
1002{
1003 return tcg_ptr_byte_diff(target, s->code_ptr);
1004}
1005
1006/**
1007 * tcg_current_code_size
1008 * @s: the tcg context
1009 *
1010 * Compute the current code size within the translation block.
1011 * This is used to fill in qemu's data structures for goto_tb.
1012 */
1013
1014static inline size_t tcg_current_code_size(TCGContext *s)
1015{
1016 return tcg_ptr_byte_diff(s->code_ptr, s->code_buf);
1017}
1018
Richard Henderson59227d52015-05-12 11:51:44 -07001019/* Combine the TCGMemOp and mmu_idx parameters into a single value. */
1020typedef uint32_t TCGMemOpIdx;
1021
1022/**
1023 * make_memop_idx
1024 * @op: memory operation
1025 * @idx: mmu index
1026 *
1027 * Encode these values into a single parameter.
1028 */
1029static inline TCGMemOpIdx make_memop_idx(TCGMemOp op, unsigned idx)
1030{
1031 tcg_debug_assert(idx <= 15);
1032 return (op << 4) | idx;
1033}
1034
1035/**
1036 * get_memop
1037 * @oi: combined op/idx parameter
1038 *
1039 * Extract the memory operation from the combined value.
1040 */
1041static inline TCGMemOp get_memop(TCGMemOpIdx oi)
1042{
1043 return oi >> 4;
1044}
1045
1046/**
1047 * get_mmuidx
1048 * @oi: combined op/idx parameter
1049 *
1050 * Extract the mmu index from the combined value.
1051 */
1052static inline unsigned get_mmuidx(TCGMemOpIdx oi)
1053{
1054 return oi & 15;
1055}
1056
Richard Henderson52a1f642014-03-31 14:27:27 -07001057/**
Peter Maydell09800112013-02-22 18:10:00 +00001058 * tcg_qemu_tb_exec:
Sergey Fedorov819af242016-04-21 15:58:23 +03001059 * @env: pointer to CPUArchState for the CPU
Peter Maydell09800112013-02-22 18:10:00 +00001060 * @tb_ptr: address of generated code for the TB to execute
1061 *
1062 * Start executing code from a given translation block.
1063 * Where translation blocks have been linked, execution
1064 * may proceed from the given TB into successive ones.
1065 * Control eventually returns only when some action is needed
1066 * from the top-level loop: either control must pass to a TB
1067 * which has not yet been directly linked, or an asynchronous
1068 * event such as an interrupt needs handling.
1069 *
Sergey Fedorov819af242016-04-21 15:58:23 +03001070 * Return: The return value is the value passed to the corresponding
1071 * tcg_gen_exit_tb() at translation time of the last TB attempted to execute.
1072 * The value is either zero or a 4-byte aligned pointer to that TB combined
1073 * with additional information in its two least significant bits. The
1074 * additional information is encoded as follows:
Peter Maydell09800112013-02-22 18:10:00 +00001075 * 0, 1: the link between this TB and the next is via the specified
1076 * TB index (0 or 1). That is, we left the TB via (the equivalent
1077 * of) "goto_tb <index>". The main loop uses this to determine
1078 * how to link the TB just executed to the next.
1079 * 2: we are using instruction counting code generation, and we
1080 * did not start executing this TB because the instruction counter
Sergey Fedorov819af242016-04-21 15:58:23 +03001081 * would hit zero midway through it. In this case the pointer
Peter Maydell09800112013-02-22 18:10:00 +00001082 * returned is the TB we were about to execute, and the caller must
1083 * arrange to execute the remaining count of instructions.
Peter Maydell378df4b2013-02-22 18:10:03 +00001084 * 3: we stopped because the CPU's exit_request flag was set
1085 * (usually meaning that there is an interrupt that needs to be
Sergey Fedorov819af242016-04-21 15:58:23 +03001086 * handled). The pointer returned is the TB we were about to execute
1087 * when we noticed the pending exit request.
Peter Maydell09800112013-02-22 18:10:00 +00001088 *
1089 * If the bottom two bits indicate an exit-via-index then the CPU
1090 * state is correctly synchronised and ready for execution of the next
1091 * TB (and in particular the guest PC is the address to execute next).
1092 * Otherwise, we gave up on execution of this TB before it started, and
Peter Crosthwaitefee068e2015-04-29 00:52:21 -07001093 * the caller must fix up the CPU state by calling the CPU's
Sergey Fedorov819af242016-04-21 15:58:23 +03001094 * synchronize_from_tb() method with the TB pointer we return (falling
Peter Crosthwaitefee068e2015-04-29 00:52:21 -07001095 * back to calling the CPU's set_pc method with tb->pb if no
1096 * synchronize_from_tb() method exists).
Peter Maydell09800112013-02-22 18:10:00 +00001097 *
1098 * Note that TCG targets may use a different definition of tcg_qemu_tb_exec
1099 * to this default (which just calls the prologue.code emitted by
1100 * tcg_target_qemu_prologue()).
1101 */
1102#define TB_EXIT_MASK 3
1103#define TB_EXIT_IDX0 0
1104#define TB_EXIT_IDX1 1
Peter Maydell378df4b2013-02-22 18:10:03 +00001105#define TB_EXIT_REQUESTED 3
Peter Maydell09800112013-02-22 18:10:00 +00001106
Paolo Bonzini5a58e882015-05-19 09:59:34 +02001107#ifdef HAVE_TCG_QEMU_TB_EXEC
1108uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
1109#else
Stefan Weilce285b12011-09-30 21:23:06 +02001110# define tcg_qemu_tb_exec(env, tb_ptr) \
Richard Henderson04d5a1d2013-08-20 14:35:34 -07001111 ((uintptr_t (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr)
bellard932a6902008-05-30 20:56:52 +00001112#endif
Richard Henderson813da622012-03-19 12:25:11 -07001113
1114void tcg_register_jit(void *buf, size_t buf_size);
Yeongkyoon Leeb76f0d82012-10-31 16:04:25 +09001115
Richard Hendersone58eb532013-08-27 13:13:44 -07001116/*
1117 * Memory helpers that will be used by TCG generated code.
1118 */
1119#ifdef CONFIG_SOFTMMU
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001120/* Value zero-extended to tcg register size. */
1121tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001122 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001123tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001124 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001125tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001126 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001127uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001128 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001129tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001130 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001131tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001132 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001133uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001134 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Hendersone58eb532013-08-27 13:13:44 -07001135
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001136/* Value sign-extended to tcg register size. */
1137tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001138 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001139tcg_target_ulong helper_le_ldsw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001140 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001141tcg_target_ulong helper_le_ldsl_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001142 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001143tcg_target_ulong helper_be_ldsw_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001144 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001145tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr,
Richard Henderson3972ef62015-05-13 09:10:33 -07001146 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Hendersonc8f94df2013-08-27 14:09:14 -07001147
Richard Hendersone58eb532013-08-27 13:13:44 -07001148void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001149 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001150void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001151 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001152void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001153 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001154void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001155 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001156void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001157 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001158void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001159 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001160void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
Richard Henderson3972ef62015-05-13 09:10:33 -07001161 TCGMemOpIdx oi, uintptr_t retaddr);
Richard Henderson867b3202013-09-04 11:45:20 -07001162
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001163uint8_t helper_ret_ldb_cmmu(CPUArchState *env, target_ulong addr,
1164 TCGMemOpIdx oi, uintptr_t retaddr);
1165uint16_t helper_le_ldw_cmmu(CPUArchState *env, target_ulong addr,
1166 TCGMemOpIdx oi, uintptr_t retaddr);
1167uint32_t helper_le_ldl_cmmu(CPUArchState *env, target_ulong addr,
1168 TCGMemOpIdx oi, uintptr_t retaddr);
1169uint64_t helper_le_ldq_cmmu(CPUArchState *env, target_ulong addr,
1170 TCGMemOpIdx oi, uintptr_t retaddr);
1171uint16_t helper_be_ldw_cmmu(CPUArchState *env, target_ulong addr,
1172 TCGMemOpIdx oi, uintptr_t retaddr);
1173uint32_t helper_be_ldl_cmmu(CPUArchState *env, target_ulong addr,
1174 TCGMemOpIdx oi, uintptr_t retaddr);
1175uint64_t helper_be_ldq_cmmu(CPUArchState *env, target_ulong addr,
1176 TCGMemOpIdx oi, uintptr_t retaddr);
1177
Richard Henderson867b3202013-09-04 11:45:20 -07001178/* Temporary aliases until backends are converted. */
1179#ifdef TARGET_WORDS_BIGENDIAN
1180# define helper_ret_ldsw_mmu helper_be_ldsw_mmu
1181# define helper_ret_lduw_mmu helper_be_lduw_mmu
1182# define helper_ret_ldsl_mmu helper_be_ldsl_mmu
1183# define helper_ret_ldul_mmu helper_be_ldul_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001184# define helper_ret_ldl_mmu helper_be_ldul_mmu
Richard Henderson867b3202013-09-04 11:45:20 -07001185# define helper_ret_ldq_mmu helper_be_ldq_mmu
1186# define helper_ret_stw_mmu helper_be_stw_mmu
1187# define helper_ret_stl_mmu helper_be_stl_mmu
1188# define helper_ret_stq_mmu helper_be_stq_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001189# define helper_ret_ldw_cmmu helper_be_ldw_cmmu
1190# define helper_ret_ldl_cmmu helper_be_ldl_cmmu
1191# define helper_ret_ldq_cmmu helper_be_ldq_cmmu
Richard Henderson867b3202013-09-04 11:45:20 -07001192#else
1193# define helper_ret_ldsw_mmu helper_le_ldsw_mmu
1194# define helper_ret_lduw_mmu helper_le_lduw_mmu
1195# define helper_ret_ldsl_mmu helper_le_ldsl_mmu
1196# define helper_ret_ldul_mmu helper_le_ldul_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001197# define helper_ret_ldl_mmu helper_le_ldul_mmu
Richard Henderson867b3202013-09-04 11:45:20 -07001198# define helper_ret_ldq_mmu helper_le_ldq_mmu
1199# define helper_ret_stw_mmu helper_le_stw_mmu
1200# define helper_ret_stl_mmu helper_le_stl_mmu
1201# define helper_ret_stq_mmu helper_le_stq_mmu
Pavel Dovgalyuk282dffc2015-07-10 12:56:50 +03001202# define helper_ret_ldw_cmmu helper_le_ldw_cmmu
1203# define helper_ret_ldl_cmmu helper_le_ldl_cmmu
1204# define helper_ret_ldq_cmmu helper_le_ldq_cmmu
Richard Henderson867b3202013-09-04 11:45:20 -07001205#endif
Richard Hendersone58eb532013-08-27 13:13:44 -07001206
Richard Hendersonc482cb12016-06-28 11:37:27 -07001207uint32_t helper_atomic_cmpxchgb_mmu(CPUArchState *env, target_ulong addr,
1208 uint32_t cmpv, uint32_t newv,
1209 TCGMemOpIdx oi, uintptr_t retaddr);
1210uint32_t helper_atomic_cmpxchgw_le_mmu(CPUArchState *env, target_ulong addr,
1211 uint32_t cmpv, uint32_t newv,
1212 TCGMemOpIdx oi, uintptr_t retaddr);
1213uint32_t helper_atomic_cmpxchgl_le_mmu(CPUArchState *env, target_ulong addr,
1214 uint32_t cmpv, uint32_t newv,
1215 TCGMemOpIdx oi, uintptr_t retaddr);
1216uint64_t helper_atomic_cmpxchgq_le_mmu(CPUArchState *env, target_ulong addr,
1217 uint64_t cmpv, uint64_t newv,
1218 TCGMemOpIdx oi, uintptr_t retaddr);
1219uint32_t helper_atomic_cmpxchgw_be_mmu(CPUArchState *env, target_ulong addr,
1220 uint32_t cmpv, uint32_t newv,
1221 TCGMemOpIdx oi, uintptr_t retaddr);
1222uint32_t helper_atomic_cmpxchgl_be_mmu(CPUArchState *env, target_ulong addr,
1223 uint32_t cmpv, uint32_t newv,
1224 TCGMemOpIdx oi, uintptr_t retaddr);
1225uint64_t helper_atomic_cmpxchgq_be_mmu(CPUArchState *env, target_ulong addr,
1226 uint64_t cmpv, uint64_t newv,
1227 TCGMemOpIdx oi, uintptr_t retaddr);
1228
1229#define GEN_ATOMIC_HELPER(NAME, TYPE, SUFFIX) \
1230TYPE helper_atomic_ ## NAME ## SUFFIX ## _mmu \
1231 (CPUArchState *env, target_ulong addr, TYPE val, \
1232 TCGMemOpIdx oi, uintptr_t retaddr);
1233
Richard Hendersondf79b992016-09-02 12:23:57 -07001234#ifdef CONFIG_ATOMIC64
Richard Hendersonc482cb12016-06-28 11:37:27 -07001235#define GEN_ATOMIC_HELPER_ALL(NAME) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001236 GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001237 GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001238 GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001239 GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001240 GEN_ATOMIC_HELPER(NAME, uint32_t, l_be) \
Richard Hendersondf79b992016-09-02 12:23:57 -07001241 GEN_ATOMIC_HELPER(NAME, uint64_t, q_le) \
Richard Hendersonc482cb12016-06-28 11:37:27 -07001242 GEN_ATOMIC_HELPER(NAME, uint64_t, q_be)
Richard Hendersondf79b992016-09-02 12:23:57 -07001243#else
1244#define GEN_ATOMIC_HELPER_ALL(NAME) \
1245 GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
1246 GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
1247 GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
1248 GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
1249 GEN_ATOMIC_HELPER(NAME, uint32_t, l_be)
1250#endif
Richard Hendersonc482cb12016-06-28 11:37:27 -07001251
1252GEN_ATOMIC_HELPER_ALL(fetch_add)
1253GEN_ATOMIC_HELPER_ALL(fetch_sub)
1254GEN_ATOMIC_HELPER_ALL(fetch_and)
1255GEN_ATOMIC_HELPER_ALL(fetch_or)
1256GEN_ATOMIC_HELPER_ALL(fetch_xor)
1257
1258GEN_ATOMIC_HELPER_ALL(add_fetch)
1259GEN_ATOMIC_HELPER_ALL(sub_fetch)
1260GEN_ATOMIC_HELPER_ALL(and_fetch)
1261GEN_ATOMIC_HELPER_ALL(or_fetch)
1262GEN_ATOMIC_HELPER_ALL(xor_fetch)
1263
1264GEN_ATOMIC_HELPER_ALL(xchg)
1265
1266#undef GEN_ATOMIC_HELPER_ALL
1267#undef GEN_ATOMIC_HELPER
Richard Hendersone58eb532013-08-27 13:13:44 -07001268#endif /* CONFIG_SOFTMMU */
1269
Richard Henderson7ebee432016-06-29 21:10:59 -07001270#ifdef CONFIG_ATOMIC128
1271#include "qemu/int128.h"
1272
1273/* These aren't really a "proper" helpers because TCG cannot manage Int128.
1274 However, use the same format as the others, for use by the backends. */
1275Int128 helper_atomic_cmpxchgo_le_mmu(CPUArchState *env, target_ulong addr,
1276 Int128 cmpv, Int128 newv,
1277 TCGMemOpIdx oi, uintptr_t retaddr);
1278Int128 helper_atomic_cmpxchgo_be_mmu(CPUArchState *env, target_ulong addr,
1279 Int128 cmpv, Int128 newv,
1280 TCGMemOpIdx oi, uintptr_t retaddr);
1281
1282Int128 helper_atomic_ldo_le_mmu(CPUArchState *env, target_ulong addr,
1283 TCGMemOpIdx oi, uintptr_t retaddr);
1284Int128 helper_atomic_ldo_be_mmu(CPUArchState *env, target_ulong addr,
1285 TCGMemOpIdx oi, uintptr_t retaddr);
1286void helper_atomic_sto_le_mmu(CPUArchState *env, target_ulong addr, Int128 val,
1287 TCGMemOpIdx oi, uintptr_t retaddr);
1288void helper_atomic_sto_be_mmu(CPUArchState *env, target_ulong addr, Int128 val,
1289 TCGMemOpIdx oi, uintptr_t retaddr);
1290
1291#endif /* CONFIG_ATOMIC128 */
1292
Richard Hendersone58eb532013-08-27 13:13:44 -07001293#endif /* TCG_H */