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