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 */
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* define it to use liveness analysis (better code) */
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USE_LIVENESS_ANALYSIS
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "config.h"
295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* define it to suppress various consistency checks (faster) */
325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NDEBUG
335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdarg.h>
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <inttypes.h>
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <malloc.h>
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _AIX
445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <alloca.h>
455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h"
485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "cache-utils.h"
49b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#include "host-utils.h"
506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "qemu-timer.h"
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: the long term plan is to reduce the dependancies on the QEMU
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   CPU definitions. Currently they are used for qemu_ld/st
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   instructions */
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NO_CPU_IO_DEFS
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "cpu.h"
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "exec-all.h"
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg-op.h"
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "elf.h"
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
62b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE)
63b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#error GUEST_BASE not supported on this host.
64b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif
65b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
66f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void tcg_target_init(TCGContext *s);
67f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void tcg_target_qemu_prologue(TCGContext *s);
68b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turnerstatic void patch_reloc(uint8_t *code_ptr, int type,
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tcg_target_long value, tcg_target_long addend);
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic TCGOpDef tcg_op_defs[] = {
72f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg-opc.h"
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DEF
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic TCGRegSet tcg_target_available_regs[2];
785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic TCGRegSet tcg_target_call_clobber_regs;
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: move that inside the context */
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint16_t *gen_opc_ptr;
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTCGArg *gen_opparam_ptr;
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/*
865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Memchecker addition in this module is intended to build a map that matches
875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * translated PC to a guest PC. Map is built in tcg_gen_code_common routine,
885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * and is saved into temporary gen_opc_tpc2gpc_ptr array, that later will be
895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * copied into the TranslationBlock that represents the translated code.
905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck/memcheck_api.h"
925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_out8(TCGContext *s, uint8_t v)
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *s->code_ptr++ = v;
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_out16(TCGContext *s, uint16_t v)
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *(uint16_t *)s->code_ptr = v;
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_ptr += 2;
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_out32(TCGContext *s, uint32_t v)
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *(uint32_t *)s->code_ptr = v;
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_ptr += 4;
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* label relocation processing */
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
113f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   int label_index, long addend)
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGLabel *l;
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGRelocation *r;
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    l = &s->labels[label_index];
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (l->has_value) {
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* FIXME: This may break relocations on RISC targets that
122b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner           modify instruction fields in place.  The caller may not have
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           written the initial value.  */
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        patch_reloc(code_ptr, type, l->u.value, addend);
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* add a new relocation entry */
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        r = tcg_malloc(sizeof(TCGRelocation));
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        r->type = type;
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        r->ptr = code_ptr;
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        r->addend = addend;
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        r->next = l->u.first_reloc;
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        l->u.first_reloc = r;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
136b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turnerstatic void tcg_out_label(TCGContext *s, int label_index,
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          tcg_target_long value)
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGLabel *l;
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGRelocation *r;
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    l = &s->labels[label_index];
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (l->has_value)
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r = l->u.first_reloc;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (r != NULL) {
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        patch_reloc(r->ptr, r->type, value, r->addend);
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        r = r->next;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    l->has_value = 1;
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    l->u.value = value;
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint gen_new_label(void)
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int idx;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGLabel *l;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->nb_labels >= TCG_MAX_LABELS)
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    idx = s->nb_labels++;
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    l = &s->labels[idx];
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    l->has_value = 0;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    l->u.first_reloc = NULL;
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return idx;
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg-target.c"
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* pool based memory allocation */
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid *tcg_malloc_internal(TCGContext *s, int size)
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGPool *p;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int pool_size;
176b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (size > TCG_POOL_CHUNK_SIZE) {
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* big malloc: insert a new pool (XXX: could optimize) */
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = qemu_malloc(sizeof(TCGPool) + size);
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p->size = size;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->pool_current)
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->pool_current->next = p;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->pool_first = p;
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p->next = s->pool_current;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = s->pool_current;
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!p) {
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = s->pool_first;
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!p)
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto new_pool;
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!p->next) {
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            new_pool:
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                pool_size = TCG_POOL_CHUNK_SIZE;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p = qemu_malloc(sizeof(TCGPool) + pool_size);
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p->size = pool_size;
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p->next = NULL;
199b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner                if (s->pool_current)
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->pool_current->next = p;
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->pool_first = p;
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p = p->next;
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->pool_current = p;
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->pool_cur = p->data + size;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->pool_end = p->data + p->size;
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return p->data;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_pool_reset(TCGContext *s)
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->pool_cur = s->pool_end = NULL;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->pool_current = NULL;
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_context_init(TCGContext *s)
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int op, total_args, n;
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGOpDef *def;
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArgConstraint *args_ct;
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int *sorted_args;
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(s, 0, sizeof(*s));
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->temps = s->static_temps;
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->nb_globals = 0;
230b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Count total number of arguments and allocate the corresponding
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       space */
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    total_args = 0;
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(op = 0; op < NB_OPS; op++) {
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[op];
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = def->nb_iargs + def->nb_oargs;
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        total_args += n;
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args_ct = qemu_malloc(sizeof(TCGArgConstraint) * total_args);
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sorted_args = qemu_malloc(sizeof(int) * total_args);
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(op = 0; op < NB_OPS; op++) {
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[op];
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def->args_ct = args_ct;
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def->sorted_args = sorted_args;
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = def->nb_iargs + def->nb_oargs;
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sorted_args += n;
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args_ct += n;
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
251b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_init(s);
253f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner}
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
255f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_prologue_init(TCGContext *s)
256f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner{
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* init global prologue and epilogue */
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_buf = code_gen_prologue;
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_ptr = s->code_buf;
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_qemu_prologue(s);
261b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    flush_icache_range((unsigned long)s->code_buf,
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       (unsigned long)s->code_ptr);
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_set_frame(TCGContext *s, int reg,
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   tcg_target_long start, tcg_target_long size)
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->frame_start = start;
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->frame_end = start + size;
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->frame_reg = reg;
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_func_start(TCGContext *s)
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_pool_reset(s);
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->nb_temps = s->nb_globals;
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->first_free_temp[i] = -1;
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->nb_labels = 0;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->current_frame_offset = s->frame_start;
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gen_opc_ptr = gen_opc_buf;
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gen_opparam_ptr = gen_opparam_buf;
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_temp_alloc(TCGContext *s, int n)
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (n > TCG_MAX_TEMPS)
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int tcg_global_reg_new_internal(TCGType type, int reg,
2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                              const char *name)
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int idx;
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type != TCG_TYPE_I32)
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tcg_regset_test_reg(s->reserved_regs, reg))
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    idx = s->nb_globals;
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_temp_alloc(s, s->nb_globals + 1);
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[s->nb_globals];
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->base_type = type;
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->type = type;
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->fixed_reg = 1;
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->reg = reg;
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->name = name;
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->nb_globals++;
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_regset_set_reg(s->reserved_regs, reg);
3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return idx;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int idx;
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I32(idx);
3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I64(idx);
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int tcg_global_mem_new_internal(TCGType type, int reg,
3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                              tcg_target_long offset,
3385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                              const char *name)
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int idx;
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    idx = s->nb_globals;
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type == TCG_TYPE_I64) {
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char buf[64];
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_temp_alloc(s, s->nb_globals + 2);
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[s->nb_globals];
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->base_type = type;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->type = TCG_TYPE_I32;
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->fixed_reg = 0;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_allocated = 1;
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_reg = reg;
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset + 4;
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset;
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcpy(buf, sizeof(buf), name);
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcat(buf, sizeof(buf), "_0");
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->name = strdup(buf);
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts++;
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->base_type = type;
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->type = TCG_TYPE_I32;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->fixed_reg = 0;
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_allocated = 1;
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_reg = reg;
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset;
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset + 4;
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcpy(buf, sizeof(buf), name);
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcat(buf, sizeof(buf), "_1");
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->name = strdup(buf);
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->nb_globals += 2;
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_temp_alloc(s, s->nb_globals + 1);
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[s->nb_globals];
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->base_type = type;
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->type = type;
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->fixed_reg = 0;
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_allocated = 1;
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_reg = reg;
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset;
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->name = name;
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->nb_globals++;
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return idx;
3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                const char *name)
3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I32(idx);
4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                const char *name)
4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
4105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I64(idx);
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int tcg_temp_new_internal(TCGType type, int temp_local)
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int idx, k;
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    k = type;
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (temp_local)
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        k += TCG_TYPE_COUNT;
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    idx = s->first_free_temp[k];
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (idx != -1) {
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* There is already an available temp with the
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           right type */
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[idx];
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->first_free_temp[k] = ts->next_free_temp;
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->temp_allocated = 1;
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(ts->temp_local == temp_local);
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        idx = s->nb_temps;
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (type == TCG_TYPE_I64) {
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_temp_alloc(s, s->nb_temps + 2);
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[s->nb_temps];
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->base_type = type;
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->type = TCG_TYPE_I32;
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_allocated = 1;
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_local = temp_local;
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->name = NULL;
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts++;
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->base_type = TCG_TYPE_I32;
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->type = TCG_TYPE_I32;
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_allocated = 1;
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_local = temp_local;
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->name = NULL;
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->nb_temps += 2;
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_temp_alloc(s, s->nb_temps + 1);
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[s->nb_temps];
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->base_type = type;
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->type = type;
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_allocated = 1;
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_local = temp_local;
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->name = NULL;
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->nb_temps++;
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
463f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
464f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG)
465f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    s->temps_in_use++;
466f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif
4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return idx;
4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_temp_new_internal_i32(int temp_local)
4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I32(idx);
4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_temp_new_internal_i64(int temp_local)
4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I64(idx);
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline void tcg_temp_free_internal(int idx)
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int k;
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
492f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG)
493f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    s->temps_in_use--;
494f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    if (s->temps_in_use < 0) {
495f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        fprintf(stderr, "More temporaries freed than allocated!\n");
496f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    }
497f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif
498f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    assert(idx >= s->nb_globals && idx < s->nb_temps);
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[idx];
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    assert(ts->temp_allocated != 0);
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->temp_allocated = 0;
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    k = ts->base_type;
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ts->temp_local)
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        k += TCG_TYPE_COUNT;
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->next_free_temp = s->first_free_temp[k];
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->first_free_temp[k] = idx;
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_temp_free_i32(TCGv_i32 arg)
5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tcg_temp_free_internal(GET_TCGV_I32(arg));
5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_temp_free_i64(TCGv_i64 arg)
5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tcg_temp_free_internal(GET_TCGV_I64(arg));
5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_const_i32(int32_t val)
5215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGv_i32 t0;
5235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t0 = tcg_temp_new_i32();
5245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tcg_gen_movi_i32(t0, val);
5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return t0;
5265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_const_i64(int64_t val)
5295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGv_i64 t0;
5315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t0 = tcg_temp_new_i64();
5325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tcg_gen_movi_i64(t0, val);
5335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return t0;
5345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_const_local_i32(int32_t val)
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGv_i32 t0;
5395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t0 = tcg_temp_local_new_i32();
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_gen_movi_i32(t0, val);
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return t0;
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_const_local_i64(int64_t val)
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGv_i64 t0;
5475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t0 = tcg_temp_local_new_i64();
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_gen_movi_i64(t0, val);
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return t0;
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
552f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG)
553f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_clear_temp_count(void)
554f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner{
555f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCGContext *s = &tcg_ctx;
556f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    s->temps_in_use = 0;
557f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner}
558f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
559f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerint tcg_check_temp_count(void)
560f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner{
561f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCGContext *s = &tcg_ctx;
562f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    if (s->temps_in_use) {
563f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        /* Clear the count so that we don't give another
564f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner         * warning immediately next time around.
565f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner         */
566f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        s->temps_in_use = 0;
567f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        return 1;
568f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    }
569f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    return 0;
570f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner}
571f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif
572f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_register_helper(void *func, const char *name)
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int n;
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((s->nb_helpers + 1) > s->allocated_helpers) {
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = s->allocated_helpers;
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (n == 0) {
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            n = 4;
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            n *= 2;
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->allocated_helpers = n;
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->helpers[s->nb_helpers].name = name;
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->nb_helpers++;
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: we convert the 64 bit args to 32 bit and do some alignment
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   and endian swap. Maybe it would be better to do the alignment
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   and endian swap in tcg_reg_alloc_call(). */
5955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                   int sizemask, TCGArg ret, int nargs, TCGArg *args)
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
598f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#ifdef TCG_TARGET_I386
5995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int call_type;
600f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif
6015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
6025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int real_args;
6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nb_rets;
6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGArg *nparam;
605f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
606f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
607f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    for (i = 0; i < nargs; ++i) {
608f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        int is_64bit = sizemask & (1 << (i+1)*2);
609f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        int is_signed = sizemask & (2 << (i+1)*2);
610f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        if (!is_64bit) {
611f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            TCGv_i64 temp = tcg_temp_new_i64();
612f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
613f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            if (is_signed) {
614f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                tcg_gen_ext32s_i64(temp, orig);
615f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            } else {
616f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                tcg_gen_ext32u_i64(temp, orig);
617f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            }
618f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            args[i] = GET_TCGV_I64(temp);
619f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        }
620f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    }
621f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif /* TCG_TARGET_EXTEND_ARGS */
622f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
6235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *gen_opc_ptr++ = INDEX_op_call;
6245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nparam = gen_opparam_ptr++;
625f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#ifdef TCG_TARGET_I386
6265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    call_type = (flags & TCG_CALL_TYPE_MASK);
627f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif
6285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret != TCG_CALL_DUMMY_ARG) {
6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if TCG_TARGET_REG_BITS < 64
6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (sizemask & 1) {
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN
6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret + 1;
6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret;
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret;
6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret + 1;
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_rets = 2;
6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        {
6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret;
6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_rets = 1;
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_rets = 0;
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    real_args = 0;
6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < nargs; i++) {
6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if TCG_TARGET_REG_BITS < 64
651f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        int is_64bit = sizemask & (1 << (i+1)*2);
652f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        if (is_64bit) {
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_I386
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* REGPARM case: if the third parameter is 64 bit, it is
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               allocated on the stack */
6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (i == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                call_type = TCG_CALL_TYPE_REGPARM_2;
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                flags = (flags & ~TCG_CALL_TYPE_MASK) | call_type;
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_CALL_ALIGN_ARGS
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* some targets want aligned 64 bit args */
6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (real_args & 1) {
6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                real_args++;
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
668f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	    /* If stack grows up, then we will be placing successive
669f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	       arguments at lower addresses, which means we need to
670f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	       reverse the order compared to how we would normally
671f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	       treat either big or little-endian.  For those arguments
672f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	       that will wind up in registers, this still works for
673f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	       HPPA (the only current STACK_GROWSUP target) since the
674f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	       argument registers are *also* allocated in decreasing
675f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	       order.  If another such target is added, this logic may
676f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	       have to get more complicated to differentiate between
677f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner	       stack arguments and register arguments.  */
678f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i] + 1;
6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i];
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i];
6835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i] + 1;
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            real_args += 2;
686f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            continue;
687f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        }
688f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif /* TCG_TARGET_REG_BITS < 64 */
689f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i];
6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            real_args++;
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *gen_opparam_ptr++ = GET_TCGV_PTR(func);
6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *gen_opparam_ptr++ = flags;
6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *nparam = (nb_rets << 16) | (real_args + 1);
6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* total parameters, needed to go backward in the instruction stream */
7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
701f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
702f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
703f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    for (i = 0; i < nargs; ++i) {
704f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        int is_64bit = sizemask & (1 << (i+1)*2);
705f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        if (!is_64bit) {
706f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
707f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            tcg_temp_free_i64(temp);
708f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        }
709f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    }
710f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif /* TCG_TARGET_EXTEND_ARGS */
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        int c, int right, int arith)
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (c == 0) {
7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (c >= 32) {
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c -= 32;
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (right) {
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arith) {
7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_movi_i32(TCGV_LOW(ret), 0);
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        TCGv_i32 t0, t1;
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        t0 = tcg_temp_new_i32();
7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        t1 = tcg_temp_new_i32();
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (right) {
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arith)
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Note: ret can be the same as arg1, so we use t1 */
7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_mov_i32(TCGV_LOW(ret), t1);
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_temp_free_i32(t0);
7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_temp_free_i32(t1);
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
762f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_start(TCGContext *s)
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < s->nb_globals; i++) {
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[i];
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->fixed_reg) {
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_REG;
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_MEM;
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = s->nb_globals; i < s->nb_temps; i++) {
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[i];
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->val_type = TEMP_VAL_DEAD;
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_allocated = 0;
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->fixed_reg = 0;
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->reg_to_temp[i] = -1;
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                 int idx)
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[idx];
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (idx < s->nb_globals) {
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcpy(buf, buf_size, ts->name);
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
795b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        if (ts->temp_local)
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int helper_cmp(const void *p1, const void *p2)
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGHelperInfo *th1 = p1;
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGHelperInfo *th2 = p2;
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (th1->func < th2->func)
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if (th1->func == th2->func)
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* find helper definition (Note: A hash table would be better) */
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int m, m_min, m_max;
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGHelperInfo *th;
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_ulong v;
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (unlikely(!s->helpers_sorted)) {
833b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              helper_cmp);
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->helpers_sorted = 1;
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* binary search */
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    m_min = 0;
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    m_max = s->nb_helpers - 1;
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (m_min <= m_max) {
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        m = (m_min + m_max) >> 1;
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        th = &s->helpers[m];
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        v = th->func;
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (v == val)
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return th;
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if (val < v) {
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            m_max = m - 1;
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            m_min = m + 1;
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char * const cond_name[] =
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_EQ] = "eq",
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_NE] = "ne",
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_LT] = "lt",
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_GE] = "ge",
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_LE] = "le",
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_GT] = "gt",
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_LTU] = "ltu",
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_GEU] = "geu",
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_LEU] = "leu",
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_GTU] = "gtu"
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_dump_ops(TCGContext *s, FILE *outfile)
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const uint16_t *opc_ptr;
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArg *args;
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg arg;
875f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCGOpcode c;
876f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGOpDef *def;
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char buf[128];
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    first_insn = 1;
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    opc_ptr = gen_opc_buf;
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args = gen_opparam_buf;
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (opc_ptr < gen_opc_ptr) {
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = *opc_ptr++;
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[c];
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (c == INDEX_op_debug_insn_start) {
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint64_t pc;
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = ((uint64_t)args[1] << 32) | args[0];
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = args[0];
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
893b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            if (!first_insn)
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "\n");
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, " ---- 0x%" PRIx64, pc);
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            first_insn = 0;
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_oargs = def->nb_oargs;
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_iargs = def->nb_iargs;
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_cargs = def->nb_cargs;
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (c == INDEX_op_call) {
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            TCGArg arg;
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* variable number of arguments */
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            arg = *args++;
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_oargs = arg >> 16;
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_iargs = arg & 0xffff;
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_cargs = def->nb_cargs;
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, " %s ", def->name);
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* function name */
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, "%s",
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* flags */
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, ",$0x%" TCG_PRIlx,
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    args[nb_oargs + nb_iargs]);
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* nb out args */
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, ",$%d", nb_oargs);
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < nb_oargs; i++) {
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, ",");
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "%s",
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i]));
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < (nb_iargs - 1); i++) {
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, ",");
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, "<dummy>");
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } else {
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, "%s",
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
933b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        } else if (c == INDEX_op_movi_i32
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 64
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   || c == INDEX_op_movi_i64
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   ) {
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_target_ulong val;
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            TCGHelperInfo *th;
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_oargs = def->nb_oargs;
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_iargs = def->nb_iargs;
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_cargs = def->nb_cargs;
944b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            fprintf(outfile, " %s %s,$", def->name,
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            val = args[1];
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            th = tcg_find_helper(s, val);
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (th) {
9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(outfile, "%s", th->name);
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (c == INDEX_op_movi_i32)
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, "0x%x", (uint32_t)val);
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, " %s ", def->name);
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (c == INDEX_op_nopn) {
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* variable number of arguments */
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_cargs = *args;
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_oargs = 0;
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_iargs = 0;
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_oargs = def->nb_oargs;
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_iargs = def->nb_iargs;
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_cargs = def->nb_cargs;
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
968b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            k = 0;
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < nb_oargs; i++) {
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (k != 0)
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",");
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "%s",
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < nb_iargs; i++) {
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (k != 0)
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",");
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "%s",
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
982b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            switch (c) {
983b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_brcond_i32:
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
985b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_brcond2_i32:
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif TCG_TARGET_REG_BITS == 64
987b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_brcond_i64:
988b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif
989b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_setcond_i32:
990b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if TCG_TARGET_REG_BITS == 32
991b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_setcond2_i32:
992b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#elif TCG_TARGET_REG_BITS == 64
993b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_setcond_i64:
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",%s", cond_name[args[k++]]);
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                i = 1;
1000b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner                break;
1001b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            default:
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                i = 0;
1003b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner                break;
1004b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            }
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(; i < nb_cargs; i++) {
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (k != 0)
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",");
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                arg = args[k++];
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "$0x%" TCG_PRIlx, arg);
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(outfile, "\n");
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args += nb_iargs + nb_oargs + nb_cargs;
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* we give more priority to constraints with less registers */
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_constraint_priority(const TCGOpDef *def, int k)
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArgConstraint *arg_ct;
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, n;
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    arg_ct = &def->args_ct[k];
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (arg_ct->ct & TCG_CT_ALIAS) {
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* an alias is equivalent to a single register */
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = 1;
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!(arg_ct->ct & TCG_CT_REG))
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = 0;
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (tcg_regset_test_reg(arg_ct->u.regs, i))
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                n++;
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return TCG_TARGET_NB_REGS - n + 1;
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sort from highest priority to lowest */
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void sort_constraints(TCGOpDef *def, int start, int n)
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, j, p1, p2, tmp;
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < n; i++)
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def->sorted_args[start + i] = start + i;
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (n <= 1)
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < n - 1; i++) {
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(j = i + 1; j < n; j++) {
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p1 = get_constraint_priority(def, def->sorted_args[start + i]);
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p2 = get_constraint_priority(def, def->sorted_args[start + j]);
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (p1 < p2) {
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tmp = def->sorted_args[start + i];
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->sorted_args[start + i] = def->sorted_args[start + j];
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->sorted_args[start + j] = tmp;
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1063f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCGOpcode op;
10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGOpDef *def;
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *ct_str;
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, nb_args;
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
1069f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        if (tdefs->op == (TCGOpcode)-1)
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op = tdefs->op;
1072f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        assert((unsigned)op < NB_OPS);
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[op];
1074b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG)
1075b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        /* Duplicate entry in op definitions? */
1076b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        assert(!def->used);
1077b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        def->used = 1;
1078b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        nb_args = def->nb_iargs + def->nb_oargs;
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < nb_args; i++) {
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ct_str = tdefs->args_ct_str[i];
1082b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            /* Incomplete TCGTargetOpDef entry? */
1083b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            assert(ct_str != NULL);
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_regset_clear(def->args_ct[i].u.regs);
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            def->args_ct[i].ct = 0;
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ct_str[0] >= '0' && ct_str[0] <= '9') {
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int oarg;
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                oarg = ct_str[0] - '0';
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                assert(oarg < def->nb_oargs);
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                assert(def->args_ct[oarg].ct & TCG_CT_REG);
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* TCG_CT_ALIAS is for the output arguments. The input
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   argument is tagged with TCG_CT_IALIAS. */
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[i] = def->args_ct[oarg];
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[oarg].ct = TCG_CT_ALIAS;
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[oarg].alias_index = i;
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[i].ct |= TCG_CT_IALIAS;
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[i].alias_index = oarg;
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for(;;) {
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (*ct_str == '\0')
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    switch(*ct_str) {
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 'i':
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        def->args_ct[i].ct |= TCG_CT_CONST;
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        ct_str++;
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    default:
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    ct_str, i, def->name);
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            exit(1);
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1118b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        /* TCGTargetOpDef entry with too much information? */
1119b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1120b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* sort the constraints (XXX: this is just an heuristic) */
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sort_constraints(def, 0, def->nb_oargs);
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sort_constraints(def, def->nb_oargs, def->nb_iargs);
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int i;
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("%s: sorted=", def->name);
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                printf(" %d", def->sorted_args[i]);
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("\n");
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tdefs++;
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1138b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG)
1139f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    i = 0;
1140b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1141b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        if (op < INDEX_op_call || op == INDEX_op_debug_insn_start) {
1142b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            /* Wrong entry in op definitions? */
1143f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            if (tcg_op_defs[op].used) {
1144f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                fprintf(stderr, "Invalid op definition for %s\n",
1145f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                        tcg_op_defs[op].name);
1146f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                i = 1;
1147f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            }
1148b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        } else {
1149b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            /* Missing entry in op definitions? */
1150f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            if (!tcg_op_defs[op].used) {
1151f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                fprintf(stderr, "Missing op definition for %s\n",
1152f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                        tcg_op_defs[op].name);
1153f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                i = 1;
1154f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        }
1155b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        }
1156b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    }
1157f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    if (i == 1) {
1158f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner        tcg_abort();
1159f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    }
1160b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef USE_LIVENESS_ANALYSIS
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* set a nop for an operation using 'nb_args' */
1166b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turnerstatic inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               TCGArg *args, int nb_args)
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (nb_args == 0) {
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *opc_ptr = INDEX_op_nop;
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *opc_ptr = INDEX_op_nopn;
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[0] = nb_args;
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[nb_args - 1] = nb_args;
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* liveness analysis: end of function: globals are live, temps are
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   dead. */
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: at this stage, not used as there would be little gains because
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   most TBs end with a conditional jump. */
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(dead_temps, 0, s->nb_globals);
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* liveness analysis: end of basic block: globals are live, temps are
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   dead, local temps are live. */
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(dead_temps, 0, s->nb_globals);
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[s->nb_globals];
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = s->nb_globals; i < s->nb_temps; i++) {
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->temp_local)
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_temps[i] = 0;
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_temps[i] = 1;
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts++;
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Liveness analysis : update the opc_dead_iargs array to tell if a
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   given input arguments is dead. Instructions updating dead
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   temporaries are removed. */
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_liveness_analysis(TCGContext *s)
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1211f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
1212f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCGOpcode op;
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg *args;
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGOpDef *def;
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *dead_temps;
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int dead_iargs;
1217ddf49e53df97a349f42c733059165dc73c9907dcDavid 'Digit' Turner
1218bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    /* sanity check */
1219bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    if (gen_opc_ptr - gen_opc_buf > OPC_BUF_SIZE) {
1220bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner        fprintf(stderr, "PANIC: too many opcodes generated (%d > %d)\n",
1221d9b6cb97a8a9e93f1bbe5351874b03f7faa81783David 'Digit' Turner                (int)(gen_opc_ptr - gen_opc_buf), OPC_BUF_SIZE);
1222bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner        tcg_abort();
1223ddf49e53df97a349f42c733059165dc73c9907dcDavid 'Digit' Turner    }
1224ddf49e53df97a349f42c733059165dc73c9907dcDavid 'Digit' Turner
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gen_opc_ptr++; /* skip end */
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_ops = gen_opc_ptr - gen_opc_buf;
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1229b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
1230b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dead_temps = tcg_malloc(s->nb_temps);
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(dead_temps, 1, s->nb_temps);
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args = gen_opparam_ptr;
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    op_index = nb_ops - 1;
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (op_index >= 0) {
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op = gen_opc_buf[op_index];
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[op];
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(op) {
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_call:
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int call_flags;
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_args = args[-1];
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                args -= nb_args;
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_iargs = args[0] & 0xffff;
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_oargs = args[0] >> 16;
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                args++;
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                call_flags = args[nb_oargs + nb_iargs];
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* pure functions can be removed if their result is not
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   used */
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (call_flags & TCG_CALL_PURE) {
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for(i = 0; i < nb_oargs; i++) {
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        arg = args[i];
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (!dead_temps[arg])
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            goto do_not_remove_call;
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
1259b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner                    tcg_set_nop(s, gen_opc_buf + op_index,
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                args - 1, nb_args);
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } else {
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                do_not_remove_call:
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* output args are dead */
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for(i = 0; i < nb_oargs; i++) {
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        arg = args[i];
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dead_temps[arg] = 1;
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
1269b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
12705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!(call_flags & TCG_CALL_CONST)) {
12715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        /* globals are live (they may be used by the call) */
12725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        memset(dead_temps, 0, s->nb_globals);
12735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
12745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* input args are live */
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dead_iargs = 0;
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for(i = 0; i < nb_iargs; i++) {
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        arg = args[i + nb_oargs];
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (arg != TCG_CALL_DUMMY_ARG) {
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (dead_temps[arg]) {
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                dead_iargs |= (1 << i);
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            }
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            dead_temps[arg] = 0;
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->op_dead_iargs[op_index] = dead_iargs;
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                args--;
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_set_label:
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args--;
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* mark end of basic block */
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_la_bb_end(s, dead_temps);
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_debug_insn_start:
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args -= def->nb_args;
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nopn:
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_args = args[-1];
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args -= nb_args;
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_discard:
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args--;
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* mark the temporary as dead */
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_temps[args[0]] = 1;
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_end:
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
13125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            args -= def->nb_args;
13135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_iargs = def->nb_iargs;
13145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_oargs = def->nb_oargs;
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Test if the operation can be removed because all
13175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               its outputs are dead. We assume that nb_oargs == 0
13185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               implies side effects */
13195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
13205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                for(i = 0; i < nb_oargs; i++) {
13215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    arg = args[i];
13225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!dead_temps[arg])
13235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto do_not_remove;
13245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
13255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
13275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                s->del_op_count++;
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
13305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            do_not_remove:
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* output args are dead */
13335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                for(i = 0; i < nb_oargs; i++) {
13345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    arg = args[i];
13355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    dead_temps[arg] = 1;
13365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
13375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* if end of basic block, update */
13395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (def->flags & TCG_OPF_BB_END) {
13405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tcg_la_bb_end(s, dead_temps);
13415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
13425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    /* globals are live */
13435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    memset(dead_temps, 0, s->nb_globals);
13445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
13455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* input args are live */
13475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                dead_iargs = 0;
13485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                for(i = 0; i < nb_iargs; i++) {
13495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    arg = args[i + nb_oargs];
13505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (dead_temps[arg]) {
13515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        dead_iargs |= (1 << i);
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
13535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    dead_temps[arg] = 0;
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
13555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                s->op_dead_iargs[op_index] = dead_iargs;
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op_index--;
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args != gen_opparam_buf)
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* dummy liveness analysis */
1367f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void tcg_liveness_analysis(TCGContext *s)
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int nb_ops;
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_ops = gen_opc_ptr - gen_opc_buf;
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(s->op_dead_iargs, 0, nb_ops * sizeof(uint16_t));
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef NDEBUG
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void dump_regs(TCGContext *s)
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char buf[64];
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < s->nb_temps; i++) {
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[i];
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(ts->val_type) {
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_REG:
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("%s", tcg_target_reg_names[ts->reg]);
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_MEM:
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_CONST:
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("$0x%" TCG_PRIlx, ts->val);
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_DEAD:
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("D");
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("???");
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("\n");
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->reg_to_temp[i] >= 0) {
14095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("%s: %s\n",
14105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   tcg_target_reg_names[i],
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void check_regs(TCGContext *s)
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int reg, k;
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char buf[64];
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        k = s->reg_to_temp[reg];
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (k >= 0) {
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[k];
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type != TEMP_VAL_REG ||
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->reg != reg) {
14285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                printf("Inconsistency for register %s:\n",
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       tcg_target_reg_names[reg]);
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto fail;
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(k = 0; k < s->nb_temps; k++) {
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[k];
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->val_type == TEMP_VAL_REG &&
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            !ts->fixed_reg &&
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[ts->reg] != k) {
14395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                printf("Inconsistency for temp %s:\n",
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fail:
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                printf("reg state:\n");
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dump_regs(s);
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_abort();
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void temp_allocate_frame(TCGContext *s, int temp)
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[temp];
14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->mem_offset = s->current_frame_offset;
14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->mem_reg = s->frame_reg;
14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->mem_allocated = 1;
14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->current_frame_offset += sizeof(tcg_target_long);
14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* free register 'reg' by spilling the corresponding temporary if necessary */
14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_free(TCGContext *s, int reg)
14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int temp;
14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    temp = s->reg_to_temp[reg];
14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (temp != -1) {
14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[temp];
14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(ts->val_type == TEMP_VAL_REG);
14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!ts->mem_coherent) {
14745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            if (!ts->mem_allocated)
14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                temp_allocate_frame(s, temp);
14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->val_type = TEMP_VAL_MEM;
14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->reg_to_temp[reg] = -1;
14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Allocate a register belonging to reg1 & ~reg2 */
14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, reg;
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGRegSet reg_ct;
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_regset_andnot(reg_ct, reg1, reg2);
14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* first try free registers */
14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = tcg_target_reg_alloc_order[i];
14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return reg;
14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: do better spill choice */
14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = tcg_target_reg_alloc_order[i];
15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_regset_test_reg(reg_ct, reg)) {
15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_free(s, reg);
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return reg;
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_abort();
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* save a temporary to memory. 'allocated_regs' is used in case a
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   temporary registers needs to be allocated to store a constant. */
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int reg;
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[temp];
15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!ts->fixed_reg) {
15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(ts->val_type) {
15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_REG:
15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_free(s, ts->reg);
15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_DEAD:
15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_MEM;
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_CONST:
15275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                allocated_regs);
15295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            if (!ts->mem_allocated)
15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                temp_allocate_frame(s, temp);
15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_movi(s, ts->type, reg, ts->val);
15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_MEM;
15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_MEM:
15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_abort();
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* save globals to their cannonical location and assume they can be
15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   modified be the following code. 'allocated_regs' is used in case a
15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   temporary registers needs to be allocated to store a constant. */
15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void save_globals(TCGContext *s, TCGRegSet allocated_regs)
15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < s->nb_globals; i++) {
15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        temp_save(s, i, allocated_regs);
15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* at the end of a basic block, we assume all temporaries are dead and
15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   all globals are stored at their canonical location. */
15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = s->nb_globals; i < s->nb_temps; i++) {
15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[i];
15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->temp_local) {
15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            temp_save(s, i, allocated_regs);
15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type == TEMP_VAL_REG) {
15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[ts->reg] = -1;
15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_DEAD;
15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    save_globals(s, allocated_regs);
15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1)
15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ots;
15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_ulong val;
15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots = &s->temps[args[0]];
15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    val = args[1];
15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ots->fixed_reg) {
15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* for fixed registers, we do not do any constant
15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           propagation */
15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_movi(s, ots->type, ots->reg, val);
15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* The movi is not explicitly generated here */
15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ots->val_type == TEMP_VAL_REG)
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[ots->reg] = -1;
15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ots->val_type = TEMP_VAL_CONST;
15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ots->val = val;
15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              const TCGArg *args,
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              unsigned int dead_iargs)
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts, *ots;
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int reg;
16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArgConstraint *arg_ct;
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots = &s->temps[args[0]];
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[args[1]];
16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    arg_ct = &def->args_ct[0];
16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: always mark arg dead if IS_DEAD_IARG(0) */
16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ts->val_type == TEMP_VAL_REG) {
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) {
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* the mov can be suppressed */
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ots->val_type == TEMP_VAL_REG)
16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[ots->reg] = -1;
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = ts->reg;
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[reg] = -1;
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_DEAD;
16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ots->val_type == TEMP_VAL_REG) {
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = ots->reg;
16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->reg != reg) {
1628f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                tcg_out_mov(s, ots->type, reg, ts->reg);
16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (ts->val_type == TEMP_VAL_MEM) {
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ots->val_type == TEMP_VAL_REG) {
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = ots->reg;
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (ts->val_type == TEMP_VAL_CONST) {
16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ots->fixed_reg) {
16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = ots->reg;
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_movi(s, ots->type, reg, ts->val);
16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* propagate constant */
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ots->val_type == TEMP_VAL_REG)
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[ots->reg] = -1;
16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ots->val_type = TEMP_VAL_CONST;
16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ots->val = ts->val;
16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->reg_to_temp[reg] = args[0];
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots->reg = reg;
16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots->val_type = TEMP_VAL_REG;
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots->mem_coherent = 0;
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic void tcg_reg_alloc_op(TCGContext *s,
1660f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                             const TCGOpDef *def, TCGOpcode opc,
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             const TCGArg *args,
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             unsigned int dead_iargs)
16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGRegSet allocated_regs;
16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, k, nb_iargs, nb_oargs, reg;
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg arg;
16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArgConstraint *arg_ct;
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg new_args[TCG_MAX_OP_ARGS];
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int const_args[TCG_MAX_OP_ARGS];
16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_oargs = def->nb_oargs;
16738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_iargs = def->nb_iargs;
16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* copy constants */
16765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcpy(new_args + nb_oargs + nb_iargs,
16775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           args + nb_oargs + nb_iargs,
16788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           sizeof(TCGArg) * def->nb_cargs);
16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* satisfy input constraints */
16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_regset_set(allocated_regs, s->reserved_regs);
16828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(k = 0; k < nb_iargs; k++) {
16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        i = def->sorted_args[nb_oargs + k];
16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[i];
16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg_ct = &def->args_ct[i];
16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[arg];
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->val_type == TEMP_VAL_MEM) {
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_REG;
16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->reg = reg;
16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->mem_coherent = 1;
16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[reg] = arg;
16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (ts->val_type == TEMP_VAL_CONST) {
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (tcg_target_const_match(ts->val, arg_ct)) {
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* constant is OK for instruction */
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                const_args[i] = 1;
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                new_args[i] = ts->val;
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto iarg_end;
17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* need to move to a register */
17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_movi(s, ts->type, reg, ts->val);
17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->val_type = TEMP_VAL_REG;
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->reg = reg;
17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->mem_coherent = 0;
17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[reg] = arg;
17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(ts->val_type == TEMP_VAL_REG);
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arg_ct->ct & TCG_CT_IALIAS) {
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->fixed_reg) {
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* if fixed register, we must allocate a new register
17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   if the alias is not the same register */
17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (arg != args[arg_ct->alias_index])
17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto allocate_in_reg;
17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* if the input is aliased to an output and if it is
17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   not dead after the instruction, we must allocate
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   a new register and move it */
17215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                if (!IS_DEAD_IARG(i - nb_oargs))
17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto allocate_in_reg;
17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = ts->reg;
17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* nothing to do : the constraint is satisfied */
17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        allocate_in_reg:
17305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            /* allocate a new register matching the constraint
17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               and move the temporary register into it */
17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1733f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            tcg_out_mov(s, ts->type, reg, ts->reg);
17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        new_args[i] = reg;
17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const_args[i] = 0;
17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_regset_set_reg(allocated_regs, reg);
17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    iarg_end: ;
17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (def->flags & TCG_OPF_BB_END) {
17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_reg_alloc_bb_end(s, allocated_regs);
17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* mark dead temporaries and free the associated registers */
17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < nb_iargs; i++) {
17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            arg = args[nb_oargs + i];
17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (IS_DEAD_IARG(i)) {
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts = &s->temps[arg];
17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (!ts->fixed_reg) {
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (ts->val_type == TEMP_VAL_REG)
17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        s->reg_to_temp[ts->reg] = -1;
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    ts->val_type = TEMP_VAL_DEAD;
17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (def->flags & TCG_OPF_CALL_CLOBBER) {
17585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            /* XXX: permit generic clobber register list ? */
17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tcg_reg_free(s, reg);
17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* XXX: for load/store we could do that only for the slow path
17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               (i.e. when a memory callback is called) */
17665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* store globals and free associated registers (we assume the insn
17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               can modify any global. */
17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            save_globals(s, allocated_regs);
17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* satisfy the output constraints */
17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_regset_set(allocated_regs, s->reserved_regs);
17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(k = 0; k < nb_oargs; k++) {
17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            i = def->sorted_args[k];
17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            arg = args[i];
17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            arg_ct = &def->args_ct[i];
17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[arg];
17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arg_ct->ct & TCG_CT_ALIAS) {
17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = new_args[arg_ct->alias_index];
17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
17828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* if fixed register, we try to use it */
17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = ts->reg;
17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ts->fixed_reg &&
17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tcg_regset_test_reg(arg_ct->u.regs, reg)) {
17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto oarg_end;
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
17908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_regset_set_reg(allocated_regs, reg);
17918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* if a fixed register is used, then a move will be done afterwards */
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!ts->fixed_reg) {
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ts->val_type == TEMP_VAL_REG)
17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->reg_to_temp[ts->reg] = -1;
17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->val_type = TEMP_VAL_REG;
17968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->reg = reg;
17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* temp value is modified, so the value kept in memory is
17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   potentially not the same */
17995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                ts->mem_coherent = 0;
18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[reg] = arg;
18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        oarg_end:
18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            new_args[i] = reg;
18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* emit instruction */
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_out_op(s, opc, new_args, const_args);
18095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* move the outputs in the correct register if needed */
18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < nb_oargs; i++) {
18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[args[i]];
18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = new_args[i];
18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->fixed_reg && ts->reg != reg) {
1815f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            tcg_out_mov(s, ts->type, ts->reg, reg);
18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_STACK_GROWSUP
18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define STACK_DIR(x) (-(x))
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define STACK_DIR(x) (x)
18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1827f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                              TCGOpcode opc, const TCGArg *args,
18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              unsigned int dead_iargs)
18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg arg, func_arg;
18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_long stack_offset, call_stack_size, func_addr;
18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int const_func_arg, allocate_args;
18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGRegSet allocated_regs;
18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArgConstraint *arg_ct;
18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    arg = *args++;
18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_oargs = arg >> 16;
18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_iargs = arg & 0xffff;
18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_params = nb_iargs - 1;
18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = args[nb_oargs + nb_iargs];
18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_regs = tcg_target_get_call_iarg_regs_count(flags);
18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (nb_regs > nb_params)
18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        nb_regs = nb_params;
18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* assign stack slots first */
18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: preallocate call stack */
18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
18535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
18548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ~(TCG_TARGET_STACK_ALIGN - 1);
18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (allocate_args) {
18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
18618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = nb_regs; i < nb_params; i++) {
18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[nb_oargs + i];
18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_STACK_GROWSUP
18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stack_offset -= sizeof(tcg_target_long);
18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arg != TCG_CALL_DUMMY_ARG) {
18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[arg];
18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type == TEMP_VAL_REG) {
18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (ts->val_type == TEMP_VAL_MEM) {
18715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    s->reserved_regs);
18738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* XXX: not correct if reading values from the stack */
18748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
18758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
18768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (ts->val_type == TEMP_VAL_CONST) {
18775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
18788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    s->reserved_regs);
18798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* XXX: sign extend may be needed on some targets */
18808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_movi(s, ts->type, reg, ts->val);
18818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
18828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
18838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_abort();
18848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
18858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef TCG_TARGET_STACK_GROWSUP
18878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stack_offset += sizeof(tcg_target_long);
18888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
18918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* assign input registers */
18928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_regset_set(allocated_regs, s->reserved_regs);
18938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < nb_regs; i++) {
18948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[nb_oargs + i];
18958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arg != TCG_CALL_DUMMY_ARG) {
18968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[arg];
18978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_target_call_iarg_regs[i];
18988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_free(s, reg);
18998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type == TEMP_VAL_REG) {
19008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ts->reg != reg) {
1901f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                    tcg_out_mov(s, ts->type, reg, ts->reg);
19028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
19038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (ts->val_type == TEMP_VAL_MEM) {
19048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
19058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (ts->val_type == TEMP_VAL_CONST) {
19068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* XXX: sign extend ? */
19078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_movi(s, ts->type, reg, ts->val);
19088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
19098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_abort();
19108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
19118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_regset_set_reg(allocated_regs, reg);
19128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
19158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* assign function address */
19168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    func_arg = args[nb_oargs + nb_iargs - 1];
19178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    arg_ct = &def->args_ct[0];
19188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[func_arg];
19198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    func_addr = ts->val;
19208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const_func_arg = 0;
19218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ts->val_type == TEMP_VAL_MEM) {
19228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
19238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
19248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        func_arg = reg;
19258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_regset_set_reg(allocated_regs, reg);
19268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (ts->val_type == TEMP_VAL_REG) {
19278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = ts->reg;
19288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
19298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1930f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner            tcg_out_mov(s, ts->type, reg, ts->reg);
19318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        func_arg = reg;
19338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_regset_set_reg(allocated_regs, reg);
19348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (ts->val_type == TEMP_VAL_CONST) {
19358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_target_const_match(func_addr, arg_ct)) {
19368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            const_func_arg = 1;
19378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            func_arg = func_addr;
19388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
19408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_movi(s, ts->type, reg, func_addr);
19418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            func_arg = reg;
19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_regset_set_reg(allocated_regs, reg);
19438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
19485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
19498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* mark dead temporaries and free the associated registers */
19508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < nb_iargs; i++) {
19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[nb_oargs + i];
19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (IS_DEAD_IARG(i)) {
19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[arg];
19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!ts->fixed_reg) {
19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ts->val_type == TEMP_VAL_REG)
19568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->reg_to_temp[ts->reg] = -1;
19578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->val_type = TEMP_VAL_DEAD;
19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
19598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* clobber call registers */
19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
19648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
19658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_free(s, reg);
19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
19698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* store globals and free associated registers (we assume the call
19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       can modify any global. */
19715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!(flags & TCG_CALL_CONST)) {
19725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        save_globals(s, allocated_regs);
19735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
19748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_out_op(s, opc, &func_arg, &const_func_arg);
19765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
19778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (allocate_args) {
19788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size));
19798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* assign output registers and emit moves if needed */
19828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < nb_oargs; i++) {
19838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[i];
19848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[arg];
19858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = tcg_target_call_oarg_regs[i];
19868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(s->reg_to_temp[reg] == -1);
19878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->fixed_reg) {
19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->reg != reg) {
1989f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner                tcg_out_mov(s, ts->type, ts->reg, reg);
19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type == TEMP_VAL_REG)
19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[ts->reg] = -1;
19948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_REG;
19958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->reg = reg;
19965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            ts->mem_coherent = 0;
19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[reg] = arg;
19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return nb_iargs + nb_oargs + def->nb_cargs + 1;
20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t tcg_table_op_count[NB_OPS];
20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2008f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void dump_op_count(void)
20098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *f;
20125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    f = fopen("/tmp/op.log", "w");
20138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = INDEX_op_end; i < NB_OPS; i++) {
20145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
20158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fclose(f);
20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      long search_pc)
20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2024f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    TCGOpcode opc;
2025f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner    int op_index;
20268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGOpDef *def;
20278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int dead_iargs;
20288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArg *args;
20295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
20305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    unsigned int tpc2gpc_index = 0;
20315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
20328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20330b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh#if !SUPPORT_GLOBAL_REGISTER_VARIABLE
20340b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh    printf("ERROR: This emulator is built by compiler without global register variable\n"
20350b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh           "support!  Emulator reserves a register to point to target architecture state\n"
20360b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh           "for better code generation.  LLVM-based compilers such as clang and llvm-gcc\n"
20370b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh           "currently don't support global register variable.  Please see\n"
20380b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh           "http://source.android.com/source/initializing.html for detail.\n\n");
20390b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh    tcg_abort();
20400b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh#endif
20410b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh
20428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_DISAS
20435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
20445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_log("OP:\n");
20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_dump_ops(s, logfile);
20465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_log("\n");
20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->la_time -= profile_getclock();
20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_liveness_analysis(s);
20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->la_time += profile_getclock();
20568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_DISAS
20595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
2060b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        qemu_log("OP after liveness analysis:\n");
20618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_dump_ops(s, logfile);
20625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_log("\n");
20638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_reg_alloc_start(s);
20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_buf = gen_code_buf;
20698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_ptr = gen_code_buf;
20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args = gen_opparam_buf;
20728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    op_index = 0;
20738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
20755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    gen_opc_tpc2gpc_pairs = 0;
20765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
20775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
20788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
20795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
20805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* On condition that memcheck is enabled, and operation index reached
20815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * new operation in the guest code, save (pc_tb, pc_guest) pair into
20825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * gen_opc_tpc2gpc array. Note that we do that only on condition that
20835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * search_pc is < 0. This way we make sure that this is "normal"
20845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * translation, called from tcg_gen_code, and not from
20855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * tcg_gen_code_search_pc. */
20865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (memcheck_enabled && search_pc < 0 &&
20875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            gen_opc_instr_start[op_index]) {
2088d9b6cb97a8a9e93f1bbe5351874b03f7faa81783David 'Digit' Turner            gen_opc_tpc2gpc_ptr[tpc2gpc_index] = s->code_ptr;
20895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            tpc2gpc_index++;
2090d9b6cb97a8a9e93f1bbe5351874b03f7faa81783David 'Digit' Turner            gen_opc_tpc2gpc_ptr[tpc2gpc_index] = (void*)(ptrdiff_t)gen_opc_pc[op_index];
20915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            tpc2gpc_index++;
20925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            gen_opc_tpc2gpc_pairs++;
20935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
20945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opc = gen_opc_buf[op_index];
20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
20975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_table_op_count[opc]++;
20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[opc];
21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("%s: %d %d %d\n", def->name,
21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               def->nb_oargs, def->nb_iargs, def->nb_cargs);
21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        //        dump_regs(s);
21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(opc) {
21068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_mov_i32:
21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 64
21088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_mov_i64:
21098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_iargs = s->op_dead_iargs[op_index];
21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_alloc_mov(s, def, args, dead_iargs);
21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_movi_i32:
21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 64
21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_movi_i64:
21168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_alloc_movi(s, args);
21188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_debug_insn_start:
21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* debug instruction */
21218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nop:
21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nop1:
21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nop2:
21258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nop3:
21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nopn:
21288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args += args[0];
21298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto next;
21308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_discard:
21318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
21328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                TCGTemp *ts;
21338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts = &s->temps[args[0]];
21348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* mark the temporary as dead */
21358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (!ts->fixed_reg) {
21368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (ts->val_type == TEMP_VAL_REG)
21378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        s->reg_to_temp[ts->reg] = -1;
21388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    ts->val_type = TEMP_VAL_DEAD;
21398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
21408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
21418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_set_label:
21438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_alloc_bb_end(s, s->reserved_regs);
21448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_label(s, args[0], (long)s->code_ptr);
21458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_call:
21478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_iargs = s->op_dead_iargs[op_index];
21488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs);
21498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto next;
21508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_end:
21518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto the_end;
21528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
21538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Note: in order to speed up the code, it would be much
21548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               faster to have specialized register allocator functions for
21558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               some common argument patterns */
21568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_iargs = s->op_dead_iargs[op_index];
21578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_alloc_op(s, def, opc, args, dead_iargs);
21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args += def->nb_args;
21618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next:
21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
21638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return op_index;
21648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op_index++;
21668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef NDEBUG
21678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        check_regs(s);
21688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project the_end:
21718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
21728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
21758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
21778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int n;
21798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = (gen_opc_ptr - gen_opc_buf);
21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->op_count += n;
21818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (n > s->op_count_max)
21828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->op_count_max = n;
21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->temp_count += s->nb_temps;
21858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->nb_temps > s->temp_count_max)
21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->temp_count_max = s->nb_temps;
21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2190bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    /* sanity check */
2191bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    if (gen_opc_ptr - gen_opc_buf > OPC_BUF_SIZE) {
2192bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner        fprintf(stderr, "PANIC: too many opcodes generated (%d > %d)\n",
2193d9b6cb97a8a9e93f1bbe5351874b03f7faa81783David 'Digit' Turner                (int)(gen_opc_ptr - gen_opc_buf), OPC_BUF_SIZE);
2194bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner        tcg_abort();
2195bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    }
2196bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner
21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_gen_code_common(s, gen_code_buf, -1);
21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* flush instruction cache */
22005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    flush_icache_range((unsigned long)gen_code_buf,
22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       (unsigned long)s->code_ptr);
22028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s->code_ptr -  gen_code_buf;
22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Return the index of the micro operation such as the pc after is <
22068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   offset bytes from the start of the TB.  The contents of gen_code_buf must
22078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   not be changed, though writing the same values is ok.
22088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Return -1 if not found. */
22095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
22108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return tcg_gen_code_common(s, gen_code_buf, offset);
22128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
2215f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
22168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
22188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t tot;
22198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tot = s->interm_time + s->code_time;
22218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
22228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tot, tot / 2.4e9);
22235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
22245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                s->tb_count,
22258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->tb_count1 - s->tb_count,
22268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
22275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n",
22288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
22298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
22305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                s->tb_count ?
22318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->del_op_count / s->tb_count : 0);
22328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
22335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                s->tb_count ?
22348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->temp_count / s->tb_count : 0,
22358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->temp_count_max);
22365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
22375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "cycles/op           %0.1f\n",
22388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->op_count ? (double)tot / s->op_count : 0);
22395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "cycles/in byte      %0.1f\n",
22408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->code_in_len ? (double)tot / s->code_in_len : 0);
22415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "cycles/out byte     %0.1f\n",
22428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->code_out_len ? (double)tot / s->code_out_len : 0);
22438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tot == 0)
22448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tot = 1;
22455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "  gen_interm time   %0.1f%%\n",
22468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->interm_time / tot * 100.0);
22475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "  gen_code time     %0.1f%%\n",
22488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->code_time / tot * 100.0);
22495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "liveness/code time  %0.1f%%\n",
22508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
22518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
22528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->restore_count);
22538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "  avg cycles        %0.1f\n",
22548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2255b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
2256b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    dump_op_count();
22578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2259f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
22608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "[TCG profiler not compiled]\n");
22628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2264