18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Tiny Code Generator for QEMU
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2008 Fabrice Bellard
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions:
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software.
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE.
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h"
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg-target.h"
26b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#include "tcg-runtime.h"
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef int32_t tcg_target_long;
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef uint32_t tcg_target_ulong;
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_PRIlx PRIx32
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_PRIld PRId32
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif TCG_TARGET_REG_BITS == 64
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef int64_t tcg_target_long;
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef uint64_t tcg_target_ulong;
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_PRIlx PRIx64
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_PRIld PRId64
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#error unsupported
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_NB_REGS <= 32
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef uint32_t TCGRegSet;
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif TCG_TARGET_NB_REGS <= 64
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef uint64_t TCGRegSet;
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#error unsupported
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnertypedef enum TCGOpcode {
51f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg-opc.h"
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DEF
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    NB_OPS,
55f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner} TCGOpcode;
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_regset_clear(d) (d) = 0
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_regset_set(d, s) (d) = (s)
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_regset_set32(d, reg, val32) (d) |= (val32) << (reg)
60b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#define tcg_regset_set_reg(d, r) (d) |= 1L << (r)
61b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#define tcg_regset_reset_reg(d, r) (d) &= ~(1L << (r))
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_regset_test_reg(d, r) (((d) >> (r)) & 1)
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_regset_or(d, a, b) (d) = (a) | (b)
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_regset_and(d, a, b) (d) = (a) & (b)
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_regset_andnot(d, a, b) (d) = (a) & ~(b)
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_regset_not(d, a) (d) = ~(a)
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TCGRelocation {
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct TCGRelocation *next;
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int type;
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *ptr;
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_long addend;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TCGRelocation;
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TCGLabel {
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int has_value;
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    union {
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_target_ulong value;
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        TCGRelocation *first_reloc;
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } u;
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TCGLabel;
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TCGPool {
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct TCGPool *next;
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int size;
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t data[0] __attribute__ ((aligned));
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TCGPool;
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_POOL_CHUNK_SIZE 32768
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_MAX_LABELS 512
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_MAX_TEMPS 512
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* when the size of the arguments of a called function is smaller than
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   this value, they are statically allocated in the TB stack frame */
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_STATIC_CALL_ARGS_SIZE 128
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
99f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnertypedef enum TCGType {
100f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCG_TYPE_I32,
101f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCG_TYPE_I64,
102f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCG_TYPE_COUNT, /* number of different types */
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
104f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    /* An alias for the size of the host register.  */
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
106f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCG_TYPE_REG = TCG_TYPE_I32,
107f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#else
108f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCG_TYPE_REG = TCG_TYPE_I64,
109f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif
110f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
111f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    /* An alias for the size of the native pointer.  We don't currently
112f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner       support any hosts with 64-bit registers and 32-bit pointers.  */
113f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCG_TYPE_PTR = TCG_TYPE_REG,
114f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
115f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    /* An alias for the size of the target "long", aka register.  */
116f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if TARGET_LONG_BITS == 64
117f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCG_TYPE_TL = TCG_TYPE_I64,
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
119f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCG_TYPE_TL = TCG_TYPE_I32,
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
121f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner} TCGType;
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef tcg_target_ulong TCGArg;
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Define a type and accessor macros for varables.  Using a struct is
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   nice because it gives some level of type safely.  Ideally the compiler
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   be able to see through all this.  However in practice this is not true,
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   expecially on targets with braindamaged ABIs (e.g. i386).
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   We use plain int by default to avoid this runtime overhead.
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Users of tcg_gen_* don't need to know about any of this, and should
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   treat TCGv as an opaque type.
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   In additon we do typechecking for different types of variables.  TCGv_i32
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   and TCGv_i64 are 32/64-bit variables respectively.  TCGv and TCGv_ptr
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   are aliases for target_ulong and host pointer sized values respectively.
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
137b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#ifdef CONFIG_DEBUG_TCG
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEBUG_TCGV 1
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_TCGV
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i32;
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} TCGv_i32;
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i64;
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} TCGv_i64;
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAKE_TCGV_I32(i) __extension__                  \
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ({ TCGv_i32 make_tcgv_tmp = {i}; make_tcgv_tmp;})
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAKE_TCGV_I64(i) __extension__                  \
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ({ TCGv_i64 make_tcgv_tmp = {i}; make_tcgv_tmp;})
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_TCGV_I32(t) ((t).i32)
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_TCGV_I64(t) ((t).i64)
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t))
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1)
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !DEBUG_TCGV */
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef int TCGv_i32;
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef int TCGv_i64;
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAKE_TCGV_I32(x) (x)
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAKE_TCGV_I64(x) (x)
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_TCGV_I32(t) (t)
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_TCGV_I64(t) (t)
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCGV_LOW(t) (t)
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCGV_HIGH(t) ((t) + 1)
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* DEBUG_TCGV */
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCGV_EQUAL_I32(a, b) (GET_TCGV_I32(a) == GET_TCGV_I32(b))
1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCGV_EQUAL_I64(a, b) (GET_TCGV_I64(a) == GET_TCGV_I64(b))
1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Dummy definition to avoid compiler warnings.  */
1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1)
1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1)
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* call flags */
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CALL_TYPE_MASK      0x000f
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CALL_TYPE_STD       0x0000 /* standard C call */
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CALL_TYPE_REGPARM_1 0x0001 /* i386 style regparm call (1 reg) */
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CALL_TYPE_REGPARM_2 0x0002 /* i386 style regparm call (2 regs) */
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CALL_TYPE_REGPARM   0x0003 /* i386 style regparm call (3 regs) */
1935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* A pure function only reads its arguments and TCG global variables
1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   and cannot raise exceptions. Hence a call to a pure function can be
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   safely suppressed if the return value is not used. */
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CALL_PURE           0x0010
1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* A const function only reads its arguments and does not use TCG
1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   global variables. Hence a call to such a function does not
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   save TCG global variables back to their canonical location. */
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCG_CALL_CONST          0x0020
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* used to align parameters */
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCG_CALL_DUMMY_TCGV     MAKE_TCGV_I32(-1)
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CALL_DUMMY_ARG      ((TCGArg)(-1))
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef enum {
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_EQ,
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_NE,
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_LT,
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_GE,
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_LE,
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_GT,
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* unsigned */
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_LTU,
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_GEU,
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_LEU,
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCG_COND_GTU,
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TCGCond;
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
220b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner/* Invert the sense of the comparison.  */
221b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turnerstatic inline TCGCond tcg_invert_cond(TCGCond c)
222b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner{
223b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    return (TCGCond)(c ^ 1);
224b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner}
225b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
226b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner/* Swap the operands in a comparison.  */
227b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turnerstatic inline TCGCond tcg_swap_cond(TCGCond c)
228b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner{
229b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    int mask = (c < TCG_COND_LT ? 0 : c < TCG_COND_LTU ? 7 : 15);
230b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    return (TCGCond)(c ^ mask);
231b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner}
232b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
233b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turnerstatic inline TCGCond tcg_unsigned_cond(TCGCond c)
234b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner{
235b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    return (c >= TCG_COND_LT && c <= TCG_COND_GT ? c + 4 : c);
236b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner}
237b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TEMP_VAL_DEAD  0
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TEMP_VAL_REG   1
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TEMP_VAL_MEM   2
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TEMP_VAL_CONST 3
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: optimize memory layout */
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TCGTemp {
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGType base_type;
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGType type;
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int val_type;
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int reg;
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_long val;
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int mem_reg;
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_long mem_offset;
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int fixed_reg:1;
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int mem_coherent:1;
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int mem_allocated:1;
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int temp_local:1; /* If true, the temp is saved accross
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                  basic blocks. Otherwise, it is not
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                  preserved accross basic blocks. */
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int temp_allocated:1; /* never used for code gen */
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* index of next free temp of same base type, -1 if end */
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int next_free_temp;
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *name;
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TCGTemp;
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TCGHelperInfo {
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_ulong func;
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *name;
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TCGHelperInfo;
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TCGContext TCGContext;
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct TCGContext {
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *pool_cur, *pool_end;
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGPool *pool_first, *pool_current;
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGLabel *labels;
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int nb_labels;
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *temps; /* globals first, temps after */
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int nb_globals;
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int nb_temps;
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* index of free temps, -1 if none */
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int first_free_temp[TCG_TYPE_COUNT * 2];
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* goto_tb support */
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *code_buf;
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long *tb_next;
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t *tb_next_offset;
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* liveness analysis */
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t *op_dead_iargs; /* for each operation, each bit tells if the
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                corresponding input argument is dead */
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* tells in which temporary a given register is. It does not take
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       into account fixed registers */
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int reg_to_temp[TCG_TARGET_NB_REGS];
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGRegSet reserved_regs;
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_long current_frame_offset;
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_long frame_start;
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_long frame_end;
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int frame_reg;
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *code_ptr;
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp static_temps[TCG_MAX_TEMPS];
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGHelperInfo *helpers;
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int nb_helpers;
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int allocated_helpers;
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int helpers_sorted;
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* profiling info */
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t tb_count1;
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t tb_count;
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t op_count; /* total insn count */
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int op_count_max; /* max insn per TB */
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t temp_count;
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int temp_count_max;
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t del_op_count;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t code_in_len;
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t code_out_len;
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t interm_time;
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t code_time;
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t la_time;
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t restore_count;
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t restore_time;
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
326f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
327f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#ifdef CONFIG_DEBUG_TCG
328f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    int temps_in_use;
329f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern TCGContext tcg_ctx;
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern uint16_t *gen_opc_ptr;
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern TCGArg *gen_opparam_ptr;
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern uint16_t gen_opc_buf[];
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern TCGArg gen_opparam_buf[];
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* pool based memory allocation */
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid *tcg_malloc_internal(TCGContext *s, int size);
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_pool_reset(TCGContext *s);
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_pool_delete(TCGContext *s);
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void *tcg_malloc(int size)
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *ptr, *ptr_end;
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ptr = s->pool_cur;
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ptr_end = ptr + size;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (unlikely(ptr_end > s->pool_end)) {
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return tcg_malloc_internal(&tcg_ctx, size);
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->pool_cur = ptr_end;
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return ptr;
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_context_init(TCGContext *s);
360f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_prologue_init(TCGContext *s);
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_func_start(TCGContext *s);
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
3645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_set_frame(TCGContext *s, int reg,
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   tcg_target_long start, tcg_target_long size);
3685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
3705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
3715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                const char *name);
3725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_temp_new_internal_i32(int temp_local);
3735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline TCGv_i32 tcg_temp_new_i32(void)
3745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return tcg_temp_new_internal_i32(0);
3765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline TCGv_i32 tcg_temp_local_new_i32(void)
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return tcg_temp_new_internal_i32(1);
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_temp_free_i32(TCGv_i32 arg);
3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg);
3835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
3855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                const char *name);
3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_temp_new_internal_i64(int temp_local);
3885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline TCGv_i64 tcg_temp_new_i64(void)
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return tcg_temp_new_internal_i64(0);
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline TCGv_i64 tcg_temp_local_new_i64(void)
3935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return tcg_temp_new_internal_i64(1);
3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_temp_free_i64(TCGv_i64 arg);
3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
399f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG)
400f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner/* If you call tcg_clear_temp_count() at the start of a section of
401f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner * code which is not supposed to leak any TCG temporaries, then
402f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner * calling tcg_check_temp_count() at the end of the section will
403f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner * return 1 if the section did in fact leak a temporary.
404f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner */
405f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_clear_temp_count(void);
406f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerint tcg_check_temp_count(void);
407f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#else
408f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#define tcg_clear_temp_count() do { } while (0)
409f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#define tcg_check_temp_count() 0
410f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif
411f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
412f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CT_ALIAS  0x80
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CT_IALIAS 0x40
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CT_REG    0x01
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_CT_CONST  0x02 /* any constant of register size */
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TCGArgConstraint {
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t ct;
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t alias_index;
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    union {
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        TCGRegSet regs;
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } u;
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TCGArgConstraint;
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_MAX_OP_ARGS 16
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_OPF_BB_END     0x01 /* instruction defines the end of a basic
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                   block */
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                   and potentially update globals. */
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TCG_OPF_SIDE_EFFECTS 0x04 /* instruction has side effects : it
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                     cannot be removed if its output
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                     are not used */
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TCGOpDef {
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *name;
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t flags;
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArgConstraint *args_ct;
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int *sorted_args;
443b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG)
444b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    int used;
445b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TCGOpDef;
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TCGTargetOpDef {
449f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCGOpcode op;
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *args_ct_str[TCG_MAX_OP_ARGS];
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TCGTargetOpDef;
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_abort() \
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo {\
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    abort();\
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} while (0)
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_const_ptr tcg_const_i32
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_add_ptr tcg_add_i32
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_sub_ptr tcg_sub_i32
4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCGv_ptr TCGv_i32
4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_TCGV_PTR GET_TCGV_I32
4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define tcg_global_reg_new_ptr tcg_global_reg_new_i32
4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define tcg_global_mem_new_ptr tcg_global_mem_new_i32
4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define tcg_temp_new_ptr tcg_temp_new_i32
4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define tcg_temp_free_ptr tcg_temp_free_i32
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_const_ptr tcg_const_i64
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_add_ptr tcg_add_i64
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_sub_ptr tcg_sub_i64
4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCGv_ptr TCGv_i64
4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_TCGV_PTR GET_TCGV_I64
4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define tcg_global_reg_new_ptr tcg_global_reg_new_i64
4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define tcg_global_mem_new_ptr tcg_global_mem_new_i64
4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define tcg_temp_new_ptr tcg_temp_new_i64
4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define tcg_temp_free_ptr tcg_temp_free_i64
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
4845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                   int sizemask, TCGArg ret, int nargs, TCGArg *args);
4855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        int c, int right, int arith);
4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* only used for debugging purposes */
4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_register_helper(void *func, const char *name);
4915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *tcg_helper_get_name(TCGContext *s, void *func);
4925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_dump_ops(TCGContext *s, FILE *outfile);
4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid dump_ops(const uint16_t *opc_buf, const TCGArg *opparam_buf);
4955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_const_i32(int32_t val);
4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_const_i64(int64_t val);
4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_const_local_i32(int32_t val);
4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_const_local_i64(int64_t val);
4995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern uint8_t code_gen_prologue[];
5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(_ARCH_PPC) && !defined(_ARCH_PPC64)
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_qemu_tb_exec(tb_ptr) \
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr)
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
507