10c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* 20c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Copyright (C) 2012 The Android Open Source Project 30c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 40c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Licensed under the Apache License, Version 2.0 (the "License"); 50c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * you may not use this file except in compliance with the License. 60c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * You may obtain a copy of the License at 70c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 80c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * http://www.apache.org/licenses/LICENSE-2.0 90c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Unless required by applicable law or agreed to in writing, software 110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * distributed under the License is distributed on an "AS IS" BASIS, 120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * See the License for the specific language governing permissions and 140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * limitations under the License. 150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/*! \file LowerHelper.cpp 190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen \brief This file implements helper functions for lowering 200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenWith NCG O0: all registers are hard-coded ; 220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenWith NCG O1: the lowering module will use variables that will be allocated to a physical register by the register allocator. 230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenregister types: FS 32-bit or 64-bit; 250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen XMM: SS(32-bit) SD (64-bit); 260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen GPR: 8-bit, 16-bit, 32-bit; 270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpndRegType tells whether it is gpr, xmm or fs; 280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenOpndSize can be OpndSize_8, OpndSize_16, OpndSize_32, OpndSize_64 290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenA single native instruction can use multiple physical registers. 310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen we can't call freeReg in the middle of emitting a native instruction, 320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen since it may free the physical register used by an operand and cause two operands being allocated to the same physical register. 330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenWhen allocating a physical register for an operand, we can't spill the operands that are already allocated. To avoid that, we call startNativeCode before each native instruction, here flag "canSpill" is set to true for each physical register; 350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen when a physical register is allocated, we set its flag "canSpill" to false; 360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen at end of each native instruction, call endNativeCode to set flag "canSpill" to true. 370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "libdex/DexOpcodes.h" 400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "libdex/DexFile.h" 410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "Lower.h" 420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "NcgAot.h" 430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "enc_wrapper.h" 440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "vm/mterp/Mterp.h" 453d20456e5dc28cbbe3cf8df092e9ffafee6fad65Elliott Hughes#include "vm/mterp/common/FindInterface.h" 460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "NcgHelper.h" 470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include <math.h> 480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "interp/InterpState.h" 490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenextern "C" int64_t __divdi3(int64_t, int64_t); 510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenextern "C" int64_t __moddi3(int64_t, int64_t); 520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isScratchPhysical; 530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOp* lirTable[200]; 540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint num_lirs_in_table = 0; 550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//4 tables are defined: GPR integer ALU ops, ALU ops in FPU, SSE 32-bit, SSE 64-bit 570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//the index to the table is the opcode 580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//add_opc, or_opc, adc_opc, sbb_opc, 590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//and_opc, sub_opc, xor_opc, cmp_opc, 600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//mul_opc, imul_opc, div_opc, idiv_opc, 610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//sll_opc, srl_opc, sra, (SSE) 620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//shl_opc, shr_opc, sal_opc, sar_opc, //integer shift 630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//neg_opc, not_opc, andn_opc, (SSE) 640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//n_alu 650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!mnemonic for integer ALU operations 660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenconst Mnemonic map_of_alu_opcode_2_mnemonic[] = { 670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_ADD, Mnemonic_OR, Mnemonic_ADC, Mnemonic_SBB, 680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_AND, Mnemonic_SUB, Mnemonic_XOR, Mnemonic_CMP, 690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_MUL, Mnemonic_IMUL, Mnemonic_DIV, Mnemonic_IDIV, 700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, 710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_SHL, Mnemonic_SHR, Mnemonic_SAL, Mnemonic_SAR, 720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_NEG, Mnemonic_NOT, Mnemonic_Null, 730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null 740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen}; 750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!mnemonic for ALU operations in FPU 760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenconst Mnemonic map_of_fpu_opcode_2_mnemonic[] = { 770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_FADD, Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, 780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_FSUB, Mnemonic_Null, Mnemonic_Null, 790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_FMUL, Mnemonic_Null, Mnemonic_FDIV, Mnemonic_Null, 800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, 810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, 820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, 830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null 840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen}; 850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!mnemonic for SSE 32-bit 860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenconst Mnemonic map_of_sse_opcode_2_mnemonic[] = { 870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_ADDSD, Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, 880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_SUBSD, Mnemonic_XORPD, Mnemonic_Null, 890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_MULSD, Mnemonic_Null, Mnemonic_DIVSD, Mnemonic_Null, 900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, 910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, 920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, 930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null 940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen}; 950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!mnemonic for SSE 64-bit integer 960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenconst Mnemonic map_of_64_opcode_2_mnemonic[] = { 970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_PADDQ, Mnemonic_POR, Mnemonic_Null, Mnemonic_Null, 980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_PAND, Mnemonic_PSUBQ, Mnemonic_PXOR, Mnemonic_Null, 990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, 1000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_PSLLQ, Mnemonic_PSRLQ, Mnemonic_Null, 1010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, Mnemonic_Null, 1020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null, Mnemonic_Null, Mnemonic_PANDN, 1030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic_Null 1040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen}; 1050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//////////////////////////////////////////////// 1070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOpndReg 1080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_reg_opnd(LowOpndReg* op_reg, int reg, bool isPhysical, LowOpndRegType type) { 1110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op_reg->regType = type; 1120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isPhysical) { 1130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op_reg->logicalReg = -1; 1140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op_reg->physicalReg = reg; 1150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 1160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 1170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op_reg->logicalReg = reg; 1180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 1190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOpndMem 1210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_mem_opnd(LowOpndMem* mem, int disp, int base, bool isPhysical) { 1240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_disp.value = disp; 1250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->hasScale = false; 1260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_base.regType = LowOpndRegType_gp; 1270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isPhysical) { 1280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_base.logicalReg = -1; 1290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_base.physicalReg = base; 1300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 1310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_base.logicalReg = base; 1320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 1330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 1340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOpndMem 1360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_mem_opnd_scale(LowOpndMem* mem, int base, bool isPhysical, int disp, int index, bool indexPhysical, int scale) { 1390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->hasScale = true; 1400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_base.regType = LowOpndRegType_gp; 1410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isPhysical) { 1420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_base.logicalReg = -1; 1430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_base.physicalReg = base; 1440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 1450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_base.logicalReg = base; 1460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 1470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexPhysical) { 1480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_index.logicalReg = -1; 1490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_index.physicalReg = index; 1500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 1510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_index.logicalReg = index; 1520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 1530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_disp.value = disp; 1540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mem->m_scale.value = scale; 1550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 1560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!return either LowOpndRegType_xmm or LowOpndRegType_gp 1580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline LowOpndRegType getTypeFromIntSize(OpndSize size) { 1610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return size == OpndSize_64 ? LowOpndRegType_xmm : LowOpndRegType_gp; 1620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen// copied from JIT compiler 1650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chentypedef struct AtomMemBlock { 1660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen size_t bytesAllocated; 1670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen struct AtomMemBlock *next; 1680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen char ptr[0]; 1690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} AtomMemBlock; 1700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define ATOMBLOCK_DEFAULT_SIZE 4096 1720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenAtomMemBlock *atomMemHead = NULL; 1730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenAtomMemBlock *currentAtomMem = NULL; 1740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid * atomNew(size_t size) { 1750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen lowOpTimeStamp++; //one LowOp constructed 1760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(atomMemHead == NULL) { 1770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen atomMemHead = (AtomMemBlock*)malloc(sizeof(AtomMemBlock) + ATOMBLOCK_DEFAULT_SIZE); 1780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(atomMemHead == NULL) { 1790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("Memory allocation failed"); 1800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 1810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 1820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentAtomMem = atomMemHead; 1830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentAtomMem->bytesAllocated = 0; 1840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentAtomMem->next = NULL; 1850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 1860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen size = (size + 3) & ~3; 1870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if (size > ATOMBLOCK_DEFAULT_SIZE) { 1880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("Requesting %d bytes which exceed the maximal size allowed", size); 1890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 1900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 1910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenretry: 1920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if (size + currentAtomMem->bytesAllocated <= ATOMBLOCK_DEFAULT_SIZE) { 1930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen void *ptr; 1940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ¤tAtomMem->ptr[currentAtomMem->bytesAllocated]; 1950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return ptr; 1960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 1970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if (currentAtomMem->next) { 1980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentAtomMem = currentAtomMem->next; 1990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen goto retry; 2000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 2010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* Time to allocate a new arena */ 2020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen AtomMemBlock *newAtomMem = (AtomMemBlock*)malloc(sizeof(AtomMemBlock) + ATOMBLOCK_DEFAULT_SIZE); 2030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(newAtomMem == NULL) { 2040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("Memory allocation failed"); 2050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 2060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 2070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen newAtomMem->bytesAllocated = 0; 2080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen newAtomMem->next = NULL; 2090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentAtomMem->next = newAtomMem; 2100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentAtomMem = newAtomMem; 2110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen goto retry; 2120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("atomNew requesting %d bytes", size); 2130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 2140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid freeAtomMem() { 2170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //LOGI("free all atom memory"); 2180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen AtomMemBlock * tmpMem = atomMemHead; 2190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(tmpMem != NULL) { 2200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmpMem->bytesAllocated = 0; 2210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmpMem = tmpMem->next; 2220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 2230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentAtomMem = atomMemHead; 2240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpImm* dump_special(AtomOpCode cc, int imm) { 2270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpImm* op = (LowOpImm*)atomNew(sizeof(LowOpImm)); 2280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->lop.opCode = Mnemonic_NULL; 2290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->lop.opCode2 = cc; 2300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->lop.opnd1.type = LowOpndType_Imm; 2310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->lop.numOperands = 1; 2320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->immOpnd.value = imm; 2330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //stream = encoder_imm(m, size, imm, stream); 2340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return op; 2350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpLabel* lower_label(Mnemonic m, OpndSize size, int imm, const char* label, bool isLocal) { 2380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_imm(m, size, imm, stream); 2390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 2400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpLabel* dump_label(Mnemonic m, OpndSize size, int imm, 2430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen const char* label, bool isLocal) { 2440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_label(m, size, imm, label, isLocal); 2450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpNCG* dump_ncg(Mnemonic m, OpndSize size, int imm) { 2480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_imm(m, size, imm, stream); 2490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 2500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction with a single immediate operand 2530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 2550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpImm* lower_imm(Mnemonic m, OpndSize size, int imm, bool updateTable) { 2560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_imm(m, size, imm, stream); 2570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 2580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpImm* dump_imm(Mnemonic m, OpndSize size, int imm) { 2610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_imm(m, size, imm, true); 2620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpImm* dump_imm_with_codeaddr(Mnemonic m, OpndSize size, 2650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int imm, char* codePtr) { 2660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen encoder_imm(m, size, imm, codePtr); 2670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 2680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes a single memory operand 2710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!With NCG O1, we call freeReg to free up physical registers, then call registerAlloc to allocate a physical register for memory base 2730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMem* lower_mem(Mnemonic m, AtomOpCode m2, OpndSize size, 2740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg) { 2750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem(m, size, disp, base_reg, true, stream); 2760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 2770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMem* dump_mem(Mnemonic m, AtomOpCode m2, OpndSize size, 2800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical) { 2810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 2820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 2830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //type of the base is gpr 2840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 2850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_mem(m, m2, size, disp, regAll); 2860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 2870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem(m, size, disp, base_reg, isBasePhysical, stream); 2880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 2890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 2900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes a single reg operand 2920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!With NCG O1, wecall freeReg to free up physical registers, then call registerAlloc to allocate a physical register for the single operand 2940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpReg* lower_reg(Mnemonic m, AtomOpCode m2, OpndSize size, 2950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, LowOpndRegType type) { 2960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg(m, size, reg, true, type, stream); 2970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 2980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpReg* dump_reg(Mnemonic m, AtomOpCode m2, OpndSize size, 3010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, LowOpndRegType type) { 3020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 3030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 3040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(m == Mnemonic_MUL || m == Mnemonic_IDIV) { 3050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //these two instructions use eax & edx implicitly 3060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEax(); 3070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); 3080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true); 3100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_reg(m, m2, size, regAll, type); 3110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 3120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg(m, size, reg, isPhysical, type, stream); 3130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 3140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpReg* dump_reg_noalloc(Mnemonic m, OpndSize size, 3170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, LowOpndRegType type) { 3180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_reg(m, ATOM_NORMAL, size, reg, type); 3190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegReg* lower_reg_reg(Mnemonic m, AtomOpCode m2, OpndSize size, 3220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, int reg2, LowOpndRegType type) { 3230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(m == Mnemonic_FUCOMP || m == Mnemonic_FUCOM) { 3240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_compare_fp_stack(m == Mnemonic_FUCOMP, 3250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg-reg2, size==OpndSize_64, stream); 3260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 3280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_reg(m, size, reg, true, reg2, true, type, stream); 3290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 3310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes two reg operands 3340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//Here, both registers are physical 3360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegReg* dump_reg_reg_noalloc(Mnemonic m, OpndSize size, 3370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 3380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2, LowOpndRegType type) { 3390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_reg_reg(m, ATOM_NORMAL, size, reg, reg2, type); 3400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline bool isMnemonicMove(Mnemonic m) { 3430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return (m == Mnemonic_MOV || m == Mnemonic_MOVQ || 3440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m == Mnemonic_MOVSS || m == Mnemonic_MOVSD); 3450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes two reg operands 3470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!here dst reg is already allocated to a physical reg 3490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! we should not spill the physical register for dst when allocating for src 3500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegReg* dump_reg_reg_noalloc_dst(Mnemonic m, OpndSize size, 3510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 3520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2, LowOpndRegType type) { 3530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 3540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true); 3550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* remove move from one register to the same register */ 3560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isMnemonicMove(m) && regAll == reg2) return NULL; 3570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_reg_reg(m, ATOM_NORMAL, size, regAll, reg2, type); 3580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 3590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_reg(m, size, reg, isPhysical, reg2, isPhysical2, type, stream); 3600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 3610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes two reg operands 3640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!here src reg is already allocated to a physical reg 3660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegReg* dump_reg_reg_noalloc_src(Mnemonic m, AtomOpCode m2, OpndSize size, 3670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 3680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2, LowOpndRegType type) { 3690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 3700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll2; 3710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isMnemonicMove(m) && checkTempReg2(reg2, type, isPhysical2, reg)) { //dst reg is logical 3720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //only from get_virtual_reg_all 3730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll2 = registerAllocMove(reg2, type, isPhysical2, reg); 3740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 3750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll2 = registerAlloc(type, reg2, isPhysical2, true); 3760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_reg_reg(m, m2, size, reg, regAll2, type); 3770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 3790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_reg(m, size, reg, isPhysical, reg2, isPhysical2, type, stream); 3800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 3810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 3830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes two reg operands 3850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 3870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegReg* dump_reg_reg(Mnemonic m, AtomOpCode m2, OpndSize size, 3880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 3890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2, LowOpndRegType type) { 3900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 3910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 3920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //reg is source if m is MOV 3930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 3940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true); 3950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll2; 3960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpRegReg* op = NULL; 3970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef MOVE_OPT2 3980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isMnemonicMove(m) && 3990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ((reg != PhysicalReg_EDI && reg != PhysicalReg_ESP && reg != PhysicalReg_EBP) || (!isPhysical)) && 4000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isPhysical2 == false) { //dst reg is logical 4010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //called from move_reg_to_reg 4020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll2 = registerAllocMove(reg2, type, isPhysical2, regAll); 4030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 4040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 4050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 4060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll2 = registerAlloc(type, reg2, isPhysical2, true); 4070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op = lower_reg_reg(m, m2, size, regAll, regAll2, type); 4080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef MOVE_OPT2 4090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 4110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 4120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return op; 4130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 4150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_reg(m, size, reg, isPhysical, reg2, isPhysical2, type, stream); 4160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 4180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 4190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* lower_mem_reg(Mnemonic m, AtomOpCode m2, OpndSize size, 4210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, 4220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, 4230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, LowOpndRegType type, bool isMoves) { 4240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(m == Mnemonic_MOVSX) { 4250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_moves_mem_to_reg(size, disp, base_reg, true, 4260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true, stream); 4270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(m == Mnemonic_MOVZX) { 4290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_movez_mem_to_reg(size, disp, base_reg, true, 4300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true, stream); 4310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 4330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem_reg(m, size, disp, base_reg, true, 4340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true, type, stream); 4350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 4370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 4380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand 4400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Here, operands are already allocated to physical registers 4420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* dump_mem_reg_noalloc(Mnemonic m, OpndSize size, 4430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 4440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, 4450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, LowOpndRegType type) { 4460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_mem_reg(m, ATOM_NORMAL, size, disp, base_reg, mType, mIndex, reg, type, false); 4470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 4480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand 4490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Here, memory operand is already allocated to physical register 4510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* dump_mem_reg_noalloc_mem(Mnemonic m, AtomOpCode m2, OpndSize size, 4520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 4530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, 4540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, LowOpndRegType type) { 4550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 4560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true); 4570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_mem_reg(m, m2, size, disp, base_reg, mType, mIndex, regAll, type, false); 4580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 4590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem_reg(m, size, disp, base_reg, isBasePhysical, 4600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, isPhysical, type, stream); 4610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 4630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 4640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand 4650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 4670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* dump_mem_reg(Mnemonic m, AtomOpCode m2, OpndSize size, 4680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 4690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, 4700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, LowOpndRegType type) { 4710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 4720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 4730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 4740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 4750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //it is okay to use the same physical register 4760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isMnemonicMove(m)) { 4770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 4780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 4790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(baseAll); 4800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true); 4820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 4830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_mem_reg(m, m2, size, disp, baseAll, mType, mIndex, regAll, type, false); 4840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 4850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem_reg(m, size, disp, base_reg, isBasePhysical, 4860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, isPhysical, type, stream); 4870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 4890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 4900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand 4910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 4930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* dump_moves_mem_reg(Mnemonic m, OpndSize size, 4940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 4950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 4960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 4970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 4980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 4990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 5000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(baseAll); 5010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(LowOpndRegType_gp, reg, isPhysical, true); 5020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 5030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_mem_reg(m, ATOM_NORMAL, size, disp, baseAll, MemoryAccess_Unknown, -1, 5040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll, LowOpndRegType_gp, true/*moves*/); 5050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 5060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_moves_mem_to_reg(size, disp, base_reg, isBasePhysical, reg, isPhysical, stream); 5070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 5090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 5100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand 5110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 5130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* dump_movez_mem_reg(Mnemonic m, OpndSize size, 5140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 5150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 5160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 5170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 5180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 5190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 5200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(baseAll); 5210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(LowOpndRegType_gp, reg, isPhysical, true); 5220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 5230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_mem_reg(m, ATOM_NORMAL, size, disp, baseAll, MemoryAccess_Unknown, -1, 5240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll, LowOpndRegType_gp, true/*moves*/); 5250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 5260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_movez_mem_to_reg(size, disp, base_reg, isBasePhysical, reg, isPhysical, stream); 5270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 5290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 5300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one reg operand 5320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 5340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegReg* dump_movez_reg_reg(Mnemonic m, OpndSize size, 5350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 5360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 5370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpRegReg* op = (LowOpRegReg*)atomNew(sizeof(LowOpRegReg)); 5380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->lop.opCode = m; 5390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->lop.opnd1.size = OpndSize_32; 5400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->lop.opnd1.type = LowOpndType_Reg; 5410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->lop.opnd2.size = size; 5420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen op->lop.opnd2.type = LowOpndType_Reg; 5430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_reg_opnd(&(op->regOpnd1), reg2, isPhysical2, LowOpndRegType_gp); 5440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_reg_opnd(&(op->regOpnd2), reg, isPhysical, LowOpndRegType_gp); 5450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 5460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 5470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //reg is source if m is MOV 5480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 5490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(LowOpndRegType_gp, reg, isPhysical, true); 5500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 5510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll2 = registerAlloc(LowOpndRegType_gp, reg2, isPhysical2, true); 5520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_movez_reg_to_reg(size, regAll, true, regAll2, true, 5530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType_gp, stream); 5540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 5550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 5570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_movez_reg_to_reg(size, reg, isPhysical, reg2, 5580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isPhysical2, LowOpndRegType_gp, stream); 5590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 5610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 5620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand 5640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 5660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* lower_mem_scale_reg(Mnemonic m, OpndSize size, int base_reg, int disp, int index_reg, 5670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int scale, int reg, LowOpndRegType type) { 5680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isMovzs = (m == Mnemonic_MOVZX || m == Mnemonic_MOVSX); 5690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isMovzs) 5700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_movzs_mem_disp_scale_reg(m, size, base_reg, true, disp, index_reg, true, 5710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scale, reg, true, type, stream); 5720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 5730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(disp == 0) 5740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem_scale_reg(m, size, base_reg, true, index_reg, true, 5750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scale, reg, true, type, stream); 5760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 5770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem_disp_scale_reg(m, size, base_reg, true, disp, index_reg, true, 5780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scale, reg, true, type, stream); 5790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 5810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 5820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* dump_mem_scale_reg(Mnemonic m, OpndSize size, 5840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale, 5850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, LowOpndRegType type) { 5860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 5870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 5880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 5890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 5900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(baseAll); //make sure index will not use the same physical reg 5910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexAll = registerAlloc(LowOpndRegType_gp, index_reg, isIndexPhysical, true); 5920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isMnemonicMove(m)) { 5930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 5940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen doSpillReg(baseAll); //base can be used now 5950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 5960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(indexAll); 5970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isMovzs = (m == Mnemonic_MOVZX || m == Mnemonic_MOVSX); 5990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(isMovzs ? LowOpndRegType_gp : type, reg, isPhysical, true); 6000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 6010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_mem_scale_reg(m, size, baseAll, disp, indexAll, scale, regAll, type); 6020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 6030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem_scale_reg(m, size, base_reg, isBasePhysical, index_reg, 6040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isIndexPhysical, scale, reg, isPhysical, type, stream); 6050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 6060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 6070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand 6090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 6110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemReg* lower_reg_mem_scale(Mnemonic m, OpndSize size, int reg, 6120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int base_reg, int disp, int index_reg, int scale, LowOpndRegType type) { 6130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(disp == 0) 6140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_mem_scale(m, size, reg, true, base_reg, true, 6150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index_reg, true, scale, type, stream); 6160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 6170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_mem_disp_scale(m, size, reg, true, base_reg, true, 6180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen disp, index_reg, true, scale, type, stream); 6190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 6200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemReg* dump_reg_mem_scale(Mnemonic m, OpndSize size, 6230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 6240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale, 6250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType type) { 6260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 6270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 6280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 6290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 6300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(baseAll); 6310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexAll = registerAlloc(LowOpndRegType_gp, index_reg, isIndexPhysical, true); 6320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(indexAll); 6330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true); 6340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 6350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_reg_mem_scale(m, size, regAll, baseAll, disp, indexAll, scale, type); 6360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 6370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_mem_scale(m, size, reg, isPhysical, base_reg, isBasePhysical, 6380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index_reg, isIndexPhysical, scale, type, stream); 6390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 6400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 6410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand 6430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Here operands are already allocated 6450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemReg* lower_reg_mem(Mnemonic m, AtomOpCode m2, OpndSize size, int reg, 6460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, MemoryAccessType mType, int mIndex, 6470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType type) { 6480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_mem(m, size, reg, true, disp, base_reg, true, type, stream); 6490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 6500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemReg* dump_reg_mem_noalloc(Mnemonic m, OpndSize size, 6530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 6540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 6550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, LowOpndRegType type) { 6560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_reg_mem(m, ATOM_NORMAL, size, reg, disp, base_reg, mType, mIndex, type); 6570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one reg operand and one mem operand 6590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 6610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemReg* dump_reg_mem(Mnemonic m, AtomOpCode m2, OpndSize size, 6620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 6630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 6640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, LowOpndRegType type) { 6650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 6660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 6670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 6680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 6690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(baseAll); 6700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true); 6710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 6720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_reg_mem(m, m2, size, regAll, disp, baseAll, mType, mIndex, type); 6730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 6740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_mem(m, size, reg, isPhysical, disp, base_reg, isBasePhysical, type, stream); 6750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 6760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 6770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one immediate and one reg operand 6790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!The reg operand is allocated already 6810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegImm* lower_imm_reg(Mnemonic m, AtomOpCode m2, OpndSize size, 6820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int imm, int reg, LowOpndRegType type, bool chaining) { 6830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_imm_reg(m, size, imm, reg, true, type, stream); 6840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 6850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegImm* dump_imm_reg_noalloc(Mnemonic m, OpndSize size, 6880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int imm, int reg, bool isPhysical, LowOpndRegType type) { 6890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_imm_reg(m, ATOM_NORMAL, size, imm, reg, type, false); 6900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one immediate and one reg operand 6920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 6940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegImm* dump_imm_reg(Mnemonic m, AtomOpCode m2, OpndSize size, 6950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int imm, int reg, bool isPhysical, LowOpndRegType type, bool chaining) { 6960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 6970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 6980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true); 6990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_imm_reg(m, m2, size, imm, regAll, type, chaining); 7000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 7010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_imm_reg(m, size, imm, reg, isPhysical, type, stream); 7020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 7040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 7050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one immediate and one mem operand 7060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!The mem operand is already allocated 7080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemImm* lower_imm_mem(Mnemonic m, AtomOpCode m2, OpndSize size, int imm, 7090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, MemoryAccessType mType, int mIndex, 7100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool chaining) { 7110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_imm_mem(m, size, imm, disp, base_reg, true, stream); 7120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 7130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 7140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemImm* dump_imm_mem_noalloc(Mnemonic m, OpndSize size, 7160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int imm, 7170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 7180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex) { 7190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_imm_mem(m, ATOM_NORMAL, size, imm, disp, base_reg, mType, mIndex, false); 7200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 7210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that takes one immediate and one mem operand 7220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 7240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemImm* dump_imm_mem(Mnemonic m, AtomOpCode m2, OpndSize size, 7250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int imm, 7260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 7270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, bool chaining) { 7280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 7290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* do not free register if the base is %edi, %esp, or %ebp 7300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen make sure dump_imm_mem will only generate a single instruction */ 7310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isBasePhysical || (base_reg != PhysicalReg_EDI && 7320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen base_reg != PhysicalReg_ESP && 7330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen base_reg != PhysicalReg_EBP)) { 7340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 7350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 7370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_imm_mem(m, m2, size, imm, disp, baseAll, mType, mIndex, chaining); 7380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 7390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_imm_mem(m, size, imm, disp, base_reg, isBasePhysical, stream); 7400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 7420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 7430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that uses the FP stack and takes one mem operand 7440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 7460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemReg* lower_fp_mem(Mnemonic m, OpndSize size, int reg, 7470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, MemoryAccessType mType, int mIndex) { 7480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_fp_mem(m, size, reg, disp, base_reg, true, stream); 7490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 7500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 7510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemReg* dump_fp_mem(Mnemonic m, OpndSize size, int reg, 7530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 7540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex) { 7550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 7560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 7570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 7580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_fp_mem(m, size, reg, disp, baseAll, mType, mIndex); 7590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 7600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_fp_mem(m, size, reg, disp, base_reg, isBasePhysical, stream); 7610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 7630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 7640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update fields of LowOp and generate a x86 instruction that uses the FP stack and takes one mem operand 7650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 7670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* lower_mem_fp(Mnemonic m, OpndSize size, int disp, int base_reg, 7680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, int reg) { 7690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem_fp(m, size, disp, base_reg, true, reg, stream); 7700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 7710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 7720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* dump_mem_fp(Mnemonic m, OpndSize size, 7740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 7750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, 7760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg) { 7770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 7780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 7790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseAll = registerAlloc(LowOpndRegType_gp, base_reg, isBasePhysical, true); 7800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return lower_mem_fp(m, size, disp, baseAll, mType, mIndex, reg); 7810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 7820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_mem_fp(m, size, disp, base_reg, isBasePhysical, reg, stream); 7830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 7850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 7860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/////////////////////////////////////////////////////////////// 7870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/////////////////////////////////////////////////////////////// 7880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//OPERAND ORDER: 7890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//LowOp same as EncoderBase destination first 7900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//parameter order of function: src first 7910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen////////////////////////////////// IA32 native instructions ////////////// 7930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! generate a native instruction lea 7940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 7960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid load_effective_addr(int disp, int base_reg, bool isBasePhysical, 7970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 7980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_LEA; 7990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, OpndSize_32, disp, base_reg, isBasePhysical, 8000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp); 8010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! generate a native instruction lea 8030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid load_effective_addr_scale(int base_reg, bool isBasePhysical, 8060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index_reg, bool isIndexPhysical, int scale, 8070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 8080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_LEA; 8090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_scale_reg(m, OpndSize_32, 8100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen base_reg, isBasePhysical, 0/*disp*/, index_reg, isIndexPhysical, scale, 8110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, isPhysical, LowOpndRegType_gp); 8120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!fldcw 8140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid load_fpu_cw(int disp, int base_reg, bool isBasePhysical) { 8170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_FLDCW; 8180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem(m, ATOM_NORMAL, OpndSize_16, disp, base_reg, isBasePhysical); 8190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!fnstcw 8210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid store_fpu_cw(bool checkException, int disp, int base_reg, bool isBasePhysical) { 8240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(!checkException); 8250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_FNSTCW; 8260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem(m, ATOM_NORMAL, OpndSize_16, disp, base_reg, isBasePhysical); 8270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!cdq 8290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid convert_integer(OpndSize srcSize, OpndSize dstSize) { //cbw, cwd, cdq 8320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(srcSize == OpndSize_32 && dstSize == OpndSize_64); 8330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_CDQ; 8340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL, OpndSize_32, PhysicalReg_EAX, true, PhysicalReg_EDX, true, LowOpndRegType_gp); 8350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!fld: load from memory (float or double) to stack 8370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid load_fp_stack(LowOp* op, OpndSize size, int disp, int base_reg, bool isBasePhysical) {//fld(s|l) 8400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_FLD; 8410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_fp(m, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, 0); //ST0 8420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! fild: load from memory (int or long) to stack 8440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid load_int_fp_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical) {//fild(ll|l) 8470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_FILD; 8480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_fp(m, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, 0); //ST0 8490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!fild: load from memory (absolute addr) 8510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid load_int_fp_stack_imm(OpndSize size, int imm) {//fild(ll|l) 8540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return load_int_fp_stack(size, imm, PhysicalReg_Null, true); 8550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!fst: store from stack to memory (float or double) 8570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid store_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical) {//fst(p)(s|l) 8600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = pop ? Mnemonic_FSTP : Mnemonic_FST; 8610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_fp_mem(m, size, 0, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1); 8620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!fist: store from stack to memory (int or long) 8640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid store_int_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical) {//fist(p)(l) 8670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = pop ? Mnemonic_FISTP : Mnemonic_FIST; 8680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_fp_mem(m, size, 0, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1); 8690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!cmp reg, mem 8710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_reg_mem(LowOp* op, OpndSize size, int reg, bool isPhysical, 8740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical) { 8750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_CMP; 8760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem(m, ATOM_NORMAL, size, reg, isPhysical, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, getTypeFromIntSize(size)); 8770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!cmp mem, reg 8790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_mem_reg(OpndSize size, 8820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 8830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 8840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_CMP; 8850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, reg, isPhysical, getTypeFromIntSize(size)); 8860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 8870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! compare a VR with a temporary variable 8880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 8900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_VR_reg_all(OpndSize size, 8910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int vA, 8920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, Mnemonic m) { 8930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType type = getTypeFromIntSize(size); 8940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType pType = type; 8950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(m == Mnemonic_COMISS) { 8960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen size = OpndSize_32; 8970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen type = LowOpndRegType_ss; 8980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen pType = LowOpndRegType_xmm; 8990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 9010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tmpValue[2]; 9020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int isConst = isVirtualRegConstant(vA, type, tmpValue, true/*updateRefCount*/); 9030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 3) { 9040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(m == Mnemonic_COMISS) { 9050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_NCG_O1 9060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LOGI("VR is const and SS in compare_VR_reg"); 9070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 9090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //dumpImmToMem(vA+1, OpndSize_32, 0); //CHECK necessary? will overwrite vA+1!!! 9100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, reg, isPhysical, pType); 9110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 9120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(size != OpndSize_64) { 9140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_NCG_O1 9150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LOGI("VR is const and 32 bits in compare_VR_reg"); 9160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg(m, ATOM_NORMAL, size, tmpValue[0], reg, isPhysical, pType, false); 9180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 9190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(size == OpndSize_64) { 9210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_NCG_O1 9220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LOGI("VR is const and 64 bits in compare_VR_reg"); 9230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 9250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]); 9260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true, 9270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, pType); 9280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 9290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 1) dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 9320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 2) dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]); 9330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 9340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = checkVirtualReg(vA, type, 0/*do not update*/); 9350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll != PhysicalReg_Null) { //do not spill regAll when allocating register for dst 9360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 9370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 9380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg_noalloc_src(m, ATOM_NORMAL, size, regAll, true, reg, isPhysical, pType); 9390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 9400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 9420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //virtual register is not allocated to a physical register 9430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc_mem(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true, 9440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, pType); 9450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vA, type); 9470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 9480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 9490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true, 9500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, pType); 9510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 9520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 9540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_VR_reg(OpndSize size, 9550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int vA, 9560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 9570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_CMP; 9580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return compare_VR_reg_all(size, vA, reg, isPhysical, m); 9590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 9600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_VR_ss_reg(int vA, int reg, bool isPhysical) { 9610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_COMISS; 9620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return compare_VR_reg_all(OpndSize_32, vA, reg, isPhysical, m); 9630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 9640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_VR_sd_reg(int vA, int reg, bool isPhysical) { 9650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_COMISD; 9660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return compare_VR_reg_all(OpndSize_64, vA, reg, isPhysical, m); 9670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 9680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!load VR to stack 9690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 9700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 9710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid load_fp_stack_VR_all(OpndSize size, int vB, Mnemonic m) { 9720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 9730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //can't load from immediate to fp stack 9740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tmpValue[2]; 9750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int isConst = isVirtualRegConstant(vB, getTypeFromIntSize(size), tmpValue, false/*updateRefCount*/); 9760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst > 0) { 9770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size != OpndSize_64) { 9780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_NCG_O1 9790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LOGI("VR is const and 32 bits in load_fp_stack"); 9800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vB, OpndSize_32, tmpValue[0]); 9820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 9840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_NCG_O1 9850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LOGI("VR is const and 64 bits in load_fp_stack_VR"); 9860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 1 || isConst == 3) dumpImmToMem(vB, OpndSize_32, tmpValue[0]); 9880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 2 || isConst == 3) dumpImmToMem(vB+1, OpndSize_32, tmpValue[1]); 9890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { //if VR was updated by a def of gp, a xfer point was inserted 9920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if VR was updated by a def of xmm, a xfer point was inserted 9930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#if 0 9940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = checkVirtualReg(vB, size, 1); 9950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll != PhysicalReg_Null) //dump from register to memory 9960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem_noalloc(m, size, regAll, true, 4*vB, PhysicalReg_FP, true, 9970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vB, getTypeFromIntSize(size)); 9980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_fp(m, size, 4*vB, PhysicalReg_FP, true, MemoryAccess_VR, vB, 0); 10010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 10020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_fp(m, size, 4*vB, PhysicalReg_FP, true, MemoryAccess_VR, vB, 0); 10030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 10050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!load VR(float or double) to stack 10060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 10080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid load_fp_stack_VR(OpndSize size, int vA) {//fld(s|l) 10090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_FLD; 10100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return load_fp_stack_VR_all(size, vA, m); 10110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 10120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!load VR(int or long) to stack 10130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 10150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid load_int_fp_stack_VR(OpndSize size, int vA) {//fild(ll|l) 10160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_FILD; 10170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return load_fp_stack_VR_all(size, vA, m); 10180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 10190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!store from stack to VR (float or double) 10200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 10220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid store_fp_stack_VR(bool pop, OpndSize size, int vA) {//fst(p)(s|l) 10230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = pop ? Mnemonic_FSTP : Mnemonic_FST; 10240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_fp_mem(m, size, 0, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA); 10250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 10260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_32) 10270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVirtualReg(vA, LowOpndRegType_fs_s); 10280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 10290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVirtualReg(vA, LowOpndRegType_fs); 10300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 10320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!store from stack to VR (int or long) 10330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 10350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid store_int_fp_stack_VR(bool pop, OpndSize size, int vA) {//fist(p)(l) 10360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = pop ? Mnemonic_FISTP : Mnemonic_FIST; 10370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_fp_mem(m, size, 0, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA); 10380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 10390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_32) 10400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVirtualReg(vA, LowOpndRegType_fs_s); 10410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 10420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVirtualReg(vA, LowOpndRegType_fs); 10430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 10450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! ALU ops in FPU, one operand is a VR 10460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 10480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid fpu_VR(ALU_Opcode opc, OpndSize size, int vA) { 10490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = map_of_fpu_opcode_2_mnemonic[opc]; 10500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 10510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tmpValue[2]; 10520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int isConst = isVirtualRegConstant(vA, getTypeFromIntSize(size), tmpValue, false/*updateRefCount*/); 10530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst > 0) { 10540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size != OpndSize_64) { 10550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //allocate a register for dst 10560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 10570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 10590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((isConst == 1 || isConst == 3) && size == OpndSize_64) { 10600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 10610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((isConst == 2 || isConst == 3) && size == OpndSize_64) { 10630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]); 10640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isInMemory(vA, size)) { 10680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("fpu_VR"); 10690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_fp(m, size, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, 0); 10710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 10720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_fp(m, size, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, 0); 10730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 10750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! cmp imm reg 10760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 10780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_imm_reg(OpndSize size, int imm, 10790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 10800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(imm == 0) { 10810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType type = getTypeFromIntSize(size); 10820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_TEST; 10830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 10840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 10850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true); 10860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen lower_reg_reg(m, ATOM_NORMAL, size, regAll, regAll, type); 10870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 10880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_reg_reg(m, size, reg, isPhysical, reg, isPhysical, type, stream); 10890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 10910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_CMP; 10930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg(m, ATOM_NORMAL, size, imm, reg, isPhysical, getTypeFromIntSize(size), false); 10940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 10950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! cmp imm mem 10960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 10980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_imm_mem(OpndSize size, int imm, 10990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical) { 11000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_CMP; 11010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem(m, ATOM_NORMAL, size, imm, disp, 11020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen base_reg, isBasePhysical, MemoryAccess_Unknown, -1, false); 11030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! cmp imm VR 11050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 11070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_imm_VR(OpndSize size, int imm, 11080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int vA) { 11090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_CMP; 11100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 11110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size != OpndSize_32) ALOGE("only 32 bits supported in compare_imm_VR"); 11120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tmpValue[2]; 11130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int isConst = isVirtualRegConstant(vA, getTypeFromIntSize(size), tmpValue, false/*updateRefCount*/); 11140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst > 0) { 11150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 11160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 11170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = checkVirtualReg(vA, getTypeFromIntSize(size), 0); 11180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll != PhysicalReg_Null) 11190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg_noalloc(m, size, imm, regAll, true, LowOpndRegType_gp); 11200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 11210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem_noalloc(m, size, imm, 4*vA, PhysicalReg_FP, true, 11220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA); 11230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vA, getTypeFromIntSize(size)); 11240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 11250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem(m, ATOM_NORMAL, size, imm, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, false); 11260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 11270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! cmp reg reg 11290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 11310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_reg_reg(int reg1, bool isPhysical1, 11320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 11330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_CMP; 11340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL, OpndSize_32, reg1, isPhysical1, reg2, isPhysical2, LowOpndRegType_gp); 11350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_reg_reg_16(int reg1, bool isPhysical1, 11370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 11380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_CMP; 11390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL, OpndSize_16, reg1, isPhysical1, reg2, isPhysical2, LowOpndRegType_gp); 11400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! comiss mem reg 11430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!SSE, XMM: comparison of floating point numbers 11450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_ss_mem_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical, 11460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 11470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_COMISS; 11480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, OpndSize_32, disp, base_reg, isBasePhysical, 11490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_xmm); 11500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! comiss reg reg 11520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 11540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_ss_reg_with_reg(LowOp* op, int reg1, bool isPhysical1, 11550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 11560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_COMISS; 11570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL, OpndSize_32, reg1, isPhysical1, reg2, isPhysical2, LowOpndRegType_xmm); 11580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! comisd mem reg 11600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 11620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_sd_mem_with_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical, 11630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 11640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_COMISD; 11650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, OpndSize_64, disp, base_reg, isBasePhysical, 11660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_xmm); 11670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! comisd reg reg 11690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 11710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_sd_reg_with_reg(LowOp* op, int reg1, bool isPhysical1, 11720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 11730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_COMISD; 11740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL, OpndSize_64, reg1, isPhysical1, reg2, isPhysical2, LowOpndRegType_xmm); 11750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! fucom[p] 11770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 11790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid compare_fp_stack(bool pop, int reg, bool isDouble) { //compare ST(0) with ST(reg) 11800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = pop ? Mnemonic_FUCOMP : Mnemonic_FUCOM; 11810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen lower_reg_reg(m, ATOM_NORMAL, isDouble ? OpndSize_64 : OpndSize_32, 11820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen PhysicalReg_ST0+reg, PhysicalReg_ST0, LowOpndRegType_fs); 11830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/*! 11850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen\brief generate a single return instruction 11860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 11880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOp* lower_return() { 11890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream = encoder_return(stream); 11900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 11910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid x86_return() { 11940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen lower_return(); 11950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!test imm reg 11980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 12000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid test_imm_reg(OpndSize size, int imm, int reg, bool isPhysical) { 12010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg(Mnemonic_TEST, ATOM_NORMAL, size, imm, reg, isPhysical, getTypeFromIntSize(size), false); 12020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!test imm mem 12040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 12060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid test_imm_mem(OpndSize size, int imm, int disp, int reg, bool isPhysical) { 12070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem(Mnemonic_TEST, ATOM_NORMAL, size, imm, disp, reg, isPhysical, MemoryAccess_Unknown, -1, false); 12080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!alu unary op with one reg operand 12100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 12120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_unary_reg(OpndSize size, ALU_Opcode opc, int reg, bool isPhysical) { 12130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m; 12140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) 12150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_64_opcode_2_mnemonic[opc]; 12160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 12170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_alu_opcode_2_mnemonic[opc]; 12180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg(m, ATOM_NORMAL_ALU, size, reg, isPhysical, getTypeFromIntSize(size)); 12190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!alu unary op with one mem operand 12210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 12230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_unary_mem(LowOp* op, OpndSize size, ALU_Opcode opc, int disp, int base_reg, bool isBasePhysical) { 12240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m; 12250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) 12260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_64_opcode_2_mnemonic[opc]; 12270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 12280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_alu_opcode_2_mnemonic[opc]; 12290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem(m, ATOM_NORMAL_ALU, size, disp, base_reg, isBasePhysical); 12300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!alu binary op with immediate and one mem operand 12320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 12340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_binary_imm_mem(OpndSize size, ALU_Opcode opc, int imm, int disp, int base_reg, bool isBasePhysical) { 12350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m; 12360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) 12370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_64_opcode_2_mnemonic[opc]; 12380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 12390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_alu_opcode_2_mnemonic[opc]; 12400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem(m, ATOM_NORMAL_ALU, size, imm, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, false); 12410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!alu binary op with immediate and one reg operand 12430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 12450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_binary_imm_reg(OpndSize size, ALU_Opcode opc, int imm, int reg, bool isPhysical) { 12460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m; 12470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) 12480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_64_opcode_2_mnemonic[opc]; 12490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 12500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_alu_opcode_2_mnemonic[opc]; 12510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg(m, ATOM_NORMAL_ALU, size, imm, reg, isPhysical, getTypeFromIntSize(size), false); 12520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!alu binary op with one mem operand and one reg operand 12540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 12560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_binary_mem_reg(OpndSize size, ALU_Opcode opc, 12570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 12580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 12590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m; 12600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) 12610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_64_opcode_2_mnemonic[opc]; 12620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 12630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_alu_opcode_2_mnemonic[opc]; 12640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL_ALU, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, reg, isPhysical, getTypeFromIntSize(size)); 12650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_sd_binary_VR_reg(ALU_Opcode opc, int vA, int reg, bool isPhysical, bool isSD) { 12680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m; 12690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isSD) m = map_of_sse_opcode_2_mnemonic[opc]; 12700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else m = (Mnemonic)(map_of_sse_opcode_2_mnemonic[opc]+1); //from SD to SS 12710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize size = isSD ? OpndSize_64 : OpndSize_32; 12720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 12730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType type = isSD ? LowOpndRegType_xmm : LowOpndRegType_ss; //type of the mem operand 12740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tmpValue[2]; 12750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int isConst = isVirtualRegConstant(vA, type, tmpValue, 12760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen true/*updateRefCount*/); 12770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 3 && !isSD) { 12780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //isConst can be 0 or 3, mem32, use xmm 12790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 12800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL_ALU, OpndSize_32, 4*vA, PhysicalReg_FP, true, 12810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, 12820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType_xmm); 12830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 12840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 3 && isSD) { 12860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 12870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]); 12880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL_ALU, OpndSize_64, 4*vA, PhysicalReg_FP, true, 12890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, LowOpndRegType_xmm); 12900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 12910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 1) dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 12930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 2) dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]); 12940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 12950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = checkVirtualReg(vA, type, 0/*do not update refCount*/); 12970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll != PhysicalReg_Null) { 12980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); //should we use vA, type 12990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //CHECK: callupdateVRAtUse 13000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 13010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg_noalloc_src(m, ATOM_NORMAL_ALU, size, regAll, true, reg, 13020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isPhysical, LowOpndRegType_xmm); 13030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 13040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 13060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc_mem(m, ATOM_NORMAL_ALU, size, 4*vA, PhysicalReg_FP, true, 13070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, LowOpndRegType_xmm); 13080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vA, type); 13100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 13120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true, 13130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, LowOpndRegType_xmm); 13140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 13160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!alu binary op with a VR and one reg operand 13180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 13200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_binary_VR_reg(OpndSize size, ALU_Opcode opc, int vA, int reg, bool isPhysical) { 13210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m; 13220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) 13230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_64_opcode_2_mnemonic[opc]; 13240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 13250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_alu_opcode_2_mnemonic[opc]; 13260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 13270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tmpValue[2]; 13280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int isConst = isVirtualRegConstant(vA, getTypeFromIntSize(size), tmpValue, 13290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen true/*updateRefCount*/); 13300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 3 && size != OpndSize_64) { 13310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //allocate a register for dst 13320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg(m, ATOM_NORMAL_ALU, size, tmpValue[0], reg, isPhysical, 13330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getTypeFromIntSize(size), false); 13340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 13350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 3 && size == OpndSize_64) { 13370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 13380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]); 13390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL_ALU, size, 4*vA, PhysicalReg_FP, true, 13400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, getTypeFromIntSize(size)); 13410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 13420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 1) dumpImmToMem(vA, OpndSize_32, tmpValue[0]); 13440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 2) dumpImmToMem(vA+1, OpndSize_32, tmpValue[1]); 13450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 13470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = checkVirtualReg(vA, getTypeFromIntSize(size), 0); 13480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll != PhysicalReg_Null) { 13490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 13500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 13510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg_noalloc_src(m, ATOM_NORMAL_ALU, size, regAll, true, reg, 13520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isPhysical, getTypeFromIntSize(size)); 13530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 13540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 13560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc_mem(m, ATOM_NORMAL_ALU, size, 4*vA, PhysicalReg_FP, true, 13570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, getTypeFromIntSize(size)); 13580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vA, getTypeFromIntSize(size)); 13600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 13620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, size, 4*vA, PhysicalReg_FP, true, 13630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, reg, isPhysical, getTypeFromIntSize(size)); 13640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 13660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!alu binary op with two reg operands 13670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 13690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_binary_reg_reg(OpndSize size, ALU_Opcode opc, 13700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg1, bool isPhysical1, 13710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 13720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m; 13730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) 13740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_64_opcode_2_mnemonic[opc]; 13750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 13760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_alu_opcode_2_mnemonic[opc]; 13770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL_ALU, size, reg1, isPhysical1, reg2, isPhysical2, getTypeFromIntSize(size)); 13780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 13790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!alu binary op with one reg operand and one mem operand 13800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 13820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_binary_reg_mem(OpndSize size, ALU_Opcode opc, 13830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 13840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical) { //destination is mem!! 13850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m; 13860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) 13870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_64_opcode_2_mnemonic[opc]; 13880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 13890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m = map_of_alu_opcode_2_mnemonic[opc]; 13900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem(m, ATOM_NORMAL_ALU, size, reg, isPhysical, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, getTypeFromIntSize(size)); 13910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 13920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!FPU ops with one mem operand 13930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 13950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid fpu_mem(LowOp* op, ALU_Opcode opc, OpndSize size, int disp, int base_reg, bool isBasePhysical) { 13960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = map_of_fpu_opcode_2_mnemonic[opc]; 13970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_fp(m, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, 0); 13980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 13990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!SSE 32-bit ALU 14000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 14020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_ss_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical, 14030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 14040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (Mnemonic)(map_of_sse_opcode_2_mnemonic[opc]+1); //from SD to SS 14050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL_ALU, OpndSize_32, reg, isPhysical, reg2, isPhysical2, LowOpndRegType_xmm); 14060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!SSE 64-bit ALU 14080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 14100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid alu_sd_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical, 14110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 14120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = map_of_sse_opcode_2_mnemonic[opc]; 14130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL_ALU, OpndSize_64, reg, isPhysical, reg2, isPhysical2, LowOpndRegType_xmm); 14140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!push reg to native stack 14160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 14180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid push_reg_to_stack(OpndSize size, int reg, bool isPhysical) { 14190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg(Mnemonic_PUSH, ATOM_NORMAL, size, reg, isPhysical, getTypeFromIntSize(size)); 14200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!push mem to native stack 14220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 14240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid push_mem_to_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical) { 14250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem(Mnemonic_PUSH, ATOM_NORMAL, size, disp, base_reg, isBasePhysical); 14260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!move from reg to memory 14280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 14300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_reg_to_mem(OpndSize size, 14310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 14320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical) { 14330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 14340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem(m, ATOM_NORMAL, size, reg, isPhysical, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, getTypeFromIntSize(size)); 14350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!move from reg to memory 14370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Operands are already allocated 14390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_reg_to_mem_noalloc(OpndSize size, 14400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 14410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 14420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex) { 14430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 14440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem_noalloc(m, size, reg, isPhysical, disp, base_reg, isBasePhysical, mType, mIndex, getTypeFromIntSize(size)); 14450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!move from memory to reg 14470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 14490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* move_mem_to_reg(OpndSize size, 14500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 14510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 14520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 14530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return dump_mem_reg(m, ATOM_NORMAL, size, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, reg, isPhysical, getTypeFromIntSize(size)); 14540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!move from memory to reg 14560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Operands are already allocated 14580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* move_mem_to_reg_noalloc(OpndSize size, 14590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 14600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, 14610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 14620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 14630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return dump_mem_reg_noalloc(m, size, disp, base_reg, isBasePhysical, mType, mIndex, reg, isPhysical, getTypeFromIntSize(size)); 14640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!movss from memory to reg 14660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Operands are already allocated 14680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpRegMem* move_ss_mem_to_reg_noalloc(int disp, int base_reg, bool isBasePhysical, 14690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex, 14700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 14710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return dump_mem_reg_noalloc(Mnemonic_MOVSS, OpndSize_32, disp, base_reg, isBasePhysical, mType, mIndex, reg, isPhysical, LowOpndRegType_xmm); 14720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!movss from reg to memory 14740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Operands are already allocated 14760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenLowOpMemReg* move_ss_reg_to_mem_noalloc(int reg, bool isPhysical, 14770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 14780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccessType mType, int mIndex) { 14790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return dump_reg_mem_noalloc(Mnemonic_MOVSS, OpndSize_32, reg, isPhysical, disp, base_reg, isBasePhysical, mType, mIndex, LowOpndRegType_xmm); 14800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!movzx from memory to reg 14820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 14840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid movez_mem_to_reg(OpndSize size, 14850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 14860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 14870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_MOVZX; 14880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_movez_mem_reg(m, size, disp, base_reg, isBasePhysical, reg, isPhysical); 14890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!movzx from one reg to another reg 14920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 14940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid movez_reg_to_reg(OpndSize size, 14950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 14960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 14970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_MOVZX; 14980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_movez_reg_reg(m, size, reg, isPhysical, reg2, isPhysical2); 14990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid movez_mem_disp_scale_to_reg(OpndSize size, 15020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int base_reg, bool isBasePhysical, 15030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int index_reg, bool isIndexPhysical, int scale, 15040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 15050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_scale_reg(Mnemonic_MOVZX, size, base_reg, isBasePhysical, 15060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen disp, index_reg, isIndexPhysical, scale, 15070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, isPhysical, LowOpndRegType_gp); 15080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid moves_mem_disp_scale_to_reg(OpndSize size, 15100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int base_reg, bool isBasePhysical, 15110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int index_reg, bool isIndexPhysical, int scale, 15120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 15130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_scale_reg(Mnemonic_MOVSX, size, base_reg, isBasePhysical, 15140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen disp, index_reg, isIndexPhysical, scale, 15150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, isPhysical, LowOpndRegType_gp); 15160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!movsx from memory to reg 15190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 15210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid moves_mem_to_reg(LowOp* op, OpndSize size, 15220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical, 15230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 15240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_MOVSX; 15250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_moves_mem_reg(m, size, disp, base_reg, isBasePhysical, reg, isPhysical); 15260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!mov from one reg to another reg 15280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 15300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_reg_to_reg(OpndSize size, 15310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 15320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 15330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 15340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL, size, reg, isPhysical, reg2, isPhysical2, getTypeFromIntSize(size)); 15350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!mov from one reg to another reg 15370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Operands are already allocated 15390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_reg_to_reg_noalloc(OpndSize size, 15400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 15410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg2, bool isPhysical2) { 15420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 15430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg_noalloc(m, size, reg, isPhysical, reg2, isPhysical2, getTypeFromIntSize(size)); 15440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!move from memory to reg 15460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 15480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_mem_scale_to_reg(OpndSize size, 15490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale, 15500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 15510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 15520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_scale_reg(m, size, base_reg, isBasePhysical, 0/*disp*/, index_reg, isIndexPhysical, scale, 15530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, isPhysical, getTypeFromIntSize(size)); 15540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_mem_disp_scale_to_reg(OpndSize size, 15560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale, 15570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 15580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 15590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_scale_reg(m, size, base_reg, isBasePhysical, disp, index_reg, isIndexPhysical, scale, 15600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, isPhysical, getTypeFromIntSize(size)); 15610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!move from reg to memory 15630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 15650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_reg_to_mem_scale(OpndSize size, 15660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 15670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale) { 15680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 15690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem_scale(m, size, reg, isPhysical, 15700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen base_reg, isBasePhysical, 0/*disp*/, index_reg, isIndexPhysical, scale, 15710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getTypeFromIntSize(size)); 15720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_reg_to_mem_disp_scale(OpndSize size, 15740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical, 15750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale) { 15760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 15770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem_scale(m, size, reg, isPhysical, 15780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen base_reg, isBasePhysical, disp, index_reg, isIndexPhysical, scale, 15790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getTypeFromIntSize(size)); 15800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_chain_to_mem(OpndSize size, int imm, 15830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical) { 15840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem(Mnemonic_MOV, ATOM_NORMAL, size, imm, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, true); 15850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!move an immediate to memory 15880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 15900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_imm_to_mem(OpndSize size, int imm, 15910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical) { 15920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(size != OpndSize_64); 15930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) ALOGE("move_imm_to_mem with 64 bits"); 15940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem(Mnemonic_MOV, ATOM_NORMAL, size, imm, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, false); 15950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 15960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! set a VR to an immediate 15970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 15980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 15990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_VR_to_imm(u2 vA, OpndSize size, int imm) { 16000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(size != OpndSize_64); 16010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) ALOGE("move_imm_to_mem with 64 bits"); 16020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 16030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 16040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = checkVirtualReg(vA, getTypeFromIntSize(size), 0); 16050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll != PhysicalReg_Null) { 16060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg_noalloc(m, size, imm, regAll, true, LowOpndRegType_gp); 16070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vA, getTypeFromIntSize(size)); 16080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVirtualReg(vA, getTypeFromIntSize(size)); 16090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 16100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //will call freeReg 16120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 16130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll = registerAlloc(LowOpndRegType_virtual | getTypeFromIntSize(size), vA, false/*dummy*/, true); 16140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll == PhysicalReg_Null) { 16150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem_noalloc(m, size, imm, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA); 16160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 16170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg_noalloc(m, size, imm, regAll, true, LowOpndRegType_gp); 16190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVirtualReg(vA, getTypeFromIntSize(size)); 16200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 16220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem(m, ATOM_NORMAL, size, imm, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA, false); 16230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_VR_to_imm_noupdateref(LowOp* op, u2 vA, OpndSize size, int imm) { 16260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 16270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! set a VR to an immediate 16290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Do not allocate a physical register for the VR 16310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_VR_to_imm_noalloc(u2 vA, OpndSize size, int imm) { 16320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(size != OpndSize_64); 16330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) ALOGE("move_imm_to_mem with 64 bits"); 16340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 16350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem_noalloc(m, size, imm, 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA); 16360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_chain_to_reg(OpndSize size, int imm, int reg, bool isPhysical) { 16390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg(Mnemonic_MOV, ATOM_NORMAL, size, imm, reg, isPhysical, LowOpndRegType_gp, true); 16400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! move an immediate to reg 16430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 16450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_imm_to_reg(OpndSize size, int imm, int reg, bool isPhysical) { 16460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(size != OpndSize_64); 16470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) ALOGE("move_imm_to_reg with 64 bits"); 16480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_MOV; 16490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg(m, ATOM_NORMAL, size, imm, reg, isPhysical, LowOpndRegType_gp, false); 16500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! move an immediate to reg 16520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! The operand is already allocated 16540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_imm_to_reg_noalloc(OpndSize size, int imm, int reg, bool isPhysical) { 16550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(size != OpndSize_64); 16560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) ALOGE("move_imm_to_reg with 64 bits"); 16570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = Mnemonic_MOV; 16580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg_noalloc(m, size, imm, reg, isPhysical, LowOpndRegType_gp); 16590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!cmov from reg to reg 16610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 16630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid conditional_move_reg_to_reg(OpndSize size, ConditionCode cc, int reg1, bool isPhysical1, int reg, bool isPhysical) { 16640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (Mnemonic)(Mnemonic_CMOVcc+cc); 16650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg(m, ATOM_NORMAL, size, reg1, isPhysical1, reg, isPhysical, LowOpndRegType_gp); 16660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!movss from memory to reg 16680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 16700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_ss_mem_to_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical, 16710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 16720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(Mnemonic_MOVSS, ATOM_NORMAL, OpndSize_32, disp, base_reg, isBasePhysical, 16730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_xmm); 16740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!movss from reg to memory 16760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 16780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_ss_reg_to_mem(LowOp* op, int reg, bool isPhysical, 16790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical) { 16800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem(Mnemonic_MOVSS, ATOM_NORMAL, OpndSize_32, reg, isPhysical, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, LowOpndRegType_xmm); 16810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!movsd from memory to reg 16830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 16850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_sd_mem_to_reg(int disp, int base_reg, bool isBasePhysical, 16860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg, bool isPhysical) { 16870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(Mnemonic_MOVSD, ATOM_NORMAL, OpndSize_64, disp, base_reg, isBasePhysical, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_xmm); 16880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!movsd from reg to memory 16900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 16920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid move_sd_reg_to_mem(LowOp* op, int reg, bool isPhysical, 16930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int disp, int base_reg, bool isBasePhysical) { 16940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem(Mnemonic_MOVSD, ATOM_NORMAL, OpndSize_64, reg, isPhysical, 16950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen disp, base_reg, isBasePhysical, 16960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_Unknown, -1, LowOpndRegType_xmm); 16970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!load from VR to a temporary 16990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 17000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 17010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid get_virtual_reg_all(u2 vB, OpndSize size, int reg, bool isPhysical, Mnemonic m) { 17020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType type = getTypeFromIntSize(size); 17030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType pType = type;//gp or xmm 17040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize size2 = size; 17050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m2 = m; 17060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(m == Mnemonic_MOVSS) { 17070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen size = OpndSize_32; 17080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen size2 = OpndSize_64; 17090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen type = LowOpndRegType_ss; 17100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen pType = LowOpndRegType_xmm; 17110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m2 = Mnemonic_MOVQ; //to move from one xmm register to another 17120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 17140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tmpValue[2]; 17150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int isConst; 17160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isConst = isVirtualRegConstant(vB, type, tmpValue, true/*updateRefCount*/); 17170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 3) { 17180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(m == Mnemonic_MOVSS) { //load 32 bits from VR 17190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //VR is not mapped to a register but in memory 17200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vB, OpndSize_32, tmpValue[0]); 17210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //temporary reg has "pType" (which is xmm) 17220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, size, 4*vB, PhysicalReg_FP, true, 17230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vB, reg, isPhysical, pType); 17240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 17250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(m == Mnemonic_MOVSD || size == OpndSize_64) { 17270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //VR is not mapped to a register but in memory 17280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vB, OpndSize_32, tmpValue[0]); 17290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vB+1, OpndSize_32, tmpValue[1]); 17300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, size, 4*vB, PhysicalReg_FP, true, 17310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vB, reg, isPhysical, pType); 17320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 17330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(size != OpndSize_64) { 17350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //VR is not mapped to a register 17360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_reg(m, ATOM_NORMAL, size, tmpValue[0], reg, isPhysical, pType, false); 17370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 17380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 1) dumpImmToMem(vB, OpndSize_32, tmpValue[0]); 17410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 2) dumpImmToMem(vB+1, OpndSize_32, tmpValue[1]); 17420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 17430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = checkVirtualReg(vB, type, 0); 17440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll != PhysicalReg_Null) { 17450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(vB, type); 17460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 17470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check XFER_MEM_TO_XMM 17480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVRAtUse(vB, type, regAll); 17490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //temporary reg has "pType" 17500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg_noalloc_src(m2, ATOM_NORMAL, size2, regAll, true, reg, isPhysical, pType); //register allocator handles assembly move 17510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 17520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vB, type); 17530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 17540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //not allocated to a register yet, no need to check XFER_MEM_TO_XMM 17560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll = registerAlloc(LowOpndRegType_virtual | type, vB, false/*dummy*/, false); 17570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll == PhysicalReg_Null) { 17580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc(m, size, 4*vB, PhysicalReg_FP, true, 17590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vB, reg, isPhysical, pType); 17600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 17610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 17630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //temporary reg has pType 17640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(checkTempReg2(reg, pType, isPhysical, regAll)) { 17650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen registerAllocMove(reg, pType, isPhysical, regAll); 17660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc(m, size, 4*vB, PhysicalReg_FP, true, 17670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vB, regAll, true, pType); 17680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vB, type); 17690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 17700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 17720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc(m, size, 4*vB, PhysicalReg_FP, true, 17730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vB, regAll, true, pType); 17740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //xmm with 32 bits 17750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(vB, type); 17760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 17770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg_noalloc_src(m2, ATOM_NORMAL, size2, regAll, true, reg, isPhysical, pType); 17780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 17790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vB, type); 17800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 17810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 17840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg(m, ATOM_NORMAL, size, 4*vB, PhysicalReg_FP, true, 17850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vB, reg, isPhysical, pType); 17860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 17880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid get_virtual_reg(u2 vB, OpndSize size, int reg, bool isPhysical) { 17890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 17900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return get_virtual_reg_all(vB, size, reg, isPhysical, m); 17910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 17920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid get_virtual_reg_noalloc(u2 vB, OpndSize size, int reg, bool isPhysical) { 17930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 17940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc(m, size, 4*vB, PhysicalReg_FP, true, 17950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vB, reg, isPhysical, getTypeFromIntSize(size)); 17960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 17970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//3 cases: gp, xmm, ss 17980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//ss: the temporary register is xmm 17990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!load from a temporary to a VR 18000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 18010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 18020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_virtual_reg_all(u2 vA, OpndSize size, int reg, bool isPhysical, Mnemonic m) { 18030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType type = getTypeFromIntSize(size); 18040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType pType = type;//gp or xmm 18050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize size2 = size; 18060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m2 = m; 18070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(m == Mnemonic_MOVSS) { 18080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen size = OpndSize_32; 18090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen size2 = OpndSize_64; 18100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen type = LowOpndRegType_ss; 18110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen pType = LowOpndRegType_xmm; 18120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen m2 = Mnemonic_MOVQ; 18130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 18150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //3 cases 18160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //1: virtual register is already allocated to a physical register 18170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // call dump_reg_reg_noalloc_dst 18180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //2: src reg is already allocated, VR is not yet allocated 18190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // allocate VR to the same physical register used by src reg 18200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // [call registerAllocMove] 18210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //3: both not yet allocated 18220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // allocate a physical register for the VR 18230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // then call dump_reg_reg_noalloc_dst 18240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //may need to convert from gp to xmm or the other way 18250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 18260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = checkVirtualReg(vA, type, 0); 18270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll != PhysicalReg_Null) { //case 1 18280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 18290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 18300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg_noalloc_dst(m2, size2, reg, isPhysical, regAll, true, pType); //temporary reg is "pType" 18310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 18320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vA, type); 18330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVirtualReg(vA, type); //will dump VR to memory, should happen afterwards 18340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 18350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll = checkTempReg(reg, pType, isPhysical, vA); //vA is not used inside 18370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll != PhysicalReg_Null) { //case 2 18380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen registerAllocMove(vA, LowOpndRegType_virtual | type, false, regAll); 18390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVirtualReg(vA, type); //will dump VR to memory, should happen afterwards 18400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; //next native instruction starts at op 18410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //case 3 18430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll = registerAlloc(LowOpndRegType_virtual | type, vA, false/*dummy*/, false); 18440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regAll == PhysicalReg_Null) { 18450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem_noalloc(m, size, reg, isPhysical, 4*vA, PhysicalReg_FP, true, 18460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, pType); 18470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 18480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 18500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 18510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg_noalloc_dst(m2, size2, reg, isPhysical, regAll, true, pType); 18520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 18530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount(vA, type); 18540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateVirtualReg(vA, type); 18550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 18570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem(m, ATOM_NORMAL, size, reg, isPhysical, 4*vA, PhysicalReg_FP, true, 18580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, pType); 18590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_virtual_reg(u2 vA, OpndSize size, int reg, bool isPhysical) { 18620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 18630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return set_virtual_reg_all(vA, size, reg, isPhysical, m); 18640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_virtual_reg_noalloc(u2 vA, OpndSize size, int reg, bool isPhysical) { 18660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Mnemonic m = (size == OpndSize_64) ? Mnemonic_MOVQ : Mnemonic_MOV; 18670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_mem_noalloc(m, size, reg, isPhysical, 4*vA, PhysicalReg_FP, true, 18680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vA, getTypeFromIntSize(size)); 18690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid get_VR_ss(int vB, int reg, bool isPhysical) { 18710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return get_virtual_reg_all(vB, OpndSize_64, reg, isPhysical, Mnemonic_MOVSS); 18720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_VR_ss(int vA, int reg, bool isPhysical) { 18740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return set_virtual_reg_all(vA, OpndSize_64, reg, isPhysical, Mnemonic_MOVSS); 18750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid get_VR_sd(int vB, int reg, bool isPhysical) { 18770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return get_virtual_reg_all(vB, OpndSize_64, reg, isPhysical, Mnemonic_MOVSD); 18780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid set_VR_sd(int vA, int reg, bool isPhysical) { 18800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return set_virtual_reg_all(vA, OpndSize_64, reg, isPhysical, Mnemonic_MOVSD); 18810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen////////////////////////////////// END: IA32 native instructions ////////////// 18830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! generate native instructions to get current PC in the stack frame 18840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 18850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 18860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_currentpc(int reg, bool isPhysical) { 18870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, -sizeofStackSaveArea+offStackSaveArea_localRefTop, PhysicalReg_FP, true, reg, isPhysical); 18880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 1; 18890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to perform null check 18910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 18920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!This function does not export PC 18930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint simpleNullCheck(int reg, bool isPhysical, int vr) { 18940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVRNullCheck(vr, OpndSize_32)) { 18950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(reg, LowOpndRegType_gp, isPhysical); 18960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_removed_nullCheck++; 18970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 18980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compare_imm_reg(OpndSize_32, 0, reg, isPhysical); 19000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump_global_API(Condition_E, "common_errNullObject", false); 19010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setVRNullCheck(vr, OpndSize_32); 19020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 19030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* only for O1 code generator */ 19060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint boundCheck(int vr_array, int reg_array, bool isPhysical_array, 19070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int vr_index, int reg_index, bool isPhysical_index, 19080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int exceptionNum) { 19090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef BOUNDCHECK_OPT 19100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVRBoundCheck(vr_array, vr_index)) { 19110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(reg_array, LowOpndRegType_gp, isPhysical_array); 19120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(reg_index, LowOpndRegType_gp, isPhysical_index); 19130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 19140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 19150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 19160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compare_mem_reg(OpndSize_32, offArrayObject_length, 19170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg_array, isPhysical_array, 19180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg_index, isPhysical_index); 19190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen char errName[256]; 19210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen sprintf(errName, "common_errArrayIndex"); 19220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen handlePotentialException( 19230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Condition_NC, Condition_C, 19240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen exceptionNum, errName); 19250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef BOUNDCHECK_OPT 19260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setVRBoundCheck(vr_array, vr_index); 19270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 19280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 19290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to perform null check 19320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 19340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint nullCheck(int reg, bool isPhysical, int exceptionNum, int vr) { 19350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen char label[LABEL_SIZE]; 19360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 19380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //nullCheck optimization is available in O1 mode only 19390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVRNullCheck(vr, OpndSize_32)) { 19400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(reg, LowOpndRegType_gp, isPhysical); 19410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(exceptionNum <= 1) { 19420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(PhysicalReg_EDX, LowOpndRegType_gp, true); 19430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(PhysicalReg_EDX, LowOpndRegType_gp, true); 19440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 19450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_removed_nullCheck++; 19460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 19470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 19480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compare_imm_reg(OpndSize_32, 0, reg, isPhysical); 19490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rememberState(exceptionNum); 19500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen snprintf(label, LABEL_SIZE, "after_exception_%d", exceptionNum); 19510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump(Condition_NE, label, true); 19520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(exceptionNum > 1) 19530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen nextVersionOfHardReg(PhysicalReg_EDX, 2); //next version has 2 ref count 19540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen export_pc(); //use %edx 19550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen constVREndOfBB(); 19560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("exception"); //dump GG, GL VRs 19570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unconditional_jump_global_API("common_errNullObject", false); 19580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(label, true); 19590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen goToState(exceptionNum); 19600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setVRNullCheck(vr, OpndSize_32); 19610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 19620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compare_imm_reg(OpndSize_32, 0, reg, isPhysical); 19630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen snprintf(label, LABEL_SIZE, "after_exception_%d", exceptionNum); 19640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump(Condition_NE, label, true); 19650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen export_pc(); //use %edx 19660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unconditional_jump_global_API("common_errNullObject", false); 19670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(label, true); 19680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 19690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 19700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to handle potential exception 19720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 19740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint handlePotentialException( 19750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ConditionCode code_excep, ConditionCode code_okay, 19760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int exceptionNum, const char* errName) { 19770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen char label[LABEL_SIZE]; 19780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 19800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rememberState(exceptionNum); 19810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen snprintf(label, LABEL_SIZE, "after_exception_%d", exceptionNum); 19820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump(code_okay, label, true); 19830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(exceptionNum > 1) 19840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen nextVersionOfHardReg(PhysicalReg_EDX, 2); //next version has 2 ref count 19850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen export_pc(); //use %edx 19860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen constVREndOfBB(); 19870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("exception"); //dump GG, GL VRs 19880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!strcmp(errName, "common_throw_message")) { 19890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_imm_to_reg(OpndSize_32, LstrInstantiationErrorPtr, PhysicalReg_ECX, true); 19900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 19910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unconditional_jump_global_API(errName, false); 19920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(label, true); 19930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen goToState(exceptionNum); 19940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 19950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen snprintf(label, LABEL_SIZE, "after_exception_%d", exceptionNum); 19960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump(code_okay, label, true); 19970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen export_pc(); //use %edx 19980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!strcmp(errName, "common_throw_message")) { 19990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_imm_to_reg(OpndSize_32, LstrInstantiationErrorPtr, PhysicalReg_ECX, true); 20000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unconditional_jump_global_API(errName, false); 20020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(label, true); 20030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 20050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 20060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get the self pointer from glue 20070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 20080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses one scratch register 20090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_self_pointer(int reg, bool isPhysical) { 20100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offEBP_self, PhysicalReg_EBP, true, reg, isPhysical); 20110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 20120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 20130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get ResStrings from glue 20140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 20150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses two scratch registers 20160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_res_strings(int reg, bool isPhysical) { 20170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 || reg != NULL, use registerAlloc 20180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) { 20190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 20200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // load from spilled location, update spill_loc_index & physicalReg 20210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#if 0 20220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(C_SCRATCH_1, LowOpndRegType_gp, isScratchPhysical); 20230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(C_SCRATCH_1, LowOpndRegType_gp, isScratchPhysical); 20240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(C_SCRATCH_2, LowOpndRegType_gp, isScratchPhysical); 20250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateRefCount2(C_SCRATCH_2, LowOpndRegType_gp, isScratchPhysical); 20260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 20270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 20280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 20290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/); 20300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 20310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc_mem(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, offDvmDex_pResStrings, regAll, true, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp); 20320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 20330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 20350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen { 20360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 20370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical); 20380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //glue is not in a physical reg nor in a spilled location 20390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateGlue(C_SCRATCH_2, isScratchPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg 20400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offDvmDex_pResStrings, C_SCRATCH_2, isScratchPhysical, reg, isPhysical); 20410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 20430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 20440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_res_classes(int reg, bool isPhysical) { 20450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 || reg != NULL, use registerAlloc 20460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) { 20470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 20480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // load from spilled location, updte spill_loc_index & physicalReg 20490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 20500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 20510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/); 20520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 20530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc_mem(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, offDvmDex_pResClasses, regAll, true, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp); 20540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 20550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 20570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen { 20580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 20590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical); 20600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //glue is not in a physical reg nor in a spilled location 20610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateGlue(C_SCRATCH_2, isScratchPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg 20620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offDvmDex_pResClasses, C_SCRATCH_2, isScratchPhysical, reg, isPhysical); 20630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 20650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 20660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get ResFields from glue 20670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 20680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses two scratch registers 20690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_res_fields(int reg, bool isPhysical) { 20700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 || reg != NULL, use registerAlloc 20710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) { 20720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 20730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // load from spilled location, updte spill_loc_index & physicalReg 20740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 20750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 20760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/); 20770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 20780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc_mem(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, offDvmDex_pResFields, regAll, true, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp); 20790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 20800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 20820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen { 20830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 20840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical); 20850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //glue is not in a physical reg nor in a spilled location 20860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateGlue(C_SCRATCH_2, isScratchPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg 20870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offDvmDex_pResFields, C_SCRATCH_2, isScratchPhysical, reg, isPhysical); 20880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 20900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 20910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get ResMethods from glue 20920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 20930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses two scratch registers 20940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_res_methods(int reg, bool isPhysical) { 20950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 || reg != NULL, use registerAlloc 20960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) { 20970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 20980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // load from spilled location, updte spill_loc_index & physicalReg 20990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 21000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 21010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/); 21020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 21030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_mem_reg_noalloc_mem(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, offDvmDex_pResMethods, regAll, true, MemoryAccess_Unknown, -1, reg, isPhysical, LowOpndRegType_gp); 21040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 21050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 21070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen { 21080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 21090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical); 21100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //glue is not in a physical reg nor in a spilled location 21110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateGlue(C_SCRATCH_2, isScratchPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg 21120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offDvmDex_pResMethods, C_SCRATCH_2, isScratchPhysical, reg, isPhysical); 21130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 21150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 21160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get the current class object from glue 21170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses two scratch registers 21190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_glue_method_class(int reg, bool isPhysical) { 21200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 21210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.method), C_SCRATCH_1, isScratchPhysical, C_SCRATCH_2, isScratchPhysical); 21220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offMethod_clazz, C_SCRATCH_2, isScratchPhysical, reg, isPhysical); 21230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 21240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 21250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get the current method from glue 21260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses one scratch register 21280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_glue_method(int reg, bool isPhysical) { 21290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 21300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.method), C_SCRATCH_1, isScratchPhysical, reg, isPhysical); 21310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 21320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 21330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to set the current method in glue 21340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses one scratch register 21360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint set_glue_method(int reg, bool isPhysical) { 21370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 21380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, reg, isPhysical, offsetof(Thread, interpSave.method), C_SCRATCH_1, isScratchPhysical); 21390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 21400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 21410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get DvmDex from glue 21430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses one scratch register 21450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_glue_dvmdex(int reg, bool isPhysical) { 21460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 || reg != NULL, use registerAlloc 21470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isGlueHandled(PhysicalReg_GLUE_DVMDEX)) { 21480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if spill_loc_index > 0 21490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // load from spilled location, updte spill_loc_index & physicalReg 21500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 21510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 21520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(LowOpndRegType_gp, PhysicalReg_GLUE_DVMDEX, false, false/*updateRefCount*/); 21530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen donotSpillReg(regAll); 21540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_reg_reg_noalloc_src(Mnemonic_MOV, ATOM_NORMAL, OpndSize_32, regAll, true, 21550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, isPhysical, LowOpndRegType_gp); 21560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endNativeCode(); 21570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 21590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen { 21600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 21610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical, reg, isPhysical); 21620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //glue is not in a physical reg nor in a spilled location 21630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateGlue(reg, isPhysical, PhysicalReg_GLUE_DVMDEX); //spill_loc_index is -1, set physicalReg 21640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 21660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 21670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to set DvmDex in glue 21680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses one scratch register 21700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint set_glue_dvmdex(int reg, bool isPhysical) { 21710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 21720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, reg, isPhysical, offsetof(Thread, interpSave.methodClassDex), C_SCRATCH_1, isScratchPhysical); 21730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 21740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 21750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get SuspendCount from glue 21760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses one scratch register 21780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_suspendCount(int reg, bool isPhysical) { 21790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 21800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offsetof(Thread, suspendCount), C_SCRATCH_1, isScratchPhysical, reg, isPhysical); 21810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 21820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 21830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get retval from glue 21850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses one scratch register 21870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_return_value(OpndSize size, int reg, bool isPhysical) { 21880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 21890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(size, offsetof(Thread, interpSave.retval), C_SCRATCH_1, isScratchPhysical, reg, isPhysical); 21900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 21910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 21920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to set retval in glue 21930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses one scratch register 21950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint set_return_value(OpndSize size, int reg, bool isPhysical) { 21960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 21970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(size, reg, isPhysical, offsetof(Thread, interpSave.retval), C_SCRATCH_1, isScratchPhysical); 21980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 21990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to clear exception object in glue 22010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses two scratch registers 22030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint clear_exception() { 22040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_2, isScratchPhysical); 22050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_imm_to_mem(OpndSize_32, 0, offsetof(Thread, exception), C_SCRATCH_2, isScratchPhysical); 22060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 22070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to get exception object in glue 22090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses two scratch registers 22110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint get_exception(int reg, bool isPhysical) { 22120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_2, isScratchPhysical); 22130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, offsetof(Thread, exception), C_SCRATCH_2, isScratchPhysical, reg, isPhysical); 22140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 22150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to set exception object in glue 22170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses two scratch registers 22190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint set_exception(int reg, bool isPhysical) { 22200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_2, isScratchPhysical); 22210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, reg, isPhysical, offsetof(Thread, exception), C_SCRATCH_2, isScratchPhysical); 22220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 22230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to save frame pointer and current PC in stack frame to glue 22250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It uses two scratch registers 22270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint save_pc_fp_to_glue() { 22280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 22290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, PhysicalReg_FP, true, offsetof(Thread, interpSave.curFrame), C_SCRATCH_1, isScratchPhysical); 22300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //from stack-save currentPc 22320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg(OpndSize_32, -sizeofStackSaveArea+offStackSaveArea_localRefTop, PhysicalReg_FP, true, C_SCRATCH_2, isScratchPhysical); 22330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, C_SCRATCH_2, isScratchPhysical, offsetof(Thread, interpSave.pc), C_SCRATCH_1, isScratchPhysical); 22340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 22350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! get SaveArea pointer 22370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 22390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint savearea_from_fp(int reg, bool isPhysical) { 22400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(-sizeofStackSaveArea, PhysicalReg_FP, true, reg, isPhysical); 22410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 22420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_CALL_STACK3 22450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_debug_dumpSwitch() { 22460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(int); 22470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = debug_dumpSwitch; 22480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "debug_dumpSwitch"); 22490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 22500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 22520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmQuasiAtomicSwap64() { 22540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef int64_t (*vmHelper)(int64_t, volatile int64_t*); 22550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmQuasiAtomicSwap64; 22560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 22570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmQuasiAtomicSwap64"); 22580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmQuasiAtomicSwap64"); 22590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmQuasiAtomicSwap64"); 22600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 22610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmQuasiAtomicSwap64"); 22620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 22640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmQuasiAtomicRead64() { 22670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef int64_t (*vmHelper)(volatile const int64_t*); 22680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmQuasiAtomicRead64; 22690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 22700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmQuasiAtomiRead64"); 22710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmQuasiAtomicRead64"); 22720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmQuasiAtomicRead64"); 22730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEax(); //for return value 22740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); 22750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 22760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmQuasiAtomicRead64"); 22770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 22790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmJitToInterpPunt() { 22820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(int); 22830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmJitToInterpPunt; 22840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitToInterpPunt"); 22850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 22860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmJitToInterpNormal() { 22890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(int); 22900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmJitToInterpNormal; 22910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 22920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmJitToInterpNormal"); 22930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitToInterpNormal"); 22940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmJitToInterpNormal"); 22950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); 22960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 22970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitToInterpNormal"); 22980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 23000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 23010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmJitToInterpTraceSelectNoChain() { 23030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(int); 23040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmJitToInterpTraceSelectNoChain; 23050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 23060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmJitToInterpTraceSelectNoChain"); 23070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitToInterpTraceSelectNoChain"); 23080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmJitToInterpTraceSelectNoChain"); 23090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); 23100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 23110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitToInterpTraceSelectNoChain"); 23120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 23140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 23150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmJitToInterpTraceSelect() { 23170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(int); 23180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmJitToInterpTraceSelect; 23190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 23200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmJitToInterpTraceSelect"); 23210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitToInterpTraceSelect"); 23220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmJitToInterpTraceSelect"); 23230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); 23240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 23250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitToInterpTraceSelect"); 23260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 23280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 23290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmJitToPatchPredictedChain() { 23310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef const Method * (*vmHelper)(const Method *method, 23320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Thread *self, 23330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen PredictedChainingCell *cell, 23340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen const ClassObject *clazz); 23350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmJitToPatchPredictedChain; 23360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 23370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmJitToPatchPredictedChain"); 23380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitToPatchPredictedChain"); 23390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmJitToPatchPredictedChain"); 23400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 23410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitToPatchPredictedChain"); 23420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 23440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 23450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call __moddi3 23470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 23490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_moddi3() { 23500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 23510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("moddi3"); 23520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((intptr_t)__moddi3, "__moddi3"); 23530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("moddi3"); 23540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 23550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((intptr_t)__moddi3, "__moddi3"); 23560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 23580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 23590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call __divdi3 23600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 23620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_divdi3() { 23630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 23640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("divdi3"); 23650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((intptr_t)__divdi3, "__divdi3"); 23660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("divdi3"); 23670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 23680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((intptr_t)__divdi3, "__divdi3"); 23690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 23710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 23720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call fmod 23740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 23760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_fmod() { 23770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef double (*libHelper)(double, double); 23780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen libHelper funcPtr = fmod; 23790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 23800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("fmod"); 23810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "fmod"); 23820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("fmod"); 23830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 23840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "fmod"); 23850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 23870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 23880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call fmodf 23890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 23910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_fmodf() { 23920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef float (*libHelper)(float, float); 23930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen libHelper funcPtr = fmodf; 23940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 23950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("fmodf"); 23960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "fmodf"); 23970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("fmodf"); 23980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 23990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "fmodf"); 24000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 24020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 24030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmFindCatchBlock 24040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 24060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmFindCatchBlock() { 24070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //int dvmFindCatchBlock(Thread* self, int relPc, Object* exception, 24080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //bool doUnroll, void** newFrame) 24090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef int (*vmHelper)(Thread*, int, Object*, bool, void**); 24100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmFindCatchBlock; 24110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 24120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmFindCatchBlock"); 24130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmFindCatchBlock"); 24140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmFindCatchBlock"); 24150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 24160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmFindCatchBlock"); 24170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 24190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 24200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmThrowVerificationError 24210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 24230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmThrowVerificationError() { 24240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(const Method*, int, int); 24250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmThrowVerificationError; 24260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 24270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmThrowVerificationError"); 24280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmThrowVerificationError"); 24290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmThrowVerificationError"); 24300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 24310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmThrowVerificationError"); 24320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 24340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 24350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmResolveMethod 24370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 24390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmResolveMethod() { 24400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //Method* dvmResolveMethod(const ClassObject* referrer, u4 methodIdx, MethodType methodType); 24410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef Method* (*vmHelper)(const ClassObject*, u4, MethodType); 24420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmResolveMethod; 24430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 24440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmResolveMethod"); 24450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveMethod"); 24460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmResolveMethod"); 24470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 24480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveMethod"); 24490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 24510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 24520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmResolveClass 24530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 24550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmResolveClass() { 24560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //ClassObject* dvmResolveClass(const ClassObject* referrer, u4 classIdx, bool fromUnverifiedConstant) 24570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef ClassObject* (*vmHelper)(const ClassObject*, u4, bool); 24580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmResolveClass; 24590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 24600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmResolveClass"); 24610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveClass"); 24620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmResolveClass"); 24630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 24640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveClass"); 24650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 24670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 24680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmInstanceofNonTrivial 24700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 24720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmInstanceofNonTrivial() { 24730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef int (*vmHelper)(const ClassObject*, const ClassObject*); 24740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmInstanceofNonTrivial; 24750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 24760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmInstanceofNonTrivial"); 24770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmInstanceofNonTrivial"); 24780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmInstanceofNonTrivial"); 24790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 24800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmInstanceofNonTrivial"); 24810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 24830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 24840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmThrowException 24850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 24870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmThrow() { 24880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(ClassObject* exceptionClass, const char*); 24890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmThrowException; 24900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 24910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmThrowException"); 24920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmThrowException"); 24930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmThrowException"); 24940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 24950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmThrowException"); 24960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 24980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 24990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmThrowExceptionWithClassMessage 25000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 25020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmThrowWithMessage() { 25030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(ClassObject* exceptionClass, const char*); 25040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmThrowExceptionWithClassMessage; 25050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 25060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmThrowExceptionWithClassMessage"); 25070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmThrowExceptionWithClassMessage"); 25080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmThrowExceptionWithClassMessage"); 25090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 25100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmThrowExceptionWithClassMessage"); 25110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 25130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 25140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmCheckSuspendPending 25150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 25170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmCheckSuspendPending() { 25180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef bool (*vmHelper)(Thread*); 25190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmCheckSuspendPending; 25200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 25210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmCheckSuspendPending"); 25220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmCheckSuspendPending"); 25230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmCheckSuspendPending"); 25240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 25250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmCheckSuspendPending"); 25260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 25280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 25290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmLockObject 25300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 25320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmLockObject() { 25330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(struct Thread*, struct Object*); 25340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmLockObject; 25350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 25360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmLockObject"); 25370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmLockObject"); 25380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmLockObject"); 25390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 25400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmLockObject"); 25410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 25430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 25440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmUnlockObject 25450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 25470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmUnlockObject() { 25480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef bool (*vmHelper)(Thread*, Object*); 25490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmUnlockObject; 25500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 25510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmUnlockObject"); 25520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmUnlockObject"); 25530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmUnlockObject"); 25540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 25550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmUnlockObject"); 25560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 25580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 25590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmInitClass 25600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 25620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmInitClass() { 25630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef bool (*vmHelper)(ClassObject*); 25640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmInitClass; 25650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 25660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmInitClass"); 25670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmInitClass"); 25680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmInitClass"); 25690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 25700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmInitClass"); 25710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 25730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 25740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmAllocObject 25750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 25770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmAllocObject() { 25780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef Object* (*vmHelper)(ClassObject*, int); 25790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmAllocObject; 25800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 25810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmAllocObject"); 25820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmAllocObject"); 25830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmAllocObject"); 25840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 25850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmAllocObject"); 25860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 25880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 25890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmAllocArrayByClass 25900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 25920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmAllocArrayByClass() { 25930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef ArrayObject* (*vmHelper)(ClassObject*, size_t, int); 25940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmAllocArrayByClass; 25950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 25960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmAllocArrayByClass"); 25970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmAllocArrayByClass"); 25980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmAllocArrayByClass"); 25990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 26000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmAllocArrayByClass"); 26010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 26030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 26040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmAllocPrimitiveArray 26050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 26070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmAllocPrimitiveArray() { 26080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef ArrayObject* (*vmHelper)(char, size_t, int); 26090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmAllocPrimitiveArray; 26100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 26110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmAllocPrimitiveArray"); 26120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmAllocPrimitiveArray"); 26130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmAllocPrimitiveArray"); 26140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 26150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmAllocPrimitiveArray"); 26160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 26180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 26190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmInterpHandleFillArrayData 26200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 26220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmInterpHandleFillArrayData() { 26230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef bool (*vmHelper)(ArrayObject*, const u2*); 26240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmInterpHandleFillArrayData; 26250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 26260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmInterpHandleFillArrayData"); //before move_imm_to_reg to avoid spilling C_SCRATCH_1 26270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmInterpHandleFillArrayData"); 26280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmInterpHandleFillArrayData"); 26290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 26300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmInterpHandleFillArrayData"); 26310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 26330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 26340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmNcgHandlePackedSwitch 26360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 26380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmNcgHandlePackedSwitch() { 26390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef s4 (*vmHelper)(const s4*, s4, u2, s4); 26400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmNcgHandlePackedSwitch; 26410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 26420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmNcgHandlePackedSwitch"); 26430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmNcgHandlePackedSwitch"); 26440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmNcgHandlePackedSwitch"); 26450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 26460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmNcgHandlePackedSwitch"); 26470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 26490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 26500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmJitHandlePackedSwitch() { 26520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef s4 (*vmHelper)(const s4*, s4, u2, s4); 26530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmJitHandlePackedSwitch; 26540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 26550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmJitHandlePackedSwitch"); 26560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitHandlePackedSwitch"); 26570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmJitHandlePackedSwitch"); 26580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 26590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitHandlePackedSwitch"); 26600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 26620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 26630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmNcgHandleSparseSwitch 26650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 26670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmNcgHandleSparseSwitch() { 26680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef s4 (*vmHelper)(const s4*, u2, s4); 26690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmNcgHandleSparseSwitch; 26700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 26710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmNcgHandleSparseSwitch"); 26720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmNcgHandleSparseSwitch"); 26730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmNcgHandleSparseSwitch"); 26740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 26750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmNcgHandleSparseSwitch"); 26760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 26780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 26790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmJitHandleSparseSwitch() { 26810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef s4 (*vmHelper)(const s4*, u2, s4); 26820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmJitHandleSparseSwitch; 26830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 26840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmJitHandleSparseSwitch"); 26850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitHandleSparseSwitch"); 26860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmJitHandleSparseSwitch"); 26870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 26880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmJitHandleSparseSwitch"); 26890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 26910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 26920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmCanPutArrayElement 26940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 26960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmCanPutArrayElement() { 26970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef bool (*vmHelper)(const ClassObject*, const ClassObject*); 26980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmCanPutArrayElement; 26990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 27000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmCanPutArrayElement"); 27010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmCanPutArrayElement"); 27020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmCanPutArrayElement"); 27030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 27040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmCanPutArrayElement"); 27050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 27070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 27080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27093d20456e5dc28cbbe3cf8df092e9ffafee6fad65Elliott Hughes//!generate native code to call dvmFindInterfaceMethodInCache 27100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 27120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmFindInterfaceMethodInCache() { 27130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef Method* (*vmHelper)(ClassObject*, u4, const Method*, DvmDex*); 27143d20456e5dc28cbbe3cf8df092e9ffafee6fad65Elliott Hughes vmHelper funcPtr = dvmFindInterfaceMethodInCache; 27150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 27163d20456e5dc28cbbe3cf8df092e9ffafee6fad65Elliott Hughes beforeCall("dvmFindInterfaceMethodInCache"); 27173d20456e5dc28cbbe3cf8df092e9ffafee6fad65Elliott Hughes callFuncPtr((int)funcPtr, "dvmFindInterfaceMethodInCache"); 27183d20456e5dc28cbbe3cf8df092e9ffafee6fad65Elliott Hughes afterCall("dvmFindInterfaceMethodInCache"); 27190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 27203d20456e5dc28cbbe3cf8df092e9ffafee6fad65Elliott Hughes callFuncPtr((int)funcPtr, "dvmFindInterfaceMethodInCache"); 27210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 27230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 27240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmHandleStackOverflow 27260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 27280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmHandleStackOverflow() { 27290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(Thread*, const Method*); 27300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmHandleStackOverflow; 27310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 27320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmHandleStackOverflow"); 27330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmHandleStackOverflow"); 27340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmHandleStackOverflow"); 27350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 27360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmHandleStackOverflow"); 27370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 27390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 27400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmResolveString 27410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 27430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmResolveString() { 27440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //StringObject* dvmResolveString(const ClassObject* referrer, u4 stringIdx) 27450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef StringObject* (*vmHelper)(const ClassObject*, u4); 27460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmResolveString; 27470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 27480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmResolveString"); 27490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveString"); 27500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmResolveString"); 27510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 27520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveString"); 27530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 27550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 27560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmResolveInstField 27570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 27590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmResolveInstField() { 27600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //InstField* dvmResolveInstField(const ClassObject* referrer, u4 ifieldIdx) 27610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef InstField* (*vmHelper)(const ClassObject*, u4); 27620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmResolveInstField; 27630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 27640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmResolveInstField"); 27650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveInstField"); 27660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmResolveInstField"); 27670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 27680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveInstField"); 27690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 27710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 27720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!generate native code to call dvmResolveStaticField 27730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 27750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint call_dvmResolveStaticField() { 27760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //StaticField* dvmResolveStaticField(const ClassObject* referrer, u4 sfieldIdx) 27770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef StaticField* (*vmHelper)(const ClassObject*, u4); 27780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = dvmResolveStaticField; 27790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvm.executionMode == kExecutionModeNcgO1) { 27800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen beforeCall("dvmResolveStaticField"); 27810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveStaticField"); 27820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen afterCall("dvmResolveStaticField"); 27830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 27840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen callFuncPtr((int)funcPtr, "dvmResolveStaticField"); 27850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 27870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 27880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define P_GPR_2 PhysicalReg_ECX 27900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/*! 27910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen\brief This function is used to resolve a string reference 27920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenINPUT: const pool index in %eax 27940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenOUTPUT: resolved string in %eax 27960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe registers are hard-coded, 2 physical registers %esi and %edx are used as scratch registers; 27980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenIt calls a C function dvmResolveString; 27990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe only register that is still live after this function is ebx 28000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 28010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint const_string_resolve() { 28020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX; 28030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null; 28040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(".const_string_resolve", false); 28050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //method stored in glue structure as well as on the interpreted stack 28060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_glue_method_class(P_GPR_2, true); 28070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 28080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, PhysicalReg_EAX, true, 4, PhysicalReg_ESP, true); 28090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, P_GPR_2, true, 0, PhysicalReg_ESP, true); 28100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen call_dvmResolveString(); 28110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 28120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compare_imm_reg( OpndSize_32, 0, PhysicalReg_EAX, true); 28130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump(Condition_E, "common_exceptionThrown", false); 28140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen x86_return(); 28150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 28160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 28170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#undef P_GPR_2 28180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/*! 28190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen\brief This function is used to resolve a class 28200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenINPUT: const pool index in argument "indexReg" (%eax) 28220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenOUTPUT: resolved class in %eax 28240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe registers are hard-coded, 3 physical registers (%esi, %edx, startLR:%eax) are used as scratch registers. 28260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenIt calls a C function dvmResolveClass; 28270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe only register that is still live after this function is ebx 28280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 28290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint resolve_class2( 28300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int startLR/*scratch register*/, bool isPhysical, int indexReg/*const pool index*/, 28310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool indexPhysical, int thirdArg) { 28320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(".class_resolve", false); 28330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX; 28340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null; 28350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //push index to stack first, to free indexReg 28370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 28380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, indexReg, indexPhysical, 4, PhysicalReg_ESP, true); 28390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_glue_method_class(startLR, isPhysical); 28400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_imm_to_mem(OpndSize_32, thirdArg, 8, PhysicalReg_ESP, true); 28410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, startLR, isPhysical, 0, PhysicalReg_ESP, true); 28420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen call_dvmResolveClass(); 28430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 28440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true); 28450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump(Condition_E, "common_exceptionThrown", false); 28460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen x86_return(); 28480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 28490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 28500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/*! 28510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen\brief This function is used to resolve a method, and it is called once with %eax for both indexReg and startLR 28520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenINPUT: const pool index in argument "indexReg" (%eax) 28540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenOUTPUT: resolved method in %eax 28560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe registers are hard-coded, 3 physical registers (%esi, %edx, startLR:%eax) are used as scratch registers. 28580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenIt calls a C function dvmResolveMethod; 28590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe only register that is still live after this function is ebx 28600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 28610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint resolve_method2( 28620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/, 28630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool indexPhysical, 28640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int thirdArg/*VIRTUAL*/) { 28650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(thirdArg == METHOD_VIRTUAL) 28660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(".virtual_method_resolve", false); 28670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(thirdArg == METHOD_DIRECT) 28680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(".direct_method_resolve", false); 28690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(thirdArg == METHOD_STATIC) 28700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(".static_method_resolve", false); 28710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(-12, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 28730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, indexReg, indexPhysical, 4, PhysicalReg_ESP, true); 28740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX; 28760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null; 28770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_glue_method_class(startLR, isPhysical); 28780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_imm_to_mem(OpndSize_32, thirdArg, 8, PhysicalReg_ESP, true); 28800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, startLR, isPhysical, 0, PhysicalReg_ESP, true); 28810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen call_dvmResolveMethod(); 28820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(12, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 28830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true); 28840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump(Condition_E, "common_exceptionThrown", false); 28850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen x86_return(); 28870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 28880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 28890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/*! 28900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen\brief This function is used to resolve an instance field 28910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenINPUT: const pool index in argument "indexReg" (%eax) 28930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenOUTPUT: resolved field in %eax 28950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe registers are hard-coded, 3 physical registers (%esi, %edx, startLR:%eax) are used as scratch registers. 28970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenIt calls a C function dvmResolveInstField; 28980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe only register that is still live after this function is ebx 28990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 29000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint resolve_inst_field2( 29010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int startLR/*logical register index*/, bool isPhysical, 29020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexReg/*const pool index*/, bool indexPhysical) { 29030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(".inst_field_resolve", false); 29040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX; 29050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null; 29060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 29080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, indexReg, indexPhysical, 4, PhysicalReg_ESP, true); 29090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //method stored in glue structure as well as interpreted stack 29100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_glue_method_class(startLR, isPhysical); 29110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, startLR, isPhysical, 0, PhysicalReg_ESP, true); 29120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen call_dvmResolveInstField(); 29130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 29140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true); 29150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump(Condition_E, "common_exceptionThrown", false); 29160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen x86_return(); 29180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 29190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 29200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/*! 29210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen\brief This function is used to resolve a static field 29220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenINPUT: const pool index in argument "indexReg" (%eax) 29240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenOUTPUT: resolved field in %eax 29260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe registers are hard-coded, 3 physical registers (%esi, %edx, startLR:%eax) are used as scratch registers. 29280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenIt calls a C function dvmResolveStaticField; 29290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenThe only register that is still live after this function is ebx 29300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 29310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint resolve_static_field2( 29320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/, 29330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool indexPhysical) { 29340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLabel(".static_field_resolve", false); 29350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[0] = PhysicalReg_ESI; scratchRegs[1] = PhysicalReg_EDX; 29360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null; 29370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 29390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, indexReg, indexPhysical, 4, PhysicalReg_ESP, true); 29400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_glue_method_class(startLR, isPhysical); 29410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem(OpndSize_32, startLR, isPhysical, 0, PhysicalReg_ESP, true); 29420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen call_dvmResolveStaticField(); 29430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 29440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compare_imm_reg(OpndSize_32, 0, PhysicalReg_EAX, true); 29450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen conditional_jump(Condition_E, "common_exceptionThrown", false); 29460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen x86_return(); 29480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 29490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 29500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint pushAllRegs() { 29520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(-28, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 29530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EAX, true, 24, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1); 29540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EBX, true, 20, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1); 29550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_ECX, true, 16, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1); 29560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EDX, true, 12, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1); 29570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_ESI, true, 8, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1); 29580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EDI, true, 4, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1); 29590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EBP, true, 0, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1); 29600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 29610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 29620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint popAllRegs() { 29630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(OpndSize_32, 24, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EAX, true); 29640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(OpndSize_32, 20, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EBX, true); 29650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(OpndSize_32, 16, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_ECX, true); 29660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(OpndSize_32, 12, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EDX, true); 29670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(OpndSize_32, 8, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_ESI, true); 29680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(OpndSize_32, 4, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EDI, true); 29690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(OpndSize_32, 0, PhysicalReg_ESP, true, MemoryAccess_Unknown, -1, PhysicalReg_EBP, true); 29700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(28, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 29710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 29720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 29730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dump_nop(int size) { 29750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen switch(size) { 29760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen case 1: 29770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen *stream = 0x90; 29780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 29790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen case 2: 29800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen *stream = 0x66; 29810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen *(stream +1) = 0x90; 29820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 29830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen case 3: 29840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen *stream = 0x0f; 29850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen *(stream + 1) = 0x1f; 29860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen *(stream + 2) = 0x00; 29870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 29880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen default: 29890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //TODO: add more cases. 29900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 29910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stream += size; 29930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 2994