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 2786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#define USE_TCG_OPTIMIZATIONS 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "config.h" 305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* Define to jump the ELF file used to communicate with GDB. */ 3286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#undef DEBUG_JIT 3386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG) 355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* define it to suppress various consistency checks (faster) */ 365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NDEBUG 375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h" 4037dc41a01f33a1e6aca0458b205c2b1609fe82c3David 'Digit' Turner#include "qemu/cache-utils.h" 41e90d665cd63a0bc5c3306e1ee3e98ad362546b16David 'Digit' Turner#include "qemu/host-utils.h" 427a78db75ad42aea283f5073f51891464104a9fc3David 'Digit' Turner#include "qemu/timer.h" 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: the long term plan is to reduce the dependancies on the QEMU 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project CPU definitions. Currently they are used for qemu_ld/st 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project instructions */ 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NO_CPU_IO_DEFS 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "cpu.h" 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg-op.h" 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#if UINTPTR_MAX == UINT32_MAX 5386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner# define ELF_CLASS ELFCLASS32 5486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#else 5586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner# define ELF_CLASS ELFCLASS64 56b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif 5786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef HOST_WORDS_BIGENDIAN 5886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner# define ELF_DATA ELFDATA2MSB 5986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#else 6086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner# define ELF_DATA ELFDATA2LSB 6186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 6286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 6386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#include "elf.h" 64b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner 6586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* Forward declarations for functions declared in tcg-target.c and used here. */ 66f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void tcg_target_init(TCGContext *s); 67f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void tcg_target_qemu_prologue(TCGContext *s); 6886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void patch_reloc(uint8_t *code_ptr, int type, 6986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner intptr_t value, intptr_t addend); 7086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 7186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* The CIE and FDE header definitions will be common to all hosts. */ 7286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnertypedef struct { 7386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint32_t len __attribute__((aligned((sizeof(void *))))); 7486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint32_t id; 7586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t version; 7686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner char augmentation[1]; 7786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t code_align; 7886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t data_align; 7986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t return_column; 8086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} DebugFrameCIE; 8186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 8286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnertypedef struct QEMU_PACKED { 8386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint32_t len __attribute__((aligned((sizeof(void *))))); 8486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint32_t cie_offset; 8586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uintptr_t func_start; 8686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uintptr_t func_len; 8786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} DebugFrameFDEHeader; 8886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 8986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_register_jit_int(void *buf, size_t size, 9086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner void *debug_frame, size_t debug_frame_size) 9186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner __attribute__((unused)); 9286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 9386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* Forward declarations for functions declared and used in tcg-target.c. */ 9486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str); 9586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, 9686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner intptr_t arg2); 9786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); 9886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_out_movi(TCGContext *s, TCGType type, 9986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner TCGReg ret, tcg_target_long arg); 10086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, 10186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const int *const_args); 10286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, 10386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner intptr_t arg2); 10486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic int tcg_target_const_match(tcg_target_long val, 10586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const TCGArgConstraint *arg_ct); 10686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_out_tb_init(TCGContext *s); 10786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_out_tb_finalize(TCGContext *s); 10886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 10986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 11086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' TurnerTCGOpDef tcg_op_defs[] = { 111f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags }, 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg-opc.h" 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DEF 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 11586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerconst size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs); 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic TCGRegSet tcg_target_available_regs[2]; 1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic TCGRegSet tcg_target_call_clobber_regs; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_out8(TCGContext *s, uint8_t v) 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *s->code_ptr++ = v; 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_out16(TCGContext *s, uint16_t v) 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t *p = s->code_ptr; 12886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *(uint16_t *)p = v; 12986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->code_ptr = p + 2; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_out32(TCGContext *s, uint32_t v) 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t *p = s->code_ptr; 13586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *(uint32_t *)p = v; 13686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->code_ptr = p + 4; 13786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 13886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 13986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic inline void tcg_out64(TCGContext *s, uint64_t v) 14086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 14186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t *p = s->code_ptr; 14286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *(uint64_t *)p = v; 14386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->code_ptr = p + 8; 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* label relocation processing */ 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 148f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, 14986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner int label_index, intptr_t addend) 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGLabel *l; 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGRelocation *r; 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project l = &s->labels[label_index]; 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (l->has_value) { 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* FIXME: This may break relocations on RISC targets that 15786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner modify instruction fields in place. The caller may not have 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project written the initial value. */ 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project patch_reloc(code_ptr, type, l->u.value, addend); 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add a new relocation entry */ 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project r = tcg_malloc(sizeof(TCGRelocation)); 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project r->type = type; 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project r->ptr = code_ptr; 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project r->addend = addend; 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project r->next = l->u.first_reloc; 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project l->u.first_reloc = r; 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_out_label(TCGContext *s, int label_index, void *ptr) 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGLabel *l; 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGRelocation *r; 17586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner intptr_t value = (intptr_t)ptr; 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project l = &s->labels[label_index]; 17886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (l->has_value) { 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 18086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project r = l->u.first_reloc; 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (r != NULL) { 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project patch_reloc(r->ptr, r->type, value, r->addend); 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project r = r->next; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project l->has_value = 1; 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project l->u.value = value; 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint gen_new_label(void) 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGContext *s = &tcg_ctx; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int idx; 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGLabel *l; 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->nb_labels >= TCG_MAX_LABELS) 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project idx = s->nb_labels++; 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project l = &s->labels[idx]; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project l->has_value = 0; 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project l->u.first_reloc = NULL; 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return idx; 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg-target.c" 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* pool based memory allocation */ 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid *tcg_malloc_internal(TCGContext *s, int size) 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGPool *p; 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int pool_size; 21286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size > TCG_POOL_CHUNK_SIZE) { 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* big malloc: insert a new pool (XXX: could optimize) */ 215aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner p = g_malloc(sizeof(TCGPool) + size); 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->size = size; 21786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner p->next = s->pool_first_large; 21886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->pool_first_large = p; 21986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return p->data; 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = s->pool_current; 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p) { 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = s->pool_first; 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p) 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto new_pool; 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p->next) { 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_pool: 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pool_size = TCG_POOL_CHUNK_SIZE; 230aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner p = g_malloc(sizeof(TCGPool) + pool_size); 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->size = pool_size; 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->next = NULL; 23386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (s->pool_current) 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->pool_current->next = p; 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->pool_first = p; 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = p->next; 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->pool_current = p; 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->pool_cur = p->data + size; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->pool_end = p->data + p->size; 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return p->data; 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_pool_reset(TCGContext *s) 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner TCGPool *p, *t; 25186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner for (p = s->pool_first_large; p; p = t) { 25286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner t = p->next; 25386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner g_free(p); 25486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 25586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->pool_first_large = NULL; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->pool_cur = s->pool_end = NULL; 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->pool_current = NULL; 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26026d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner#include "helper.h" 26126d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner 26226d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turnertypedef struct TCGHelperInfo { 26386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner void *func; 26486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const char *name; 26526d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner} TCGHelperInfo; 26626d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner 26726d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turnerstatic const TCGHelperInfo all_helpers[] = { 26826d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner#define GEN_HELPER 2 26926d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner#include "helper.h" 27086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 27186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Include tcg-runtime.c functions. */ 27286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_div_i32, "div_i32" }, 27386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_rem_i32, "rem_i32" }, 27486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_divu_i32, "divu_i32" }, 27586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_remu_i32, "remu_i32" }, 27686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 27786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_shl_i64, "shl_i64" }, 27886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_shr_i64, "shr_i64" }, 27986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_sar_i64, "sar_i64" }, 28086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_div_i64, "div_i64" }, 28186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_rem_i64, "rem_i64" }, 28286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_divu_i64, "divu_i64" }, 28386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_remu_i64, "remu_i64" }, 28486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_mulsh_i64, "mulsh_i64" }, 28586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { tcg_helper_muluh_i64, "muluh_i64" }, 28626d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner}; 28726d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_context_init(TCGContext *s) 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 29026d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner int op, total_args, n, i; 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGOpDef *def; 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGArgConstraint *args_ct; 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int *sorted_args; 29426d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner GHashTable *helper_table; 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset(s, 0, sizeof(*s)); 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->nb_globals = 0; 29886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Count total number of arguments and allocate the corresponding 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project space */ 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_args = 0; 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(op = 0; op < NB_OPS; op++) { 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def = &tcg_op_defs[op]; 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = def->nb_iargs + def->nb_oargs; 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_args += n; 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 308aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args); 309aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner sorted_args = g_malloc(sizeof(int) * total_args); 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(op = 0; op < NB_OPS; op++) { 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def = &tcg_op_defs[op]; 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->args_ct = args_ct; 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->sorted_args = sorted_args; 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = def->nb_iargs + def->nb_oargs; 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sorted_args += n; 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args_ct += n; 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 319c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 32086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Register helpers. */ 32186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Use g_direct_hash/equal for direct pointer comparisons on func. */ 32226d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner s->helpers = helper_table = g_hash_table_new(NULL, NULL); 32326d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner 32426d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) { 32526d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func, 32626d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner (gpointer)all_helpers[i].name); 32726d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner } 32826d285dfa9f482e5b2f6d6df2bcb0eaed06cb1a9David 'Digit' Turner 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_target_init(s); 330f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner} 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 332f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_prologue_init(TCGContext *s) 333f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner{ 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* init global prologue and epilogue */ 335975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner s->code_buf = s->code_gen_prologue; 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->code_ptr = s->code_buf; 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_target_qemu_prologue(s); 33886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr); 33986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 34086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef DEBUG_DISAS 34186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { 34286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner size_t size = s->code_ptr - s->code_buf; 34386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("PROLOGUE: [size=%zu]\n", size); 34486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner log_disas(s->code_buf, size); 34586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("\n"); 34686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log_flush(); 34786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 34886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 35186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size) 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->frame_start = start; 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->frame_end = start + size; 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->frame_reg = reg; 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_func_start(TCGContext *s) 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_pool_reset(s); 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->nb_temps = s->nb_globals; 36286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 36386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* No temps have been previously allocated for size or locality. */ 36486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(s->free_temps, 0, sizeof(s->free_temps)); 36586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS); 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->nb_labels = 0; 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->current_frame_offset = s->frame_start; 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 37086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef CONFIG_DEBUG_TCG 37186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->goto_tb_issue_mask = 0; 37286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 37386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 374975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner s->gen_opc_ptr = s->gen_opc_buf; 375975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner s->gen_opparam_ptr = s->gen_opparam_buf; 37686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 37786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->be = tcg_malloc(sizeof(TCGBackendData)); 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tcg_temp_alloc(TCGContext *s, int n) 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n > TCG_MAX_TEMPS) 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int tcg_global_reg_new_internal(TCGType type, int reg, 3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *name) 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGContext *s = &tcg_ctx; 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int idx; 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type != TCG_TYPE_I32) 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcg_regset_test_reg(s->reserved_regs, reg)) 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project idx = s->nb_globals; 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_temp_alloc(s, s->nb_globals + 1); 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[s->nb_globals]; 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->base_type = type; 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->type = type; 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->fixed_reg = 1; 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->reg = reg; 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->name = name; 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->nb_globals++; 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set_reg(s->reserved_regs, reg); 4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return idx; 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_global_reg_new_i32(int reg, const char *name) 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int idx; 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner idx = tcg_global_reg_new_internal(TCG_TYPE_I32, reg, name); 4175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return MAKE_TCGV_I32(idx); 4185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_global_reg_new_i64(int reg, const char *name) 4215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int idx; 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name); 4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return MAKE_TCGV_I64(idx); 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int tcg_global_mem_new_internal(TCGType type, int reg, 42986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner intptr_t offset, 4305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *name) 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGContext *s = &tcg_ctx; 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int idx; 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project idx = s->nb_globals; 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == TCG_TYPE_I64) { 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf[64]; 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_temp_alloc(s, s->nb_globals + 2); 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[s->nb_globals]; 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->base_type = type; 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->type = TCG_TYPE_I32; 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->fixed_reg = 0; 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_allocated = 1; 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_reg = reg; 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_offset = offset + 4; 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_offset = offset; 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(buf, sizeof(buf), name); 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcat(buf, sizeof(buf), "_0"); 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->name = strdup(buf); 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts++; 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->base_type = type; 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->type = TCG_TYPE_I32; 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->fixed_reg = 0; 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_allocated = 1; 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_reg = reg; 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_offset = offset; 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_offset = offset + 4; 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(buf, sizeof(buf), name); 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcat(buf, sizeof(buf), "_1"); 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->name = strdup(buf); 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->nb_globals += 2; 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_temp_alloc(s, s->nb_globals + 1); 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[s->nb_globals]; 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->base_type = type; 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->type = type; 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->fixed_reg = 0; 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_allocated = 1; 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_reg = reg; 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_offset = offset; 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->name = name; 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->nb_globals++; 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return idx; 4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 48986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' TurnerTCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name) 4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 49186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name); 4925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return MAKE_TCGV_I32(idx); 4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 49586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' TurnerTCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name) 4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 49786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name); 4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return MAKE_TCGV_I64(idx); 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int tcg_temp_new_internal(TCGType type, int temp_local) 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGContext *s = &tcg_ctx; 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int idx, k; 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 50786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner k = type + (temp_local ? TCG_TYPE_COUNT : 0); 50886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS); 50986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (idx < TCG_MAX_TEMPS) { 51086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* There is already an available temp with the right type. */ 51186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner clear_bit(idx, s->free_temps[k].l); 51286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[idx]; 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->temp_allocated = 1; 51586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(ts->base_type == type); 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project assert(ts->temp_local == temp_local); 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project idx = s->nb_temps; 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == TCG_TYPE_I64) { 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_temp_alloc(s, s->nb_temps + 2); 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[s->nb_temps]; 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->base_type = type; 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->type = TCG_TYPE_I32; 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->temp_allocated = 1; 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->temp_local = temp_local; 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->name = NULL; 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts++; 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->base_type = TCG_TYPE_I32; 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->type = TCG_TYPE_I32; 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->temp_allocated = 1; 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->temp_local = temp_local; 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->name = NULL; 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->nb_temps += 2; 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_temp_alloc(s, s->nb_temps + 1); 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[s->nb_temps]; 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->base_type = type; 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->type = type; 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->temp_allocated = 1; 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->temp_local = temp_local; 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->name = NULL; 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->nb_temps++; 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 548f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner 549f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG) 550f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner s->temps_in_use++; 551f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif 5525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return idx; 5535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_temp_new_internal_i32(int temp_local) 5565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int idx; 5585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner idx = tcg_temp_new_internal(TCG_TYPE_I32, temp_local); 5605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return MAKE_TCGV_I32(idx); 5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_temp_new_internal_i64(int temp_local) 5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int idx; 5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner idx = tcg_temp_new_internal(TCG_TYPE_I64, temp_local); 5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return MAKE_TCGV_I64(idx); 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 57186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_temp_free_internal(int idx) 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGContext *s = &tcg_ctx; 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int k; 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 577f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG) 578f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner s->temps_in_use--; 579f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner if (s->temps_in_use < 0) { 580f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner fprintf(stderr, "More temporaries freed than allocated!\n"); 581f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 582f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif 583f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project assert(idx >= s->nb_globals && idx < s->nb_temps); 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[idx]; 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project assert(ts->temp_allocated != 0); 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->temp_allocated = 0; 58886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 58986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner k = ts->type + (ts->temp_local ? TCG_TYPE_COUNT : 0); 59086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner set_bit(idx, s->free_temps[k].l); 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_temp_free_i32(TCGv_i32 arg) 5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_temp_free_internal(GET_TCGV_I32(arg)); 5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_temp_free_i64(TCGv_i64 arg) 5995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 6005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_temp_free_internal(GET_TCGV_I64(arg)); 6015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_const_i32(int32_t val) 6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner TCGv_i32 t0; 6065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t0 = tcg_temp_new_i32(); 6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_movi_i32(t0, val); 6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return t0; 6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_const_i64(int64_t val) 6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner TCGv_i64 t0; 6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t0 = tcg_temp_new_i64(); 6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_movi_i64(t0, val); 6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return t0; 6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i32 tcg_const_local_i32(int32_t val) 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner TCGv_i32 t0; 6225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t0 = tcg_temp_local_new_i32(); 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_movi_i32(t0, val); 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return t0; 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerTCGv_i64 tcg_const_local_i64(int64_t val) 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner TCGv_i64 t0; 6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t0 = tcg_temp_local_new_i64(); 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_movi_i64(t0, val); 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return t0; 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 635f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG) 636f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_clear_temp_count(void) 637f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner{ 638f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner TCGContext *s = &tcg_ctx; 639f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner s->temps_in_use = 0; 640f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner} 641f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner 642f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerint tcg_check_temp_count(void) 643f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner{ 644f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner TCGContext *s = &tcg_ctx; 645f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner if (s->temps_in_use) { 646f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner /* Clear the count so that we don't give another 647f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner * warning immediately next time around. 648f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner */ 649f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner s->temps_in_use = 0; 650f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner return 1; 651f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 652f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner return 0; 653f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner} 654f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif 655f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: we convert the 64 bit args to 32 bit and do some alignment 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project and endian swap. Maybe it would be better to do the alignment 6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project and endian swap in tcg_reg_alloc_call(). */ 6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, 6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int sizemask, TCGArg ret, int nargs, TCGArg *args) 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int i; 6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int real_args; 6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nb_rets; 6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner TCGArg *nparam; 666f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner 667f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 668f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner for (i = 0; i < nargs; ++i) { 669f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner int is_64bit = sizemask & (1 << (i+1)*2); 670f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner int is_signed = sizemask & (2 << (i+1)*2); 671f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner if (!is_64bit) { 672f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner TCGv_i64 temp = tcg_temp_new_i64(); 673f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner TCGv_i64 orig = MAKE_TCGV_I64(args[i]); 674f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner if (is_signed) { 675f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner tcg_gen_ext32s_i64(temp, orig); 676f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } else { 677f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner tcg_gen_ext32u_i64(temp, orig); 678f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 679f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner args[i] = GET_TCGV_I64(temp); 680f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 681f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 682f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif /* TCG_TARGET_EXTEND_ARGS */ 683f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner 684975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opc_ptr++ = INDEX_op_call; 685975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner nparam = s->gen_opparam_ptr++; 6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret != TCG_CALL_DUMMY_ARG) { 6875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if TCG_TARGET_REG_BITS < 64 6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sizemask & 1) { 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_WORDS_BIGENDIAN 690975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = ret + 1; 691975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = ret; 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 693975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = ret; 694975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = ret + 1; 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_rets = 2; 6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else 6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 700975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = ret; 7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_rets = 1; 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_rets = 0; 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner real_args = 0; 7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (i = 0; i < nargs; i++) { 7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if TCG_TARGET_REG_BITS < 64 709f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner int is_64bit = sizemask & (1 << (i+1)*2); 710f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner if (is_64bit) { 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_CALL_ALIGN_ARGS 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* some targets want aligned 64 bit args */ 7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (real_args & 1) { 714975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG; 7155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner real_args++; 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 718f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner /* If stack grows up, then we will be placing successive 719f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner arguments at lower addresses, which means we need to 720f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner reverse the order compared to how we would normally 721f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner treat either big or little-endian. For those arguments 722f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner that will wind up in registers, this still works for 723f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner HPPA (the only current STACK_GROWSUP target) since the 724f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner argument registers are *also* allocated in decreasing 725f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner order. If another such target is added, this logic may 726f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner have to get more complicated to differentiate between 727f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner stack arguments and register arguments. */ 728f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP) 729975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = args[i] + 1; 730975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = args[i]; 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 732975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = args[i]; 733975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = args[i] + 1; 7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner real_args += 2; 736f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner continue; 737f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 738f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif /* TCG_TARGET_REG_BITS < 64 */ 739f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner 74086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *s->gen_opparam_ptr++ = args[i]; 74186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner real_args++; 74286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 743975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = GET_TCGV_PTR(func); 7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 745975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = flags; 7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *nparam = (nb_rets << 16) | (real_args + 1); 7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* total parameters, needed to go backward in the instruction stream */ 750975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner *s->gen_opparam_ptr++ = 1 + nb_rets + real_args + 3; 751f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner 752f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 753f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner for (i = 0; i < nargs; ++i) { 754f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner int is_64bit = sizemask & (1 << (i+1)*2); 755f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner if (!is_64bit) { 756f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner TCGv_i64 temp = MAKE_TCGV_I64(args[i]); 757f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner tcg_temp_free_i64(temp); 758f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 759f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 760f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner#endif /* TCG_TARGET_EXTEND_ARGS */ 7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TCG_TARGET_REG_BITS == 32 7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, 7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c, int right, int arith) 7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c == 0) { 7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); 7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); 7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (c >= 32) { 7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c -= 32; 7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (right) { 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arith) { 7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31); 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c); 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_movi_i32(TCGV_HIGH(ret), 0); 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c); 7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_movi_i32(TCGV_LOW(ret), 0); 7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner TCGv_i32 t0, t1; 7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t0 = tcg_temp_new_i32(); 7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t1 = tcg_temp_new_i32(); 7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (right) { 7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_shli_i32(t0, TCGV_HIGH(arg1), 32 - c); 7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arith) 7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_sari_i32(t1, TCGV_HIGH(arg1), c); 7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_shri_i32(t1, TCGV_HIGH(arg1), c); 7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c); 7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t0); 7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_mov_i32(TCGV_HIGH(ret), t1); 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c); 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Note: ret can be the same as arg1, so we use t1 */ 8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_shli_i32(t1, TCGV_LOW(arg1), c); 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c); 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0); 8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_gen_mov_i32(TCGV_LOW(ret), t1); 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_temp_free_i32(t0); 8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_temp_free_i32(t1); 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 81286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic inline TCGMemOp tcg_canonicalize_memop(TCGMemOp op, bool is64, bool st) 81386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 81486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner switch (op & MO_SIZE) { 81586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case MO_8: 81686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op &= ~MO_BSWAP; 81786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner break; 81886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case MO_16: 81986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner break; 82086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case MO_32: 82186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!is64) { 82286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op &= ~MO_SIGN; 82386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 82486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner break; 82586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case MO_64: 82686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!is64) { 82786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_abort(); 82886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 82986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner break; 83086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 83186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (st) { 83286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op &= ~MO_SIGN; 83386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 83486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return op; 83586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 83686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 83786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic const TCGOpcode old_ld_opc[8] = { 83886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_UB] = INDEX_op_qemu_ld8u, 83986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_SB] = INDEX_op_qemu_ld8s, 84086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_UW] = INDEX_op_qemu_ld16u, 84186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_SW] = INDEX_op_qemu_ld16s, 84286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#if TCG_TARGET_REG_BITS == 32 84386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_UL] = INDEX_op_qemu_ld32, 84486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_SL] = INDEX_op_qemu_ld32, 84586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#else 84686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_UL] = INDEX_op_qemu_ld32u, 84786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_SL] = INDEX_op_qemu_ld32s, 84886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 84986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_Q] = INDEX_op_qemu_ld64, 85086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner}; 85186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 85286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic const TCGOpcode old_st_opc[4] = { 85386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_UB] = INDEX_op_qemu_st8, 85486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_UW] = INDEX_op_qemu_st16, 85586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_UL] = INDEX_op_qemu_st32, 85686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_Q] = INDEX_op_qemu_st64, 85786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner}; 85886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 85986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop) 86086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 86186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memop = tcg_canonicalize_memop(memop, 0, 0); 86286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 86386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (TCG_TARGET_HAS_new_ldst) { 86486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i32; 86586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i32(val); 86686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 86786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = memop; 86886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 86986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return; 87086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 87186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 87286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The old opcodes only support target-endian memory operations. */ 87386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8); 87486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(old_ld_opc[memop & MO_SSIZE] != 0); 87586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 87686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (TCG_TARGET_REG_BITS == 32) { 87786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = old_ld_opc[memop & MO_SSIZE]; 87886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i32(val); 87986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 88086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 88186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 88286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner TCGv_i64 val64 = tcg_temp_new_i64(); 88386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 88486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = old_ld_opc[memop & MO_SSIZE]; 88586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i64(val64); 88686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 88786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 88886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 88986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_gen_trunc_i64_i32(val, val64); 89086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_temp_free_i64(val64); 89186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 89286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 89386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 89486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop) 89586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 89686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memop = tcg_canonicalize_memop(memop, 0, 1); 89786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 89886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (TCG_TARGET_HAS_new_ldst) { 89986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i32; 90086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i32(val); 90186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 90286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = memop; 90386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 90486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return; 90586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 90686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 90786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The old opcodes only support target-endian memory operations. */ 90886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8); 90986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(old_st_opc[memop & MO_SIZE] != 0); 91086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 91186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (TCG_TARGET_REG_BITS == 32) { 91286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = old_st_opc[memop & MO_SIZE]; 91386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i32(val); 91486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 91586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 91686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 91786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner TCGv_i64 val64 = tcg_temp_new_i64(); 91886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 91986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_gen_extu_i32_i64(val64, val); 92086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 92186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = old_st_opc[memop & MO_SIZE]; 92286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i64(val64); 92386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 92486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 92586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 92686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_temp_free_i64(val64); 92786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 92886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 92986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 93086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop) 93186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 93286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memop = tcg_canonicalize_memop(memop, 1, 0); 93386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 93486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#if TCG_TARGET_REG_BITS == 32 93586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if ((memop & MO_SIZE) < MO_64) { 93686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop); 93786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (memop & MO_SIGN) { 93886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_gen_sari_i32(TCGV_HIGH(val), TCGV_LOW(val), 31); 93986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 94086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_gen_movi_i32(TCGV_HIGH(val), 0); 94186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 94286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return; 94386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 94486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 94586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 94686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (TCG_TARGET_HAS_new_ldst) { 94786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_ld_i64; 94886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i64(val); 94986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 95086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = memop; 95186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 95286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return; 95386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 95486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 95586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The old opcodes only support target-endian memory operations. */ 95686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8); 95786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(old_ld_opc[memop & MO_SSIZE] != 0); 95886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 95986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = old_ld_opc[memop & MO_SSIZE]; 96086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i64(val); 96186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 96286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 96386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 96486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 96586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop) 96686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 96786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memop = tcg_canonicalize_memop(memop, 1, 1); 96886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 96986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#if TCG_TARGET_REG_BITS == 32 97086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if ((memop & MO_SIZE) < MO_64) { 97186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop); 97286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return; 97386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 97486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 97586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 97686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (TCG_TARGET_HAS_new_ldst) { 97786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = INDEX_op_qemu_st_i64; 97886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i64(val); 97986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 98086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = memop; 98186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 98286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return; 98386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 98486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 98586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The old opcodes only support target-endian memory operations. */ 98686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert((memop & MO_BSWAP) == MO_TE || (memop & MO_SIZE) == MO_8); 98786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(old_st_opc[memop & MO_SIZE] != 0); 98886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 98986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opc_ptr++ = old_st_opc[memop & MO_SIZE]; 99086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_i64(val); 99186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_add_param_tl(addr); 99286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *tcg_ctx.gen_opparam_ptr++ = idx; 99386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 994f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_start(TCGContext *s) 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < s->nb_globals; i++) { 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[i]; 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->fixed_reg) { 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->val_type = TEMP_VAL_REG; 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->val_type = TEMP_VAL_MEM; 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = s->nb_globals; i < s->nb_temps; i++) { 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[i]; 100986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (ts->temp_local) { 101086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->val_type = TEMP_VAL_MEM; 101186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 101286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->val_type = TEMP_VAL_DEAD; 101386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_allocated = 0; 10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->fixed_reg = 0; 10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < TCG_TARGET_NB_REGS; i++) { 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reg_to_temp[i] = -1; 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size, 10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int idx) 10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 102786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(idx >= 0 && idx < s->nb_temps); 10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[idx]; 10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (idx < s->nb_globals) { 10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pstrcpy(buf, buf_size, ts->name); 10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 103286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (ts->temp_local) 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, "loc%d", idx - s->nb_globals); 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals); 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg) 10415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 10425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg)); 10435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 10445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg) 10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg)); 10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 105086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* Find helper name. */ 10519142071536d74f1b8370f79851c9c2ca92496628David 'Digit' Turnerstatic inline const char *tcg_find_helper(TCGContext *s, uintptr_t val) 10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10539142071536d74f1b8370f79851c9c2ca92496628David 'Digit' Turner const char *ret = NULL; 10549142071536d74f1b8370f79851c9c2ca92496628David 'Digit' Turner if (s->helpers) { 10559142071536d74f1b8370f79851c9c2ca92496628David 'Digit' Turner ret = g_hash_table_lookup(s->helpers, (gpointer)val); 10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10579142071536d74f1b8370f79851c9c2ca92496628David 'Digit' Turner return ret; 10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char * const cond_name[] = 10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 106286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [TCG_COND_NEVER] = "never", 106386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [TCG_COND_ALWAYS] = "always", 10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_EQ] = "eq", 10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_NE] = "ne", 10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_LT] = "lt", 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_GE] = "ge", 10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_LE] = "le", 10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_GT] = "gt", 10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_LTU] = "ltu", 10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_GEU] = "geu", 10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_LEU] = "leu", 10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [TCG_COND_GTU] = "gtu" 10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 107686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic const char * const ldst_name[] = 107786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 107886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_UB] = "ub", 107986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_SB] = "sb", 108086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_LEUW] = "leuw", 108186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_LESW] = "lesw", 108286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_LEUL] = "leul", 108386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_LESL] = "lesl", 108486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_LEQ] = "leq", 108586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_BEUW] = "beuw", 108686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_BESW] = "besw", 108786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_BEUL] = "beul", 108886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_BESL] = "besl", 108986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [MO_BEQ] = "beq", 109086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner}; 109186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 109286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid tcg_dump_ops(TCGContext *s) 10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint16_t *opc_ptr; 10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const TCGArg *args; 10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGArg arg; 1097f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner TCGOpcode c; 1098f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn; 10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const TCGOpDef *def; 11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf[128]; 11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project first_insn = 1; 1103975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner opc_ptr = s->gen_opc_buf; 1104975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner args = s->gen_opparam_buf; 1105975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner while (opc_ptr < s->gen_opc_ptr) { 11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = *opc_ptr++; 11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def = &tcg_op_defs[c]; 11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c == INDEX_op_debug_insn_start) { 11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint64_t pc; 11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS 11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = ((uint64_t)args[1] << 32) | args[0]; 11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = args[0]; 11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 111586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!first_insn) { 111686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("\n"); 111786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 111886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(" ---- 0x%" PRIx64, pc); 11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project first_insn = 0; 11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_oargs = def->nb_oargs; 11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_iargs = def->nb_iargs; 11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_cargs = def->nb_cargs; 11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (c == INDEX_op_call) { 11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGArg arg; 11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* variable number of arguments */ 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = *args++; 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_oargs = arg >> 16; 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_iargs = arg & 0xffff; 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_cargs = def->nb_cargs; 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 113286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(" %s ", def->name); 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* function name */ 113586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("%s", 113686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_get_arg_str_idx(s, buf, sizeof(buf), 113786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[nb_oargs + nb_iargs - 1])); 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* flags */ 113986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(",$0x%" TCG_PRIlx, args[nb_oargs + nb_iargs]); 11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* nb out args */ 114186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(",$%d", nb_oargs); 11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < nb_oargs; i++) { 114386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(","); 114486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), 114586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[i])); 11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < (nb_iargs - 1); i++) { 114886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(","); 11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (args[nb_oargs + i] == TCG_CALL_DUMMY_ARG) { 115086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("<dummy>"); 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 115286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), 115386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[nb_oargs + i])); 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 115686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) { 11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_target_ulong val; 11589142071536d74f1b8370f79851c9c2ca92496628David 'Digit' Turner const char *name; 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_oargs = def->nb_oargs; 11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_iargs = def->nb_iargs; 11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_cargs = def->nb_cargs; 116386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(" %s %s,$", def->name, 116486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0])); 11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project val = args[1]; 11669142071536d74f1b8370f79851c9c2ca92496628David 'Digit' Turner name = tcg_find_helper(s, val); 11679142071536d74f1b8370f79851c9c2ca92496628David 'Digit' Turner if (name) { 116886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("%s", name); 11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 117086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (c == INDEX_op_movi_i32) { 117186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("0x%x", (uint32_t)val); 117286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 117386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("0x%" PRIx64 , (uint64_t)val); 117486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 117786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(" %s ", def->name); 11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c == INDEX_op_nopn) { 11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* variable number of arguments */ 11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_cargs = *args; 11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_oargs = 0; 11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_iargs = 0; 11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_oargs = def->nb_oargs; 11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_iargs = def->nb_iargs; 11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_cargs = def->nb_cargs; 11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 118886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project k = 0; 11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < nb_oargs; i++) { 119186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (k != 0) { 119286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(","); 119386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 119486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), 119586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[k++])); 11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < nb_iargs; i++) { 119886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (k != 0) { 119986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(","); 120086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 120186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), 120286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[k++])); 12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1204b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner switch (c) { 1205b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner case INDEX_op_brcond_i32: 1206b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner case INDEX_op_setcond_i32: 120786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_movcond_i32: 120886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_brcond2_i32: 1209b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner case INDEX_op_setcond2_i32: 121086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_brcond_i64: 1211b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner case INDEX_op_setcond_i64: 121286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_movcond_i64: 121386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) { 121486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(",%s", cond_name[args[k++]]); 121586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 121686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(",$0x%" TCG_PRIlx, args[k++]); 121786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 121886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner i = 1; 121986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner break; 122086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_qemu_ld_i32: 122186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_qemu_st_i32: 122286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_qemu_ld_i64: 122386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_qemu_st_i64: 122486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (args[k] < ARRAY_SIZE(ldst_name) && ldst_name[args[k]]) { 122586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(",%s", ldst_name[args[k++]]); 122686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 122786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(",$0x%" TCG_PRIlx, args[k++]); 122886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = 1; 1230b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner break; 1231b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner default: 12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = 0; 1233b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner break; 1234b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner } 12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(; i < nb_cargs; i++) { 123686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (k != 0) { 123786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log(","); 123886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = args[k++]; 124086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("$0x%" TCG_PRIlx, arg); 12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 124386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("\n"); 12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args += nb_iargs + nb_oargs + nb_cargs; 12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* we give more priority to constraints with less registers */ 12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_constraint_priority(const TCGOpDef *def, int k) 12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const TCGArgConstraint *arg_ct; 12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i, n; 12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg_ct = &def->args_ct[k]; 12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arg_ct->ct & TCG_CT_ALIAS) { 12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* an alias is equivalent to a single register */ 12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = 1; 12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(arg_ct->ct & TCG_CT_REG)) 12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = 0; 12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < TCG_TARGET_NB_REGS; i++) { 12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcg_regset_test_reg(arg_ct->u.regs, i)) 12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n++; 12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return TCG_TARGET_NB_REGS - n + 1; 12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sort from highest priority to lowest */ 12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void sort_constraints(TCGOpDef *def, int start, int n) 12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i, j, p1, p2, tmp; 12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < n; i++) 12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->sorted_args[start + i] = start + i; 12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n <= 1) 12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < n - 1; i++) { 12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(j = i + 1; j < n; j++) { 12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p1 = get_constraint_priority(def, def->sorted_args[start + i]); 12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p2 = get_constraint_priority(def, def->sorted_args[start + j]); 12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p1 < p2) { 12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = def->sorted_args[start + i]; 12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->sorted_args[start + i] = def->sorted_args[start + j]; 12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->sorted_args[start + j] = tmp; 12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs) 12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1294f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner TCGOpcode op; 12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGOpDef *def; 12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *ct_str; 12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i, nb_args; 12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;) { 1300f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner if (tdefs->op == (TCGOpcode)-1) 13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op = tdefs->op; 1303f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner assert((unsigned)op < NB_OPS); 13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def = &tcg_op_defs[op]; 1305b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG) 1306b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner /* Duplicate entry in op definitions? */ 1307b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner assert(!def->used); 1308b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner def->used = 1; 1309b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif 13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_args = def->nb_iargs + def->nb_oargs; 13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < nb_args; i++) { 13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ct_str = tdefs->args_ct_str[i]; 1313b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner /* Incomplete TCGTargetOpDef entry? */ 1314b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner assert(ct_str != NULL); 13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_clear(def->args_ct[i].u.regs); 13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->args_ct[i].ct = 0; 13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ct_str[0] >= '0' && ct_str[0] <= '9') { 13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int oarg; 13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oarg = ct_str[0] - '0'; 13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project assert(oarg < def->nb_oargs); 13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project assert(def->args_ct[oarg].ct & TCG_CT_REG); 13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* TCG_CT_ALIAS is for the output arguments. The input 13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project argument is tagged with TCG_CT_IALIAS. */ 13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->args_ct[i] = def->args_ct[oarg]; 13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->args_ct[oarg].ct = TCG_CT_ALIAS; 13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->args_ct[oarg].alias_index = i; 13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->args_ct[i].ct |= TCG_CT_IALIAS; 13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->args_ct[i].alias_index = oarg; 13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;) { 13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*ct_str == '\0') 13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(*ct_str) { 13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 'i': 13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->args_ct[i].ct |= TCG_CT_CONST; 13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ct_str++; 13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) { 13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n", 13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ct_str, i, def->name); 13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project exit(1); 13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1349b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner /* TCGTargetOpDef entry with too much information? */ 1350b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner assert(i == TCG_MAX_OP_ARGS || tdefs->args_ct_str[i] == NULL); 1351b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner 13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* sort the constraints (XXX: this is just an heuristic) */ 13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sort_constraints(def, 0, def->nb_oargs); 13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sort_constraints(def, def->nb_oargs, def->nb_iargs); 13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("%s: sorted=", def->name); 13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < def->nb_oargs + def->nb_iargs; i++) 13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf(" %d", def->sorted_args[i]); 13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("\n"); 13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tdefs++; 13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1369b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#if defined(CONFIG_DEBUG_TCG) 1370f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner i = 0; 1371b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) { 137286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const TCGOpDef *def = &tcg_op_defs[op]; 137386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (def->flags & TCG_OPF_NOT_PRESENT) { 1374b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner /* Wrong entry in op definitions? */ 137586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (def->used) { 137686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner fprintf(stderr, "Invalid op definition for %s\n", def->name); 1377f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner i = 1; 1378f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 1379b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner } else { 1380b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner /* Missing entry in op definitions? */ 138186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!def->used) { 138286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner fprintf(stderr, "Missing op definition for %s\n", def->name); 1383f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner i = 1; 138486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 1385b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner } 1386b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner } 1387f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner if (i == 1) { 1388f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner tcg_abort(); 1389f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner } 1390b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner#endif 13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef USE_LIVENESS_ANALYSIS 13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* set a nop for an operation using 'nb_args' */ 139686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr, 13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGArg *args, int nb_args) 13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nb_args == 0) { 14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *opc_ptr = INDEX_op_nop; 14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *opc_ptr = INDEX_op_nopn; 14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args[0] = nb_args; 14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args[nb_args - 1] = nb_args; 14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 140886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* liveness analysis: end of function: all temps are dead, and globals 140986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner should be in memory. */ 141086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps, 141186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t *mem_temps) 14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 141386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(dead_temps, 1, s->nb_temps); 141486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(mem_temps, 1, s->nb_globals); 141586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(mem_temps + s->nb_globals, 0, s->nb_temps - s->nb_globals); 14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 141886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* liveness analysis: end of basic block: all temps are dead, globals 141986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner and local temps should be in memory. */ 142086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps, 142186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t *mem_temps) 14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 142586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(dead_temps, 1, s->nb_temps); 142686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(mem_temps, 1, s->nb_globals); 14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = s->nb_globals; i < s->nb_temps; i++) { 142886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner mem_temps[i] = s->temps[i].temp_local; 14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 143253a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner/* Liveness analysis : update the opc_dead_args array to tell if a 14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project given input arguments is dead. Instructions updating dead 14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temporaries are removed. */ 14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_liveness_analysis(TCGContext *s) 14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1437f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops; 143886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner TCGOpcode op, op_new, op_new2; 14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGArg *args; 14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const TCGOpDef *def; 144186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t *dead_temps, *mem_temps; 144286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint16_t dead_args; 144386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t sync_args; 144486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner bool have_op_new2; 144586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 1446975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner s->gen_opc_ptr++; /* skip end */ 14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1448975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner nb_ops = s->gen_opc_ptr - s->gen_opc_buf; 14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 145053a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t)); 145186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t)); 145286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dead_temps = tcg_malloc(s->nb_temps); 145486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner mem_temps = tcg_malloc(s->nb_temps); 145586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_la_func_end(s, dead_temps, mem_temps); 14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1457975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner args = s->gen_opparam_ptr; 14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op_index = nb_ops - 1; 14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (op_index >= 0) { 1460975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner op = s->gen_opc_buf[op_index]; 14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def = &tcg_op_defs[op]; 14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(op) { 14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_call: 14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int call_flags; 14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_args = args[-1]; 14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args -= nb_args; 14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_iargs = args[0] & 0xffff; 14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_oargs = args[0] >> 16; 14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args++; 14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call_flags = args[nb_oargs + nb_iargs]; 14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* pure functions can be removed if their result is not 14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project used */ 147686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (call_flags & TCG_CALL_NO_SIDE_EFFECTS) { 14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < nb_oargs; i++) { 14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = args[i]; 147986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!dead_temps[arg] || mem_temps[arg]) { 14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_not_remove_call; 148186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1483975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner tcg_set_nop(s, s->gen_opc_buf + op_index, 14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args - 1, nb_args); 14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do_not_remove_call: 14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* output args are dead */ 14899bf492c3fedbd13ee0e2af94424c8bf48cb2fec5David 'Digit' Turner dead_args = 0; 149086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner sync_args = 0; 14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < nb_oargs; i++) { 14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = args[i]; 14939bf492c3fedbd13ee0e2af94424c8bf48cb2fec5David 'Digit' Turner if (dead_temps[arg]) { 14949bf492c3fedbd13ee0e2af94424c8bf48cb2fec5David 'Digit' Turner dead_args |= (1 << i); 14959bf492c3fedbd13ee0e2af94424c8bf48cb2fec5David 'Digit' Turner } 149686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (mem_temps[arg]) { 149786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner sync_args |= (1 << i); 149886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 149986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner dead_temps[arg] = 1; 150086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner mem_temps[arg] = 0; 15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1502c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner 150386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!(call_flags & TCG_CALL_NO_READ_GLOBALS)) { 150486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* globals should be synced to memory */ 150586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(mem_temps, 1, s->nb_globals); 150686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 150786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!(call_flags & (TCG_CALL_NO_WRITE_GLOBALS | 150886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner TCG_CALL_NO_READ_GLOBALS))) { 150986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* globals should go back to memory */ 151086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(dead_temps, 1, s->nb_globals); 15115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 15125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* input args are live */ 151453a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 151553a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner arg = args[i]; 15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arg != TCG_CALL_DUMMY_ARG) { 15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dead_temps[arg]) { 151853a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner dead_args |= (1 << i); 15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dead_temps[arg] = 0; 15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 152353a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner s->op_dead_args[op_index] = dead_args; 152486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->op_sync_args[op_index] = sync_args; 15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args--; 15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_debug_insn_start: 15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args -= def->nb_args; 15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_nopn: 15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_args = args[-1]; 15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args -= nb_args; 15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_discard: 15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args--; 15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* mark the temporary as dead */ 15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dead_temps[args[0]] = 1; 154086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner mem_temps[args[0]] = 0; 15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_end: 15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 154486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 154586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_add2_i32: 154686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new = INDEX_op_add_i32; 154786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_addsub2; 154886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_sub2_i32: 154986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new = INDEX_op_sub_i32; 155086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_addsub2; 155186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_add2_i64: 155286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new = INDEX_op_add_i64; 155386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_addsub2; 155486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_sub2_i64: 155586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new = INDEX_op_sub_i64; 155686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner do_addsub2: 155786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args -= 6; 155886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner nb_iargs = 4; 155986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner nb_oargs = 2; 156086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Test if the high part of the operation is dead, but not 156186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner the low part. The result can be optimized to a simple 156286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner add or sub. This happens often for x86_64 guest when the 156386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu mode is set to 32 bit. */ 156486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (dead_temps[args[1]] && !mem_temps[args[1]]) { 156586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (dead_temps[args[0]] && !mem_temps[args[0]]) { 156686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_remove; 156786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 156886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Create the single operation plus nop. */ 156986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->gen_opc_buf[op_index] = op = op_new; 157086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[1] = args[2]; 157186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[2] = args[4]; 157286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop); 157386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 3); 157486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Fall through and mark the single-word operation live. */ 157586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner nb_iargs = 2; 157686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner nb_oargs = 1; 157786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 157886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_not_remove; 157986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 158086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_mulu2_i32: 158186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new = INDEX_op_mul_i32; 158286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new2 = INDEX_op_muluh_i32; 158386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner have_op_new2 = TCG_TARGET_HAS_muluh_i32; 158486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_mul2; 158586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_muls2_i32: 158686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new = INDEX_op_mul_i32; 158786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new2 = INDEX_op_mulsh_i32; 158886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner have_op_new2 = TCG_TARGET_HAS_mulsh_i32; 158986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_mul2; 159086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_mulu2_i64: 159186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new = INDEX_op_mul_i64; 159286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new2 = INDEX_op_muluh_i64; 159386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner have_op_new2 = TCG_TARGET_HAS_muluh_i64; 159486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_mul2; 159586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case INDEX_op_muls2_i64: 159686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new = INDEX_op_mul_i64; 159786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner op_new2 = INDEX_op_mulsh_i64; 159886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner have_op_new2 = TCG_TARGET_HAS_mulsh_i64; 159986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_mul2; 160086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner do_mul2: 160186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args -= 4; 160286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner nb_iargs = 2; 160386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner nb_oargs = 2; 160486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (dead_temps[args[1]] && !mem_temps[args[1]]) { 160586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (dead_temps[args[0]] && !mem_temps[args[0]]) { 160686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Both parts of the operation are dead. */ 160786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_remove; 160886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 160986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The high part of the operation is dead; generate the low. */ 161086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->gen_opc_buf[op_index] = op = op_new; 161186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[1] = args[2]; 161286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[2] = args[3]; 161386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else if (have_op_new2 && dead_temps[args[0]] 161486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner && !mem_temps[args[0]]) { 161586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The low part of the operation is dead; generate the high. */ 161686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->gen_opc_buf[op_index] = op = op_new2; 161786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[0] = args[1]; 161886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[1] = args[2]; 161986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args[2] = args[3]; 162086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 162186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_not_remove; 162286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 162386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop); 162486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1); 162586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Mark the single-word operation live. */ 162686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner nb_oargs = 1; 162786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner goto do_not_remove; 162886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 163086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */ 16315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner args -= def->nb_args; 16325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_iargs = def->nb_iargs; 16335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nb_oargs = def->nb_oargs; 16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Test if the operation can be removed because all 16365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner its outputs are dead. We assume that nb_oargs == 0 16375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner implies side effects */ 16385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) { 16395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < nb_oargs; i++) { 16405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner arg = args[i]; 164186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!dead_temps[arg] || mem_temps[arg]) { 16425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto do_not_remove; 164386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 16445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 164586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner do_remove: 1646975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args); 16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER 16485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->del_op_count++; 16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 16505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 16515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner do_not_remove: 16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* output args are dead */ 16549bf492c3fedbd13ee0e2af94424c8bf48cb2fec5David 'Digit' Turner dead_args = 0; 165586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner sync_args = 0; 16565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for(i = 0; i < nb_oargs; i++) { 16575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner arg = args[i]; 16589bf492c3fedbd13ee0e2af94424c8bf48cb2fec5David 'Digit' Turner if (dead_temps[arg]) { 16599bf492c3fedbd13ee0e2af94424c8bf48cb2fec5David 'Digit' Turner dead_args |= (1 << i); 16609bf492c3fedbd13ee0e2af94424c8bf48cb2fec5David 'Digit' Turner } 166186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (mem_temps[arg]) { 166286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner sync_args |= (1 << i); 166386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 166486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner dead_temps[arg] = 1; 166586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner mem_temps[arg] = 0; 16665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 16675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 16685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* if end of basic block, update */ 16695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (def->flags & TCG_OPF_BB_END) { 167086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_la_bb_end(s, dead_temps, mem_temps); 167186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else if (def->flags & TCG_OPF_SIDE_EFFECTS) { 167286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* globals should be synced to memory */ 167386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(mem_temps, 1, s->nb_globals); 16745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 16755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 16765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* input args are live */ 167753a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 167853a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner arg = args[i]; 16795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (dead_temps[arg]) { 168053a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner dead_args |= (1 << i); 16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dead_temps[arg] = 0; 16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 168453a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner s->op_dead_args[op_index] = dead_args; 168586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->op_sync_args[op_index] = sync_args; 16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op_index--; 16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 169286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (args != s->gen_opparam_buf) { 16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 169486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* dummy liveness analysis */ 1698f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void tcg_liveness_analysis(TCGContext *s) 16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nb_ops; 1701975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner nb_ops = s->gen_opc_ptr - s->gen_opc_buf; 17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 170353a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t)); 170453a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t)); 170586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t)); 170686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memset(s->op_sync_args, 0, nb_ops * sizeof(uint8_t)); 17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef NDEBUG 17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void dump_regs(TCGContext *s) 17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf[64]; 17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < s->nb_temps; i++) { 17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[i]; 17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf(" %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i)); 17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(ts->val_type) { 17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TEMP_VAL_REG: 17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("%s", tcg_target_reg_names[ts->reg]); 17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TEMP_VAL_MEM: 17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("%d(%s)", (int)ts->mem_offset, tcg_target_reg_names[ts->mem_reg]); 17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TEMP_VAL_CONST: 17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("$0x%" TCG_PRIlx, ts->val); 17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TEMP_VAL_DEAD: 17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("D"); 17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("???"); 17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("\n"); 17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < TCG_TARGET_NB_REGS; i++) { 17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->reg_to_temp[i] >= 0) { 174286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner printf("%s: %s\n", 174386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_target_reg_names[i], 17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_get_arg_str_idx(s, buf, sizeof(buf), s->reg_to_temp[i])); 17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void check_regs(TCGContext *s) 17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int reg, k; 17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf[64]; 17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) { 17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project k = s->reg_to_temp[reg]; 17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (k >= 0) { 17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[k]; 17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->val_type != TEMP_VAL_REG || 17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->reg != reg) { 176186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner printf("Inconsistency for register %s:\n", 17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_target_reg_names[reg]); 17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto fail; 17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(k = 0; k < s->nb_temps; k++) { 17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[k]; 17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->val_type == TEMP_VAL_REG && 17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project !ts->fixed_reg && 17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reg_to_temp[ts->reg] != k) { 177286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner printf("Inconsistency for temp %s:\n", 17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_get_arg_str_idx(s, buf, sizeof(buf), k)); 17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fail: 17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("reg state:\n"); 17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dump_regs(s); 17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 17828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void temp_allocate_frame(TCGContext *s, int temp) 17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[temp]; 178786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64) 178886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Sparc64 stack is accessed with offset of 2047 */ 17896b1f7efc7fd26332676d7626f7f139f5b98b756cDavid 'Digit' Turner s->current_frame_offset = (s->current_frame_offset + 17906b1f7efc7fd26332676d7626f7f139f5b98b756cDavid 'Digit' Turner (tcg_target_long)sizeof(tcg_target_long) - 1) & 17916b1f7efc7fd26332676d7626f7f139f5b98b756cDavid 'Digit' Turner ~(sizeof(tcg_target_long) - 1); 17922e787a1d54ea4a34a6b75dcffe7dc9fa3aecb83fDavid 'Digit' Turner#endif 17936b1f7efc7fd26332676d7626f7f139f5b98b756cDavid 'Digit' Turner if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) > 17946b1f7efc7fd26332676d7626f7f139f5b98b756cDavid 'Digit' Turner s->frame_end) { 17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 17966b1f7efc7fd26332676d7626f7f139f5b98b756cDavid 'Digit' Turner } 17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_offset = s->current_frame_offset; 17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_reg = s->frame_reg; 17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_allocated = 1; 180086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->current_frame_offset += sizeof(tcg_target_long); 180186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 180286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 180386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* sync register 'reg' by saving it to the corresponding temporary */ 180486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic inline void tcg_reg_sync(TCGContext *s, int reg) 180586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 180686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner TCGTemp *ts; 180786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner int temp; 180886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 180986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp = s->reg_to_temp[reg]; 181086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts = &s->temps[temp]; 181186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(ts->val_type == TEMP_VAL_REG); 181286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!ts->mem_coherent && !ts->fixed_reg) { 181386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!ts->mem_allocated) { 181486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_allocate_frame(s, temp); 181586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 181686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset); 181786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 181886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->mem_coherent = 1; 18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* free register 'reg' by spilling the corresponding temporary if necessary */ 18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_free(TCGContext *s, int reg) 18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int temp; 18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temp = s->reg_to_temp[reg]; 18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (temp != -1) { 182886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_reg_sync(s, reg); 182986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->temps[temp].val_type = TEMP_VAL_MEM; 18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reg_to_temp[reg] = -1; 18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Allocate a register belonging to reg1 & ~reg2 */ 18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2) 18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i, reg; 18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGRegSet reg_ct; 18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_andnot(reg_ct, reg1, reg2); 18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* first try free registers */ 18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) { 18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_target_reg_alloc_order[i]; 18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcg_regset_test_reg(reg_ct, reg) && s->reg_to_temp[reg] == -1) 18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return reg; 18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX: do better spill choice */ 18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < ARRAY_SIZE(tcg_target_reg_alloc_order); i++) { 18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_target_reg_alloc_order[i]; 18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcg_regset_test_reg(reg_ct, reg)) { 18538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_reg_free(s, reg); 18548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return reg; 18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 186186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* mark a temporary as dead. */ 186286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic inline void temp_dead(TCGContext *s, int temp) 186386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 186486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner TCGTemp *ts; 186586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 186686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts = &s->temps[temp]; 186786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!ts->fixed_reg) { 186886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (ts->val_type == TEMP_VAL_REG) { 186986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->reg_to_temp[ts->reg] = -1; 187086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 187186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (temp < s->nb_globals || ts->temp_local) { 187286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->val_type = TEMP_VAL_MEM; 187386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 187486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->val_type = TEMP_VAL_DEAD; 187586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 187686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 187786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 187886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 187986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* sync a temporary to memory. 'allocated_regs' is used in case a 18808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temporary registers needs to be allocated to store a constant. */ 188186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic inline void temp_sync(TCGContext *s, int temp, TCGRegSet allocated_regs) 18828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 18838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 18848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[temp]; 18868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!ts->fixed_reg) { 18878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(ts->val_type) { 188886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner case TEMP_VAL_CONST: 188986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 189086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner allocated_regs); 189186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->val_type = TEMP_VAL_REG; 189286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->reg_to_temp[ts->reg] = temp; 189386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->mem_coherent = 0; 189486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_out_movi(s, ts->type, ts->reg, ts->val); 189586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* fallthrough*/ 18968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TEMP_VAL_REG: 189786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_reg_sync(s, ts->reg); 18988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 18998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TEMP_VAL_DEAD: 19008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TEMP_VAL_MEM: 19018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 19038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 19048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 19078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 190886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* save a temporary to memory. 'allocated_regs' is used in case a 190986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temporary registers needs to be allocated to store a constant. */ 191086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic inline void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs) 191186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 191286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef USE_LIVENESS_ANALYSIS 191386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The liveness analysis already ensures that globals are back 191486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner in memory. Keep an assert for safety. */ 191586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(s->temps[temp].val_type == TEMP_VAL_MEM || s->temps[temp].fixed_reg); 191686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#else 191786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_sync(s, temp, allocated_regs); 191886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, temp); 191986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 192086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 192186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 192286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* save globals to their canonical location and assume they can be 19238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project modified be the following code. 'allocated_regs' is used in case a 19248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temporary registers needs to be allocated to store a constant. */ 19258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void save_globals(TCGContext *s, TCGRegSet allocated_regs) 19268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 19278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 19288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < s->nb_globals; i++) { 19308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temp_save(s, i, allocated_regs); 19318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 19338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 193486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* sync globals to their canonical location and assume they can be 193586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner read by the following code. 'allocated_regs' is used in case a 193686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temporary registers needs to be allocated to store a constant. */ 193786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void sync_globals(TCGContext *s, TCGRegSet allocated_regs) 193886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 193986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner int i; 194086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 194186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner for (i = 0; i < s->nb_globals; i++) { 194286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef USE_LIVENESS_ANALYSIS 194386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(s->temps[i].val_type != TEMP_VAL_REG || s->temps[i].fixed_reg || 194486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->temps[i].mem_coherent); 194586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#else 194686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_sync(s, i, allocated_regs); 194786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 194886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 194986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 195086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* at the end of a basic block, we assume all temporaries are dead and 19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project all globals are stored at their canonical location. */ 19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs) 19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 19568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 19578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = s->nb_globals; i < s->nb_temps; i++) { 19598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[i]; 19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->temp_local) { 19618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temp_save(s, i, allocated_regs); 19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 196386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef USE_LIVENESS_ANALYSIS 196486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The liveness analysis already ensures that temps are dead. 196586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner Keep an assert for safety. */ 196686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(ts->val_type == TEMP_VAL_DEAD); 196786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#else 196886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, i); 196986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project save_globals(s, allocated_regs); 19748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 197653a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1) 197786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#define NEED_SYNC_ARG(n) ((sync_args >> (n)) & 1) 19788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 197986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args, 198086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint16_t dead_args, uint8_t sync_args) 19818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 19828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ots; 19838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_target_ulong val; 19848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ots = &s->temps[args[0]]; 19868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project val = args[1]; 19878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ots->fixed_reg) { 19898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* for fixed registers, we do not do any constant 19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project propagation */ 19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_movi(s, ots->type, ots->reg, val); 19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* The movi is not explicitly generated here */ 19948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ots->val_type == TEMP_VAL_REG) 19958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reg_to_temp[ots->reg] = -1; 19968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ots->val_type = TEMP_VAL_CONST; 19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ots->val = val; 19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 199986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (NEED_SYNC_ARG(0)) { 200086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_sync(s, args[0], s->reserved_regs); 200186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 200286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (IS_DEAD_ARG(0)) { 200386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, args[0]); 200486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 20068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, 200886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const TCGArg *args, uint16_t dead_args, 200986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t sync_args) 20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 201186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner TCGRegSet allocated_regs; 20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts, *ots; 201386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const TCGArgConstraint *arg_ct, *oarg_ct; 20148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 201586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_regset_set(allocated_regs, s->reserved_regs); 20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ots = &s->temps[args[0]]; 20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[args[1]]; 201886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner oarg_ct = &def->args_ct[0]; 201986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner arg_ct = &def->args_ct[1]; 202086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 202186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* If the source value is not in a register, and we're going to be 202286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner forced to have it in a register in order to perform the copy, 202386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner then copy the SOURCE value into its own register first. That way 202486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner we don't have to reload SOURCE the next time it is used. */ 202586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (((NEED_SYNC_ARG(0) || ots->fixed_reg) && ts->val_type != TEMP_VAL_REG) 202686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner || ts->val_type == TEMP_VAL_MEM) { 202786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 202886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (ts->val_type == TEMP_VAL_MEM) { 202986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_out_ld(s, ts->type, ts->reg, ts->mem_reg, ts->mem_offset); 203086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->mem_coherent = 1; 203186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else if (ts->val_type == TEMP_VAL_CONST) { 203286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_out_movi(s, ts->type, ts->reg, ts->val); 203386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 203486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->reg_to_temp[ts->reg] = args[1]; 203586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->val_type = TEMP_VAL_REG; 203686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 20378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 203886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (IS_DEAD_ARG(0) && !ots->fixed_reg) { 203986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* mov to a non-saved dead register makes no sense (even with 204086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner liveness analysis disabled). */ 204186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(NEED_SYNC_ARG(0)); 204286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The code above should have moved the temp to a register. */ 204386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(ts->val_type == TEMP_VAL_REG); 204486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (!ots->mem_allocated) { 204586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_allocate_frame(s, args[0]); 204686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 204786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_out_st(s, ots->type, ts->reg, ots->mem_reg, ots->mem_offset); 204886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (IS_DEAD_ARG(1)) { 204986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, args[1]); 205086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 205186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, args[0]); 205286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else if (ts->val_type == TEMP_VAL_CONST) { 205386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* propagate constant */ 205486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (ots->val_type == TEMP_VAL_REG) { 205586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->reg_to_temp[ots->reg] = -1; 205686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 205786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ots->val_type = TEMP_VAL_CONST; 205886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ots->val = ts->val; 205986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 206086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* The code in the first if block should have moved the 206186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp to a register. */ 206286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner assert(ts->val_type == TEMP_VAL_REG); 206353a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) { 20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* the mov can be suppressed */ 20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ots->val_type == TEMP_VAL_REG) { 206686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->reg_to_temp[ots->reg] = -1; 20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 206886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ots->reg = ts->reg; 206986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, args[1]); 20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 207186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (ots->val_type != TEMP_VAL_REG) { 207286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* When allocating a new register, make sure to not spill the 207386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner input one. */ 207486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_regset_set_reg(allocated_regs, ts->reg); 207586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ots->reg = tcg_reg_alloc(s, oarg_ct->u.regs, allocated_regs); 207686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 207786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_out_mov(s, ots->type, ots->reg, ts->reg); 20788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 207986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ots->val_type = TEMP_VAL_REG; 208086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ots->mem_coherent = 0; 208186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->reg_to_temp[ots->reg] = args[0]; 208286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (NEED_SYNC_ARG(0)) { 208386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_reg_sync(s, ots->reg); 20848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 20878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 208886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_reg_alloc_op(TCGContext *s, 2089f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner const TCGOpDef *def, TCGOpcode opc, 209086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const TCGArg *args, uint16_t dead_args, 209186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t sync_args) 20928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 20938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGRegSet allocated_regs; 20948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i, k, nb_iargs, nb_oargs, reg; 20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGArg arg; 20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const TCGArgConstraint *arg_ct; 20978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGArg new_args[TCG_MAX_OP_ARGS]; 20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int const_args[TCG_MAX_OP_ARGS]; 21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_oargs = def->nb_oargs; 21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_iargs = def->nb_iargs; 21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* copy constants */ 210586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memcpy(new_args + nb_oargs + nb_iargs, 210686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args + nb_oargs + nb_iargs, 21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sizeof(TCGArg) * def->nb_cargs); 21088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 210986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* satisfy input constraints */ 21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set(allocated_regs, s->reserved_regs); 21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(k = 0; k < nb_iargs; k++) { 21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = def->sorted_args[nb_oargs + k]; 21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = args[i]; 21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg_ct = &def->args_ct[i]; 21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[arg]; 21168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->val_type == TEMP_VAL_MEM) { 21178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 21188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); 21198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->val_type = TEMP_VAL_REG; 21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->reg = reg; 21218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_coherent = 1; 21228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reg_to_temp[reg] = arg; 21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ts->val_type == TEMP_VAL_CONST) { 21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcg_target_const_match(ts->val, arg_ct)) { 21258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* constant is OK for instruction */ 21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const_args[i] = 1; 21278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_args[i] = ts->val; 21288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto iarg_end; 21298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 21308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* need to move to a register */ 21318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 21328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_movi(s, ts->type, reg, ts->val); 21338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->val_type = TEMP_VAL_REG; 21348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->reg = reg; 21358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->mem_coherent = 0; 21368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reg_to_temp[reg] = arg; 21378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project assert(ts->val_type == TEMP_VAL_REG); 21408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arg_ct->ct & TCG_CT_IALIAS) { 21418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->fixed_reg) { 21428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if fixed register, we must allocate a new register 21438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if the alias is not the same register */ 21448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arg != args[arg_ct->alias_index]) 21458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto allocate_in_reg; 21468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 21478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if the input is aliased to an output and if it is 21488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project not dead after the instruction, we must allocate 21498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a new register and move it */ 215053a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner if (!IS_DEAD_ARG(i)) { 21518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto allocate_in_reg; 215253a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner } 21538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = ts->reg; 21568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcg_regset_test_reg(arg_ct->u.regs, reg)) { 21578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* nothing to do : the constraint is satisfied */ 21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 21598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project allocate_in_reg: 216086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* allocate a new register matching the constraint 21618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project and move the temporary register into it */ 21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 2163f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner tcg_out_mov(s, ts->type, reg, ts->reg); 21648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_args[i] = reg; 21668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const_args[i] = 0; 21678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set_reg(allocated_regs, reg); 21688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iarg_end: ; 21698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 217086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 217186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* mark dead temporaries and free the associated registers */ 217286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) { 217386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (IS_DEAD_ARG(i)) { 217486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, args[i]); 217586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 217686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 21775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (def->flags & TCG_OPF_BB_END) { 21798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_reg_alloc_bb_end(s, allocated_regs); 21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 21818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (def->flags & TCG_OPF_CALL_CLOBBER) { 218286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* XXX: permit generic clobber register list ? */ 21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) { 21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) { 21858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_reg_free(s, reg); 21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 218986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (def->flags & TCG_OPF_SIDE_EFFECTS) { 219086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* sync globals if the op has side effects and might trigger 219186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner an exception. */ 219286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner sync_globals(s, allocated_regs); 219386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 219486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 21958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* satisfy the output constraints */ 21968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set(allocated_regs, s->reserved_regs); 21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(k = 0; k < nb_oargs; k++) { 21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = def->sorted_args[k]; 21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = args[i]; 22008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg_ct = &def->args_ct[i]; 22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[arg]; 22028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arg_ct->ct & TCG_CT_ALIAS) { 22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = new_args[arg_ct->alias_index]; 22048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 22058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if fixed register, we try to use it */ 22068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = ts->reg; 22078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->fixed_reg && 22088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_test_reg(arg_ct->u.regs, reg)) { 22098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto oarg_end; 22108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 22128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set_reg(allocated_regs, reg); 22148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if a fixed register is used, then a move will be done afterwards */ 22158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!ts->fixed_reg) { 221686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (ts->val_type == TEMP_VAL_REG) { 22178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reg_to_temp[ts->reg] = -1; 22180352ce4b5167ebc185bdec779e9642af75f1ccacDavid 'Digit' Turner } 221986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->val_type = TEMP_VAL_REG; 222086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->reg = reg; 222186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* temp value is modified, so the value kept in memory is 222286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner potentially not the same */ 222386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->mem_coherent = 0; 222486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->reg_to_temp[reg] = arg; 22258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oarg_end: 22278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_args[i] = reg; 22288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* emit instruction */ 22328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_op(s, opc, new_args, const_args); 223386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 22348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* move the outputs in the correct register if needed */ 22358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < nb_oargs; i++) { 22368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[args[i]]; 22378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = new_args[i]; 22388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->fixed_reg && ts->reg != reg) { 2239f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner tcg_out_mov(s, ts->type, ts->reg, reg); 22408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 224186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (NEED_SYNC_ARG(i)) { 224286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_reg_sync(s, reg); 224386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 224486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (IS_DEAD_ARG(i)) { 224586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, args[i]); 224686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 22478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 22498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_STACK_GROWSUP 22518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define STACK_DIR(x) (-(x)) 22528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 22538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define STACK_DIR(x) (x) 22548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 22558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, 2257f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner TCGOpcode opc, const TCGArg *args, 225886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint16_t dead_args, uint8_t sync_args) 22598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 22608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params; 22618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGArg arg, func_arg; 22628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGTemp *ts; 226386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner intptr_t stack_offset; 226486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner size_t call_stack_size; 226586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uintptr_t func_addr; 22668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int const_func_arg, allocate_args; 22678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGRegSet allocated_regs; 22688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const TCGArgConstraint *arg_ct; 22698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = *args++; 22718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_oargs = arg >> 16; 22738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_iargs = arg & 0xffff; 22748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_params = nb_iargs - 1; 22758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags = args[nb_oargs + nb_iargs]; 22778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 227886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs); 22798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nb_regs > nb_params) 22808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nb_regs = nb_params; 22818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* assign stack slots first */ 22838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long); 228486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 22858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ~(TCG_TARGET_STACK_ALIGN - 1); 22868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE); 22878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (allocate_args) { 228898c6a2d2a100cca93f5112ab0ef6d24e51f931f8David 'Digit' Turner /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed, 228998c6a2d2a100cca93f5112ab0ef6d24e51f931f8David 'Digit' Turner preallocate call stack */ 229098c6a2d2a100cca93f5112ab0ef6d24e51f931f8David 'Digit' Turner tcg_abort(); 22918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stack_offset = TCG_TARGET_CALL_STACK_OFFSET; 22948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = nb_regs; i < nb_params; i++) { 22958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = args[nb_oargs + i]; 22968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCG_TARGET_STACK_GROWSUP 22978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stack_offset -= sizeof(tcg_target_long); 22988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 22998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arg != TCG_CALL_DUMMY_ARG) { 23008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[arg]; 23018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->val_type == TEMP_VAL_REG) { 23028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset); 23038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ts->val_type == TEMP_VAL_MEM) { 230486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 23058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reserved_regs); 23068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX: not correct if reading values from the stack */ 23078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); 23088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset); 23098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ts->val_type == TEMP_VAL_CONST) { 231086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type], 23118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reserved_regs); 23128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX: sign extend may be needed on some targets */ 23138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_movi(s, ts->type, reg, ts->val); 23148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_st(s, ts->type, reg, TCG_REG_CALL_STACK, stack_offset); 23158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 23168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 23178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef TCG_TARGET_STACK_GROWSUP 23208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stack_offset += sizeof(tcg_target_long); 23218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 23228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 232386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 23248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* assign input registers */ 23258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set(allocated_regs, s->reserved_regs); 23268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < nb_regs; i++) { 23278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = args[nb_oargs + i]; 23288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arg != TCG_CALL_DUMMY_ARG) { 23298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[arg]; 23308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_target_call_iarg_regs[i]; 23318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_reg_free(s, reg); 23328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->val_type == TEMP_VAL_REG) { 23338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->reg != reg) { 2334f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner tcg_out_mov(s, ts->type, reg, ts->reg); 23358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ts->val_type == TEMP_VAL_MEM) { 23378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); 23388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ts->val_type == TEMP_VAL_CONST) { 23398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX: sign extend ? */ 23408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_movi(s, ts->type, reg, ts->val); 23418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 23428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 23438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set_reg(allocated_regs, reg); 23458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 234786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 23488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* assign function address */ 23498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project func_arg = args[nb_oargs + nb_iargs - 1]; 23508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg_ct = &def->args_ct[0]; 23518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[func_arg]; 23528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project func_addr = ts->val; 23538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const_func_arg = 0; 23548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->val_type == TEMP_VAL_MEM) { 23558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 23568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); 23578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project func_arg = reg; 23588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set_reg(allocated_regs, reg); 23598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ts->val_type == TEMP_VAL_REG) { 23608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = ts->reg; 23618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) { 23628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 2363f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner tcg_out_mov(s, ts->type, reg, ts->reg); 23648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project func_arg = reg; 23668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set_reg(allocated_regs, reg); 23678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (ts->val_type == TEMP_VAL_CONST) { 23688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcg_target_const_match(func_addr, arg_ct)) { 23698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const_func_arg = 1; 23708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project func_arg = func_addr; 23718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 23728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); 23738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_movi(s, ts->type, reg, func_addr); 23748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project func_arg = reg; 23758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_regset_set_reg(allocated_regs, reg); 23768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 23788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_abort(); 23798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 238086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 238186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 23828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* mark dead temporaries and free the associated registers */ 238386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) { 238453a08edf171bdbc7e3a2d89b78b96a33361a2760David 'Digit' Turner if (IS_DEAD_ARG(i)) { 238586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, args[i]); 23868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 238886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 23898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* clobber call registers */ 23908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) { 23918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) { 23928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_reg_free(s, reg); 23938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 239686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Save globals if they might be written by the helper, sync them if 239786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner they might be read. */ 239886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (flags & TCG_CALL_NO_READ_GLOBALS) { 239986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Nothing to do */ 240086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else if (flags & TCG_CALL_NO_WRITE_GLOBALS) { 240186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner sync_globals(s, allocated_regs); 240286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } else { 24035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner save_globals(s, allocated_regs); 24045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 24058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_out_op(s, opc, &func_arg, &const_func_arg); 24075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 24088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* assign output registers and emit moves if needed */ 24098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = 0; i < nb_oargs; i++) { 24108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arg = args[i]; 24118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts = &s->temps[arg]; 24128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project reg = tcg_target_call_oarg_regs[i]; 24138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project assert(s->reg_to_temp[reg] == -1); 24148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->fixed_reg) { 24158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ts->reg != reg) { 2416f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner tcg_out_mov(s, ts->type, ts->reg, reg); 24178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 241986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (ts->val_type == TEMP_VAL_REG) { 24208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->reg_to_temp[ts->reg] = -1; 242186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 242286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->val_type = TEMP_VAL_REG; 242386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->reg = reg; 242486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ts->mem_coherent = 0; 242586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->reg_to_temp[reg] = arg; 242686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (NEED_SYNC_ARG(i)) { 242786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_reg_sync(s, reg); 242886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 24290352ce4b5167ebc185bdec779e9642af75f1ccacDavid 'Digit' Turner if (IS_DEAD_ARG(i)) { 243086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, args[i]); 24310352ce4b5167ebc185bdec779e9642af75f1ccacDavid 'Digit' Turner } 24328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 243486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 24358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return nb_iargs + nb_oargs + def->nb_cargs + 1; 24368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER 24398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t tcg_table_op_count[NB_OPS]; 24418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2442f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnerstatic void dump_op_count(void) 24438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 24458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FILE *f; 24465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner f = fopen("/tmp/op.log", "w"); 24478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(i = INDEX_op_end; i < NB_OPS; i++) { 24485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]); 24498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fclose(f); 24518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 24538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, 24568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project long search_pc) 24578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2458f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner TCGOpcode opc; 2459f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turner int op_index; 24608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const TCGOpDef *def; 24618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const TCGArg *args; 24620b3979707c09e058442c22d046b326ce244edda1Andrew Hsieh 24638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_DISAS 24645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { 24655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_log("OP:\n"); 246686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_dump_ops(s); 24675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_log("\n"); 24688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 24708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER 247286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->opt_time -= profile_getclock(); 247386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 247486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 247586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef USE_TCG_OPTIMIZATIONS 247686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->gen_opparam_ptr = 247786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs); 247886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 247986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 248086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef CONFIG_PROFILER 248186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->opt_time += profile_getclock(); 24828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->la_time -= profile_getclock(); 24838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 248486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 24858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_liveness_analysis(s); 248686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 24878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER 24888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->la_time += profile_getclock(); 24898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 24908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_DISAS 24925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) { 249386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner qemu_log("OP after optimization and liveness analysis:\n"); 249486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_dump_ops(s); 24955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_log("\n"); 24968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 24988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_reg_alloc_start(s); 25008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->code_buf = gen_code_buf; 25028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->code_ptr = gen_code_buf; 25038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 250486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_out_tb_init(s); 250586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 2506975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner args = s->gen_opparam_buf; 25078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op_index = 0; 25088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;) { 2510975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner opc = s->gen_opc_buf[op_index]; 25118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER 25125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcg_table_op_count[opc]++; 25138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 25148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def = &tcg_op_defs[opc]; 25158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 25168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("%s: %d %d %d\n", def->name, 25178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project def->nb_oargs, def->nb_iargs, def->nb_cargs); 25188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // dump_regs(s); 25198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 25208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(opc) { 25218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_mov_i32: 25228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_mov_i64: 252386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_reg_alloc_mov(s, def, args, s->op_dead_args[op_index], 252486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->op_sync_args[op_index]); 25258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 25268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_movi_i32: 25278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_movi_i64: 252886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_reg_alloc_movi(s, args, s->op_dead_args[op_index], 252986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->op_sync_args[op_index]); 25308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 25318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_debug_insn_start: 25328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* debug instruction */ 25338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 25348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_nop: 25358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_nop1: 25368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_nop2: 25378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_nop3: 25388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 25398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_nopn: 25408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args += args[0]; 25418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto next; 25428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_discard: 254386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner temp_dead(s, args[0]); 25448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 25458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_set_label: 25468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_reg_alloc_bb_end(s, s->reserved_regs); 254786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_out_label(s, args[0], s->code_ptr); 25488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 25498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_call: 255086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner args += tcg_reg_alloc_call(s, def, opc, args, 255186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->op_dead_args[op_index], 255286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->op_sync_args[op_index]); 25538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto next; 25548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case INDEX_op_end: 25558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto the_end; 25568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 255786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Sanity check that we've not introduced any unhandled opcodes. */ 255886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (def->flags & TCG_OPF_NOT_PRESENT) { 255986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_abort(); 256086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 25618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Note: in order to speed up the code, it would be much 25628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project faster to have specialized register allocator functions for 25638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project some common argument patterns */ 256486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_reg_alloc_op(s, def, opc, args, s->op_dead_args[op_index], 256586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->op_sync_args[op_index]); 25668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 25678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project args += def->nb_args; 25698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next: 25708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) { 25718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return op_index; 25728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op_index++; 25748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef NDEBUG 25758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project check_regs(s); 25768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 25778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project the_end: 257986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Generate TB finalization at the end of block */ 258086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner tcg_out_tb_finalize(s); 25818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 25828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf) 25858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER 25878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n; 2589975bba804aed54452f774cdbf79a7b4732fc7696David 'Digit' Turner n = (s->gen_opc_ptr - s->gen_opc_buf); 25908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->op_count += n; 25918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n > s->op_count_max) 25928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->op_count_max = n; 25938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->temp_count += s->nb_temps; 25958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->nb_temps > s->temp_count_max) 25968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->temp_count_max = s->nb_temps; 25978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 25998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcg_gen_code_common(s, gen_code_buf, -1); 26018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* flush instruction cache */ 260386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner flush_icache_range((uintptr_t)gen_code_buf, (uintptr_t)s->code_ptr); 260486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 26058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->code_ptr - gen_code_buf; 26068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Return the index of the micro operation such as the pc after is < 26098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset bytes from the start of the TB. The contents of gen_code_buf must 26108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project not be changed, though writing the same values is ok. 26118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Return -1 if not found. */ 26125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset) 26138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return tcg_gen_code_common(s, gen_code_buf, offset); 26158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_PROFILER 2618f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_dump_info(FILE *f, fprintf_function cpu_fprintf) 26198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCGContext *s = &tcg_ctx; 26218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t tot; 26228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tot = s->interm_time + s->code_time; 26248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n", 26258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tot, tot / 2.4e9); 262686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 262786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->tb_count, 26288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->tb_count1 - s->tb_count, 26298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0); 263086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n", 26318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max); 26328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_fprintf(f, "deleted ops/TB %0.2f\n", 263386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->tb_count ? 26348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (double)s->del_op_count / s->tb_count : 0); 26358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n", 263686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner s->tb_count ? 26378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (double)s->temp_count / s->tb_count : 0, 26388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->temp_count_max); 263986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 264086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu_fprintf(f, "cycles/op %0.1f\n", 26418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->op_count ? (double)tot / s->op_count : 0); 264286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu_fprintf(f, "cycles/in byte %0.1f\n", 26438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->code_in_len ? (double)tot / s->code_in_len : 0); 264486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu_fprintf(f, "cycles/out byte %0.1f\n", 26458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->code_out_len ? (double)tot / s->code_out_len : 0); 26468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tot == 0) 26478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tot = 1; 264886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu_fprintf(f, " gen_interm time %0.1f%%\n", 26498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (double)s->interm_time / tot * 100.0); 265086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu_fprintf(f, " gen_code time %0.1f%%\n", 26518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (double)s->code_time / tot * 100.0); 265286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu_fprintf(f, "optim./code time %0.1f%%\n", 265386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner (double)s->opt_time / (s->code_time ? s->code_time : 1) 265486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner * 100.0); 265586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner cpu_fprintf(f, "liveness/code time %0.1f%%\n", 26568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0); 26578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_fprintf(f, "cpu_restore count %" PRId64 "\n", 26588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->restore_count); 26598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_fprintf(f, " avg cycles %0.1f\n", 26608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->restore_count ? (double)s->restore_time / s->restore_count : 0); 2661b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner 2662b9317727862dd690cc67bb51f71991c404f9e4f6David 'Digit' Turner dump_op_count(); 26638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 2665f1d9bf153726533acf659efd796aa484dfd0b412David 'Digit' Turnervoid tcg_dump_info(FILE *f, fprintf_function cpu_fprintf) 26668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_fprintf(f, "[TCG profiler not compiled]\n"); 26688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 267086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 267186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef ELF_HOST_MACHINE 267286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* In order to use this feature, the backend needs to do three things: 267386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 267486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner (1) Define ELF_HOST_MACHINE to indicate both what value to 267586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner put into the ELF image and to indicate support for the feature. 267686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 267786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner (2) Define tcg_register_jit. This should create a buffer containing 267886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner the contents of a .debug_frame section that describes the post- 267986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner prologue unwind info for the tcg machine. 268086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 268186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner (3) Call tcg_register_jit_int, with the constructed .debug_frame. 268286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner*/ 268386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 268486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */ 268586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnertypedef enum { 268686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner JIT_NOACTION = 0, 268786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner JIT_REGISTER_FN, 268886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner JIT_UNREGISTER_FN 268986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} jit_actions_t; 269086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 269186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstruct jit_code_entry { 269286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner struct jit_code_entry *next_entry; 269386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner struct jit_code_entry *prev_entry; 269486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const void *symfile_addr; 269586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint64_t symfile_size; 269686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner}; 269786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 269886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstruct jit_descriptor { 269986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint32_t version; 270086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint32_t action_flag; 270186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner struct jit_code_entry *relevant_entry; 270286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner struct jit_code_entry *first_entry; 270386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner}; 270486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 270586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid __jit_debug_register_code(void) __attribute__((noinline)); 270686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid __jit_debug_register_code(void) 270786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 270886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner asm(""); 270986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 271086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 271186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* Must statically initialize the version, because GDB may check 271286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner the version before we can set it. */ 271386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstruct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 271486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 271586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* End GDB interface. */ 271686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 271786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic int find_string(const char *strtab, const char *str) 271886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 271986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner const char *p = strtab + 1; 272086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 272186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner while (1) { 272286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (strcmp(p, str) == 0) { 272386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner return p - strtab; 272486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 272586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner p += strlen(p) + 1; 272686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 272786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 272886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 272986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_register_jit_int(void *buf_ptr, size_t buf_size, 273086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner void *debug_frame, size_t debug_frame_size) 273186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 273286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner struct __attribute__((packed)) DebugInfo { 273386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint32_t len; 273486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint16_t version; 273586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint32_t abbrev; 273686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t ptr_size; 273786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t cu_die; 273886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint16_t cu_lang; 273986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uintptr_t cu_low_pc; 274086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uintptr_t cu_high_pc; 274186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t fn_die; 274286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner char fn_name[16]; 274386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uintptr_t fn_low_pc; 274486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uintptr_t fn_high_pc; 274586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t cu_eoc; 274686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }; 274786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 274886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner struct ElfImage { 274986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ElfW(Ehdr) ehdr; 275086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ElfW(Phdr) phdr; 275186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ElfW(Shdr) shdr[7]; 275286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ElfW(Sym) sym[2]; 275386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner struct DebugInfo di; 275486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uint8_t da[24]; 275586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner char str[80]; 275686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }; 275786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 275886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner struct ElfImage *img; 275986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 276086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner static const struct ElfImage img_template = { 276186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .ehdr = { 276286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_ident[EI_MAG0] = ELFMAG0, 276386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_ident[EI_MAG1] = ELFMAG1, 276486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_ident[EI_MAG2] = ELFMAG2, 276586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_ident[EI_MAG3] = ELFMAG3, 276686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_ident[EI_CLASS] = ELF_CLASS, 276786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_ident[EI_DATA] = ELF_DATA, 276886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_ident[EI_VERSION] = EV_CURRENT, 276986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_type = ET_EXEC, 277086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_machine = ELF_HOST_MACHINE, 277186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_version = EV_CURRENT, 277286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_phoff = offsetof(struct ElfImage, phdr), 277386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_shoff = offsetof(struct ElfImage, shdr), 277486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_ehsize = sizeof(ElfW(Shdr)), 277586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_phentsize = sizeof(ElfW(Phdr)), 277686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_phnum = 1, 277786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_shentsize = sizeof(ElfW(Shdr)), 277886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_shnum = ARRAY_SIZE(img->shdr), 277986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_shstrndx = ARRAY_SIZE(img->shdr) - 1, 278086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef ELF_HOST_FLAGS 278186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_flags = ELF_HOST_FLAGS, 278286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 278386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef ELF_OSABI 278486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .e_ident[EI_OSABI] = ELF_OSABI, 278586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 278686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 278786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .phdr = { 278886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .p_type = PT_LOAD, 278986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .p_flags = PF_X, 279086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 279186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .shdr = { 279286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [0] = { .sh_type = SHT_NULL }, 279386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Trick: The contents of code_gen_buffer are not present in 279486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner this fake ELF file; that got allocated elsewhere. Therefore 279586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner we mark .text as SHT_NOBITS (similar to .bss) so that readers 279686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner will not look for contents. We can record any address. */ 279786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [1] = { /* .text */ 279886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_type = SHT_NOBITS, 279986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_flags = SHF_EXECINSTR | SHF_ALLOC, 280086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 280186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [2] = { /* .debug_info */ 280286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_type = SHT_PROGBITS, 280386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_offset = offsetof(struct ElfImage, di), 280486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_size = sizeof(struct DebugInfo), 280586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 280686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [3] = { /* .debug_abbrev */ 280786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_type = SHT_PROGBITS, 280886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_offset = offsetof(struct ElfImage, da), 280986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_size = sizeof(img->da), 281086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 281186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [4] = { /* .debug_frame */ 281286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_type = SHT_PROGBITS, 281386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_offset = sizeof(struct ElfImage), 281486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 281586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [5] = { /* .symtab */ 281686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_type = SHT_SYMTAB, 281786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_offset = offsetof(struct ElfImage, sym), 281886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_size = sizeof(img->sym), 281986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_info = 1, 282086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_link = ARRAY_SIZE(img->shdr) - 1, 282186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_entsize = sizeof(ElfW(Sym)), 282286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 282386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [6] = { /* .strtab */ 282486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_type = SHT_STRTAB, 282586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_offset = offsetof(struct ElfImage, str), 282686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sh_size = sizeof(img->str), 282786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 282886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 282986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .sym = { 283086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner [1] = { /* code_gen_buffer */ 283186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC), 283286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .st_shndx = 1, 283386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 283486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 283586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .di = { 283686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .len = sizeof(struct DebugInfo) - 4, 283786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .version = 2, 283886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .ptr_size = sizeof(void *), 283986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .cu_die = 1, 284086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */ 284186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .fn_die = 2, 284286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .fn_name = "code_gen_buffer" 284386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 284486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .da = { 284586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 1, /* abbrev number (the cu) */ 284686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0x11, 1, /* DW_TAG_compile_unit, has children */ 284786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */ 284886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */ 284986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */ 285086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0, 0, /* end of abbrev */ 285186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 2, /* abbrev number (the fn) */ 285286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0x2e, 0, /* DW_TAG_subprogram, no children */ 285386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0x3, 0x8, /* DW_AT_name, DW_FORM_string */ 285486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */ 285586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */ 285686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0, 0, /* end of abbrev */ 285786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 0 /* no more abbrev */ 285886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }, 285986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0" 286086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer", 286186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner }; 286286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 286386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* We only need a single jit entry; statically allocate it. */ 286486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner static struct jit_code_entry one_entry; 286586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 286686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner uintptr_t buf = (uintptr_t)buf_ptr; 286786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner size_t img_size = sizeof(struct ElfImage) + debug_frame_size; 286886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 286986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img = g_malloc(img_size); 287086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner *img = img_template; 287186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner memcpy(img + 1, debug_frame, debug_frame_size); 287286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 287386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->phdr.p_vaddr = buf; 287486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->phdr.p_paddr = buf; 287586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->phdr.p_memsz = buf_size; 287686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 287786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->shdr[1].sh_name = find_string(img->str, ".text"); 287886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->shdr[1].sh_addr = buf; 287986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->shdr[1].sh_size = buf_size; 288086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 288186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->shdr[2].sh_name = find_string(img->str, ".debug_info"); 288286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev"); 288386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 288486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->shdr[4].sh_name = find_string(img->str, ".debug_frame"); 288586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->shdr[4].sh_size = debug_frame_size; 288686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 288786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->shdr[5].sh_name = find_string(img->str, ".symtab"); 288886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->shdr[6].sh_name = find_string(img->str, ".strtab"); 288986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 289086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->sym[1].st_name = find_string(img->str, "code_gen_buffer"); 289186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->sym[1].st_value = buf; 289286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->sym[1].st_size = buf_size; 289386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 289486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->di.cu_low_pc = buf; 289586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->di.cu_high_pc = buf + buf_size; 289686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->di.fn_low_pc = buf; 289786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner img->di.fn_high_pc = buf + buf_size; 289886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 289986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#ifdef DEBUG_JIT 290086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Enable this block to be able to debug the ELF image file creation. 290186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner One can use readelf, objdump, or other inspection utilities. */ 290286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner { 290386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner FILE *f = fopen("/tmp/qemu.jit", "w+b"); 290486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (f) { 290586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner if (fwrite(img, img_size, 1, f) != img_size) { 290686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner /* Avoid stupid unused return value warning for fwrite. */ 290786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 290886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner fclose(f); 290986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 291086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner } 291186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif 291286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 291386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner one_entry.symfile_addr = img; 291486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner one_entry.symfile_size = img_size; 291586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 291686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; 291786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner __jit_debug_descriptor.relevant_entry = &one_entry; 291886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner __jit_debug_descriptor.first_entry = &one_entry; 291986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner __jit_debug_register_code(); 292086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 292186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#else 292286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner/* No support for the feature. Provide the entry point expected by exec.c, 292386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner and implement the internal function we declared earlier. */ 292486b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 292586b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnerstatic void tcg_register_jit_int(void *buf, size_t size, 292686b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner void *debug_frame, size_t debug_frame_size) 292786b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 292886b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 292986b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner 293086b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turnervoid tcg_register_jit(void *buf, size_t buf_size) 293186b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner{ 293286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner} 293386b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#endif /* ELF_HOST_MACHINE */ 2934