• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
170 typedef 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 */
179 typedef 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 */
186 typedef enum InstanceAccess {
187     IGET, IGET_WIDE, IPUT, IPUT_WIDE
188 } InstanceAccess;
189 /*! An enum type
190     to list bytecodes for SGET, SPUT
191 */
192 typedef enum StaticAccess {
193     SGET, SGET_WIDE, SPUT, SPUT_WIDE
194 } StaticAccess;
195 
196 typedef 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 */
208 typedef enum LowOpndType {
209   LowOpndType_Imm = 0,
210   LowOpndType_Reg,
211   LowOpndType_Mem,
212   LowOpndType_Label,
213   LowOpndType_NCG,
214   LowOpndType_Chain
215 } LowOpndType;
216 typedef enum LowOpndDefUse {
217   LowOpndDefUse_Def = 0,
218   LowOpndDefUse_Use,
219   LowOpndDefUse_UseDef
220 } LowOpndDefUse;
221 
222 /*!
223 \brief base data structure for an operand */
224 typedef struct LowOpnd {
225   LowOpndType type;
226   OpndSize size;
227   LowOpndDefUse defuse;
228 } LowOpnd;
229 /*!
230 \brief data structure for a register operand */
231 typedef struct LowOpndReg {
232   LowOpndRegType regType;
233   int logicalReg;
234   int physicalReg;
235 } LowOpndReg;
236 /*!
237 \brief data structure for an immediate operand */
238 typedef struct LowOpndImm {
239   union {
240     s4 value;
241     unsigned char bytes[4];
242   };
243 } LowOpndImm;
244 
245 typedef struct LowOpndNCG {
246   union {
247     s4 value;
248     unsigned char bytes[4];
249   };
250 } LowOpndNCG;
251 
252 #define LABEL_SIZE 256
253 typedef 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 */
260 typedef enum MemoryAccessType {
261   MemoryAccess_GLUE,
262   MemoryAccess_VR,
263   MemoryAccess_SPILL,
264   MemoryAccess_Unknown
265 } MemoryAccessType;
266 typedef enum UseDefEntryType {
267   UseDefType_Ctrl = 0,
268   UseDefType_Float,
269   UseDefType_MemVR,
270   UseDefType_MemSpill,
271   UseDefType_MemUnknown,
272   UseDefType_Reg
273 } UseDefEntryType;
274 typedef 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 */
280 typedef 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 */
289 typedef 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 
299 typedef 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 
318 typedef enum DependencyType {
319   Dependency_RAW,
320   Dependency_WAW,
321   Dependency_WAR,
322   Dependency_FLAG
323 } DependencyType;
324 typedef struct DependencyStruct {
325   DependencyType dType;
326   int nodeId;
327   int latency;
328 } DependencyStruct;
329 
330 typedef struct LowOpBlock {
331   LIR generic;
332   Mnemonic opCode;
333   AtomOpCode opCode2;
334 } LowOpBlock;
335 
336 /*!
337 \brief data structure for a lowered operation */
338 typedef struct LowOp {
339   LIR generic;
340   Mnemonic opCode;
341   AtomOpCode opCode2;
342   LowOpnd opnd1;
343   LowOpnd opnd2;
344   int numOperands;
345 } LowOp;
346 
347 typedef struct LowOpLabel {
348   LowOp lop;
349   LowOpndLabel labelOpnd;
350 }LowOpLabel;
351 
352 typedef struct LowOpNCG {
353   LowOp lop;
354   LowOpndNCG ncgOpnd;
355 }LowOpNCG;
356 
357 typedef struct LowOpBlockLabel {
358   LowOpBlock lop;
359   LowOpndImm immOpnd;
360 } LowOpBlockLabel;
361 
362 typedef struct LowOpImm {
363   LowOp lop;
364   LowOpndImm immOpnd;
365 } LowOpImm;
366 
367 typedef struct LowOpMem {
368   LowOp lop;
369   LowOpndMem memOpnd;
370 } LowOpMem;
371 
372 typedef struct LowOpReg {
373   LowOp lop;
374   LowOpndReg regOpnd;
375 } LowOpReg;
376 
377 typedef struct LowOpImmImm {
378   LowOp lop;
379   LowOpndImm immOpnd1;
380   LowOpndImm immOpnd2;
381 } LowOpImmImm;
382 
383 typedef struct LowOpImmReg {
384   LowOp lop;
385   LowOpndImm immOpnd1;
386   LowOpndReg regOpnd2;
387 } LowOpImmReg;
388 
389 typedef struct LowOpImmMem {
390   LowOp lop;
391   LowOpndImm immOpnd1;
392   LowOpndMem memOpnd2;
393 } LowOpImmMem;
394 
395 typedef struct LowOpRegImm {
396   LowOp lop;
397   LowOpndReg regOpnd1;
398   LowOpndImm immOpnd2;
399 } LowOpRegImm;
400 
401 typedef struct LowOpRegReg {
402   LowOp lop;
403   LowOpndReg regOpnd1;
404   LowOpndReg regOpnd2;
405 } LowOpRegReg;
406 
407 typedef struct LowOpRegMem {
408   LowOp lop;
409   LowOpndReg regOpnd1;
410   LowOpndMem memOpnd2;
411 } LowOpRegMem;
412 
413 typedef struct LowOpMemImm {
414   LowOp lop;
415   LowOpndMem memOpnd1;
416   LowOpndImm immOpnd2;
417 } LowOpMemImm;
418 
419 typedef struct LowOpMemReg {
420   LowOp lop;
421   LowOpndMem memOpnd1;
422   LowOpndReg regOpnd2;
423 } LowOpMemReg;
424 
425 typedef 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 
434 four label maps are defined: globalMap globalShortMap globalWorklist globalShortWorklist
435 globalMap: global labels where codePtr points to the label
436            freeLabelMap called in clearNCG
437 globalWorklist: 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
443 globalShortMap: local labels where codePtr points to the label
444                 freeShortMap called after generation of one bytecode
445 globalShortWorklist: local labels where codePtr points to an instruction using the label
446                 accessed by insertShortWorklist & insertLabel
447 definition of local label: life time of the label is within a bytecode or within a helper function
448 extra label maps are used by code cache:
449   globalDataWorklist VMAPIWorklist
450 */
451 typedef 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 
461 accessed by insertNCGWorklist & performNCGWorklist
462 */
463 typedef 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 
475 two data worklist are defined: globalDataWorklist (used by code cache) & methodDataWorklist
476 methodDataWorklist is accessed by insertDataWorklist & performDataWorklist
477 */
478 typedef 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
488 typedef 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 
503 extern int LstrClassCastExceptionPtr, LstrInstantiationErrorPtr, LstrInternalError, LstrFilledNewArrayNotImpl;
504 extern int LstrArithmeticException, LstrArrayIndexException, LstrArrayStoreException, LstrStringIndexOutOfBoundsException;
505 extern int LstrDivideByZero, LstrNegativeArraySizeException, LstrNoSuchMethodError, LstrNullPointerException;
506 extern int LdoubNeg, LvaluePosInfLong, LvalueNegInfLong, LvalueNanLong, LshiftMask, Lvalue64, L64bits, LintMax, LintMin;
507 
508 extern LabelMap* globalMap;
509 extern LabelMap* globalShortMap;
510 extern LabelMap* globalWorklist;
511 extern LabelMap* globalShortWorklist;
512 extern NCGWorklist* globalNCGWorklist;
513 extern DataWorklist* methodDataWorklist;
514 #ifdef ENABLE_TRACING
515 extern MapWorklist* methodMapWorklist;
516 #endif
517 extern 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 
523 extern LowOp* ops[BUFFER_SIZE];
524 extern bool isScratchPhysical;
525 extern u2* rPC;
526 extern u2 inst;
527 extern int offsetPC;
528 extern int offsetNCG;
529 extern int mapFromBCtoNCG[BYTECODE_SIZE_PER_METHOD];
530 extern char* streamStart;
531 
532 extern char* streamCode;
533 
534 extern char* streamMethodStart; //start of the method
535 extern char* stream; //current stream pointer
536 extern char* streamMisPred;
537 extern int lowOpTimeStamp;
538 extern Method* currentMethod;
539 extern int currentExceptionBlockIdx;
540 
541 extern int globalMapNum;
542 extern int globalWorklistNum;
543 extern int globalDataWorklistNum;
544 extern int globalPCWorklistNum;
545 extern int chainingWorklistNum;
546 extern int VMAPIWorklistNum;
547 
548 extern LabelMap* globalDataWorklist;
549 extern LabelMap* globalPCWorklist;
550 extern LabelMap* chainingWorklist;
551 extern LabelMap* VMAPIWorklist;
552 
553 extern int ncgClassNum;
554 extern int ncgMethodNum;
555 
556 extern LowOp* lirTable[200]; //Number of LIRs for all bytecodes do not exceed 200
557 extern int num_lirs_in_table;
558 
559 bool existATryBlock(Method* method, int startPC, int endPC);
560 // interface between register allocator & lowering
561 extern int num_removed_nullCheck;
562 
563 int registerAlloc(int type, int reg, bool isPhysical, bool updateRef);
564 int registerAllocMove(int reg, int type, bool isPhysical, int srcReg);
565 int checkVirtualReg(int reg, LowOpndRegType type, int updateRef); //returns the physical register
566 int updateRefCount(int reg, LowOpndRegType type);
567 int updateRefCount2(int reg, int type, bool isPhysical);
568 int spillVirtualReg(int vrNum, LowOpndRegType type, bool updateTable);
569 int isVirtualRegConstant(int regNum, LowOpndRegType type, int* valuePtr, bool updateRef);
570 int checkTempReg(int reg, int type, bool isPhysical, int vA);
571 bool checkTempReg2(int reg, int type, bool isPhysical, int physicalRegForVR);
572 int freeReg(bool spillGL);
573 int nextVersionOfHardReg(PhysicalReg pReg, int refCount);
574 int updateVirtualReg(int reg, LowOpndRegType type);
575 void setVRNullCheck(int regNum, OpndSize size);
576 bool isVRNullCheck(int regNum, OpndSize size);
577 void setVRBoundCheck(int vr_array, int vr_index);
578 bool isVRBoundCheck(int vr_array, int vr_index);
579 int requestVRFreeDelay(int regNum, u4 reason);
580 void cancelVRFreeDelayRequest(int regNum, u4 reason);
581 bool getVRFreeDelayRequested(int regNum);
582 bool isGlueHandled(int glue_reg);
583 void resetGlue(int glue_reg);
584 void updateGlue(int reg, bool isPhysical, int glue_reg);
585 int updateVRAtUse(int reg, LowOpndRegType pType, int regAll);
586 int touchEcx();
587 int touchEax();
588 int touchEdx();
589 int beforeCall(const char* target);
590 int afterCall(const char* target);
591 void startBranch();
592 void endBranch();
593 void rememberState(int);
594 void goToState(int);
595 void transferToState(int);
596 void globalVREndOfBB(const Method*);
597 void constVREndOfBB();
598 void startNativeCode(int num, int type);
599 void endNativeCode();
600 void donotSpillReg(int physicalReg);
601 void 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]
610 void load_effective_addr(int disp, int base_reg, bool isBasePhysical,
611                           int reg, bool isPhysical);
612 void load_effective_addr_scale(int base_reg, bool isBasePhysical,
613                                 int index_reg, bool isIndexPhysical, int scale,
614                                 int reg, bool isPhysical);
615 void load_fpu_cw(int disp, int base_reg, bool isBasePhysical);
616 void store_fpu_cw(bool checkException, int disp, int base_reg, bool isBasePhysical);
617 void convert_integer(OpndSize srcSize, OpndSize dstSize);
618 void load_fp_stack(LowOp* op, OpndSize size, int disp, int base_reg, bool isBasePhysical);
619 void load_int_fp_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical);
620 void load_int_fp_stack_imm(OpndSize size, int imm);
621 void store_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical);
622 void store_int_fp_stack(LowOp* op, bool pop, OpndSize size, int disp, int base_reg, bool isBasePhysical);
623 
624 void load_fp_stack_VR(OpndSize size, int vA);
625 void load_int_fp_stack_VR(OpndSize size, int vA);
626 void store_fp_stack_VR(bool pop, OpndSize size, int vA);
627 void store_int_fp_stack_VR(bool pop, OpndSize size, int vA);
628 void compare_VR_ss_reg(int vA, int reg, bool isPhysical);
629 void compare_VR_sd_reg(int vA, int reg, bool isPhysical);
630 void fpu_VR(ALU_Opcode opc, OpndSize size, int vA);
631 void compare_reg_mem(LowOp* op, OpndSize size, int reg, bool isPhysical,
632                            int disp, int base_reg, bool isBasePhysical);
633 void compare_mem_reg(OpndSize size,
634                            int disp, int base_reg, bool isBasePhysical,
635                            int reg, bool isPhysical);
636 void compare_VR_reg(OpndSize size,
637                            int vA,
638                            int reg, bool isPhysical);
639 void compare_imm_reg(OpndSize size, int imm,
640                            int reg, bool isPhysical);
641 void compare_imm_mem(OpndSize size, int imm,
642                            int disp, int base_reg, bool isBasePhysical);
643 void compare_imm_VR(OpndSize size, int imm,
644                            int vA);
645 void compare_reg_reg(int reg1, bool isPhysical1,
646                            int reg2, bool isPhysical2);
647 void compare_reg_reg_16(int reg1, bool isPhysical1,
648                          int reg2, bool isPhysical2);
649 void compare_ss_mem_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
650                               int reg, bool isPhysical);
651 void compare_ss_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
652                               int reg2, bool isPhysical2);
653 void compare_sd_mem_with_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
654                               int reg, bool isPhysical);
655 void compare_sd_reg_with_reg(LowOp* op, int reg1, bool isPhysical1,
656                               int reg2, bool isPhysical2);
657 void compare_fp_stack(bool pop, int reg, bool isDouble);
658 void test_imm_reg(OpndSize size, int imm, int reg, bool isPhysical);
659 void test_imm_mem(OpndSize size, int imm, int disp, int reg, bool isPhysical);
660 
661 void conditional_move_reg_to_reg(OpndSize size, ConditionCode cc, int reg1, bool isPhysical1, int reg, bool isPhysical);
662 void move_ss_mem_to_reg(LowOp* op, int disp, int base_reg, bool isBasePhysical,
663                         int reg, bool isPhysical);
664 void move_ss_reg_to_mem(LowOp* op, int reg, bool isPhysical,
665                          int disp, int base_reg, bool isBasePhysical);
666 LowOpRegMem* move_ss_mem_to_reg_noalloc(int disp, int base_reg, bool isBasePhysical,
667                          MemoryAccessType mType, int mIndex,
668                          int reg, bool isPhysical);
669 LowOpMemReg* move_ss_reg_to_mem_noalloc(int reg, bool isPhysical,
670                          int disp, int base_reg, bool isBasePhysical,
671                          MemoryAccessType mType, int mIndex);
672 void move_sd_mem_to_reg(int disp, int base_reg, bool isBasePhysical,
673                          int reg, bool isPhysical);
674 void move_sd_reg_to_mem(LowOp* op, int reg, bool isPhysical,
675                          int disp, int base_reg, bool isBasePhysical);
676 
677 void conditional_jump(ConditionCode cc, const char* target, bool isShortTerm);
678 void unconditional_jump(const char* target, bool isShortTerm);
679 void conditional_jump_int(ConditionCode cc, int target, OpndSize size);
680 void unconditional_jump_int(int target, OpndSize size);
681 void unconditional_jump_reg(int reg, bool isPhysical);
682 void call(const char* target);
683 void call_reg(int reg, bool isPhysical);
684 void call_reg_noalloc(int reg, bool isPhysical);
685 void call_mem(int disp, int reg, bool isPhysical);
686 void x86_return();
687 
688 void alu_unary_reg(OpndSize size, ALU_Opcode opc, int reg, bool isPhysical);
689 void alu_unary_mem(LowOp* op, OpndSize size, ALU_Opcode opc, int disp, int base_reg, bool isBasePhysical);
690 
691 void alu_binary_imm_mem(OpndSize size, ALU_Opcode opc,
692                          int imm, int disp, int base_reg, bool isBasePhysical);
693 void alu_binary_imm_reg(OpndSize size, ALU_Opcode opc, int imm, int reg, bool isPhysical);
694 void alu_binary_mem_reg(OpndSize size, ALU_Opcode opc,
695                          int disp, int base_reg, bool isBasePhysical,
696                          int reg, bool isPhysical);
697 void alu_binary_VR_reg(OpndSize size, ALU_Opcode opc, int vA, int reg, bool isPhysical);
698 void alu_sd_binary_VR_reg(ALU_Opcode opc, int vA, int reg, bool isPhysical, bool isSD);
699 void alu_binary_reg_reg(OpndSize size, ALU_Opcode opc,
700                          int reg1, bool isPhysical1,
701                          int reg2, bool isPhysical2);
702 void alu_binary_reg_mem(OpndSize size, ALU_Opcode opc,
703                          int reg, bool isPhysical,
704                          int disp, int base_reg, bool isBasePhysical);
705 
706 void fpu_mem(LowOp* op, ALU_Opcode opc, OpndSize size, int disp, int base_reg, bool isBasePhysical);
707 void alu_ss_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
708                             int reg2, bool isPhysical2);
709 void alu_sd_binary_reg_reg(ALU_Opcode opc, int reg, bool isPhysical,
710                             int reg2, bool isPhysical2);
711 
712 void push_mem_to_stack(OpndSize size, int disp, int base_reg, bool isBasePhysical);
713 void push_reg_to_stack(OpndSize size, int reg, bool isPhysical);
714 
715 //returns the pointer to end of the native code
716 void move_reg_to_mem(OpndSize size,
717                       int reg, bool isPhysical,
718                       int disp, int base_reg, bool isBasePhysical);
719 LowOpRegMem* move_mem_to_reg(OpndSize size,
720                       int disp, int base_reg, bool isBasePhysical,
721                       int reg, bool isPhysical);
722 void movez_mem_to_reg(OpndSize size,
723                       int disp, int base_reg, bool isBasePhysical,
724                       int reg, bool isPhysical);
725 void movez_reg_to_reg(OpndSize size,
726                       int reg, bool isPhysical,
727                       int reg2, bool isPhysical2);
728 void moves_mem_to_reg(LowOp* op, OpndSize size,
729                       int disp, int base_reg, bool isBasePhysical,
730                       int reg, bool isPhysical);
731 void 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);
735 void 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);
739 void move_reg_to_reg(OpndSize size,
740                       int reg, bool isPhysical,
741                       int reg2, bool isPhysical2);
742 void move_reg_to_reg_noalloc(OpndSize size,
743                       int reg, bool isPhysical,
744                       int reg2, bool isPhysical2);
745 void 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);
748 void 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);
751 void 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);
754 void 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);
757 void move_imm_to_mem(OpndSize size, int imm,
758                       int disp, int base_reg, bool isBasePhysical);
759 void set_VR_to_imm(u2 vA, OpndSize size, int imm);
760 void set_VR_to_imm_noalloc(u2 vA, OpndSize size, int imm);
761 void set_VR_to_imm_noupdateref(LowOp* op, u2 vA, OpndSize size, int imm);
762 void move_imm_to_reg(OpndSize size, int imm, int reg, bool isPhysical);
763 void 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]
768 void get_virtual_reg(u2 vB, OpndSize size, int reg, bool isPhysical);
769 void get_virtual_reg_noalloc(u2 vB, OpndSize size, int reg, bool isPhysical);
770 //VR[v] = LR[reg]
771 //or
772 //VR[v] = PR[reg]
773 void set_virtual_reg(u2 vA, OpndSize size, int reg, bool isPhysical);
774 void set_virtual_reg_noalloc(u2 vA, OpndSize size, int reg, bool isPhysical);
775 void get_VR_ss(int vB, int reg, bool isPhysical);
776 void set_VR_ss(int vA, int reg, bool isPhysical);
777 void get_VR_sd(int vB, int reg, bool isPhysical);
778 void set_VR_sd(int vA, int reg, bool isPhysical);
779 
780 int spill_reg(int reg, bool isPhysical);
781 int unspill_reg(int reg, bool isPhysical);
782 
783 void 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);
787 LowOpRegMem* 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 //////////////////////////////////////////////////////////////
793 int insertLabel(const char* label, bool checkDup);
794 int export_pc();
795 int simpleNullCheck(int reg, bool isPhysical, int vr);
796 int nullCheck(int reg, bool isPhysical, int exceptionNum, int vr);
797 int handlePotentialException(
798                              ConditionCode code_excep, ConditionCode code_okay,
799                              int exceptionNum, const char* errName);
800 int get_currentpc(int reg, bool isPhysical);
801 int get_self_pointer(int reg, bool isPhysical);
802 int get_res_strings(int reg, bool isPhysical);
803 int get_res_classes(int reg, bool isPhysical);
804 int get_res_fields(int reg, bool isPhysical);
805 int get_res_methods(int reg, bool isPhysical);
806 int get_glue_method_class(int reg, bool isPhysical);
807 int get_glue_method(int reg, bool isPhysical);
808 int set_glue_method(int reg, bool isPhysical);
809 int get_glue_dvmdex(int reg, bool isPhysical);
810 int set_glue_dvmdex(int reg, bool isPhysical);
811 int get_suspendCount(int reg, bool isPhysical);
812 int get_return_value(OpndSize size, int reg, bool isPhysical);
813 int set_return_value(OpndSize size, int reg, bool isPhysical);
814 int clear_exception();
815 int get_exception(int reg, bool isPhysical);
816 int set_exception(int reg, bool isPhysical);
817 int save_pc_fp_to_glue();
818 int savearea_from_fp(int reg, bool isPhysical);
819 
820 int call_moddi3();
821 int call_divdi3();
822 int call_fmod();
823 int call_fmodf();
824 int call_dvmFindCatchBlock();
825 int call_dvmThrowVerificationError();
826 int call_dvmAllocObject();
827 int call_dvmAllocArrayByClass();
828 int call_dvmResolveMethod();
829 int call_dvmResolveClass();
830 int call_dvmInstanceofNonTrivial();
831 int call_dvmThrow();
832 int call_dvmThrowWithMessage();
833 int call_dvmCheckSuspendPending();
834 int call_dvmLockObject();
835 int call_dvmUnlockObject();
836 int call_dvmInitClass();
837 int call_dvmAllocPrimitiveArray();
838 int call_dvmInterpHandleFillArrayData();
839 int call_dvmNcgHandlePackedSwitch();
840 int call_dvmNcgHandleSparseSwitch();
841 int call_dvmJitHandlePackedSwitch();
842 int call_dvmJitHandleSparseSwitch();
843 int call_dvmJitToInterpTraceSelectNoChain();
844 int call_dvmJitToPatchPredictedChain();
845 int call_dvmJitToInterpNormal();
846 int call_dvmJitToInterpTraceSelect();
847 int call_dvmQuasiAtomicSwap64();
848 int call_dvmQuasiAtomicRead64();
849 int call_dvmCanPutArrayElement();
850 int call_dvmFindInterfaceMethodInCache();
851 int call_dvmHandleStackOverflow();
852 int call_dvmResolveString();
853 int call_dvmResolveInstField();
854 int 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 */
863 int 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 */
867 int 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 */
870 int throw_exception(int exceptionPtr, int imm,
871                     int startLR/*logical register index*/, bool startPhysical);
872 
873 void freeShortMap();
874 int insertDataWorklist(s4 relativePC, char* codePtr1);
875 #ifdef ENABLE_TRACING
876 int insertMapWorklist(s4 BCOffset, s4 NCGOffset, int isStartOfPC);
877 #endif
878 int performNCGWorklist();
879 int performDataWorklist();
880 void performLabelWorklist();
881 void performMethodLabelWorklist();
882 void freeLabelMap();
883 void performSharedWorklist();
884 void performChainingWorklist();
885 void freeNCGWorklist();
886 void freeDataWorklist();
887 void freeLabelWorklist();
888 void freeChainingWorklist();
889 
890 int common_invokeArgsDone(ArgsDoneType form, bool isJitFull);
891 int common_backwardBranch();
892 int common_exceptionThrown();
893 int common_errNullObject();
894 int common_errArrayIndex();
895 int common_errArrayStore();
896 int common_errNegArraySize();
897 int common_errNoSuchMethod();
898 int common_errDivideByZero();
899 int common_periodicChecks_entry();
900 int common_periodicChecks4();
901 int common_gotoBail();
902 int common_gotoBail_0();
903 int common_StringIndexOutOfBounds();
904 void goto_invokeArgsDone();
905 
906 //lower a bytecode
907 int lowerByteCode(const Method* method);
908 
909 int op_nop();
910 int op_move();
911 int op_move_from16();
912 int op_move_16();
913 int op_move_wide();
914 int op_move_wide_from16();
915 int op_move_wide_16();
916 int op_move_result();
917 int op_move_result_wide();
918 int op_move_exception();
919 
920 int op_return_void();
921 int op_return();
922 int op_return_wide();
923 int op_const_4();
924 int op_const_16();
925 int op_const();
926 int op_const_high16();
927 int op_const_wide_16();
928 int op_const_wide_32();
929 int op_const_wide();
930 int op_const_wide_high16();
931 int op_const_string();
932 int op_const_string_jumbo();
933 int op_const_class();
934 int op_monitor_enter();
935 int op_monitor_exit();
936 int op_check_cast();
937 int op_instance_of();
938 
939 int op_array_length();
940 int op_new_instance();
941 int op_new_array();
942 int op_filled_new_array();
943 int op_filled_new_array_range();
944 int op_fill_array_data();
945 int op_throw();
946 int op_throw_verification_error();
947 int op_goto();
948 int op_goto_16();
949 int op_goto_32();
950 int op_packed_switch();
951 int op_sparse_switch();
952 int op_if_ge();
953 int op_aget();
954 int op_aget_wide();
955 int op_aget_object();
956 int op_aget_boolean();
957 int op_aget_byte();
958 int op_aget_char();
959 int op_aget_short();
960 int op_aput();
961 int op_aput_wide();
962 int op_aput_object();
963 int op_aput_boolean();
964 int op_aput_byte();
965 int op_aput_char();
966 int op_aput_short();
967 int op_iget();
968 int op_iget_wide(bool isVolatile);
969 int op_iget_object();
970 int op_iget_boolean();
971 int op_iget_byte();
972 int op_iget_char();
973 int op_iget_short();
974 int op_iput();
975 int op_iput_wide(bool isVolatile);
976 int op_iput_object();
977 int op_iput_boolean();
978 int op_iput_byte();
979 int op_iput_char();
980 int op_iput_short();
981 int op_sget();
982 int op_sget_wide(bool isVolatile);
983 int op_sget_object();
984 int op_sget_boolean();
985 int op_sget_byte();
986 int op_sget_char();
987 int op_sget_short();
988 int op_sput(bool isObj);
989 int op_sput_wide(bool isVolatile);
990 int op_sput_object();
991 int op_sput_boolean();
992 int op_sput_byte();
993 int op_sput_char();
994 int op_sput_short();
995 int op_invoke_virtual();
996 int op_invoke_super();
997 int op_invoke_direct();
998 int op_invoke_static();
999 int op_invoke_interface();
1000 int op_invoke_virtual_range();
1001 int op_invoke_super_range();
1002 int op_invoke_direct_range();
1003 int op_invoke_static_range();
1004 int op_invoke_interface_range();
1005 int op_int_to_long();
1006 int op_add_long_2addr();
1007 int op_add_int_lit8();
1008 int op_cmpl_float();
1009 int op_cmpg_float();
1010 int op_cmpl_double();
1011 int op_cmpg_double();
1012 int op_cmp_long();
1013 int op_if_eq();
1014 int op_if_ne();
1015 int op_if_lt();
1016 int op_if_gt();
1017 int op_if_le();
1018 int op_if_eqz();
1019 int op_if_nez();
1020 int op_if_ltz();
1021 int op_if_gez();
1022 int op_if_gtz();
1023 int op_if_lez();
1024 int op_neg_int();
1025 int op_not_int();
1026 int op_neg_long();
1027 int op_not_long();
1028 int op_neg_float();
1029 int op_neg_double();
1030 int op_int_to_float();
1031 int op_int_to_double();
1032 int op_long_to_int();
1033 int op_long_to_float();
1034 int op_long_to_double();
1035 int op_float_to_int();
1036 int op_float_to_long();
1037 int op_float_to_double();
1038 int op_double_to_int();
1039 int op_double_to_long();
1040 int op_double_to_float();
1041 int op_int_to_byte();
1042 int op_int_to_char();
1043 int op_int_to_short();
1044 int op_add_int();
1045 int op_sub_int();
1046 int op_mul_int();
1047 int op_div_int();
1048 int op_rem_int();
1049 int op_and_int();
1050 int op_or_int();
1051 int op_xor_int();
1052 int op_shl_int();
1053 int op_shr_int();
1054 int op_ushr_int();
1055 int op_add_long();
1056 int op_sub_long();
1057 int op_mul_long();
1058 int op_div_long();
1059 int op_rem_long();
1060 int op_and_long();
1061 int op_or_long();
1062 int op_xor_long();
1063 int op_shl_long();
1064 int op_shr_long();
1065 int op_ushr_long();
1066 int op_add_float();
1067 int op_sub_float();
1068 int op_mul_float();
1069 int op_div_float();
1070 int op_rem_float();
1071 int op_add_double();
1072 int op_sub_double();
1073 int op_mul_double();
1074 int op_div_double();
1075 int op_rem_double();
1076 int op_add_int_2addr();
1077 int op_sub_int_2addr();
1078 int op_mul_int_2addr();
1079 int op_div_int_2addr();
1080 int op_rem_int_2addr();
1081 int op_and_int_2addr();
1082 int op_or_int_2addr();
1083 int op_xor_int_2addr();
1084 int op_shl_int_2addr();
1085 int op_shr_int_2addr();
1086 int op_ushr_int_2addr();
1087 int op_sub_long_2addr();
1088 int op_mul_long_2addr();
1089 int op_div_long_2addr();
1090 int op_rem_long_2addr();
1091 int op_and_long_2addr();
1092 int op_or_long_2addr();
1093 int op_xor_long_2addr();
1094 int op_shl_long_2addr();
1095 int op_shr_long_2addr();
1096 int op_ushr_long_2addr();
1097 int op_add_float_2addr();
1098 int op_sub_float_2addr();
1099 int op_mul_float_2addr();
1100 int op_div_float_2addr();
1101 int op_rem_float_2addr();
1102 int op_add_double_2addr();
1103 int op_sub_double_2addr();
1104 int op_mul_double_2addr();
1105 int op_div_double_2addr();
1106 int op_rem_double_2addr();
1107 int op_add_int_lit16();
1108 int op_rsub_int();
1109 int op_mul_int_lit16();
1110 int op_div_int_lit16();
1111 int op_rem_int_lit16();
1112 int op_and_int_lit16();
1113 int op_or_int_lit16();
1114 int op_xor_int_lit16();
1115 int op_rsub_int_lit8();
1116 int op_mul_int_lit8();
1117 int op_div_int_lit8();
1118 int op_rem_int_lit8();
1119 int op_and_int_lit8();
1120 int op_or_int_lit8();
1121 int op_xor_int_lit8();
1122 int op_shl_int_lit8();
1123 int op_shr_int_lit8();
1124 int op_ushr_int_lit8();
1125 int op_execute_inline(bool isRange);
1126 int op_invoke_object_init_range();
1127 int op_iget_quick();
1128 int op_iget_wide_quick();
1129 int op_iget_object_quick();
1130 int op_iput_quick();
1131 int op_iput_wide_quick();
1132 int op_iput_object_quick();
1133 int op_invoke_virtual_quick();
1134 int op_invoke_virtual_quick_range();
1135 int op_invoke_super_quick();
1136 int op_invoke_super_quick_range();
1137 
1138 ///////////////////////////////////////////////
1139 void set_reg_opnd(LowOpndReg* op_reg, int reg, bool isPhysical, LowOpndRegType type);
1140 void set_mem_opnd(LowOpndMem* mem, int disp, int base, bool isPhysical);
1141 void set_mem_opnd_scale(LowOpndMem* mem, int base, bool isPhysical, int disp, int index, bool indexPhysical, int scale);
1142 LowOpImm* dump_imm(Mnemonic m, OpndSize size,
1143                int imm);
1144 LowOpNCG* dump_ncg(Mnemonic m, OpndSize size, int imm);
1145 LowOpImm* dump_imm_with_codeaddr(Mnemonic m, OpndSize size,
1146                int imm, char* codePtr);
1147 LowOpImm* dump_special(AtomOpCode cc, int imm);
1148 LowOpMem* dump_mem(Mnemonic m, AtomOpCode m2, OpndSize size,
1149                int disp, int base_reg, bool isBasePhysical);
1150 LowOpReg* dump_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
1151                int reg, bool isPhysical, LowOpndRegType type);
1152 LowOpReg* dump_reg_noalloc(Mnemonic m, OpndSize size,
1153                int reg, bool isPhysical, LowOpndRegType type);
1154 LowOpMemImm* dump_imm_mem_noalloc(Mnemonic m, OpndSize size,
1155                            int imm,
1156                            int disp, int base_reg, bool isBasePhysical,
1157                            MemoryAccessType mType, int mIndex);
1158 LowOpRegReg* dump_reg_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
1159                    int reg, bool isPhysical,
1160                    int reg2, bool isPhysical2, LowOpndRegType type);
1161 LowOpRegReg* dump_movez_reg_reg(Mnemonic m, OpndSize size,
1162                         int reg, bool isPhysical,
1163                         int reg2, bool isPhysical2);
1164 LowOpRegMem* 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);
1168 LowOpRegMem* 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);
1172 LowOpRegMem* 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);
1175 LowOpMemReg* 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);
1179 LowOpMemReg* 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);
1183 LowOpMemReg* 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);
1187 LowOpRegImm* dump_imm_reg(Mnemonic m, AtomOpCode m2, OpndSize size,
1188                    int imm, int reg, bool isPhysical, LowOpndRegType type, bool chaining);
1189 LowOpMemImm* 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);
1193 LowOpMemReg* dump_fp_mem(Mnemonic m, OpndSize size, int reg,
1194                   int disp, int base_reg, bool isBasePhysical,
1195                   MemoryAccessType mType, int mIndex);
1196 LowOpRegMem* dump_mem_fp(Mnemonic m, OpndSize size,
1197                   int disp, int base_reg, bool isBasePhysical,
1198                   MemoryAccessType mType, int mIndex,
1199                   int reg);
1200 LowOpLabel* dump_label(Mnemonic m, OpndSize size, int imm,
1201                const char* label, bool isLocal);
1202 
1203 unsigned getJmpCallInstSize(OpndSize size, JmpCall_type type);
1204 bool lowerByteCodeJit(const Method* method, const u2* codePtr, MIR* mir);
1205 void startOfBasicBlock(struct BasicBlock* bb);
1206 extern LowOpBlockLabel* traceLabelList;
1207 extern struct BasicBlock* traceCurrentBB;
1208 extern struct MIR* traceCurrentMIR;
1209 void startOfTrace(const Method* method, LowOpBlockLabel* labelList, int, CompilationUnit*);
1210 void endOfTrace(bool freeOnly);
1211 LowOp* jumpToBasicBlock(char* instAddr, int targetId);
1212 LowOp* condJumpToBasicBlock(char* instAddr, ConditionCode cc, int targetId);
1213 bool jumpToException(const char* target);
1214 int codeGenBasicBlockJit(const Method* method, BasicBlock* bb);
1215 void endOfBasicBlock(struct BasicBlock* bb);
1216 void handleExtendedMIR(CompilationUnit *cUnit, MIR *mir);
1217 int insertChainingWorklist(int bbId, char * codeStart);
1218 void startOfTraceO1(const Method* method, LowOpBlockLabel* labelList, int exceptionBlockId, CompilationUnit *cUnit);
1219 void endOfTraceO1();
1220 int isPowerOfTwo(int imm);
1221 void move_chain_to_mem(OpndSize size, int imm,
1222                         int disp, int base_reg, bool isBasePhysical);
1223 void move_chain_to_reg(OpndSize size, int imm, int reg, bool isPhysical);
1224 
1225 void dumpImmToMem(int vrNum, OpndSize size, int value);
1226 bool isInMemory(int regNum, OpndSize size);
1227 int touchEbx();
1228 int boundCheck(int vr_array, int reg_array, bool isPhysical_array,
1229                int vr_index, int reg_index, bool isPhysical_index,
1230                int exceptionNum);
1231 int getRelativeOffset(const char* target, bool isShortTerm, JmpCall_type type, bool* unknown,
1232                       OpndSize* immSize);
1233 int getRelativeNCG(s4 tmp, JmpCall_type type, bool* unknown, OpndSize* size);
1234 void freeAtomMem();
1235 OpndSize estOpndSizeFromImm(int target);
1236 
1237 void preprocessingBB(BasicBlock* bb);
1238 void preprocessingTrace();
1239 void dump_nop(int size);
1240 #endif
1241