tcg.c revision 6a9ef1773bf874dea493ff3861782a1e577b67dd
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
66b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turnerstatic void patch_reloc(uint8_t *code_ptr, int type,
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tcg_target_long value, tcg_target_long addend);
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic TCGOpDef tcg_op_defs[] = {
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size },
71b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#define DEF2(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags, 0 },
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg-opc.h"
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DEF
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DEF2
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
113b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turnervoid 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);
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* init global prologue and epilogue */
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_buf = code_gen_prologue;
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_ptr = s->code_buf;
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_qemu_prologue(s);
258b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    flush_icache_range((unsigned long)s->code_buf,
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       (unsigned long)s->code_ptr);
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_set_frame(TCGContext *s, int reg,
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   tcg_target_long start, tcg_target_long size)
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->frame_start = start;
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->frame_end = start + size;
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->frame_reg = reg;
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_func_start(TCGContext *s)
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_pool_reset(s);
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->nb_temps = s->nb_globals;
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->first_free_temp[i] = -1;
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->nb_labels = 0;
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->current_frame_offset = s->frame_start;
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gen_opc_ptr = gen_opc_buf;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gen_opparam_ptr = gen_opparam_buf;
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_temp_alloc(TCGContext *s, int n)
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (n > TCG_MAX_TEMPS)
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int tcg_global_reg_new_internal(TCGType type, int reg,
2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                              const char *name)
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int idx;
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type != TCG_TYPE_I32)
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tcg_regset_test_reg(s->reserved_regs, reg))
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    idx = s->nb_globals;
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_temp_alloc(s, s->nb_globals + 1);
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[s->nb_globals];
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->base_type = type;
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->type = type;
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->fixed_reg = 1;
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->reg = reg;
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->name = name;
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->nb_globals++;
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_regset_set_reg(s->reserved_regs, reg);
3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return idx;
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_global_reg_new_i32(int reg, const char *name)
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int idx;
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name);
3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I32(idx);
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);
3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I64(idx);
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int tcg_global_mem_new_internal(TCGType type, int reg,
3345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                              tcg_target_long offset,
3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                              const char *name)
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int idx;
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    idx = s->nb_globals;
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type == TCG_TYPE_I64) {
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char buf[64];
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_temp_alloc(s, s->nb_globals + 2);
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[s->nb_globals];
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->base_type = type;
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->type = TCG_TYPE_I32;
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->fixed_reg = 0;
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_allocated = 1;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_reg = reg;
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset + 4;
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset;
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcpy(buf, sizeof(buf), name);
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcat(buf, sizeof(buf), "_0");
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->name = strdup(buf);
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts++;
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->base_type = type;
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->type = TCG_TYPE_I32;
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->fixed_reg = 0;
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_allocated = 1;
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_reg = reg;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset;
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset + 4;
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcpy(buf, sizeof(buf), name);
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcat(buf, sizeof(buf), "_1");
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->name = strdup(buf);
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->nb_globals += 2;
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_temp_alloc(s, s->nb_globals + 1);
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[s->nb_globals];
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->base_type = type;
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->type = type;
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->fixed_reg = 0;
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_allocated = 1;
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_reg = reg;
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_offset = offset;
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->name = name;
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->nb_globals++;
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return idx;
3925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                const char *name)
3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I32(idx);
4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                const char *name)
4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I64(idx);
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int tcg_temp_new_internal(TCGType type, int temp_local)
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int idx, k;
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    k = type;
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (temp_local)
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        k += TCG_TYPE_COUNT;
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    idx = s->first_free_temp[k];
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (idx != -1) {
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* There is already an available temp with the
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           right type */
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[idx];
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->first_free_temp[k] = ts->next_free_temp;
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->temp_allocated = 1;
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(ts->temp_local == temp_local);
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        idx = s->nb_temps;
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (type == TCG_TYPE_I64) {
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_temp_alloc(s, s->nb_temps + 2);
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[s->nb_temps];
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->base_type = type;
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->type = TCG_TYPE_I32;
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_allocated = 1;
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_local = temp_local;
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->name = NULL;
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts++;
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->base_type = TCG_TYPE_I32;
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->type = TCG_TYPE_I32;
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_allocated = 1;
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_local = temp_local;
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->name = NULL;
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->nb_temps += 2;
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_temp_alloc(s, s->nb_temps + 1);
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[s->nb_temps];
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->base_type = type;
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->type = type;
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_allocated = 1;
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->temp_local = temp_local;
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->name = NULL;
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->nb_temps++;
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return idx;
4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_temp_new_internal_i32(int temp_local)
4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local);
4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I32(idx);
4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_temp_new_internal_i64(int temp_local)
4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idx;
4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local);
4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return MAKE_TCGV_I64(idx);
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline void tcg_temp_free_internal(int idx)
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int k;
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    assert(idx >= s->nb_globals && idx < s->nb_temps);
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[idx];
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    assert(ts->temp_allocated != 0);
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->temp_allocated = 0;
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    k = ts->base_type;
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ts->temp_local)
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        k += TCG_TYPE_COUNT;
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->next_free_temp = s->first_free_temp[k];
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->first_free_temp[k] = idx;
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_temp_free_i32(TCGv_i32 arg)
4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tcg_temp_free_internal(GET_TCGV_I32(arg));
4995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_temp_free_i64(TCGv_i64 arg)
5025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tcg_temp_free_internal(GET_TCGV_I64(arg));
5045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_const_i32(int32_t val)
5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGv_i32 t0;
5095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t0 = tcg_temp_new_i32();
5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tcg_gen_movi_i32(t0, val);
5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return t0;
5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_const_i64(int64_t val)
5155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGv_i64 t0;
5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t0 = tcg_temp_new_i64();
5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tcg_gen_movi_i64(t0, val);
5195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return t0;
5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_const_local_i32(int32_t val)
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGv_i32 t0;
5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t0 = tcg_temp_local_new_i32();
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_gen_movi_i32(t0, val);
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return t0;
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_const_local_i64(int64_t val)
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGv_i64 t0;
5335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t0 = tcg_temp_local_new_i64();
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_gen_movi_i64(t0, val);
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return t0;
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_register_helper(void *func, const char *name)
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int n;
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((s->nb_helpers + 1) > s->allocated_helpers) {
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = s->allocated_helpers;
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (n == 0) {
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            n = 4;
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            n *= 2;
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->allocated_helpers = n;
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->helpers[s->nb_helpers].name = name;
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->nb_helpers++;
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: we convert the 64 bit args to 32 bit and do some alignment
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   and endian swap. Maybe it would be better to do the alignment
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   and endian swap in tcg_reg_alloc_call(). */
5605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                   int sizemask, TCGArg ret, int nargs, TCGArg *args)
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int call_type;
5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int real_args;
5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nb_rets;
5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TCGArg *nparam;
5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *gen_opc_ptr++ = INDEX_op_call;
5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nparam = gen_opparam_ptr++;
5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    call_type = (flags & TCG_CALL_TYPE_MASK);
5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret != TCG_CALL_DUMMY_ARG) {
5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if TCG_TARGET_REG_BITS < 64
5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (sizemask & 1) {
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN
5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret + 1;
5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret;
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret;
5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret + 1;
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_rets = 2;
5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        {
5855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = ret;
5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_rets = 1;
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_rets = 0;
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    real_args = 0;
5925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < nargs; i++) {
5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if TCG_TARGET_REG_BITS < 64
5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (sizemask & (2 << i)) {
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_I386
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* REGPARM case: if the third parameter is 64 bit, it is
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               allocated on the stack */
5985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (i == 2 && call_type == TCG_CALL_TYPE_REGPARM) {
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                call_type = TCG_CALL_TYPE_REGPARM_2;
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                flags = (flags & ~TCG_CALL_TYPE_MASK) | call_type;
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_CALL_ALIGN_ARGS
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* some targets want aligned 64 bit args */
6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (real_args & 1) {
6065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                real_args++;
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN
6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i] + 1;
6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i];
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i];
6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i] + 1;
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            real_args += 2;
6185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        {
6215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *gen_opparam_ptr++ = args[i];
6225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            real_args++;
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *gen_opparam_ptr++ = GET_TCGV_PTR(func);
6265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *gen_opparam_ptr++ = flags;
6285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *nparam = (nb_rets << 16) | (real_args + 1);
6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* total parameters, needed to go backward in the instruction stream */
6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        int c, int right, int arith)
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (c == 0) {
6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (c >= 32) {
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c -= 32;
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (right) {
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arith) {
6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_movi_i32(TCGV_LOW(ret), 0);
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        TCGv_i32 t0, t1;
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        t0 = tcg_temp_new_i32();
6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        t1 = tcg_temp_new_i32();
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (right) {
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c);
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arith)
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c);
6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c);
6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0);
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_gen_mov_i32(TCGV_HIGH(ret), t1);
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Note: ret can be the same as arg1, so we use t1 */
6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c);
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
6765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_gen_mov_i32(TCGV_LOW(ret), t1);
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_temp_free_i32(t0);
6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_temp_free_i32(t1);
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_start(TCGContext *s)
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < s->nb_globals; i++) {
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[i];
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->fixed_reg) {
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_REG;
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_MEM;
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = s->nb_globals; i < s->nb_temps; i++) {
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[i];
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->val_type = TEMP_VAL_DEAD;
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->mem_allocated = 0;
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->fixed_reg = 0;
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->reg_to_temp[i] = -1;
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                 int idx)
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[idx];
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (idx < s->nb_globals) {
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pstrcpy(buf, buf_size, ts->name);
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
716b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        if (ts->temp_local)
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int helper_cmp(const void *p1, const void *p2)
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGHelperInfo *th1 = p1;
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGHelperInfo *th2 = p2;
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (th1->func < th2->func)
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if (th1->func == th2->func)
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* find helper definition (Note: A hash table would be better) */
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int m, m_min, m_max;
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGHelperInfo *th;
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_ulong v;
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (unlikely(!s->helpers_sorted)) {
754b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              helper_cmp);
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->helpers_sorted = 1;
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* binary search */
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    m_min = 0;
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    m_max = s->nb_helpers - 1;
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (m_min <= m_max) {
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        m = (m_min + m_max) >> 1;
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        th = &s->helpers[m];
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        v = th->func;
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (v == val)
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return th;
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if (val < v) {
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            m_max = m - 1;
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            m_min = m + 1;
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char * const cond_name[] =
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_EQ] = "eq",
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_NE] = "ne",
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_LT] = "lt",
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_GE] = "ge",
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_LE] = "le",
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_GT] = "gt",
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_LTU] = "ltu",
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_GEU] = "geu",
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_LEU] = "leu",
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    [TCG_COND_GTU] = "gtu"
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_dump_ops(TCGContext *s, FILE *outfile)
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const uint16_t *opc_ptr;
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArg *args;
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg arg;
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int c, i, k, nb_oargs, nb_iargs, nb_cargs, first_insn;
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGOpDef *def;
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char buf[128];
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    first_insn = 1;
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    opc_ptr = gen_opc_buf;
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args = gen_opparam_buf;
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (opc_ptr < gen_opc_ptr) {
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = *opc_ptr++;
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[c];
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (c == INDEX_op_debug_insn_start) {
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint64_t pc;
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = ((uint64_t)args[1] << 32) | args[0];
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = args[0];
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
813b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            if (!first_insn)
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "\n");
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, " ---- 0x%" PRIx64, pc);
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            first_insn = 0;
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_oargs = def->nb_oargs;
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_iargs = def->nb_iargs;
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_cargs = def->nb_cargs;
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (c == INDEX_op_call) {
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            TCGArg arg;
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* variable number of arguments */
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            arg = *args++;
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_oargs = arg >> 16;
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_iargs = arg & 0xffff;
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_cargs = def->nb_cargs;
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, " %s ", def->name);
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* function name */
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, "%s",
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* flags */
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, ",$0x%" TCG_PRIlx,
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    args[nb_oargs + nb_iargs]);
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* nb out args */
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, ",$%d", nb_oargs);
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < nb_oargs; i++) {
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, ",");
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "%s",
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[i]));
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < (nb_iargs - 1); i++) {
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, ",");
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) {
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, "<dummy>");
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } else {
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, "%s",
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
853b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        } else if (c == INDEX_op_movi_i32
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 64
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   || c == INDEX_op_movi_i64
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   ) {
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_target_ulong val;
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            TCGHelperInfo *th;
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_oargs = def->nb_oargs;
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_iargs = def->nb_iargs;
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_cargs = def->nb_cargs;
864b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            fprintf(outfile, " %s %s,$", def->name,
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            val = args[1];
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            th = tcg_find_helper(s, val);
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (th) {
8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(outfile, "%s", th->name);
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (c == INDEX_op_movi_i32)
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, "0x%x", (uint32_t)val);
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(outfile, " %s ", def->name);
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (c == INDEX_op_nopn) {
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* variable number of arguments */
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_cargs = *args;
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_oargs = 0;
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_iargs = 0;
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_oargs = def->nb_oargs;
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_iargs = def->nb_iargs;
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_cargs = def->nb_cargs;
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
888b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            k = 0;
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < nb_oargs; i++) {
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (k != 0)
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",");
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "%s",
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < nb_iargs; i++) {
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (k != 0)
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",");
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "%s",
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++]));
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
902b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            switch (c) {
903b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_brcond_i32:
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32
905b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_brcond2_i32:
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif TCG_TARGET_REG_BITS == 64
907b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_brcond_i64:
908b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif
909b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_setcond_i32:
910b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if TCG_TARGET_REG_BITS == 32
911b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_setcond2_i32:
912b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#elif TCG_TARGET_REG_BITS == 64
913b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            case INDEX_op_setcond_i64:
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]])
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",%s", cond_name[args[k++]]);
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",$0x%" TCG_PRIlx, args[k++]);
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                i = 1;
920b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner                break;
921b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            default:
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                i = 0;
923b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner                break;
924b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            }
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(; i < nb_cargs; i++) {
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (k != 0)
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(outfile, ",");
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                arg = args[k++];
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(outfile, "$0x%" TCG_PRIlx, arg);
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(outfile, "\n");
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args += nb_iargs + nb_oargs + nb_cargs;
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* we give more priority to constraints with less registers */
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_constraint_priority(const TCGOpDef *def, int k)
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArgConstraint *arg_ct;
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, n;
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    arg_ct = &def->args_ct[k];
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (arg_ct->ct & TCG_CT_ALIAS) {
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* an alias is equivalent to a single register */
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = 1;
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!(arg_ct->ct & TCG_CT_REG))
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = 0;
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (tcg_regset_test_reg(arg_ct->u.regs, i))
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                n++;
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return TCG_TARGET_NB_REGS - n + 1;
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sort from highest priority to lowest */
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void sort_constraints(TCGOpDef *def, int start, int n)
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, j, p1, p2, tmp;
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < n; i++)
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def->sorted_args[start + i] = start + i;
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (n <= 1)
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < n - 1; i++) {
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(j = i + 1; j < n; j++) {
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p1 = get_constraint_priority(def, def->sorted_args[start + i]);
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p2 = get_constraint_priority(def, def->sorted_args[start + j]);
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (p1 < p2) {
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tmp = def->sorted_args[start + i];
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->sorted_args[start + i] = def->sorted_args[start + j];
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->sorted_args[start + j] = tmp;
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int op;
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGOpDef *def;
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *ct_str;
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, nb_args;
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tdefs->op < 0)
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op = tdefs->op;
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(op >= 0 && op < NB_OPS);
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[op];
994b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG)
995b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        /* Duplicate entry in op definitions? */
996b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        assert(!def->used);
997b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        def->used = 1;
998b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        nb_args = def->nb_iargs + def->nb_oargs;
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < nb_args; i++) {
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ct_str = tdefs->args_ct_str[i];
1002b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            /* Incomplete TCGTargetOpDef entry? */
1003b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            assert(ct_str != NULL);
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_regset_clear(def->args_ct[i].u.regs);
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            def->args_ct[i].ct = 0;
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ct_str[0] >= '0' && ct_str[0] <= '9') {
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int oarg;
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                oarg = ct_str[0] - '0';
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                assert(oarg < def->nb_oargs);
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                assert(def->args_ct[oarg].ct & TCG_CT_REG);
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* TCG_CT_ALIAS is for the output arguments. The input
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   argument is tagged with TCG_CT_IALIAS. */
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[i] = def->args_ct[oarg];
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[oarg].ct = TCG_CT_ALIAS;
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[oarg].alias_index = i;
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[i].ct |= TCG_CT_IALIAS;
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                def->args_ct[i].alias_index = oarg;
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for(;;) {
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (*ct_str == '\0')
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    switch(*ct_str) {
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    case 'i':
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        def->args_ct[i].ct |= TCG_CT_CONST;
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        ct_str++;
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    default:
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    ct_str, i, def->name);
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            exit(1);
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        /* TCGTargetOpDef entry with too much information? */
1039b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL);
1040b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* sort the constraints (XXX: this is just an heuristic) */
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sort_constraints(def, 0, def->nb_oargs);
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sort_constraints(def, def->nb_oargs, def->nb_iargs);
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int i;
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("%s: sorted=", def->name);
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                printf(" %d", def->sorted_args[i]);
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("\n");
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tdefs++;
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1058b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG)
1059b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
1060b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        if (op < INDEX_op_call || op == INDEX_op_debug_insn_start) {
1061b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            /* Wrong entry in op definitions? */
1062b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            assert(!tcg_op_defs[op].used);
1063b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        } else {
1064b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            /* Missing entry in op definitions? */
1065b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner            assert(tcg_op_defs[op].used);
1066b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        }
1067b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    }
1068b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef USE_LIVENESS_ANALYSIS
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* set a nop for an operation using 'nb_args' */
1074b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turnerstatic inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               TCGArg *args, int nb_args)
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (nb_args == 0) {
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *opc_ptr = INDEX_op_nop;
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *opc_ptr = INDEX_op_nopn;
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[0] = nb_args;
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[nb_args - 1] = nb_args;
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* liveness analysis: end of function: globals are live, temps are
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   dead. */
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: at this stage, not used as there would be little gains because
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   most TBs end with a conditional jump. */
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(dead_temps, 0, s->nb_globals);
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* liveness analysis: end of basic block: globals are live, temps are
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   dead, local temps are live. */
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(dead_temps, 0, s->nb_globals);
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[s->nb_globals];
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = s->nb_globals; i < s->nb_temps; i++) {
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->temp_local)
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_temps[i] = 0;
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_temps[i] = 1;
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts++;
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Liveness analysis : update the opc_dead_iargs array to tell if a
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   given input arguments is dead. Instructions updating dead
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   temporaries are removed. */
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_liveness_analysis(TCGContext *s)
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, op_index, op, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg *args;
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGOpDef *def;
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *dead_temps;
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int dead_iargs;
1124ddf49e53df97a349f42c733059165dc73c9907dcDavid 'Digit' Turner
1125bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    /* sanity check */
1126bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    if (gen_opc_ptr - gen_opc_buf > OPC_BUF_SIZE) {
1127bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner        fprintf(stderr, "PANIC: too many opcodes generated (%d > %d)\n",
1128bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner                gen_opc_ptr - gen_opc_buf, OPC_BUF_SIZE);
1129bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner        tcg_abort();
1130ddf49e53df97a349f42c733059165dc73c9907dcDavid 'Digit' Turner    }
1131ddf49e53df97a349f42c733059165dc73c9907dcDavid 'Digit' Turner
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gen_opc_ptr++; /* skip end */
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_ops = gen_opc_ptr - gen_opc_buf;
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1136b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
1137b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dead_temps = tcg_malloc(s->nb_temps);
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(dead_temps, 1, s->nb_temps);
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args = gen_opparam_ptr;
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    op_index = nb_ops - 1;
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (op_index >= 0) {
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op = gen_opc_buf[op_index];
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[op];
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(op) {
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_call:
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int call_flags;
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_args = args[-1];
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                args -= nb_args;
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_iargs = args[0] & 0xffff;
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                nb_oargs = args[0] >> 16;
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                args++;
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                call_flags = args[nb_oargs + nb_iargs];
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* pure functions can be removed if their result is not
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   used */
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (call_flags & TCG_CALL_PURE) {
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for(i = 0; i < nb_oargs; i++) {
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        arg = args[i];
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (!dead_temps[arg])
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            goto do_not_remove_call;
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
1166b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner                    tcg_set_nop(s, gen_opc_buf + op_index,
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                args - 1, nb_args);
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } else {
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                do_not_remove_call:
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* output args are dead */
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for(i = 0; i < nb_oargs; i++) {
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        arg = args[i];
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dead_temps[arg] = 1;
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
1176b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
11775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!(call_flags & TCG_CALL_CONST)) {
11785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        /* globals are live (they may be used by the call) */
11795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        memset(dead_temps, 0, s->nb_globals);
11805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
11815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* input args are live */
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dead_iargs = 0;
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for(i = 0; i < nb_iargs; i++) {
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        arg = args[i + nb_oargs];
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (arg != TCG_CALL_DUMMY_ARG) {
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (dead_temps[arg]) {
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                dead_iargs |= (1 << i);
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            }
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            dead_temps[arg] = 0;
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->op_dead_iargs[op_index] = dead_iargs;
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                args--;
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_set_label:
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args--;
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* mark end of basic block */
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_la_bb_end(s, dead_temps);
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_debug_insn_start:
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args -= def->nb_args;
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nopn:
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            nb_args = args[-1];
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args -= nb_args;
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_discard:
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args--;
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* mark the temporary as dead */
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_temps[args[0]] = 1;
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_end:
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
12195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            args -= def->nb_args;
12205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_iargs = def->nb_iargs;
12215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_oargs = def->nb_oargs;
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Test if the operation can be removed because all
12245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               its outputs are dead. We assume that nb_oargs == 0
12255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               implies side effects */
12265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
12275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                for(i = 0; i < nb_oargs; i++) {
12285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    arg = args[i];
12295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!dead_temps[arg])
12305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto do_not_remove;
12315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
12325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
12345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                s->del_op_count++;
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
12365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
12375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            do_not_remove:
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* output args are dead */
12405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                for(i = 0; i < nb_oargs; i++) {
12415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    arg = args[i];
12425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    dead_temps[arg] = 1;
12435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
12445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* if end of basic block, update */
12465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (def->flags & TCG_OPF_BB_END) {
12475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tcg_la_bb_end(s, dead_temps);
12485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
12495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    /* globals are live */
12505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    memset(dead_temps, 0, s->nb_globals);
12515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
12525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* input args are live */
12545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                dead_iargs = 0;
12555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                for(i = 0; i < nb_iargs; i++) {
12565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    arg = args[i + nb_oargs];
12575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (dead_temps[arg]) {
12585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        dead_iargs |= (1 << i);
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
12605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    dead_temps[arg] = 0;
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
12625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                s->op_dead_iargs[op_index] = dead_iargs;
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op_index--;
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (args != gen_opparam_buf)
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* dummy liveness analysis */
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_liveness_analysis(TCGContext *s)
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int nb_ops;
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_ops = gen_opc_ptr - gen_opc_buf;
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(s->op_dead_iargs, 0, nb_ops * sizeof(uint16_t));
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef NDEBUG
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void dump_regs(TCGContext *s)
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char buf[64];
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < s->nb_temps; i++) {
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[i];
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(ts->val_type) {
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_REG:
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("%s", tcg_target_reg_names[ts->reg]);
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_MEM:
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]);
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_CONST:
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("$0x%" TCG_PRIlx, ts->val);
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_DEAD:
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("D");
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("???");
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("\n");
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->reg_to_temp[i] >= 0) {
13165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("%s: %s\n",
13175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   tcg_target_reg_names[i],
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i]));
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void check_regs(TCGContext *s)
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int reg, k;
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char buf[64];
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        k = s->reg_to_temp[reg];
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (k >= 0) {
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[k];
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type != TEMP_VAL_REG ||
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->reg != reg) {
13355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                printf("Inconsistency for register %s:\n",
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       tcg_target_reg_names[reg]);
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto fail;
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(k = 0; k < s->nb_temps; k++) {
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[k];
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->val_type == TEMP_VAL_REG &&
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            !ts->fixed_reg &&
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[ts->reg] != k) {
13465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                printf("Inconsistency for temp %s:\n",
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fail:
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                printf("reg state:\n");
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dump_regs(s);
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_abort();
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void temp_allocate_frame(TCGContext *s, int temp)
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[temp];
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->mem_offset = s->current_frame_offset;
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->mem_reg = s->frame_reg;
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts->mem_allocated = 1;
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->current_frame_offset += sizeof(tcg_target_long);
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* free register 'reg' by spilling the corresponding temporary if necessary */
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_free(TCGContext *s, int reg)
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int temp;
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    temp = s->reg_to_temp[reg];
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (temp != -1) {
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[temp];
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(ts->val_type == TEMP_VAL_REG);
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!ts->mem_coherent) {
13815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            if (!ts->mem_allocated)
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                temp_allocate_frame(s, temp);
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts->val_type = TEMP_VAL_MEM;
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->reg_to_temp[reg] = -1;
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Allocate a register belonging to reg1 & ~reg2 */
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, reg;
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGRegSet reg_ct;
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_regset_andnot(reg_ct, reg1, reg2);
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* first try free registers */
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = tcg_target_reg_alloc_order[i];
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1)
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return reg;
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: do better spill choice */
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) {
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = tcg_target_reg_alloc_order[i];
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_regset_test_reg(reg_ct, reg)) {
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_free(s, reg);
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return reg;
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_abort();
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* save a temporary to memory. 'allocated_regs' is used in case a
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   temporary registers needs to be allocated to store a constant. */
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int reg;
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[temp];
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!ts->fixed_reg) {
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(ts->val_type) {
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_REG:
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_free(s, ts->reg);
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_DEAD:
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_MEM;
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_CONST:
14345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                allocated_regs);
14365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            if (!ts->mem_allocated)
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                temp_allocate_frame(s, temp);
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_movi(s, ts->type, reg, ts->val);
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_MEM;
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TEMP_VAL_MEM:
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_abort();
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* save globals to their cannonical location and assume they can be
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   modified be the following code. 'allocated_regs' is used in case a
14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   temporary registers needs to be allocated to store a constant. */
14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void save_globals(TCGContext *s, TCGRegSet allocated_regs)
14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < s->nb_globals; i++) {
14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        temp_save(s, i, allocated_regs);
14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* at the end of a basic block, we assume all temporaries are dead and
14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   all globals are stored at their canonical location. */
14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = s->nb_globals; i < s->nb_temps; i++) {
14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[i];
14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->temp_local) {
14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            temp_save(s, i, allocated_regs);
14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type == TEMP_VAL_REG) {
14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[ts->reg] = -1;
14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_DEAD;
14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    save_globals(s, allocated_regs);
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1)
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ots;
14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_ulong val;
14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots = &s->temps[args[0]];
14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    val = args[1];
14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ots->fixed_reg) {
14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* for fixed registers, we do not do any constant
14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           propagation */
14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_movi(s, ots->type, ots->reg, val);
14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* The movi is not explicitly generated here */
15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ots->val_type == TEMP_VAL_REG)
15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[ots->reg] = -1;
15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ots->val_type = TEMP_VAL_CONST;
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ots->val = val;
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              const TCGArg *args,
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              unsigned int dead_iargs)
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts, *ots;
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int reg;
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArgConstraint *arg_ct;
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots = &s->temps[args[0]];
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[args[1]];
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    arg_ct = &def->args_ct[0];
15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: always mark arg dead if IS_DEAD_IARG(0) */
15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ts->val_type == TEMP_VAL_REG) {
15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) {
15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* the mov can be suppressed */
15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ots->val_type == TEMP_VAL_REG)
15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[ots->reg] = -1;
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = ts->reg;
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[reg] = -1;
15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_DEAD;
15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ots->val_type == TEMP_VAL_REG) {
15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = ots->reg;
15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->reg != reg) {
15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_mov(s, reg, ts->reg);
15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (ts->val_type == TEMP_VAL_MEM) {
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ots->val_type == TEMP_VAL_REG) {
15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = ots->reg;
15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (ts->val_type == TEMP_VAL_CONST) {
15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ots->fixed_reg) {
15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = ots->reg;
15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_movi(s, ots->type, reg, ts->val);
15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* propagate constant */
15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ots->val_type == TEMP_VAL_REG)
15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[ots->reg] = -1;
15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ots->val_type = TEMP_VAL_CONST;
15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ots->val = ts->val;
15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->reg_to_temp[reg] = args[0];
15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots->reg = reg;
15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots->val_type = TEMP_VAL_REG;
15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ots->mem_coherent = 0;
15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic void tcg_reg_alloc_op(TCGContext *s,
15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             const TCGOpDef *def, int opc,
15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             const TCGArg *args,
15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             unsigned int dead_iargs)
15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGRegSet allocated_regs;
15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, k, nb_iargs, nb_oargs, reg;
15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg arg;
15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArgConstraint *arg_ct;
15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg new_args[TCG_MAX_OP_ARGS];
15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int const_args[TCG_MAX_OP_ARGS];
15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_oargs = def->nb_oargs;
15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_iargs = def->nb_iargs;
15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* copy constants */
15835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcpy(new_args + nb_oargs + nb_iargs,
15845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           args + nb_oargs + nb_iargs,
15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           sizeof(TCGArg) * def->nb_cargs);
15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* satisfy input constraints */
15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_regset_set(allocated_regs, s->reserved_regs);
15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(k = 0; k < nb_iargs; k++) {
15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        i = def->sorted_args[nb_oargs + k];
15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[i];
15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg_ct = &def->args_ct[i];
15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[arg];
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->val_type == TEMP_VAL_MEM) {
15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_REG;
15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->reg = reg;
15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->mem_coherent = 1;
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[reg] = arg;
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (ts->val_type == TEMP_VAL_CONST) {
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (tcg_target_const_match(ts->val, arg_ct)) {
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* constant is OK for instruction */
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                const_args[i] = 1;
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                new_args[i] = ts->val;
16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto iarg_end;
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* need to move to a register */
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_movi(s, ts->type, reg, ts->val);
16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->val_type = TEMP_VAL_REG;
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->reg = reg;
16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->mem_coherent = 0;
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[reg] = arg;
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(ts->val_type == TEMP_VAL_REG);
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arg_ct->ct & TCG_CT_IALIAS) {
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->fixed_reg) {
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* if fixed register, we must allocate a new register
16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   if the alias is not the same register */
16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (arg != args[arg_ct->alias_index])
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto allocate_in_reg;
16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* if the input is aliased to an output and if it is
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   not dead after the instruction, we must allocate
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   a new register and move it */
16285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                if (!IS_DEAD_IARG(i - nb_oargs))
16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto allocate_in_reg;
16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = ts->reg;
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* nothing to do : the constraint is satisfied */
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        allocate_in_reg:
16375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            /* allocate a new register matching the constraint
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               and move the temporary register into it */
16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_mov(s, reg, ts->reg);
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        new_args[i] = reg;
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const_args[i] = 0;
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_regset_set_reg(allocated_regs, reg);
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    iarg_end: ;
16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (def->flags & TCG_OPF_BB_END) {
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_reg_alloc_bb_end(s, allocated_regs);
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* mark dead temporaries and free the associated registers */
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < nb_iargs; i++) {
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            arg = args[nb_oargs + i];
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (IS_DEAD_IARG(i)) {
16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts = &s->temps[arg];
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (!ts->fixed_reg) {
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (ts->val_type == TEMP_VAL_REG)
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        s->reg_to_temp[ts->reg] = -1;
16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    ts->val_type = TEMP_VAL_DEAD;
16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (def->flags & TCG_OPF_CALL_CLOBBER) {
16655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            /* XXX: permit generic clobber register list ? */
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tcg_reg_free(s, reg);
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* XXX: for load/store we could do that only for the slow path
16728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               (i.e. when a memory callback is called) */
16735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* store globals and free associated registers (we assume the insn
16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               can modify any global. */
16768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            save_globals(s, allocated_regs);
16778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* satisfy the output constraints */
16808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_regset_set(allocated_regs, s->reserved_regs);
16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(k = 0; k < nb_oargs; k++) {
16828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            i = def->sorted_args[k];
16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            arg = args[i];
16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            arg_ct = &def->args_ct[i];
16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[arg];
16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (arg_ct->ct & TCG_CT_ALIAS) {
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = new_args[arg_ct->alias_index];
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* if fixed register, we try to use it */
16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = ts->reg;
16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ts->fixed_reg &&
16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tcg_regset_test_reg(arg_ct->u.regs, reg)) {
16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto oarg_end;
16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_regset_set_reg(allocated_regs, reg);
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* if a fixed register is used, then a move will be done afterwards */
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!ts->fixed_reg) {
17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ts->val_type == TEMP_VAL_REG)
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->reg_to_temp[ts->reg] = -1;
17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->val_type = TEMP_VAL_REG;
17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->reg = reg;
17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* temp value is modified, so the value kept in memory is
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   potentially not the same */
17065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                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        oarg_end:
17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            new_args[i] = reg;
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* emit instruction */
17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_out_op(s, opc, new_args, const_args);
17165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* move the outputs in the correct register if needed */
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < nb_oargs; i++) {
17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[args[i]];
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = new_args[i];
17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->fixed_reg && ts->reg != reg) {
17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_mov(s, ts->reg, reg);
17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_STACK_GROWSUP
17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define STACK_DIR(x) (-(x))
17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define STACK_DIR(x) (x)
17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              int opc, const TCGArg *args,
17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              unsigned int dead_iargs)
17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGArg arg, func_arg;
17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGTemp *ts;
17408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_target_long stack_offset, call_stack_size, func_addr;
17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int const_func_arg, allocate_args;
17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGRegSet allocated_regs;
17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArgConstraint *arg_ct;
17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    arg = *args++;
17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_oargs = arg >> 16;
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_iargs = arg & 0xffff;
17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_params = nb_iargs - 1;
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = args[nb_oargs + nb_iargs];
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nb_regs = tcg_target_get_call_iarg_regs_count(flags);
17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (nb_regs > nb_params)
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        nb_regs = nb_params;
17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* assign stack slots first */
17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: preallocate call stack */
17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
17605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) &
17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ~(TCG_TARGET_STACK_ALIGN - 1);
17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (allocate_args) {
17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = nb_regs; i < nb_params; i++) {
17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[nb_oargs + i];
17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_STACK_GROWSUP
17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stack_offset -= sizeof(tcg_target_long);
17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arg != TCG_CALL_DUMMY_ARG) {
17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[arg];
17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type == TEMP_VAL_REG) {
17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (ts->val_type == TEMP_VAL_MEM) {
17785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    s->reserved_regs);
17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* XXX: not correct if reading values from the stack */
17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
17828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (ts->val_type == TEMP_VAL_CONST) {
17845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    s->reserved_regs);
17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* XXX: sign extend may be needed on some targets */
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_movi(s, ts->type, reg, ts->val);
17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset);
17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
17908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_abort();
17918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef TCG_TARGET_STACK_GROWSUP
17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stack_offset += sizeof(tcg_target_long);
17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* assign input registers */
17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_regset_set(allocated_regs, s->reserved_regs);
18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < nb_regs; i++) {
18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[nb_oargs + i];
18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (arg != TCG_CALL_DUMMY_ARG) {
18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[arg];
18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_target_call_iarg_regs[i];
18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_free(s, reg);
18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type == TEMP_VAL_REG) {
18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ts->reg != reg) {
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tcg_out_mov(s, reg, ts->reg);
18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (ts->val_type == TEMP_VAL_MEM) {
18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (ts->val_type == TEMP_VAL_CONST) {
18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* XXX: sign extend ? */
18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_movi(s, ts->type, reg, ts->val);
18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_abort();
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_regset_set_reg(allocated_regs, reg);
18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* assign function address */
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    func_arg = args[nb_oargs + nb_iargs - 1];
18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    arg_ct = &def->args_ct[0];
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ts = &s->temps[func_arg];
18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    func_addr = ts->val;
18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const_func_arg = 0;
18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ts->val_type == TEMP_VAL_MEM) {
18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        func_arg = reg;
18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_regset_set_reg(allocated_regs, reg);
18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (ts->val_type == TEMP_VAL_REG) {
18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = ts->reg;
18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_mov(s, reg, ts->reg);
18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        func_arg = reg;
18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_regset_set_reg(allocated_regs, reg);
18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (ts->val_type == TEMP_VAL_CONST) {
18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_target_const_match(func_addr, arg_ct)) {
18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            const_func_arg = 1;
18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            func_arg = func_addr;
18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_movi(s, ts->type, reg, func_addr);
18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            func_arg = reg;
18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_regset_set_reg(allocated_regs, reg);
18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_abort();
18538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
18555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* mark dead temporaries and free the associated registers */
18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < nb_iargs; i++) {
18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[nb_oargs + i];
18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (IS_DEAD_IARG(i)) {
18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts = &s->temps[arg];
18618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!ts->fixed_reg) {
18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ts->val_type == TEMP_VAL_REG)
18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    s->reg_to_temp[ts->reg] = -1;
18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts->val_type = TEMP_VAL_DEAD;
18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* clobber call registers */
18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_free(s, reg);
18738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
18768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* store globals and free associated registers (we assume the call
18778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       can modify any global. */
18785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!(flags & TCG_CALL_CONST)) {
18795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        save_globals(s, allocated_regs);
18805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
18818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_out_op(s, opc, &func_arg, &const_func_arg);
18835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
18848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (allocate_args) {
18858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size));
18868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* assign output registers and emit moves if needed */
18898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < nb_oargs; i++) {
18908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        arg = args[i];
18918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ts = &s->temps[arg];
18928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        reg = tcg_target_call_oarg_regs[i];
18938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        assert(s->reg_to_temp[reg] == -1);
18948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ts->fixed_reg) {
18958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->reg != reg) {
18968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tcg_out_mov(s, ts->reg, reg);
18978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
18988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
18998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ts->val_type == TEMP_VAL_REG)
19008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->reg_to_temp[ts->reg] = -1;
19018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->val_type = TEMP_VAL_REG;
19028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ts->reg = reg;
19035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            ts->mem_coherent = 0;
19048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->reg_to_temp[reg] = arg;
19058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
19088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return nb_iargs + nb_oargs + def->nb_cargs + 1;
19098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
19128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t tcg_table_op_count[NB_OPS];
19148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid dump_op_count(void)
19168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
19188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *f;
19195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    f = fopen("/tmp/op.log", "w");
19208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = INDEX_op_end; i < NB_OPS; i++) {
19215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
19228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fclose(f);
19248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
19298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      long search_pc)
19308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int opc, op_index;
19328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGOpDef *def;
19338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int dead_iargs;
19348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const TCGArg *args;
19355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
19365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    unsigned int tpc2gpc_index = 0;
19375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
19388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_DISAS
19405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
19415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_log("OP:\n");
19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_dump_ops(s, logfile);
19435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_log("\n");
19448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
19488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->la_time -= profile_getclock();
19498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_liveness_analysis(s);
19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->la_time += profile_getclock();
19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_DISAS
19565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
1957b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner        qemu_log("OP after liveness analysis:\n");
19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tcg_dump_ops(s, logfile);
19595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_log("\n");
19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_reg_alloc_start(s);
19648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_buf = gen_code_buf;
19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->code_ptr = gen_code_buf;
19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args = gen_opparam_buf;
19698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    op_index = 0;
19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
19725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    gen_opc_tpc2gpc_pairs = 0;
19735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
19745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
19765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
19775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* On condition that memcheck is enabled, and operation index reached
19785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * new operation in the guest code, save (pc_tb, pc_guest) pair into
19795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * gen_opc_tpc2gpc array. Note that we do that only on condition that
19805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * search_pc is < 0. This way we make sure that this is "normal"
19815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * translation, called from tcg_gen_code, and not from
19825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * tcg_gen_code_search_pc. */
19835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (memcheck_enabled && search_pc < 0 &&
19845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            gen_opc_instr_start[op_index]) {
19855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            gen_opc_tpc2gpc_ptr[tpc2gpc_index] = (target_ulong)s->code_ptr;
19865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            tpc2gpc_index++;
19875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            gen_opc_tpc2gpc_ptr[tpc2gpc_index] = gen_opc_pc[op_index];
19885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            tpc2gpc_index++;
19895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            gen_opc_tpc2gpc_pairs++;
19905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
19915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opc = gen_opc_buf[op_index];
19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
19945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_table_op_count[opc]++;
19958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        def = &tcg_op_defs[opc];
19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("%s: %d %d %d\n", def->name,
19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               def->nb_oargs, def->nb_iargs, def->nb_cargs);
20008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        //        dump_regs(s);
20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(opc) {
20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_mov_i32:
20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 64
20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_mov_i64:
20068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_iargs = s->op_dead_iargs[op_index];
20088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_alloc_mov(s, def, args, dead_iargs);
20098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_movi_i32:
20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 64
20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_movi_i64:
20138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_alloc_movi(s, args);
20158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_debug_insn_start:
20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* debug instruction */
20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nop:
20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nop1:
20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nop2:
20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nop3:
20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
20248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_nopn:
20258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args += args[0];
20268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto next;
20278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_discard:
20288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
20298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                TCGTemp *ts;
20308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ts = &s->temps[args[0]];
20318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* mark the temporary as dead */
20328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (!ts->fixed_reg) {
20338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (ts->val_type == TEMP_VAL_REG)
20348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        s->reg_to_temp[ts->reg] = -1;
20358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    ts->val_type = TEMP_VAL_DEAD;
20368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
20378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
20388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
20398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_set_label:
20408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_alloc_bb_end(s, s->reserved_regs);
20418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_out_label(s, args[0], (long)s->code_ptr);
20428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
20438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_call:
20448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_iargs = s->op_dead_iargs[op_index];
20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs);
20468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto next;
20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case INDEX_op_end:
20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto the_end;
20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Note: in order to speed up the code, it would be much
20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               faster to have specialized register allocator functions for
20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               some common argument patterns */
20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dead_iargs = s->op_dead_iargs[op_index];
20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tcg_reg_alloc_op(s, def, opc, args, dead_iargs);
20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
20568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args += def->nb_args;
20588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next:
20598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
20608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return op_index;
20618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
20628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        op_index++;
20638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef NDEBUG
20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        check_regs(s);
20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project the_end:
20688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
20698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
20728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
20748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
20758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int n;
20768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = (gen_opc_ptr - gen_opc_buf);
20778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->op_count += n;
20788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (n > s->op_count_max)
20798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->op_count_max = n;
20808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->temp_count += s->nb_temps;
20828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->nb_temps > s->temp_count_max)
20838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->temp_count_max = s->nb_temps;
20848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2087bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    /* sanity check */
2088bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    if (gen_opc_ptr - gen_opc_buf > OPC_BUF_SIZE) {
2089bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner        fprintf(stderr, "PANIC: too many opcodes generated (%d > %d)\n",
2090bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner                gen_opc_ptr - gen_opc_buf, OPC_BUF_SIZE);
2091bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner        tcg_abort();
2092bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner    }
2093bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner
20948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tcg_gen_code_common(s, gen_code_buf, -1);
20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* flush instruction cache */
20975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    flush_icache_range((unsigned long)gen_code_buf,
20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       (unsigned long)s->code_ptr);
20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s->code_ptr -  gen_code_buf;
21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Return the index of the micro operation such as the pc after is <
21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   offset bytes from the start of the TB.  The contents of gen_code_buf must
21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   not be changed, though writing the same values is ok.
21058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Return -1 if not found. */
21065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return tcg_gen_code_common(s, gen_code_buf, offset);
21098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER
21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_dump_info(FILE *f,
21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TCGContext *s = &tcg_ctx;
21168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t tot;
21178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tot = s->interm_time + s->code_time;
21198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tot, tot / 2.4e9);
21215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
21225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                s->tb_count,
21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->tb_count1 - s->tb_count,
21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
21255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n",
21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
21278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
21285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                s->tb_count ?
21298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->del_op_count / s->tb_count : 0);
21308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "avg temps/TB        %0.2f max=%d\n",
21315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                s->tb_count ?
21328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->temp_count / s->tb_count : 0,
21338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->temp_count_max);
21345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
21355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "cycles/op           %0.1f\n",
21368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->op_count ? (double)tot / s->op_count : 0);
21375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "cycles/in byte      %0.1f\n",
21388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->code_in_len ? (double)tot / s->code_in_len : 0);
21395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "cycles/out byte     %0.1f\n",
21408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->code_out_len ? (double)tot / s->code_out_len : 0);
21418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tot == 0)
21428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tot = 1;
21435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "  gen_interm time   %0.1f%%\n",
21448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->interm_time / tot * 100.0);
21455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "  gen_code time     %0.1f%%\n",
21468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->code_time / tot * 100.0);
21475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    cpu_fprintf(f, "liveness/code time  %0.1f%%\n",
21488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
21498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
21508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->restore_count);
21518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "  avg cycles        %0.1f\n",
21528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->restore_count ? (double)s->restore_time / s->restore_count : 0);
2153b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner
2154b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner    dump_op_count();
21558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
21578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_dump_info(FILE *f,
21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
21598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_fprintf(f, "[TCG profiler not compiled]\n");
21618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2163