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 = &currentAtomMem->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