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