1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18/*! \file lower.h
19    \brief A header file to define interface between lowering and register allocator
20*/
21
22#ifndef _DALVIK_LOWER
23#define _DALVIK_LOWER
24
25#define CODE_CACHE_PADDING 1024 //code space for a single bytecode
26// comment out for phase 1 porting
27#define PREDICTED_CHAINING
28#define JIT_CHAIN
29
30#define NUM_DEPENDENCIES 24 /* max number of dependencies from a LowOp */
31//compilaton flags used by NCG O1
32#define DUMP_EXCEPTION //to measure performance, required to have correct exception handling
33/*! multiple versions for hardcoded registers */
34#define HARDREG_OPT
35#define CFG_OPT
36/*! remove redundant move ops when accessing virtual registers */
37#define MOVE_OPT
38/*! remove redundant spill of virtual registers */
39#define SPILL_OPT
40#define XFER_OPT
41//#define DSE_OPT //no perf improvement for cme
42/*! use live range analysis to allocate registers */
43#define LIVERANGE_OPT
44/*! remove redundant null check */
45#define NULLCHECK_OPT
46//#define BOUNDCHECK_OPT
47/*! optimize the access to glue structure */
48#define GLUE_OPT
49#define CALL_FIX
50#define NATIVE_FIX
51#define INVOKE_FIX //optimization
52#define GETVR_FIX //optimization
53
54#include "Dalvik.h"
55#include "enc_wrapper.h"
56#include "AnalysisO1.h"
57#include "compiler/CompilerIR.h"
58
59//compilation flags for debugging
60//#define DEBUG_INFO
61//#define DEBUG_CALL_STACK
62//#define DEBUG_IGET_OBJ
63//#define DEBUG_NCG_CODE_SIZE
64//#define DEBUG_NCG
65//#define DEBUG_NCG_1
66//#define DEBUG_LOADING
67//#define USE_INTERPRETER
68//#define DEBUG_EACH_BYTECODE
69
70/*! registers for functions are hardcoded */
71#define HARDCODE_REG_CALL
72#define HARDCODE_REG_SHARE
73#define HARDCODE_REG_HELPER
74
75#define PhysicalReg_FP PhysicalReg_EDI
76#define PhysicalReg_Glue PhysicalReg_EBP
77
78//COPIED from interp/InterpDefs.h
79#define FETCH(_offset) (rPC[(_offset)])
80#define INST_INST(_inst) ((_inst) & 0xff)
81#define INST_A(_inst)       (((_inst) >> 8) & 0x0f)
82#define INST_B(_inst)       ((_inst) >> 12)
83#define INST_AA(_inst)      ((_inst) >> 8)
84
85//#include "vm/mterp/common/asm-constants.h"
86#define offEBP_self 8
87#define offEBP_spill -56
88#define offThread_exception 68
89#define offClassObject_descriptor 24
90#define offArrayObject_length 8
91#ifdef PROFILE_FIELD_ACCESS
92#define offStaticField_value 24
93#define offInstField_byteOffset 24
94#else
95#define offStaticField_value 16
96#define offInstField_byteOffset 16
97#endif
98
99#ifdef EASY_GDB
100#define offStackSaveArea_prevFrame 4
101#define offStackSaveArea_savedPc 8
102#define offStackSaveArea_method 12
103#define offStackSaveArea_localRefTop 16 // -> StackSaveArea.xtra.locakRefCookie
104#define offStackSaveArea_returnAddr 20
105#define offStackSaveArea_isDebugInterpreted 24
106#define sizeofStackSaveArea 24
107#else
108#define offStackSaveArea_prevFrame 0
109#define offStackSaveArea_savedPc 4
110#define offStackSaveArea_method 8
111#define offStackSaveArea_localRefTop 12 // -> StackSaveArea.xtra.locakRefCookie
112#define offStackSaveArea_returnAddr 16
113#define offStackSaveArea_isDebugInterpreted 20
114#define sizeofStackSaveArea 20
115#endif
116
117#define offClassObject_status 44
118#define offClassObject_accessFlags 32
119#ifdef MTERP_NO_UNALIGN_64
120#define offArrayObject_contents 16
121#else
122#define offArrayObject_contents 12
123#endif
124
125#define offField_clazz 0
126#define offObject_clazz 0
127#define offClassObject_vtable 116
128#define offClassObject_pDvmDex 40
129#define offClassObject_super 72
130#define offClassObject_vtableCount 112
131#define offMethod_name 16
132#define offMethod_accessFlags 4
133#define offMethod_methodIndex 8
134#define offMethod_registersSize 10
135#define offMethod_outsSize 12
136#define offGlue_interpStackEnd 32
137#define offThread_inJitCodeCache 124
138#define offThread_jniLocal_nextEntry 168
139#define offMethod_insns 32
140#ifdef ENABLE_TRACING
141#define offMethod_insns_bytecode 44
142#define offMethod_insns_ncg 48
143#endif
144
145#define offGlue_pc     0
146#define offGlue_fp     4
147#define offGlue_retval 8
148
149#define offThread_curFrame 4
150#define offGlue_method 16
151#define offGlue_methodClassDex 20
152#define offGlue_self 24
153#define offGlue_pSelfSuspendCount 36
154#define offGlue_cardTable 40
155#define offGlue_pDebuggerActive 44
156#define offGlue_pActiveProfilers 48
157#define offGlue_entryPoint 52
158#define offGlue_icRechainCount 84
159#define offGlue_espEntry 88
160#define offGlue_spillRegion 92
161#define offDvmDex_pResStrings 8
162#define offDvmDex_pResClasses 12
163#define offDvmDex_pResMethods 16
164#define offDvmDex_pResFields  20
165#define offMethod_clazz       0
166
167// Definitions must be consistent with vm/mterp/x86/header.S
168#define FRAME_SIZE     124
169
170typedef enum ArgsDoneType {
171    ArgsDone_Normal = 0,
172    ArgsDone_Native,
173    ArgsDone_Full
174} ArgsDoneType;
175
176/*! An enum type
177    to list bytecodes for AGET, APUT
178*/
179typedef enum ArrayAccess {
180    AGET, AGET_WIDE, AGET_CHAR, AGET_SHORT, AGET_BOOLEAN, AGET_BYTE,
181    APUT, APUT_WIDE, APUT_CHAR, APUT_SHORT, APUT_BOOLEAN, APUT_BYTE
182} ArrayAccess;
183/*! An enum type
184    to list bytecodes for IGET, IPUT
185*/
186typedef enum InstanceAccess {
187    IGET, IGET_WIDE, IPUT, IPUT_WIDE
188} InstanceAccess;
189/*! An enum type
190    to list bytecodes for SGET, SPUT
191*/
192typedef enum StaticAccess {
193    SGET, SGET_WIDE, SPUT, SPUT_WIDE
194} StaticAccess;
195
196typedef enum JmpCall_type {
197    JmpCall_uncond = 1,
198    JmpCall_cond,
199    JmpCall_reg, //jump reg32
200    JmpCall_call
201} JmpCall_type;
202
203////////////////////////////////////////////////////////////////
204/* data structure for native codes */
205/* Due to space considation, a lowered op (LowOp) has two operands (LowOpnd), depending on
206   the type of the operand, LowOpndReg or LowOpndImm or LowOpndMem will follow */
207/*! type of an operand can be immediate, register or memory */
208typedef enum LowOpndType {
209  LowOpndType_Imm = 0,
210  LowOpndType_Reg,
211  LowOpndType_Mem,
212  LowOpndType_Label,
213  LowOpndType_NCG,
214  LowOpndType_Chain
215} LowOpndType;
216typedef enum LowOpndDefUse {
217  LowOpndDefUse_Def = 0,
218  LowOpndDefUse_Use,
219  LowOpndDefUse_UseDef
220} LowOpndDefUse;
221
222/*!
223\brief base data structure for an operand */
224typedef struct LowOpnd {
225  LowOpndType type;
226  OpndSize size;
227  LowOpndDefUse defuse;
228} LowOpnd;
229/*!
230\brief data structure for a register operand */
231typedef struct LowOpndReg {
232  LowOpndRegType regType;
233  int logicalReg;
234  int physicalReg;
235} LowOpndReg;
236/*!
237\brief data structure for an immediate operand */
238typedef struct LowOpndImm {
239  union {
240    s4 value;
241    unsigned char bytes[4];
242  };
243} LowOpndImm;
244
245typedef struct LowOpndNCG {
246  union {
247    s4 value;
248    unsigned char bytes[4];
249  };
250} LowOpndNCG;
251
252#define LABEL_SIZE 256
253typedef struct LowOpndLabel {
254  char label[LABEL_SIZE];
255  bool isLocal;
256} LowOpndLabel;
257
258/* get ready for optimizations at LIR
259   add MemoryAccessType & virtualRegNum to memory operands */
260typedef enum MemoryAccessType {
261  MemoryAccess_GLUE,
262  MemoryAccess_VR,
263  MemoryAccess_SPILL,
264  MemoryAccess_Unknown
265} MemoryAccessType;
266typedef enum UseDefEntryType {
267  UseDefType_Ctrl = 0,
268  UseDefType_Float,
269  UseDefType_MemVR,
270  UseDefType_MemSpill,
271  UseDefType_MemUnknown,
272  UseDefType_Reg
273} UseDefEntryType;
274typedef struct UseDefProducerEntry {
275  UseDefEntryType type;
276  int index; //enum PhysicalReg for "Reg" type
277  int producerSlot;
278} UseDefProducerEntry;
279#define MAX_USE_PER_ENTRY 50 /* at most 10 uses for each entry */
280typedef struct UseDefUserEntry {
281  UseDefEntryType type;
282  int index;
283  int useSlots[MAX_USE_PER_ENTRY];
284  int num_uses_per_entry;
285} UseDefUserEntry;
286
287/*!
288\brief data structure for a memory operand */
289typedef struct LowOpndMem {
290  LowOpndImm m_disp;
291  LowOpndImm m_scale;
292  LowOpndReg m_index;
293  LowOpndReg m_base;
294  bool hasScale;
295  MemoryAccessType mType;
296  int index;
297} LowOpndMem;
298
299typedef enum AtomOpCode {
300    ATOM_PSEUDO_CHAINING_CELL_BACKWARD_BRANCH = -15,
301    ATOM_NORMAL_ALU = -14,
302    ATOM_PSEUDO_ENTRY_BLOCK = -13,
303    ATOM_PSEUDO_EXIT_BLOCK = -12,
304    ATOM_PSEUDO_TARGET_LABEL = -11,
305    ATOM_PSEUDO_CHAINING_CELL_HOT = -10,
306    ATOM_PSEUDO_CHAINING_CELL_INVOKE_PREDICTED = -9,
307    ATOM_PSEUDO_CHAINING_CELL_INVOKE_SINGLETON = -8,
308    ATOM_PSEUDO_CHAINING_CELL_NORMAL = -7,
309    ATOM_PSEUDO_DALVIK_BYTECODE_BOUNDARY = -6,
310    ATOM_PSEUDO_ALIGN4 = -5,
311    ATOM_PSEUDO_PC_RECONSTRUCTION_CELL = -4,
312    ATOM_PSEUDO_PC_RECONSTRUCTION_BLOCK_LABEL = -3,
313    ATOM_PSEUDO_EH_BLOCK_LABEL = -2,
314    ATOM_PSEUDO_NORMAL_BLOCK_LABEL = -1,
315    ATOM_NORMAL,
316} AtomOpCode;
317
318typedef enum DependencyType {
319  Dependency_RAW,
320  Dependency_WAW,
321  Dependency_WAR,
322  Dependency_FLAG
323} DependencyType;
324typedef struct DependencyStruct {
325  DependencyType dType;
326  int nodeId;
327  int latency;
328} DependencyStruct;
329
330typedef struct LowOpBlock {
331  LIR generic;
332  Mnemonic opCode;
333  AtomOpCode opCode2;
334} LowOpBlock;
335
336/*!
337\brief data structure for a lowered operation */
338typedef struct LowOp {
339  LIR generic;
340  Mnemonic opCode;
341  AtomOpCode opCode2;
342  LowOpnd opnd1;
343  LowOpnd opnd2;
344  int numOperands;
345} LowOp;
346
347typedef struct LowOpLabel {
348  LowOp lop;
349  LowOpndLabel labelOpnd;
350}LowOpLabel;
351
352typedef struct LowOpNCG {
353  LowOp lop;
354  LowOpndNCG ncgOpnd;
355}LowOpNCG;
356
357typedef struct LowOpBlockLabel {
358  LowOpBlock lop;
359  LowOpndImm immOpnd;
360} LowOpBlockLabel;
361
362typedef struct LowOpImm {
363  LowOp lop;
364  LowOpndImm immOpnd;
365} LowOpImm;
366
367typedef struct LowOpMem {
368  LowOp lop;
369  LowOpndMem memOpnd;
370} LowOpMem;
371
372typedef struct LowOpReg {
373  LowOp lop;
374  LowOpndReg regOpnd;
375} LowOpReg;
376
377typedef struct LowOpImmImm {
378  LowOp lop;
379  LowOpndImm immOpnd1;
380  LowOpndImm immOpnd2;
381} LowOpImmImm;
382
383typedef struct LowOpImmReg {
384  LowOp lop;
385  LowOpndImm immOpnd1;
386  LowOpndReg regOpnd2;
387} LowOpImmReg;
388
389typedef struct LowOpImmMem {
390  LowOp lop;
391  LowOpndImm immOpnd1;
392  LowOpndMem memOpnd2;
393} LowOpImmMem;
394
395typedef struct LowOpRegImm {
396  LowOp lop;
397  LowOpndReg regOpnd1;
398  LowOpndImm immOpnd2;
399} LowOpRegImm;
400
401typedef struct LowOpRegReg {
402  LowOp lop;
403  LowOpndReg regOpnd1;
404  LowOpndReg regOpnd2;
405} LowOpRegReg;
406
407typedef struct LowOpRegMem {
408  LowOp lop;
409  LowOpndReg regOpnd1;
410  LowOpndMem memOpnd2;
411} LowOpRegMem;
412
413typedef struct LowOpMemImm {
414  LowOp lop;
415  LowOpndMem memOpnd1;
416  LowOpndImm immOpnd2;
417} LowOpMemImm;
418
419typedef struct LowOpMemReg {
420  LowOp lop;
421  LowOpndMem memOpnd1;
422  LowOpndReg regOpnd2;
423} LowOpMemReg;
424
425typedef struct LowOpMemMem {
426  LowOp lop;
427  LowOpndMem memOpnd1;
428  LowOpndMem memOpnd2;
429} LowOpMemMem;
430
431/*!
432\brief data structure for labels used when lowering a method
433
434four label maps are defined: globalMap globalShortMap globalWorklist globalShortWorklist
435globalMap: global labels where codePtr points to the label
436           freeLabelMap called in clearNCG
437globalWorklist: global labels where codePtr points to an instruciton using the label
438  standalone NCG -------
439                accessed by insertLabelWorklist & performLabelWorklist
440  code cache ------
441                inserted by performLabelWorklist(false),
442                handled & cleared by generateRelocation in NcgFile.c
443globalShortMap: local labels where codePtr points to the label
444                freeShortMap called after generation of one bytecode
445globalShortWorklist: local labels where codePtr points to an instruction using the label
446                accessed by insertShortWorklist & insertLabel
447definition of local label: life time of the label is within a bytecode or within a helper function
448extra label maps are used by code cache:
449  globalDataWorklist VMAPIWorklist
450*/
451typedef struct LabelMap {
452  char label[LABEL_SIZE];
453  char* codePtr; //code corresponding to the label or code that uses the label
454  struct LabelMap* nextItem;
455  OpndSize size;
456  uint  addend;
457} LabelMap;
458/*!
459\brief data structure to handle forward jump (GOTO, IF)
460
461accessed by insertNCGWorklist & performNCGWorklist
462*/
463typedef struct NCGWorklist {
464  //when WITH_JIT, relativePC stores the target basic block id
465  s4 relativePC; //relative offset in bytecode
466  int offsetPC;  //PC in bytecode
467  int offsetNCG; //PC in native code
468  char* codePtr; //code for native jump instruction
469  struct NCGWorklist* nextItem;
470  OpndSize size;
471}NCGWorklist;
472/*!
473\brief data structure to handle SWITCH & FILL_ARRAY_DATA
474
475two data worklist are defined: globalDataWorklist (used by code cache) & methodDataWorklist
476methodDataWorklist is accessed by insertDataWorklist & performDataWorklist
477*/
478typedef struct DataWorklist {
479  s4 relativePC; //relative offset in bytecode to access the data
480  int offsetPC;  //PC in bytecode
481  int offsetNCG; //PC in native code
482  char* codePtr; //code for native instruction add_imm_reg imm, %edx
483  char* codePtr2;//code for native instruction add_reg_reg %eax, %edx for SWITCH
484                 //                            add_imm_reg imm, %edx for FILL_ARRAY_DATA
485  struct DataWorklist* nextItem;
486}DataWorklist;
487#ifdef ENABLE_TRACING
488typedef struct MapWorklist {
489  u4 offsetPC;
490  u4 offsetNCG;
491  int isStartOfPC; //1 --> true 0 --> false
492  struct MapWorklist* nextItem;
493} MapWorklist;
494#endif
495
496#define BUFFER_SIZE 1024 //# of Low Ops buffered
497//the following three numbers are hardcoded, please CHECK
498#define BYTECODE_SIZE_PER_METHOD 81920
499#define NATIVE_SIZE_PER_DEX 19000000 //FIXME for core.jar: 16M --> 18M for O1
500#define NATIVE_SIZE_FOR_VM_STUBS 100000
501#define MAX_HANDLER_OFFSET 1024 //maximal number of handler offsets
502
503extern int LstrClassCastExceptionPtr, LstrInstantiationErrorPtr, LstrInternalError, LstrFilledNewArrayNotImpl;
504extern int LstrArithmeticException, LstrArrayIndexException, LstrArrayStoreException, LstrStringIndexOutOfBoundsException;
505extern int LstrDivideByZero, LstrNegativeArraySizeException, LstrNoSuchMethodError, LstrNullPointerException;
506extern int LdoubNeg, LvaluePosInfLong, LvalueNegInfLong, LvalueNanLong, LshiftMask, Lvalue64, L64bits, LintMax, LintMin;
507
508extern LabelMap* globalMap;
509extern LabelMap* globalShortMap;
510extern LabelMap* globalWorklist;
511extern LabelMap* globalShortWorklist;
512extern NCGWorklist* globalNCGWorklist;
513extern DataWorklist* methodDataWorklist;
514#ifdef ENABLE_TRACING
515extern MapWorklist* methodMapWorklist;
516#endif
517extern PhysicalReg scratchRegs[4];
518
519#define C_SCRATCH_1 scratchRegs[0]
520#define C_SCRATCH_2 scratchRegs[1]
521#define C_SCRATCH_3 scratchRegs[2] //scratch reg inside callee
522
523extern LowOp* ops[BUFFER_SIZE];
524extern bool isScratchPhysical;
525extern u2* rPC;
526extern u2 inst;
527extern int offsetPC;
528extern int offsetNCG;
529extern int mapFromBCtoNCG[BYTECODE_SIZE_PER_METHOD];
530extern char* streamStart;
531
532extern char* streamCode;
533
534extern char* streamMethodStart; //start of the method
535extern char* stream; //current stream pointer
536extern char* streamMisPred;
537extern int lowOpTimeStamp;
538extern Method* currentMethod;
539extern int currentExceptionBlockIdx;
540
541extern int globalMapNum;
542extern int globalWorklistNum;
543extern int globalDataWorklistNum;
544extern int globalPCWorklistNum;
545extern int chainingWorklistNum;
546extern int VMAPIWorklistNum;
547
548extern LabelMap* globalDataWorklist;
549extern LabelMap* globalPCWorklist;
550extern LabelMap* chainingWorklist;
551extern LabelMap* VMAPIWorklist;
552
553extern int ncgClassNum;
554extern int ncgMethodNum;
555
556extern LowOp* lirTable[200]; //Number of LIRs for all bytecodes do not exceed 200
557extern int num_lirs_in_table;
558
559bool existATryBlock(Method* method, int startPC, int endPC);
560// interface between register allocator & lowering
561extern int num_removed_nullCheck;
562
563int registerAlloc(int type, int reg, bool isPhysical, bool updateRef);
564int registerAllocMove(int reg, int type, bool isPhysical, int srcReg);
565int checkVirtualReg(int reg, LowOpndRegType type, int updateRef); //returns the physical register
566int updateRefCount(int reg, LowOpndRegType type);
567int updateRefCount2(int reg, int type, bool isPhysical);
568int spillVirtualReg(int vrNum, LowOpndRegType type, bool updateTable);
569int isVirtualRegConstant(int regNum, LowOpndRegType type, int* valuePtr, bool updateRef);
570int checkTempReg(int reg, int type, bool isPhysical, int vA);
571bool checkTempReg2(int reg, int type, bool isPhysical, int physicalRegForVR);
572int freeReg(bool spillGL);
573int nextVersionOfHardReg(PhysicalReg pReg, int refCount);
574int updateVirtualReg(int reg, LowOpndRegType type);
575void setVRNullCheck(int regNum, OpndSize size);
576bool isVRNullCheck(int regNum, OpndSize size);
577void setVRBoundCheck(int vr_array, int vr_index);
578bool isVRBoundCheck(int vr_array, int vr_index);
579int requestVRFreeDelay(int regNum, u4 reason);
580void cancelVRFreeDelayRequest(int regNum, u4 reason);
581bool getVRFreeDelayRequested(int regNum);
582bool isGlueHandled(int glue_reg);
583void resetGlue(int glue_reg);
584void updateGlue(int reg, bool isPhysical, int glue_reg);
585int updateVRAtUse(int reg, LowOpndRegType pType, int regAll);
586int touchEcx();
587int touchEax();
588int touchEdx();
589int beforeCall(const char* target);
590int afterCall(const char* target);
591void startBranch();
592void endBranch();
593void rememberState(int);
594void goToState(int);
595void transferToState(int);
596void globalVREndOfBB(const Method*);
597void constVREndOfBB();
598void startNativeCode(int num, int type);
599void endNativeCode();
600void donotSpillReg(int physicalReg);
601void doSpillReg(int physicalReg);
602
603#define XMM_1 PhysicalReg_XMM0
604#define XMM_2 PhysicalReg_XMM1
605#define XMM_3 PhysicalReg_XMM2
606#define XMM_4 PhysicalReg_XMM3
607
608/////////////////////////////////////////////////////////////////////////////////
609//LR[reg] = disp + PR[base_reg] or disp + LR[base_reg]
610void load_effective_addr(int disp, int base_reg, bool isBasePhysical,
611                          int reg, bool isPhysical);
612void load_effective_addr_scale(int base_reg, bool isBasePhysical,
613                                int index_reg, bool isIndexPhysical, int scale,
614                                int reg, bool isPhysical);
615void load_fpu_cw(int disp, int base_reg, bool isBasePhysical);
616void store_fpu_cw(bool checkException, int disp, int base_reg, bool isBasePhysical);
617void convert_integer(OpndSize srcSize, OpndSize dstSize);
618void load_fp_stack(LowOp* op, OpndSize size, int disp, int base_reg, bool isBasePhysical);
619void load_int_fp_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical);
620void load_int_fp_stack_imm(OpndSize size, int imm);
621void store_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical);
622void store_int_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical);
623
624void load_fp_stack_VR(OpndSize size, int vA);
625void load_int_fp_stack_VR(OpndSize size, int vA);
626void store_fp_stack_VR(bool pop, OpndSize size, int vA);
627void store_int_fp_stack_VR(bool pop, OpndSize size, int vA);
628void compare_VR_ss_reg(int vA, int reg, bool isPhysical);
629void compare_VR_sd_reg(int vA, int reg, bool isPhysical);
630void fpu_VR(ALU_Opcode opc, OpndSize size, int vA);
631void compare_reg_mem(LowOp* op, OpndSize size, int reg, bool isPhysical,
632                           int disp, int base_reg, bool isBasePhysical);
633void compare_mem_reg(OpndSize size,
634                           int disp, int base_reg, bool isBasePhysical,
635                           int reg, bool isPhysical);
636void compare_VR_reg(OpndSize size,
637                           int vA,
638                           int reg, bool isPhysical);
639void compare_imm_reg(OpndSize size, int imm,
640                           int reg, bool isPhysical);
641void compare_imm_mem(OpndSize size, int imm,
642                           int disp, int base_reg, bool isBasePhysical);
643void compare_imm_VR(OpndSize size, int imm,
644                           int vA);
645void compare_reg_reg(int reg1, bool isPhysical1,
646                           int reg2, bool isPhysical2);
647void compare_reg_reg_16(int reg1, bool isPhysical1,
648                         int reg2, bool isPhysical2);
649void compare_ss_mem_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
650                              int reg, bool isPhysical);
651void compare_ss_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
652                              int reg2, bool isPhysical2);
653void compare_sd_mem_with_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
654                              int reg, bool isPhysical);
655void compare_sd_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
656                              int reg2, bool isPhysical2);
657void compare_fp_stack(bool pop, int reg, bool isDouble);
658void test_imm_reg(OpndSize size, int imm, int reg, bool isPhysical);
659void test_imm_mem(OpndSize size, int imm, int disp, int reg, bool isPhysical);
660
661void conditional_move_reg_to_reg(OpndSize size, ConditionCode cc, int reg1, bool isPhysical1, int reg, bool isPhysical);
662void move_ss_mem_to_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
663                        int reg, bool isPhysical);
664void move_ss_reg_to_mem(LowOp* op, int reg, bool isPhysical,
665                         int disp, int base_reg, bool isBasePhysical);
666LowOpRegMem* move_ss_mem_to_reg_noalloc(int disp, int base_reg, bool isBasePhysical,
667                         MemoryAccessType mType, int mIndex,
668                         int reg, bool isPhysical);
669LowOpMemReg* move_ss_reg_to_mem_noalloc(int reg, bool isPhysical,
670                         int disp, int base_reg, bool isBasePhysical,
671                         MemoryAccessType mType, int mIndex);
672void move_sd_mem_to_reg(int disp, int base_reg, bool isBasePhysical,
673                         int reg, bool isPhysical);
674void move_sd_reg_to_mem(LowOp* op, int reg, bool isPhysical,
675                         int disp, int base_reg, bool isBasePhysical);
676
677void conditional_jump(ConditionCode cc, const char* target, bool isShortTerm);
678void unconditional_jump(const char* target, bool isShortTerm);
679void conditional_jump_int(ConditionCode cc, int target, OpndSize size);
680void unconditional_jump_int(int target, OpndSize size);
681void unconditional_jump_reg(int reg, bool isPhysical);
682void call(const char* target);
683void call_reg(int reg, bool isPhysical);
684void call_reg_noalloc(int reg, bool isPhysical);
685void call_mem(int disp, int reg, bool isPhysical);
686void x86_return();
687
688void alu_unary_reg(OpndSize size, ALU_Opcode opc, int reg, bool isPhysical);
689void alu_unary_mem(LowOp* op, OpndSize size, ALU_Opcode opc, int disp, int base_reg, bool isBasePhysical);
690
691void alu_binary_imm_mem(OpndSize size, ALU_Opcode opc,
692                         int imm, int disp, int base_reg, bool isBasePhysical);
693void alu_binary_imm_reg(OpndSize size, ALU_Opcode opc, int imm, int reg, bool isPhysical);
694void alu_binary_mem_reg(OpndSize size, ALU_Opcode opc,
695                         int disp, int base_reg, bool isBasePhysical,
696                         int reg, bool isPhysical);
697void alu_binary_VR_reg(OpndSize size, ALU_Opcode opc, int vA, int reg, bool isPhysical);
698void alu_sd_binary_VR_reg(ALU_Opcode opc, int vA, int reg, bool isPhysical, bool isSD);
699void alu_binary_reg_reg(OpndSize size, ALU_Opcode opc,
700                         int reg1, bool isPhysical1,
701                         int reg2, bool isPhysical2);
702void alu_binary_reg_mem(OpndSize size, ALU_Opcode opc,
703                         int reg, bool isPhysical,
704                         int disp, int base_reg, bool isBasePhysical);
705
706void fpu_mem(LowOp* op, ALU_Opcode opc, OpndSize size, int disp, int base_reg, bool isBasePhysical);
707void alu_ss_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
708                            int reg2, bool isPhysical2);
709void alu_sd_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
710                            int reg2, bool isPhysical2);
711
712void push_mem_to_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical);
713void push_reg_to_stack(OpndSize size, int reg, bool isPhysical);
714
715//returns the pointer to end of the native code
716void move_reg_to_mem(OpndSize size,
717                      int reg, bool isPhysical,
718                      int disp, int base_reg, bool isBasePhysical);
719LowOpRegMem* move_mem_to_reg(OpndSize size,
720                      int disp, int base_reg, bool isBasePhysical,
721                      int reg, bool isPhysical);
722void movez_mem_to_reg(OpndSize size,
723                      int disp, int base_reg, bool isBasePhysical,
724                      int reg, bool isPhysical);
725void movez_reg_to_reg(OpndSize size,
726                      int reg, bool isPhysical,
727                      int reg2, bool isPhysical2);
728void moves_mem_to_reg(LowOp* op, OpndSize size,
729                      int disp, int base_reg, bool isBasePhysical,
730                      int reg, bool isPhysical);
731void movez_mem_disp_scale_to_reg(OpndSize size,
732                      int base_reg, bool isBasePhysical,
733                      int disp, int index_reg, bool isIndexPhysical, int scale,
734                      int reg, bool isPhysical);
735void moves_mem_disp_scale_to_reg(OpndSize size,
736                      int base_reg, bool isBasePhysical,
737                      int disp, int index_reg, bool isIndexPhysical, int scale,
738                      int reg, bool isPhysical);
739void move_reg_to_reg(OpndSize size,
740                      int reg, bool isPhysical,
741                      int reg2, bool isPhysical2);
742void move_reg_to_reg_noalloc(OpndSize size,
743                      int reg, bool isPhysical,
744                      int reg2, bool isPhysical2);
745void move_mem_scale_to_reg(OpndSize size,
746                            int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale,
747                            int reg, bool isPhysical);
748void move_mem_disp_scale_to_reg(OpndSize size,
749                int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
750                int reg, bool isPhysical);
751void move_reg_to_mem_scale(OpndSize size,
752                            int reg, bool isPhysical,
753                            int base_reg, bool isBasePhysical, int index_reg, bool isIndexPhysical, int scale);
754void move_reg_to_mem_disp_scale(OpndSize size,
755                            int reg, bool isPhysical,
756                            int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale);
757void move_imm_to_mem(OpndSize size, int imm,
758                      int disp, int base_reg, bool isBasePhysical);
759void set_VR_to_imm(u2 vA, OpndSize size, int imm);
760void set_VR_to_imm_noalloc(u2 vA, OpndSize size, int imm);
761void set_VR_to_imm_noupdateref(LowOp* op, u2 vA, OpndSize size, int imm);
762void move_imm_to_reg(OpndSize size, int imm, int reg, bool isPhysical);
763void move_imm_to_reg_noalloc(OpndSize size, int imm, int reg, bool isPhysical);
764
765//LR[reg] = VR[vB]
766//or
767//PR[reg] = VR[vB]
768void get_virtual_reg(u2 vB, OpndSize size, int reg, bool isPhysical);
769void get_virtual_reg_noalloc(u2 vB, OpndSize size, int reg, bool isPhysical);
770//VR[v] = LR[reg]
771//or
772//VR[v] = PR[reg]
773void set_virtual_reg(u2 vA, OpndSize size, int reg, bool isPhysical);
774void set_virtual_reg_noalloc(u2 vA, OpndSize size, int reg, bool isPhysical);
775void get_VR_ss(int vB, int reg, bool isPhysical);
776void set_VR_ss(int vA, int reg, bool isPhysical);
777void get_VR_sd(int vB, int reg, bool isPhysical);
778void set_VR_sd(int vA, int reg, bool isPhysical);
779
780int spill_reg(int reg, bool isPhysical);
781int unspill_reg(int reg, bool isPhysical);
782
783void move_reg_to_mem_noalloc(OpndSize size,
784                      int reg, bool isPhysical,
785                      int disp, int base_reg, bool isBasePhysical,
786                      MemoryAccessType mType, int mIndex);
787LowOpRegMem* move_mem_to_reg_noalloc(OpndSize size,
788                      int disp, int base_reg, bool isBasePhysical,
789                      MemoryAccessType mType, int mIndex,
790                      int reg, bool isPhysical);
791
792//////////////////////////////////////////////////////////////
793int insertLabel(const char* label, bool checkDup);
794int export_pc();
795int simpleNullCheck(int reg, bool isPhysical, int vr);
796int nullCheck(int reg, bool isPhysical, int exceptionNum, int vr);
797int handlePotentialException(
798                             ConditionCode code_excep, ConditionCode code_okay,
799                             int exceptionNum, const char* errName);
800int get_currentpc(int reg, bool isPhysical);
801int get_self_pointer(int reg, bool isPhysical);
802int get_res_strings(int reg, bool isPhysical);
803int get_res_classes(int reg, bool isPhysical);
804int get_res_fields(int reg, bool isPhysical);
805int get_res_methods(int reg, bool isPhysical);
806int get_glue_method_class(int reg, bool isPhysical);
807int get_glue_method(int reg, bool isPhysical);
808int set_glue_method(int reg, bool isPhysical);
809int get_glue_dvmdex(int reg, bool isPhysical);
810int set_glue_dvmdex(int reg, bool isPhysical);
811int get_suspendCount(int reg, bool isPhysical);
812int get_return_value(OpndSize size, int reg, bool isPhysical);
813int set_return_value(OpndSize size, int reg, bool isPhysical);
814int clear_exception();
815int get_exception(int reg, bool isPhysical);
816int set_exception(int reg, bool isPhysical);
817int save_pc_fp_to_glue();
818int savearea_from_fp(int reg, bool isPhysical);
819
820int call_moddi3();
821int call_divdi3();
822int call_fmod();
823int call_fmodf();
824int call_dvmFindCatchBlock();
825int call_dvmThrowVerificationError();
826int call_dvmAllocObject();
827int call_dvmAllocArrayByClass();
828int call_dvmResolveMethod();
829int call_dvmResolveClass();
830int call_dvmInstanceofNonTrivial();
831int call_dvmThrow();
832int call_dvmThrowWithMessage();
833int call_dvmCheckSuspendPending();
834int call_dvmLockObject();
835int call_dvmUnlockObject();
836int call_dvmInitClass();
837int call_dvmAllocPrimitiveArray();
838int call_dvmInterpHandleFillArrayData();
839int call_dvmNcgHandlePackedSwitch();
840int call_dvmNcgHandleSparseSwitch();
841int call_dvmJitHandlePackedSwitch();
842int call_dvmJitHandleSparseSwitch();
843int call_dvmJitToInterpTraceSelectNoChain();
844int call_dvmJitToPatchPredictedChain();
845int call_dvmJitToInterpNormal();
846int call_dvmJitToInterpTraceSelect();
847int call_dvmQuasiAtomicSwap64();
848int call_dvmQuasiAtomicRead64();
849int call_dvmCanPutArrayElement();
850int call_dvmFindInterfaceMethodInCache();
851int call_dvmHandleStackOverflow();
852int call_dvmResolveString();
853int call_dvmResolveInstField();
854int call_dvmResolveStaticField();
855
856//labels and branches
857//shared branch to resolve class: 2 specialized versions
858//OPTION 1: call & ret
859//OPTION 2: store jump back label in a fixed register or memory
860//jump to .class_resolve, then jump back
861//OPTION 3: share translator code
862/* global variables: ncg_rPC */
863int resolve_class(
864                  int startLR/*logical register index*/, bool isPhysical, int tmp/*const pool index*/,
865                  int thirdArg);
866/* EXPORT_PC; movl exceptionPtr, -8(%esp); movl descriptor, -4(%esp); lea; call; lea; jmp */
867int throw_exception_message(int exceptionPtr, int obj_reg, bool isPhysical,
868                            int startLR/*logical register index*/, bool startPhysical);
869/* EXPORT_PC; movl exceptionPtr, -8(%esp); movl imm, -4(%esp); lea; call; lea; jmp */
870int throw_exception(int exceptionPtr, int imm,
871                    int startLR/*logical register index*/, bool startPhysical);
872
873void freeShortMap();
874int insertDataWorklist(s4 relativePC, char* codePtr1);
875#ifdef ENABLE_TRACING
876int insertMapWorklist(s4 BCOffset, s4 NCGOffset, int isStartOfPC);
877#endif
878int performNCGWorklist();
879int performDataWorklist();
880void performLabelWorklist();
881void performMethodLabelWorklist();
882void freeLabelMap();
883void performSharedWorklist();
884void performChainingWorklist();
885void freeNCGWorklist();
886void freeDataWorklist();
887void freeLabelWorklist();
888void freeChainingWorklist();
889
890int common_invokeArgsDone(ArgsDoneType form, bool isJitFull);
891int common_backwardBranch();
892int common_exceptionThrown();
893int common_errNullObject();
894int common_errArrayIndex();
895int common_errArrayStore();
896int common_errNegArraySize();
897int common_errNoSuchMethod();
898int common_errDivideByZero();
899int common_periodicChecks_entry();
900int common_periodicChecks4();
901int common_gotoBail();
902int common_gotoBail_0();
903int common_StringIndexOutOfBounds();
904void goto_invokeArgsDone();
905
906//lower a bytecode
907int lowerByteCode(const Method* method);
908
909int op_nop();
910int op_move();
911int op_move_from16();
912int op_move_16();
913int op_move_wide();
914int op_move_wide_from16();
915int op_move_wide_16();
916int op_move_result();
917int op_move_result_wide();
918int op_move_exception();
919
920int op_return_void();
921int op_return();
922int op_return_wide();
923int op_const_4();
924int op_const_16();
925int op_const();
926int op_const_high16();
927int op_const_wide_16();
928int op_const_wide_32();
929int op_const_wide();
930int op_const_wide_high16();
931int op_const_string();
932int op_const_string_jumbo();
933int op_const_class();
934int op_monitor_enter();
935int op_monitor_exit();
936int op_check_cast();
937int op_instance_of();
938
939int op_array_length();
940int op_new_instance();
941int op_new_array();
942int op_filled_new_array();
943int op_filled_new_array_range();
944int op_fill_array_data();
945int op_throw();
946int op_throw_verification_error();
947int op_goto();
948int op_goto_16();
949int op_goto_32();
950int op_packed_switch();
951int op_sparse_switch();
952int op_if_ge();
953int op_aget();
954int op_aget_wide();
955int op_aget_object();
956int op_aget_boolean();
957int op_aget_byte();
958int op_aget_char();
959int op_aget_short();
960int op_aput();
961int op_aput_wide();
962int op_aput_object();
963int op_aput_boolean();
964int op_aput_byte();
965int op_aput_char();
966int op_aput_short();
967int op_iget();
968int op_iget_wide(bool isVolatile);
969int op_iget_object();
970int op_iget_boolean();
971int op_iget_byte();
972int op_iget_char();
973int op_iget_short();
974int op_iput();
975int op_iput_wide(bool isVolatile);
976int op_iput_object();
977int op_iput_boolean();
978int op_iput_byte();
979int op_iput_char();
980int op_iput_short();
981int op_sget();
982int op_sget_wide(bool isVolatile);
983int op_sget_object();
984int op_sget_boolean();
985int op_sget_byte();
986int op_sget_char();
987int op_sget_short();
988int op_sput(bool isObj);
989int op_sput_wide(bool isVolatile);
990int op_sput_object();
991int op_sput_boolean();
992int op_sput_byte();
993int op_sput_char();
994int op_sput_short();
995int op_invoke_virtual();
996int op_invoke_super();
997int op_invoke_direct();
998int op_invoke_static();
999int op_invoke_interface();
1000int op_invoke_virtual_range();
1001int op_invoke_super_range();
1002int op_invoke_direct_range();
1003int op_invoke_static_range();
1004int op_invoke_interface_range();
1005int op_int_to_long();
1006int op_add_long_2addr();
1007int op_add_int_lit8();
1008int op_cmpl_float();
1009int op_cmpg_float();
1010int op_cmpl_double();
1011int op_cmpg_double();
1012int op_cmp_long();
1013int op_if_eq();
1014int op_if_ne();
1015int op_if_lt();
1016int op_if_gt();
1017int op_if_le();
1018int op_if_eqz();
1019int op_if_nez();
1020int op_if_ltz();
1021int op_if_gez();
1022int op_if_gtz();
1023int op_if_lez();
1024int op_neg_int();
1025int op_not_int();
1026int op_neg_long();
1027int op_not_long();
1028int op_neg_float();
1029int op_neg_double();
1030int op_int_to_float();
1031int op_int_to_double();
1032int op_long_to_int();
1033int op_long_to_float();
1034int op_long_to_double();
1035int op_float_to_int();
1036int op_float_to_long();
1037int op_float_to_double();
1038int op_double_to_int();
1039int op_double_to_long();
1040int op_double_to_float();
1041int op_int_to_byte();
1042int op_int_to_char();
1043int op_int_to_short();
1044int op_add_int();
1045int op_sub_int();
1046int op_mul_int();
1047int op_div_int();
1048int op_rem_int();
1049int op_and_int();
1050int op_or_int();
1051int op_xor_int();
1052int op_shl_int();
1053int op_shr_int();
1054int op_ushr_int();
1055int op_add_long();
1056int op_sub_long();
1057int op_mul_long();
1058int op_div_long();
1059int op_rem_long();
1060int op_and_long();
1061int op_or_long();
1062int op_xor_long();
1063int op_shl_long();
1064int op_shr_long();
1065int op_ushr_long();
1066int op_add_float();
1067int op_sub_float();
1068int op_mul_float();
1069int op_div_float();
1070int op_rem_float();
1071int op_add_double();
1072int op_sub_double();
1073int op_mul_double();
1074int op_div_double();
1075int op_rem_double();
1076int op_add_int_2addr();
1077int op_sub_int_2addr();
1078int op_mul_int_2addr();
1079int op_div_int_2addr();
1080int op_rem_int_2addr();
1081int op_and_int_2addr();
1082int op_or_int_2addr();
1083int op_xor_int_2addr();
1084int op_shl_int_2addr();
1085int op_shr_int_2addr();
1086int op_ushr_int_2addr();
1087int op_sub_long_2addr();
1088int op_mul_long_2addr();
1089int op_div_long_2addr();
1090int op_rem_long_2addr();
1091int op_and_long_2addr();
1092int op_or_long_2addr();
1093int op_xor_long_2addr();
1094int op_shl_long_2addr();
1095int op_shr_long_2addr();
1096int op_ushr_long_2addr();
1097int op_add_float_2addr();
1098int op_sub_float_2addr();
1099int op_mul_float_2addr();
1100int op_div_float_2addr();
1101int op_rem_float_2addr();
1102int op_add_double_2addr();
1103int op_sub_double_2addr();
1104int op_mul_double_2addr();
1105int op_div_double_2addr();
1106int op_rem_double_2addr();
1107int op_add_int_lit16();
1108int op_rsub_int();
1109int op_mul_int_lit16();
1110int op_div_int_lit16();
1111int op_rem_int_lit16();
1112int op_and_int_lit16();
1113int op_or_int_lit16();
1114int op_xor_int_lit16();
1115int op_rsub_int_lit8();
1116int op_mul_int_lit8();
1117int op_div_int_lit8();
1118int op_rem_int_lit8();
1119int op_and_int_lit8();
1120int op_or_int_lit8();
1121int op_xor_int_lit8();
1122int op_shl_int_lit8();
1123int op_shr_int_lit8();
1124int op_ushr_int_lit8();
1125int op_execute_inline(bool isRange);
1126int op_invoke_object_init_range();
1127int op_iget_quick();
1128int op_iget_wide_quick();
1129int op_iget_object_quick();
1130int op_iput_quick();
1131int op_iput_wide_quick();
1132int op_iput_object_quick();
1133int op_invoke_virtual_quick();
1134int op_invoke_virtual_quick_range();
1135int op_invoke_super_quick();
1136int op_invoke_super_quick_range();
1137
1138///////////////////////////////////////////////
1139void set_reg_opnd(LowOpndReg* op_reg, int reg, bool isPhysical, LowOpndRegType type);
1140void set_mem_opnd(LowOpndMem* mem, int disp, int base, bool isPhysical);
1141void set_mem_opnd_scale(LowOpndMem* mem, int base, bool isPhysical, int disp, int index, bool indexPhysical, int scale);
1142LowOpImm* dump_imm(Mnemonic m, OpndSize size,
1143               int imm);
1144LowOpNCG* dump_ncg(Mnemonic m, OpndSize size, int imm);
1145LowOpImm* dump_imm_with_codeaddr(Mnemonic m, OpndSize size,
1146               int imm, char* codePtr);
1147LowOpImm* dump_special(AtomOpCode cc, int imm);
1148LowOpMem* dump_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
1149               int disp, int base_reg, bool isBasePhysical);
1150LowOpReg* dump_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
1151               int reg, bool isPhysical, LowOpndRegType type);
1152LowOpReg* dump_reg_noalloc(Mnemonic m, OpndSize size,
1153               int reg, bool isPhysical, LowOpndRegType type);
1154LowOpMemImm* dump_imm_mem_noalloc(Mnemonic m, OpndSize size,
1155                           int imm,
1156                           int disp, int base_reg, bool isBasePhysical,
1157                           MemoryAccessType mType, int mIndex);
1158LowOpRegReg* dump_reg_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
1159                   int reg, bool isPhysical,
1160                   int reg2, bool isPhysical2, LowOpndRegType type);
1161LowOpRegReg* dump_movez_reg_reg(Mnemonic m, OpndSize size,
1162                        int reg, bool isPhysical,
1163                        int reg2, bool isPhysical2);
1164LowOpRegMem* dump_mem_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
1165                   int disp, int base_reg, bool isBasePhysical,
1166                   MemoryAccessType mType, int mIndex,
1167                   int reg, bool isPhysical, LowOpndRegType type);
1168LowOpRegMem* dump_mem_reg_noalloc(Mnemonic m, OpndSize size,
1169                           int disp, int base_reg, bool isBasePhysical,
1170                           MemoryAccessType mType, int mIndex,
1171                           int reg, bool isPhysical, LowOpndRegType type);
1172LowOpRegMem* dump_mem_scale_reg(Mnemonic m, OpndSize size,
1173                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
1174                         int reg, bool isPhysical, LowOpndRegType type);
1175LowOpMemReg* dump_reg_mem_scale(Mnemonic m, OpndSize size,
1176                         int reg, bool isPhysical,
1177                         int base_reg, bool isBasePhysical, int disp, int index_reg, bool isIndexPhysical, int scale,
1178                         LowOpndRegType type);
1179LowOpMemReg* dump_reg_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
1180                   int reg, bool isPhysical,
1181                   int disp, int base_reg, bool isBasePhysical,
1182                   MemoryAccessType mType, int mIndex, LowOpndRegType type);
1183LowOpMemReg* dump_reg_mem_noalloc(Mnemonic m, OpndSize size,
1184                           int reg, bool isPhysical,
1185                           int disp, int base_reg, bool isBasePhysical,
1186                           MemoryAccessType mType, int mIndex, LowOpndRegType type);
1187LowOpRegImm* dump_imm_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
1188                   int imm, int reg, bool isPhysical, LowOpndRegType type, bool chaining);
1189LowOpMemImm* dump_imm_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
1190                   int imm,
1191                   int disp, int base_reg, bool isBasePhysical,
1192                   MemoryAccessType mType, int mIndex, bool chaining);
1193LowOpMemReg* dump_fp_mem(Mnemonic m, OpndSize size, int reg,
1194                  int disp, int base_reg, bool isBasePhysical,
1195                  MemoryAccessType mType, int mIndex);
1196LowOpRegMem* dump_mem_fp(Mnemonic m, OpndSize size,
1197                  int disp, int base_reg, bool isBasePhysical,
1198                  MemoryAccessType mType, int mIndex,
1199                  int reg);
1200LowOpLabel* dump_label(Mnemonic m, OpndSize size, int imm,
1201               const char* label, bool isLocal);
1202
1203unsigned getJmpCallInstSize(OpndSize size, JmpCall_type type);
1204bool lowerByteCodeJit(const Method* method, const u2* codePtr, MIR* mir);
1205void startOfBasicBlock(struct BasicBlock* bb);
1206extern LowOpBlockLabel* traceLabelList;
1207extern struct BasicBlock* traceCurrentBB;
1208extern struct MIR* traceCurrentMIR;
1209void startOfTrace(const Method* method, LowOpBlockLabel* labelList, int, CompilationUnit*);
1210void endOfTrace(bool freeOnly);
1211LowOp* jumpToBasicBlock(char* instAddr, int targetId);
1212LowOp* condJumpToBasicBlock(char* instAddr, ConditionCode cc, int targetId);
1213bool jumpToException(const char* target);
1214int codeGenBasicBlockJit(const Method* method, BasicBlock* bb);
1215void endOfBasicBlock(struct BasicBlock* bb);
1216void handleExtendedMIR(CompilationUnit *cUnit, MIR *mir);
1217int insertChainingWorklist(int bbId, char * codeStart);
1218void startOfTraceO1(const Method* method, LowOpBlockLabel* labelList, int exceptionBlockId, CompilationUnit *cUnit);
1219void endOfTraceO1();
1220int isPowerOfTwo(int imm);
1221void move_chain_to_mem(OpndSize size, int imm,
1222                        int disp, int base_reg, bool isBasePhysical);
1223void move_chain_to_reg(OpndSize size, int imm, int reg, bool isPhysical);
1224
1225void dumpImmToMem(int vrNum, OpndSize size, int value);
1226bool isInMemory(int regNum, OpndSize size);
1227int touchEbx();
1228int boundCheck(int vr_array, int reg_array, bool isPhysical_array,
1229               int vr_index, int reg_index, bool isPhysical_index,
1230               int exceptionNum);
1231int getRelativeOffset(const char* target, bool isShortTerm, JmpCall_type type, bool* unknown,
1232                      OpndSize* immSize);
1233int getRelativeNCG(s4 tmp, JmpCall_type type, bool* unknown, OpndSize* size);
1234void freeAtomMem();
1235OpndSize estOpndSizeFromImm(int target);
1236
1237void preprocessingBB(BasicBlock* bb);
1238void preprocessingTrace();
1239void dump_nop(int size);
1240#endif
1241