summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen/x86/Lower.h
diff options
context:
space:
mode:
authorDong-Yuan Chen <dong-yuan.chen@intel.com>2012-07-03 13:13:07 -0700
committerElliott Hughes <enh@google.com>2012-07-20 12:27:18 -0700
commit0c2dc522d0e120f346cf0a40c8cf0c93346131c2 (patch)
treef7ca4c8e3ca1150b7e8c5f4b68c60972641dc77f /vm/compiler/codegen/x86/Lower.h
parentabede656a1f2330e3d31281fb208be7c04e8eb56 (diff)
downloadandroid_dalvik-0c2dc522d0e120f346cf0a40c8cf0c93346131c2.tar.gz
android_dalvik-0c2dc522d0e120f346cf0a40c8cf0c93346131c2.tar.bz2
android_dalvik-0c2dc522d0e120f346cf0a40c8cf0c93346131c2.zip
[X86] X86 trace JIT compiler support
This patch provides a fully functional x86 trace JIT compiler for Dalvik VM. It is built on top of the existing x86 fast interpreter with bug fixes and needed extension to support trace JIT interface. The x86 trace JIT code generator was developed independent of the existing template-based code generator and thus does not share exactly the same infrastructure. Included in this patch are: * Deprecated and removed the x86-atom fast interpreter that is no longer functional since ICS. * Augmented x86 fast interpreter to provide interfaces for x86 trace JIT compiler. * Added x86 trace JIT code generator with full JDWP debugging support. * Method JIT and self-verification mode are not supported. The x86 code generator uses the x86 instruction encoder/decoder library from the Apache Harmony project. Additional wrapper extension and bug fixes were added to support the x86 trace JIT code generator. The x86 instruction encoder/decoder is embedded inside the x86 code generator under the libenc subdirectory. Change-Id: I241113681963a16c13a3562390813cbaaa6eedf0 Signed-off-by: Dong-Yuan Chen <dong-yuan.chen@intel.com> Signed-off-by: Yixin Shou <yixin.shou@intel.com> Signed-off-by: Johnnie Birch <johnnie.l.birch.jr@intel.com> Signed-off-by: Udayan <udayan.banerji@intel.com> Signed-off-by: Sushma Kyasaralli Thimmappa <sushma.kyasaralli.thimmappa@intel.com> Signed-off-by: Bijoy Jose <bijoy.a.jose@intel.com> Signed-off-by: Razvan A Lupusoru <razvan.a.lupusoru@intel.com> Signed-off-by: Tim Hartley <timothy.d.hartley@intel.com>
Diffstat (limited to 'vm/compiler/codegen/x86/Lower.h')
-rw-r--r--vm/compiler/codegen/x86/Lower.h1240
1 files changed, 1240 insertions, 0 deletions
diff --git a/vm/compiler/codegen/x86/Lower.h b/vm/compiler/codegen/x86/Lower.h
new file mode 100644
index 000000000..630ccb98d
--- /dev/null
+++ b/vm/compiler/codegen/x86/Lower.h
@@ -0,0 +1,1240 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file lower.h
+ \brief A header file to define interface between lowering and register allocator
+*/
+
+#ifndef _DALVIK_LOWER
+#define _DALVIK_LOWER
+
+#define CODE_CACHE_PADDING 1024 //code space for a single bytecode
+// comment out for phase 1 porting
+#define PREDICTED_CHAINING
+#define JIT_CHAIN
+
+#define NUM_DEPENDENCIES 24 /* max number of dependencies from a LowOp */
+//compilaton flags used by NCG O1
+#define DUMP_EXCEPTION //to measure performance, required to have correct exception handling
+/*! multiple versions for hardcoded registers */
+#define HARDREG_OPT
+#define CFG_OPT
+/*! remove redundant move ops when accessing virtual registers */
+#define MOVE_OPT
+/*! remove redundant spill of virtual registers */
+#define SPILL_OPT
+#define XFER_OPT
+//#define DSE_OPT //no perf improvement for cme
+/*! use live range analysis to allocate registers */
+#define LIVERANGE_OPT
+/*! remove redundant null check */
+#define NULLCHECK_OPT
+//#define BOUNDCHECK_OPT
+/*! optimize the access to glue structure */
+#define GLUE_OPT
+#define CALL_FIX
+#define NATIVE_FIX
+#define INVOKE_FIX //optimization
+#define GETVR_FIX //optimization
+
+#include "Dalvik.h"
+#include "enc_wrapper.h"
+#include "AnalysisO1.h"
+#include "compiler/CompilerIR.h"
+
+//compilation flags for debugging
+//#define DEBUG_INFO
+//#define DEBUG_CALL_STACK
+//#define DEBUG_IGET_OBJ
+//#define DEBUG_NCG_CODE_SIZE
+//#define DEBUG_NCG
+//#define DEBUG_NCG_1
+//#define DEBUG_LOADING
+//#define USE_INTERPRETER
+//#define DEBUG_EACH_BYTECODE
+
+/*! registers for functions are hardcoded */
+#define HARDCODE_REG_CALL
+#define HARDCODE_REG_SHARE
+#define HARDCODE_REG_HELPER
+
+#define PhysicalReg_FP PhysicalReg_EDI
+#define PhysicalReg_Glue PhysicalReg_EBP
+
+//COPIED from interp/InterpDefs.h
+#define FETCH(_offset) (rPC[(_offset)])
+#define INST_INST(_inst) ((_inst) & 0xff)
+#define INST_A(_inst) (((_inst) >> 8) & 0x0f)
+#define INST_B(_inst) ((_inst) >> 12)
+#define INST_AA(_inst) ((_inst) >> 8)
+
+//#include "vm/mterp/common/asm-constants.h"
+#define offEBP_self 8
+#define offEBP_spill -56
+#define offThread_exception 68
+#define offClassObject_descriptor 24
+#define offArrayObject_length 8
+#ifdef PROFILE_FIELD_ACCESS
+#define offStaticField_value 24
+#define offInstField_byteOffset 24
+#else
+#define offStaticField_value 16
+#define offInstField_byteOffset 16
+#endif
+
+#ifdef EASY_GDB
+#define offStackSaveArea_prevFrame 4
+#define offStackSaveArea_savedPc 8
+#define offStackSaveArea_method 12
+#define offStackSaveArea_localRefTop 16 // -> StackSaveArea.xtra.locakRefCookie
+#define offStackSaveArea_returnAddr 20
+#define offStackSaveArea_isDebugInterpreted 24
+#define sizeofStackSaveArea 24
+#else
+#define offStackSaveArea_prevFrame 0
+#define offStackSaveArea_savedPc 4
+#define offStackSaveArea_method 8
+#define offStackSaveArea_localRefTop 12 // -> StackSaveArea.xtra.locakRefCookie
+#define offStackSaveArea_returnAddr 16
+#define offStackSaveArea_isDebugInterpreted 20
+#define sizeofStackSaveArea 20
+#endif
+
+#define offClassObject_status 44
+#define offClassObject_accessFlags 32
+#ifdef MTERP_NO_UNALIGN_64
+#define offArrayObject_contents 16
+#else
+#define offArrayObject_contents 12
+#endif
+
+#define offField_clazz 0
+#define offObject_clazz 0
+#define offClassObject_vtable 116
+#define offClassObject_pDvmDex 40
+#define offClassObject_super 72
+#define offClassObject_vtableCount 112
+#define offMethod_name 16
+#define offMethod_accessFlags 4
+#define offMethod_methodIndex 8
+#define offMethod_registersSize 10
+#define offMethod_outsSize 12
+#define offGlue_interpStackEnd 32
+#define offThread_inJitCodeCache 124
+#define offThread_jniLocal_nextEntry 168
+#define offMethod_insns 32
+#ifdef ENABLE_TRACING
+#define offMethod_insns_bytecode 44
+#define offMethod_insns_ncg 48
+#endif
+
+#define offGlue_pc 0
+#define offGlue_fp 4
+#define offGlue_retval 8
+
+#define offThread_curFrame 4
+#define offGlue_method 16
+#define offGlue_methodClassDex 20
+#define offGlue_self 24
+#define offGlue_pSelfSuspendCount 36
+#define offGlue_cardTable 40
+#define offGlue_pDebuggerActive 44
+#define offGlue_pActiveProfilers 48
+#define offGlue_entryPoint 52
+#define offGlue_icRechainCount 84
+#define offGlue_espEntry 88
+#define offGlue_spillRegion 92
+#define offDvmDex_pResStrings 8
+#define offDvmDex_pResClasses 12
+#define offDvmDex_pResMethods 16
+#define offDvmDex_pResFields 20
+#define offMethod_clazz 0
+
+// Definitions must be consistent with vm/mterp/x86/header.S
+#define FRAME_SIZE 124
+
+typedef enum ArgsDoneType {
+ ArgsDone_Normal = 0,
+ ArgsDone_Native,
+ ArgsDone_Full
+} ArgsDoneType;
+
+/*! An enum type
+ to list bytecodes for AGET, APUT
+*/
+typedef enum ArrayAccess {
+ AGET, AGET_WIDE, AGET_CHAR, AGET_SHORT, AGET_BOOLEAN, AGET_BYTE,
+ APUT, APUT_WIDE, APUT_CHAR, APUT_SHORT, APUT_BOOLEAN, APUT_BYTE
+} ArrayAccess;
+/*! An enum type
+ to list bytecodes for IGET, IPUT
+*/
+typedef enum InstanceAccess {
+ IGET, IGET_WIDE, IPUT, IPUT_WIDE
+} InstanceAccess;
+/*! An enum type
+ to list bytecodes for SGET, SPUT
+*/
+typedef enum StaticAccess {
+ SGET, SGET_WIDE, SPUT, SPUT_WIDE
+} StaticAccess;
+
+typedef enum JmpCall_type {
+ JmpCall_uncond = 1,
+ JmpCall_cond,
+ JmpCall_reg, //jump reg32
+ JmpCall_call
+} JmpCall_type;
+
+////////////////////////////////////////////////////////////////
+/* data structure for native codes */
+/* Due to space considation, a lowered op (LowOp) has two operands (LowOpnd), depending on
+ the type of the operand, LowOpndReg or LowOpndImm or LowOpndMem will follow */
+/*! type of an operand can be immediate, register or memory */
+typedef enum LowOpndType {
+ LowOpndType_Imm = 0,
+ LowOpndType_Reg,
+ LowOpndType_Mem,
+ LowOpndType_Label,
+ LowOpndType_NCG,
+ LowOpndType_Chain
+} LowOpndType;
+typedef enum LowOpndDefUse {
+ LowOpndDefUse_Def = 0,
+ LowOpndDefUse_Use,
+ LowOpndDefUse_UseDef
+} LowOpndDefUse;
+
+/*!
+\brief base data structure for an operand */
+typedef struct LowOpnd {
+ LowOpndType type;
+ OpndSize size;
+ LowOpndDefUse defuse;
+} LowOpnd;
+/*!
+\brief data structure for a register operand */
+typedef struct LowOpndReg {
+ LowOpndRegType regType;
+ int logicalReg;
+ int physicalReg;
+} LowOpndReg;
+/*!
+\brief data structure for an immediate operand */
+typedef struct LowOpndImm {
+ union {
+ s4 value;
+ unsigned char bytes[4];
+ };
+} LowOpndImm;
+
+typedef struct LowOpndNCG {
+ union {
+ s4 value;
+ unsigned char bytes[4];
+ };
+} LowOpndNCG;
+
+#define LABEL_SIZE 256
+typedef struct LowOpndLabel {
+ char label[LABEL_SIZE];
+ bool isLocal;
+} LowOpndLabel;
+
+/* get ready for optimizations at LIR
+ add MemoryAccessType & virtualRegNum to memory operands */
+typedef enum MemoryAccessType {
+ MemoryAccess_GLUE,
+ MemoryAccess_VR,
+ MemoryAccess_SPILL,
+ MemoryAccess_Unknown
+} MemoryAccessType;
+typedef enum UseDefEntryType {
+ UseDefType_Ctrl = 0,
+ UseDefType_Float,
+ UseDefType_MemVR,
+ UseDefType_MemSpill,
+ UseDefType_MemUnknown,
+ UseDefType_Reg
+} UseDefEntryType;
+typedef struct UseDefProducerEntry {
+ UseDefEntryType type;
+ int index; //enum PhysicalReg for "Reg" type
+ int producerSlot;
+} UseDefProducerEntry;
+#define MAX_USE_PER_ENTRY 50 /* at most 10 uses for each entry */
+typedef struct UseDefUserEntry {
+ UseDefEntryType type;
+ int index;
+ int useSlots[MAX_USE_PER_ENTRY];
+ int num_uses_per_entry;
+} UseDefUserEntry;
+
+/*!
+\brief data structure for a memory operand */
+typedef struct LowOpndMem {
+ LowOpndImm m_disp;
+ LowOpndImm m_scale;
+ LowOpndReg m_index;
+ LowOpndReg m_base;
+ bool hasScale;
+ MemoryAccessType mType;
+ int index;
+} LowOpndMem;
+
+typedef enum AtomOpCode {
+ ATOM_PSEUDO_CHAINING_CELL_BACKWARD_BRANCH = -15,
+ ATOM_NORMAL_ALU = -14,
+ ATOM_PSEUDO_ENTRY_BLOCK = -13,
+ ATOM_PSEUDO_EXIT_BLOCK = -12,
+ ATOM_PSEUDO_TARGET_LABEL = -11,
+ ATOM_PSEUDO_CHAINING_CELL_HOT = -10,
+ ATOM_PSEUDO_CHAINING_CELL_INVOKE_PREDICTED = -9,
+ ATOM_PSEUDO_CHAINING_CELL_INVOKE_SINGLETON = -8,
+ ATOM_PSEUDO_CHAINING_CELL_NORMAL = -7,
+ ATOM_PSEUDO_DALVIK_BYTECODE_BOUNDARY = -6,
+ ATOM_PSEUDO_ALIGN4 = -5,
+ ATOM_PSEUDO_PC_RECONSTRUCTION_CELL = -4,
+ ATOM_PSEUDO_PC_RECONSTRUCTION_BLOCK_LABEL = -3,
+ ATOM_PSEUDO_EH_BLOCK_LABEL = -2,
+ ATOM_PSEUDO_NORMAL_BLOCK_LABEL = -1,
+ ATOM_NORMAL,
+} AtomOpCode;
+
+typedef enum DependencyType {
+ Dependency_RAW,
+ Dependency_WAW,
+ Dependency_WAR,
+ Dependency_FLAG
+} DependencyType;
+typedef struct DependencyStruct {
+ DependencyType dType;
+ int nodeId;
+ int latency;
+} DependencyStruct;
+
+typedef struct LowOpBlock {
+ LIR generic;
+ Mnemonic opCode;
+ AtomOpCode opCode2;
+} LowOpBlock;
+
+/*!
+\brief data structure for a lowered operation */
+typedef struct LowOp {
+ LIR generic;
+ Mnemonic opCode;
+ AtomOpCode opCode2;
+ LowOpnd opnd1;
+ LowOpnd opnd2;
+ int numOperands;
+} LowOp;
+
+typedef struct LowOpLabel {
+ LowOp lop;
+ LowOpndLabel labelOpnd;
+}LowOpLabel;
+
+typedef struct LowOpNCG {
+ LowOp lop;
+ LowOpndNCG ncgOpnd;
+}LowOpNCG;
+
+typedef struct LowOpBlockLabel {
+ LowOpBlock lop;
+ LowOpndImm immOpnd;
+} LowOpBlockLabel;
+
+typedef struct LowOpImm {
+ LowOp lop;
+ LowOpndImm immOpnd;
+} LowOpImm;
+
+typedef struct LowOpMem {
+ LowOp lop;
+ LowOpndMem memOpnd;
+} LowOpMem;
+
+typedef struct LowOpReg {
+ LowOp lop;
+ LowOpndReg regOpnd;
+} LowOpReg;
+
+typedef struct LowOpImmImm {
+ LowOp lop;
+ LowOpndImm immOpnd1;
+ LowOpndImm immOpnd2;
+} LowOpImmImm;
+
+typedef struct LowOpImmReg {
+ LowOp lop;
+ LowOpndImm immOpnd1;
+ LowOpndReg regOpnd2;
+} LowOpImmReg;
+
+typedef struct LowOpImmMem {
+ LowOp lop;
+ LowOpndImm immOpnd1;
+ LowOpndMem memOpnd2;
+} LowOpImmMem;
+
+typedef struct LowOpRegImm {
+ LowOp lop;
+ LowOpndReg regOpnd1;
+ LowOpndImm immOpnd2;
+} LowOpRegImm;
+
+typedef struct LowOpRegReg {
+ LowOp lop;
+ LowOpndReg regOpnd1;
+ LowOpndReg regOpnd2;
+} LowOpRegReg;
+
+typedef struct LowOpRegMem {
+ LowOp lop;
+ LowOpndReg regOpnd1;
+ LowOpndMem memOpnd2;
+} LowOpRegMem;
+
+typedef struct LowOpMemImm {
+ LowOp lop;
+ LowOpndMem memOpnd1;
+ LowOpndImm immOpnd2;
+} LowOpMemImm;
+
+typedef struct LowOpMemReg {
+ LowOp lop;
+ LowOpndMem memOpnd1;
+ LowOpndReg regOpnd2;
+} LowOpMemReg;
+
+typedef struct LowOpMemMem {
+ LowOp lop;
+ LowOpndMem memOpnd1;
+ LowOpndMem memOpnd2;
+} LowOpMemMem;
+
+/*!
+\brief data structure for labels used when lowering a method
+
+four label maps are defined: globalMap globalShortMap globalWorklist globalShortWorklist
+globalMap: global labels where codePtr points to the label
+ freeLabelMap called in clearNCG
+globalWorklist: global labels where codePtr points to an instruciton using the label
+ standalone NCG -------
+ accessed by insertLabelWorklist & performLabelWorklist
+ code cache ------
+ inserted by performLabelWorklist(false),
+ handled & cleared by generateRelocation in NcgFile.c
+globalShortMap: local labels where codePtr points to the label
+ freeShortMap called after generation of one bytecode
+globalShortWorklist: local labels where codePtr points to an instruction using the label
+ accessed by insertShortWorklist & insertLabel
+definition of local label: life time of the label is within a bytecode or within a helper function
+extra label maps are used by code cache:
+ globalDataWorklist VMAPIWorklist
+*/
+typedef struct LabelMap {
+ char label[LABEL_SIZE];
+ char* codePtr; //code corresponding to the label or code that uses the label
+ struct LabelMap* nextItem;
+ OpndSize size;
+ uint addend;
+} LabelMap;
+/*!
+\brief data structure to handle forward jump (GOTO, IF)
+
+accessed by insertNCGWorklist & performNCGWorklist
+*/
+typedef struct NCGWorklist {
+ //when WITH_JIT, relativePC stores the target basic block id
+ s4 relativePC; //relative offset in bytecode
+ int offsetPC; //PC in bytecode
+ int offsetNCG; //PC in native code
+ char* codePtr; //code for native jump instruction
+ struct NCGWorklist* nextItem;
+ OpndSize size;
+}NCGWorklist;
+/*!
+\brief data structure to handle SWITCH & FILL_ARRAY_DATA
+
+two data worklist are defined: globalDataWorklist (used by code cache) & methodDataWorklist
+methodDataWorklist is accessed by insertDataWorklist & performDataWorklist
+*/
+typedef struct DataWorklist {
+ s4 relativePC; //relative offset in bytecode to access the data
+ int offsetPC; //PC in bytecode
+ int offsetNCG; //PC in native code
+ char* codePtr; //code for native instruction add_imm_reg imm, %edx
+ char* codePtr2;//code for native instruction add_reg_reg %eax, %edx for SWITCH
+ // add_imm_reg imm, %edx for FILL_ARRAY_DATA
+ struct DataWorklist* nextItem;
+}DataWorklist;
+#ifdef ENABLE_TRACING
+typedef struct MapWorklist {
+ u4 offsetPC;
+ u4 offsetNCG;
+ int isStartOfPC; //1 --> true 0 --> false
+ struct MapWorklist* nextItem;
+} MapWorklist;
+#endif
+
+#define BUFFER_SIZE 1024 //# of Low Ops buffered
+//the following three numbers are hardcoded, please CHECK
+#define BYTECODE_SIZE_PER_METHOD 81920
+#define NATIVE_SIZE_PER_DEX 19000000 //FIXME for core.jar: 16M --> 18M for O1
+#define NATIVE_SIZE_FOR_VM_STUBS 100000
+#define MAX_HANDLER_OFFSET 1024 //maximal number of handler offsets
+
+extern int LstrClassCastExceptionPtr, LstrInstantiationErrorPtr, LstrInternalError, LstrFilledNewArrayNotImpl;
+extern int LstrArithmeticException, LstrArrayIndexException, LstrArrayStoreException, LstrStringIndexOutOfBoundsException;
+extern int LstrDivideByZero, LstrNegativeArraySizeException, LstrNoSuchMethodError, LstrNullPointerException;
+extern int LdoubNeg, LvaluePosInfLong, LvalueNegInfLong, LvalueNanLong, LshiftMask, Lvalue64, L64bits, LintMax, LintMin;
+
+extern LabelMap* globalMap;
+extern LabelMap* globalShortMap;
+extern LabelMap* globalWorklist;
+extern LabelMap* globalShortWorklist;
+extern NCGWorklist* globalNCGWorklist;
+extern DataWorklist* methodDataWorklist;
+#ifdef ENABLE_TRACING
+extern MapWorklist* methodMapWorklist;
+#endif
+extern PhysicalReg scratchRegs[4];
+
+#define C_SCRATCH_1 scratchRegs[0]
+#define C_SCRATCH_2 scratchRegs[1]
+#define C_SCRATCH_3 scratchRegs[2] //scratch reg inside callee
+
+extern LowOp* ops[BUFFER_SIZE];
+extern bool isScratchPhysical;
+extern u2* rPC;
+extern u2 inst;
+extern int offsetPC;
+extern int offsetNCG;
+extern int mapFromBCtoNCG[BYTECODE_SIZE_PER_METHOD];
+extern char* streamStart;
+
+extern char* streamCode;
+
+extern char* streamMethodStart; //start of the method
+extern char* stream; //current stream pointer
+extern char* streamMisPred;
+extern int lowOpTimeStamp;
+extern Method* currentMethod;
+extern int currentExceptionBlockIdx;
+
+extern int globalMapNum;
+extern int globalWorklistNum;
+extern int globalDataWorklistNum;
+extern int globalPCWorklistNum;
+extern int chainingWorklistNum;
+extern int VMAPIWorklistNum;
+
+extern LabelMap* globalDataWorklist;
+extern LabelMap* globalPCWorklist;
+extern LabelMap* chainingWorklist;
+extern LabelMap* VMAPIWorklist;
+
+extern int ncgClassNum;
+extern int ncgMethodNum;
+
+extern LowOp* lirTable[200]; //Number of LIRs for all bytecodes do not exceed 200
+extern int num_lirs_in_table;
+
+bool existATryBlock(Method* method, int startPC, int endPC);
+// interface between register allocator & lowering
+extern int num_removed_nullCheck;
+
+int registerAlloc(int type, int reg, bool isPhysical, bool updateRef);
+int registerAllocMove(int reg, int type, bool isPhysical, int srcReg);
+int checkVirtualReg(int reg, LowOpndRegType type, int updateRef); //returns the physical register
+int updateRefCount(int reg, LowOpndRegType type);
+int updateRefCount2(int reg, int type, bool isPhysical);
+int spillVirtualReg(int vrNum, LowOpndRegType type, bool updateTable);
+int isVirtualRegConstant(int regNum, LowOpndRegType type, int* valuePtr, bool updateRef);
+int checkTempReg(int reg, int type, bool isPhysical, int vA);
+bool checkTempReg2(int reg, int type, bool isPhysical, int physicalRegForVR);
+int freeReg(bool spillGL);
+int nextVersionOfHardReg(PhysicalReg pReg, int refCount);
+int updateVirtualReg(int reg, LowOpndRegType type);
+void setVRNullCheck(int regNum, OpndSize size);
+bool isVRNullCheck(int regNum, OpndSize size);
+void setVRBoundCheck(int vr_array, int vr_index);
+bool isVRBoundCheck(int vr_array, int vr_index);
+int requestVRFreeDelay(int regNum, u4 reason);
+void cancelVRFreeDelayRequest(int regNum, u4 reason);
+bool getVRFreeDelayRequested(int regNum);
+bool isGlueHandled(int glue_reg);
+void resetGlue(int glue_reg);
+void updateGlue(int reg, bool isPhysical, int glue_reg);
+int updateVRAtUse(int reg, LowOpndRegType pType, int regAll);
+int touchEcx();
+int touchEax();
+int touchEdx();
+int beforeCall(const char* target);
+int afterCall(const char* target);
+void startBranch();
+void endBranch();
+void rememberState(int);
+void goToState(int);
+void transferToState(int);
+void globalVREndOfBB(const Method*);
+void constVREndOfBB();
+void startNativeCode(int num, int type);
+void endNativeCode();
+void donotSpillReg(int physicalReg);
+void doSpillReg(int physicalReg);
+
+#define XMM_1 PhysicalReg_XMM0
+#define XMM_2 PhysicalReg_XMM1
+#define XMM_3 PhysicalReg_XMM2
+#define XMM_4 PhysicalReg_XMM3
+
+/////////////////////////////////////////////////////////////////////////////////
+//LR[reg] = disp + PR[base_reg] or disp + LR[base_reg]
+void load_effective_addr(int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void load_effective_addr_scale(int base_reg, bool isBasePhysical,
+ int index_reg, bool isIndexPhysical, int scale,
+ int reg, bool isPhysical);
+void load_fpu_cw(int disp, int base_reg, bool isBasePhysical);
+void store_fpu_cw(bool checkException, int disp, int base_reg, bool isBasePhysical);
+void convert_integer(OpndSize srcSize, OpndSize dstSize);
+void load_fp_stack(LowOp* op, OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void load_int_fp_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void load_int_fp_stack_imm(OpndSize size, int imm);
+void store_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void store_int_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical);
+
+void load_fp_stack_VR(OpndSize size, int vA);
+void load_int_fp_stack_VR(OpndSize size, int vA);
+void store_fp_stack_VR(bool pop, OpndSize size, int vA);
+void store_int_fp_stack_VR(bool pop, OpndSize size, int vA);
+void compare_VR_ss_reg(int vA, int reg, bool isPhysical);
+void compare_VR_sd_reg(int vA, int reg, bool isPhysical);
+void fpu_VR(ALU_Opcode opc, OpndSize size, int vA);
+void compare_reg_mem(LowOp* op, OpndSize size, int reg, bool isPhysical,
+ int disp, int base_reg, bool isBasePhysical);
+void compare_mem_reg(OpndSize size,
+ int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void compare_VR_reg(OpndSize size,
+ int vA,
+ int reg, bool isPhysical);
+void compare_imm_reg(OpndSize size, int imm,
+ int reg, bool isPhysical);
+void compare_imm_mem(OpndSize size, int imm,
+ int disp, int base_reg, bool isBasePhysical);
+void compare_imm_VR(OpndSize size, int imm,
+ int vA);
+void compare_reg_reg(int reg1, bool isPhysical1,
+ int reg2, bool isPhysical2);
+void compare_reg_reg_16(int reg1, bool isPhysical1,
+ int reg2, bool isPhysical2);
+void compare_ss_mem_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void compare_ss_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
+ int reg2, bool isPhysical2);
+void compare_sd_mem_with_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void compare_sd_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
+ int reg2, bool isPhysical2);
+void compare_fp_stack(bool pop, int reg, bool isDouble);
+void test_imm_reg(OpndSize size, int imm, int reg, bool isPhysical);
+void test_imm_mem(OpndSize size, int imm, int disp, int reg, bool isPhysical);
+
+void conditional_move_reg_to_reg(OpndSize size, ConditionCode cc, int reg1, bool isPhysical1, int reg, bool isPhysical);
+void move_ss_mem_to_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void move_ss_reg_to_mem(LowOp* op, int reg, bool isPhysical,
+ int disp, int base_reg, bool isBasePhysical);
+LowOpRegMem* move_ss_mem_to_reg_noalloc(int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex,
+ int reg, bool isPhysical);
+LowOpMemReg* move_ss_reg_to_mem_noalloc(int reg, bool isPhysical,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex);
+void move_sd_mem_to_reg(int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void move_sd_reg_to_mem(LowOp* op, int reg, bool isPhysical,
+ int disp, int base_reg, bool isBasePhysical);
+
+void conditional_jump(ConditionCode cc, const char* target, bool isShortTerm);
+void unconditional_jump(const char* target, bool isShortTerm);
+void conditional_jump_int(ConditionCode cc, int target, OpndSize size);
+void unconditional_jump_int(int target, OpndSize size);
+void unconditional_jump_reg(int reg, bool isPhysical);
+void call(const char* target);
+void call_reg(int reg, bool isPhysical);
+void call_reg_noalloc(int reg, bool isPhysical);
+void call_mem(int disp, int reg, bool isPhysical);
+void x86_return();
+
+void alu_unary_reg(OpndSize size, ALU_Opcode opc, int reg, bool isPhysical);
+void alu_unary_mem(LowOp* op, OpndSize size, ALU_Opcode opc, int disp, int base_reg, bool isBasePhysical);
+
+void alu_binary_imm_mem(OpndSize size, ALU_Opcode opc,
+ int imm, int disp, int base_reg, bool isBasePhysical);
+void alu_binary_imm_reg(OpndSize size, ALU_Opcode opc, int imm, int reg, bool isPhysical);
+void alu_binary_mem_reg(OpndSize size, ALU_Opcode opc,
+ int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void alu_binary_VR_reg(OpndSize size, ALU_Opcode opc, int vA, int reg, bool isPhysical);
+void alu_sd_binary_VR_reg(ALU_Opcode opc, int vA, int reg, bool isPhysical, bool isSD);
+void alu_binary_reg_reg(OpndSize size, ALU_Opcode opc,
+ int reg1, bool isPhysical1,
+ int reg2, bool isPhysical2);
+void alu_binary_reg_mem(OpndSize size, ALU_Opcode opc,
+ int reg, bool isPhysical,
+ int disp, int base_reg, bool isBasePhysical);
+
+void fpu_mem(LowOp* op, ALU_Opcode opc, OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void alu_ss_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
+ int reg2, bool isPhysical2);
+void alu_sd_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
+ int reg2, bool isPhysical2);
+
+void push_mem_to_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical);
+void push_reg_to_stack(OpndSize size, int reg, bool isPhysical);
+
+//returns the pointer to end of the native code
+void move_reg_to_mem(OpndSize size,
+ int reg, bool isPhysical,
+ int disp, int base_reg, bool isBasePhysical);
+LowOpRegMem* move_mem_to_reg(OpndSize size,
+ int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void movez_mem_to_reg(OpndSize size,
+ int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void movez_reg_to_reg(OpndSize size,
+ int reg, bool isPhysical,
+ int reg2, bool isPhysical2);
+void moves_mem_to_reg(LowOp* op, OpndSize size,
+ int disp, int base_reg, bool isBasePhysical,
+ int reg, bool isPhysical);
+void movez_mem_disp_scale_to_reg(OpndSize size,
+ int base_reg, bool isBasePhysical,
+ int disp, int index_reg, bool isIndexPhysical, int scale,
+ int reg, bool isPhysical);
+void moves_mem_disp_scale_to_reg(OpndSize size,
+ int base_reg, bool isBasePhysical,
+ int disp, int index_reg, bool isIndexPhysical, int scale,
+ int reg, bool isPhysical);
+void move_reg_to_reg(OpndSize size,
+ int reg, bool isPhysical,
+ int reg2, bool isPhysical2);
+void move_reg_to_reg_noalloc(OpndSize size,
+ int reg, bool isPhysical,
+ int reg2, bool isPhysical2);
+void move_mem_scale_to_reg(OpndSize size,
+ int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale,
+ int reg, bool isPhysical);
+void move_mem_disp_scale_to_reg(OpndSize size,
+ int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+ int reg, bool isPhysical);
+void move_reg_to_mem_scale(OpndSize size,
+ int reg, bool isPhysical,
+ int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale);
+void move_reg_to_mem_disp_scale(OpndSize size,
+ int reg, bool isPhysical,
+ int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale);
+void move_imm_to_mem(OpndSize size, int imm,
+ int disp, int base_reg, bool isBasePhysical);
+void set_VR_to_imm(u2 vA, OpndSize size, int imm);
+void set_VR_to_imm_noalloc(u2 vA, OpndSize size, int imm);
+void set_VR_to_imm_noupdateref(LowOp* op, u2 vA, OpndSize size, int imm);
+void move_imm_to_reg(OpndSize size, int imm, int reg, bool isPhysical);
+void move_imm_to_reg_noalloc(OpndSize size, int imm, int reg, bool isPhysical);
+
+//LR[reg] = VR[vB]
+//or
+//PR[reg] = VR[vB]
+void get_virtual_reg(u2 vB, OpndSize size, int reg, bool isPhysical);
+void get_virtual_reg_noalloc(u2 vB, OpndSize size, int reg, bool isPhysical);
+//VR[v] = LR[reg]
+//or
+//VR[v] = PR[reg]
+void set_virtual_reg(u2 vA, OpndSize size, int reg, bool isPhysical);
+void set_virtual_reg_noalloc(u2 vA, OpndSize size, int reg, bool isPhysical);
+void get_VR_ss(int vB, int reg, bool isPhysical);
+void set_VR_ss(int vA, int reg, bool isPhysical);
+void get_VR_sd(int vB, int reg, bool isPhysical);
+void set_VR_sd(int vA, int reg, bool isPhysical);
+
+int spill_reg(int reg, bool isPhysical);
+int unspill_reg(int reg, bool isPhysical);
+
+void move_reg_to_mem_noalloc(OpndSize size,
+ int reg, bool isPhysical,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex);
+LowOpRegMem* move_mem_to_reg_noalloc(OpndSize size,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex,
+ int reg, bool isPhysical);
+
+//////////////////////////////////////////////////////////////
+int insertLabel(const char* label, bool checkDup);
+int export_pc();
+int simpleNullCheck(int reg, bool isPhysical, int vr);
+int nullCheck(int reg, bool isPhysical, int exceptionNum, int vr);
+int handlePotentialException(
+ ConditionCode code_excep, ConditionCode code_okay,
+ int exceptionNum, const char* errName);
+int get_currentpc(int reg, bool isPhysical);
+int get_self_pointer(int reg, bool isPhysical);
+int get_res_strings(int reg, bool isPhysical);
+int get_res_classes(int reg, bool isPhysical);
+int get_res_fields(int reg, bool isPhysical);
+int get_res_methods(int reg, bool isPhysical);
+int get_glue_method_class(int reg, bool isPhysical);
+int get_glue_method(int reg, bool isPhysical);
+int set_glue_method(int reg, bool isPhysical);
+int get_glue_dvmdex(int reg, bool isPhysical);
+int set_glue_dvmdex(int reg, bool isPhysical);
+int get_suspendCount(int reg, bool isPhysical);
+int get_return_value(OpndSize size, int reg, bool isPhysical);
+int set_return_value(OpndSize size, int reg, bool isPhysical);
+int clear_exception();
+int get_exception(int reg, bool isPhysical);
+int set_exception(int reg, bool isPhysical);
+int save_pc_fp_to_glue();
+int savearea_from_fp(int reg, bool isPhysical);
+
+int call_moddi3();
+int call_divdi3();
+int call_fmod();
+int call_fmodf();
+int call_dvmFindCatchBlock();
+int call_dvmThrowVerificationError();
+int call_dvmAllocObject();
+int call_dvmAllocArrayByClass();
+int call_dvmResolveMethod();
+int call_dvmResolveClass();
+int call_dvmInstanceofNonTrivial();
+int call_dvmThrow();
+int call_dvmThrowWithMessage();
+int call_dvmCheckSuspendPending();
+int call_dvmLockObject();
+int call_dvmUnlockObject();
+int call_dvmInitClass();
+int call_dvmAllocPrimitiveArray();
+int call_dvmInterpHandleFillArrayData();
+int call_dvmNcgHandlePackedSwitch();
+int call_dvmNcgHandleSparseSwitch();
+int call_dvmJitHandlePackedSwitch();
+int call_dvmJitHandleSparseSwitch();
+int call_dvmJitToInterpTraceSelectNoChain();
+int call_dvmJitToPatchPredictedChain();
+int call_dvmJitToInterpNormal();
+int call_dvmJitToInterpTraceSelect();
+int call_dvmQuasiAtomicSwap64();
+int call_dvmQuasiAtomicRead64();
+int call_dvmCanPutArrayElement();
+int call_dvmFindInterfaceMethodInCache();
+int call_dvmHandleStackOverflow();
+int call_dvmResolveString();
+int call_dvmResolveInstField();
+int call_dvmResolveStaticField();
+
+//labels and branches
+//shared branch to resolve class: 2 specialized versions
+//OPTION 1: call & ret
+//OPTION 2: store jump back label in a fixed register or memory
+//jump to .class_resolve, then jump back
+//OPTION 3: share translator code
+/* global variables: ncg_rPC */
+int resolve_class(
+ int startLR/*logical register index*/, bool isPhysical, int tmp/*const pool index*/,
+ int thirdArg);
+/* EXPORT_PC; movl exceptionPtr, -8(%esp); movl descriptor, -4(%esp); lea; call; lea; jmp */
+int throw_exception_message(int exceptionPtr, int obj_reg, bool isPhysical,
+ int startLR/*logical register index*/, bool startPhysical);
+/* EXPORT_PC; movl exceptionPtr, -8(%esp); movl imm, -4(%esp); lea; call; lea; jmp */
+int throw_exception(int exceptionPtr, int imm,
+ int startLR/*logical register index*/, bool startPhysical);
+
+void freeShortMap();
+int insertDataWorklist(s4 relativePC, char* codePtr1);
+#ifdef ENABLE_TRACING
+int insertMapWorklist(s4 BCOffset, s4 NCGOffset, int isStartOfPC);
+#endif
+int performNCGWorklist();
+int performDataWorklist();
+void performLabelWorklist();
+void performMethodLabelWorklist();
+void freeLabelMap();
+void performSharedWorklist();
+void performChainingWorklist();
+void freeNCGWorklist();
+void freeDataWorklist();
+void freeLabelWorklist();
+void freeChainingWorklist();
+
+int common_invokeArgsDone(ArgsDoneType form, bool isJitFull);
+int common_backwardBranch();
+int common_exceptionThrown();
+int common_errNullObject();
+int common_errArrayIndex();
+int common_errArrayStore();
+int common_errNegArraySize();
+int common_errNoSuchMethod();
+int common_errDivideByZero();
+int common_periodicChecks_entry();
+int common_periodicChecks4();
+int common_gotoBail();
+int common_gotoBail_0();
+int common_StringIndexOutOfBounds();
+void goto_invokeArgsDone();
+
+//lower a bytecode
+int lowerByteCode(const Method* method);
+
+int op_nop();
+int op_move();
+int op_move_from16();
+int op_move_16();
+int op_move_wide();
+int op_move_wide_from16();
+int op_move_wide_16();
+int op_move_result();
+int op_move_result_wide();
+int op_move_exception();
+
+int op_return_void();
+int op_return();
+int op_return_wide();
+int op_const_4();
+int op_const_16();
+int op_const();
+int op_const_high16();
+int op_const_wide_16();
+int op_const_wide_32();
+int op_const_wide();
+int op_const_wide_high16();
+int op_const_string();
+int op_const_string_jumbo();
+int op_const_class();
+int op_monitor_enter();
+int op_monitor_exit();
+int op_check_cast();
+int op_instance_of();
+
+int op_array_length();
+int op_new_instance();
+int op_new_array();
+int op_filled_new_array();
+int op_filled_new_array_range();
+int op_fill_array_data();
+int op_throw();
+int op_throw_verification_error();
+int op_goto();
+int op_goto_16();
+int op_goto_32();
+int op_packed_switch();
+int op_sparse_switch();
+int op_if_ge();
+int op_aget();
+int op_aget_wide();
+int op_aget_object();
+int op_aget_boolean();
+int op_aget_byte();
+int op_aget_char();
+int op_aget_short();
+int op_aput();
+int op_aput_wide();
+int op_aput_object();
+int op_aput_boolean();
+int op_aput_byte();
+int op_aput_char();
+int op_aput_short();
+int op_iget();
+int op_iget_wide(bool isVolatile);
+int op_iget_object();
+int op_iget_boolean();
+int op_iget_byte();
+int op_iget_char();
+int op_iget_short();
+int op_iput();
+int op_iput_wide(bool isVolatile);
+int op_iput_object();
+int op_iput_boolean();
+int op_iput_byte();
+int op_iput_char();
+int op_iput_short();
+int op_sget();
+int op_sget_wide(bool isVolatile);
+int op_sget_object();
+int op_sget_boolean();
+int op_sget_byte();
+int op_sget_char();
+int op_sget_short();
+int op_sput(bool isObj);
+int op_sput_wide(bool isVolatile);
+int op_sput_object();
+int op_sput_boolean();
+int op_sput_byte();
+int op_sput_char();
+int op_sput_short();
+int op_invoke_virtual();
+int op_invoke_super();
+int op_invoke_direct();
+int op_invoke_static();
+int op_invoke_interface();
+int op_invoke_virtual_range();
+int op_invoke_super_range();
+int op_invoke_direct_range();
+int op_invoke_static_range();
+int op_invoke_interface_range();
+int op_int_to_long();
+int op_add_long_2addr();
+int op_add_int_lit8();
+int op_cmpl_float();
+int op_cmpg_float();
+int op_cmpl_double();
+int op_cmpg_double();
+int op_cmp_long();
+int op_if_eq();
+int op_if_ne();
+int op_if_lt();
+int op_if_gt();
+int op_if_le();
+int op_if_eqz();
+int op_if_nez();
+int op_if_ltz();
+int op_if_gez();
+int op_if_gtz();
+int op_if_lez();
+int op_neg_int();
+int op_not_int();
+int op_neg_long();
+int op_not_long();
+int op_neg_float();
+int op_neg_double();
+int op_int_to_float();
+int op_int_to_double();
+int op_long_to_int();
+int op_long_to_float();
+int op_long_to_double();
+int op_float_to_int();
+int op_float_to_long();
+int op_float_to_double();
+int op_double_to_int();
+int op_double_to_long();
+int op_double_to_float();
+int op_int_to_byte();
+int op_int_to_char();
+int op_int_to_short();
+int op_add_int();
+int op_sub_int();
+int op_mul_int();
+int op_div_int();
+int op_rem_int();
+int op_and_int();
+int op_or_int();
+int op_xor_int();
+int op_shl_int();
+int op_shr_int();
+int op_ushr_int();
+int op_add_long();
+int op_sub_long();
+int op_mul_long();
+int op_div_long();
+int op_rem_long();
+int op_and_long();
+int op_or_long();
+int op_xor_long();
+int op_shl_long();
+int op_shr_long();
+int op_ushr_long();
+int op_add_float();
+int op_sub_float();
+int op_mul_float();
+int op_div_float();
+int op_rem_float();
+int op_add_double();
+int op_sub_double();
+int op_mul_double();
+int op_div_double();
+int op_rem_double();
+int op_add_int_2addr();
+int op_sub_int_2addr();
+int op_mul_int_2addr();
+int op_div_int_2addr();
+int op_rem_int_2addr();
+int op_and_int_2addr();
+int op_or_int_2addr();
+int op_xor_int_2addr();
+int op_shl_int_2addr();
+int op_shr_int_2addr();
+int op_ushr_int_2addr();
+int op_sub_long_2addr();
+int op_mul_long_2addr();
+int op_div_long_2addr();
+int op_rem_long_2addr();
+int op_and_long_2addr();
+int op_or_long_2addr();
+int op_xor_long_2addr();
+int op_shl_long_2addr();
+int op_shr_long_2addr();
+int op_ushr_long_2addr();
+int op_add_float_2addr();
+int op_sub_float_2addr();
+int op_mul_float_2addr();
+int op_div_float_2addr();
+int op_rem_float_2addr();
+int op_add_double_2addr();
+int op_sub_double_2addr();
+int op_mul_double_2addr();
+int op_div_double_2addr();
+int op_rem_double_2addr();
+int op_add_int_lit16();
+int op_rsub_int();
+int op_mul_int_lit16();
+int op_div_int_lit16();
+int op_rem_int_lit16();
+int op_and_int_lit16();
+int op_or_int_lit16();
+int op_xor_int_lit16();
+int op_rsub_int_lit8();
+int op_mul_int_lit8();
+int op_div_int_lit8();
+int op_rem_int_lit8();
+int op_and_int_lit8();
+int op_or_int_lit8();
+int op_xor_int_lit8();
+int op_shl_int_lit8();
+int op_shr_int_lit8();
+int op_ushr_int_lit8();
+int op_execute_inline(bool isRange);
+int op_invoke_object_init_range();
+int op_iget_quick();
+int op_iget_wide_quick();
+int op_iget_object_quick();
+int op_iput_quick();
+int op_iput_wide_quick();
+int op_iput_object_quick();
+int op_invoke_virtual_quick();
+int op_invoke_virtual_quick_range();
+int op_invoke_super_quick();
+int op_invoke_super_quick_range();
+
+///////////////////////////////////////////////
+void set_reg_opnd(LowOpndReg* op_reg, int reg, bool isPhysical, LowOpndRegType type);
+void set_mem_opnd(LowOpndMem* mem, int disp, int base, bool isPhysical);
+void set_mem_opnd_scale(LowOpndMem* mem, int base, bool isPhysical, int disp, int index, bool indexPhysical, int scale);
+LowOpImm* dump_imm(Mnemonic m, OpndSize size,
+ int imm);
+LowOpNCG* dump_ncg(Mnemonic m, OpndSize size, int imm);
+LowOpImm* dump_imm_with_codeaddr(Mnemonic m, OpndSize size,
+ int imm, char* codePtr);
+LowOpImm* dump_special(AtomOpCode cc, int imm);
+LowOpMem* dump_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+ int disp, int base_reg, bool isBasePhysical);
+LowOpReg* dump_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+ int reg, bool isPhysical, LowOpndRegType type);
+LowOpReg* dump_reg_noalloc(Mnemonic m, OpndSize size,
+ int reg, bool isPhysical, LowOpndRegType type);
+LowOpMemImm* dump_imm_mem_noalloc(Mnemonic m, OpndSize size,
+ int imm,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex);
+LowOpRegReg* dump_reg_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+ int reg, bool isPhysical,
+ int reg2, bool isPhysical2, LowOpndRegType type);
+LowOpRegReg* dump_movez_reg_reg(Mnemonic m, OpndSize size,
+ int reg, bool isPhysical,
+ int reg2, bool isPhysical2);
+LowOpRegMem* dump_mem_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex,
+ int reg, bool isPhysical, LowOpndRegType type);
+LowOpRegMem* dump_mem_reg_noalloc(Mnemonic m, OpndSize size,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex,
+ int reg, bool isPhysical, LowOpndRegType type);
+LowOpRegMem* dump_mem_scale_reg(Mnemonic m, OpndSize size,
+ int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+ int reg, bool isPhysical, LowOpndRegType type);
+LowOpMemReg* dump_reg_mem_scale(Mnemonic m, OpndSize size,
+ int reg, bool isPhysical,
+ int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
+ LowOpndRegType type);
+LowOpMemReg* dump_reg_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+ int reg, bool isPhysical,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex, LowOpndRegType type);
+LowOpMemReg* dump_reg_mem_noalloc(Mnemonic m, OpndSize size,
+ int reg, bool isPhysical,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex, LowOpndRegType type);
+LowOpRegImm* dump_imm_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
+ int imm, int reg, bool isPhysical, LowOpndRegType type, bool chaining);
+LowOpMemImm* dump_imm_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
+ int imm,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex, bool chaining);
+LowOpMemReg* dump_fp_mem(Mnemonic m, OpndSize size, int reg,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex);
+LowOpRegMem* dump_mem_fp(Mnemonic m, OpndSize size,
+ int disp, int base_reg, bool isBasePhysical,
+ MemoryAccessType mType, int mIndex,
+ int reg);
+LowOpLabel* dump_label(Mnemonic m, OpndSize size, int imm,
+ const char* label, bool isLocal);
+
+unsigned getJmpCallInstSize(OpndSize size, JmpCall_type type);
+bool lowerByteCodeJit(const Method* method, const u2* codePtr, MIR* mir);
+void startOfBasicBlock(struct BasicBlock* bb);
+extern LowOpBlockLabel* traceLabelList;
+extern struct BasicBlock* traceCurrentBB;
+extern struct MIR* traceCurrentMIR;
+void startOfTrace(const Method* method, LowOpBlockLabel* labelList, int, CompilationUnit*);
+void endOfTrace(bool freeOnly);
+LowOp* jumpToBasicBlock(char* instAddr, int targetId);
+LowOp* condJumpToBasicBlock(char* instAddr, ConditionCode cc, int targetId);
+bool jumpToException(const char* target);
+int codeGenBasicBlockJit(const Method* method, BasicBlock* bb);
+void endOfBasicBlock(struct BasicBlock* bb);
+void handleExtendedMIR(CompilationUnit *cUnit, MIR *mir);
+int insertChainingWorklist(int bbId, char * codeStart);
+void startOfTraceO1(const Method* method, LowOpBlockLabel* labelList, int exceptionBlockId, CompilationUnit *cUnit);
+void endOfTraceO1();
+int isPowerOfTwo(int imm);
+void move_chain_to_mem(OpndSize size, int imm,
+ int disp, int base_reg, bool isBasePhysical);
+void move_chain_to_reg(OpndSize size, int imm, int reg, bool isPhysical);
+
+void dumpImmToMem(int vrNum, OpndSize size, int value);
+bool isInMemory(int regNum, OpndSize size);
+int touchEbx();
+int boundCheck(int vr_array, int reg_array, bool isPhysical_array,
+ int vr_index, int reg_index, bool isPhysical_index,
+ int exceptionNum);
+int getRelativeOffset(const char* target, bool isShortTerm, JmpCall_type type, bool* unknown,
+ OpndSize* immSize);
+int getRelativeNCG(s4 tmp, JmpCall_type type, bool* unknown, OpndSize* size);
+void freeAtomMem();
+OpndSize estOpndSizeFromImm(int target);
+
+void preprocessingBB(BasicBlock* bb);
+void preprocessingTrace();
+void dump_nop(int size);
+#endif