• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 #ifndef DALVIK_VM_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
18 #define DALVIK_VM_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
19 
20 #include "Dalvik.h"
21 #include "compiler/CompilerInternals.h"
22 
23 /*
24  * zero is always the value 0
25  * at is scratch for Jit (normally used as temp reg by assembler)
26  * v0, v1 are scratch for Jit (normally hold subroutine return values)
27  * a0-a3 are scratch for Jit (normally hold subroutine arguments)
28  * t0-t7 are scratch for Jit
29  * t8 is scratch for Jit
30  * t9 is scratch for Jit (normally used for function calls)
31  * s0 (rFP) is reserved [holds Dalvik frame pointer]
32  * s1 (rSELF) is reserved [holds current &Thread]
33  * s2 (rINST) is scratch for Jit
34  * s3 (rIBASE) is scratch for Jit
35  * s4-s7 are scratch for Jit
36  * k0, k1 are reserved for use by interrupt handlers
37  * gp is reserved for global pointer
38  * sp is reserved
39  * s8 is scratch for Jit
40  * ra is scratch for Jit (normally holds the return addr)
41  *
42  * Preserved across C calls: s0-s8
43  * Trashed across C calls: at, v0-v1, a0-a3, t0-t9, gp, ra
44  *
45  * Floating pointer registers
46  * NOTE: there are 32 fp registers (16 df pairs), but current Jit code
47  *       only support 16 fp registers (8 df pairs).
48  * f0-f15
49  * df0-df7, where df0={f0,f1}, df1={f2,f3}, ... , df7={f14,f15}
50  *
51  * f0-f15 (df0-df7) trashed across C calls
52  *
53  * For mips32 code use:
54  *      a0-a3 to hold operands
55  *      v0-v1 to hold results
56  *      t0-t9 for temps
57  *
58  * All jump/branch instructions have a delay slot after it.
59  *
60  */
61 
62 /* Offset to distingish FP regs */
63 #define FP_REG_OFFSET 32
64 /* Offset to distinguish DP FP regs */
65 #define FP_DOUBLE 64
66 /* Offset to distingish the extra regs */
67 #define EXTRA_REG_OFFSET 128
68 /* Reg types */
69 #define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE))
70 #define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
71 #define EXTRAREG(x) ((x & EXTRA_REG_OFFSET) == EXTRA_REG_OFFSET)
72 #define LOWREG(x) ((x & 0x1f) == x)
73 #define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
74 #define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
75 /*
76  * Note: the low register of a floating point pair is sufficient to
77  * create the name of a double, but require both names to be passed to
78  * allow for asserts to verify that the pair is consecutive if significant
79  * rework is done in this area.  Also, it is a good reminder in the calling
80  * code that reg locations always describe doubles as a pair of singles.
81  */
82 #define S2D(x,y) ((x) | FP_DOUBLE)
83 /* Mask to strip off fp flags */
84 #define FP_REG_MASK (FP_REG_OFFSET-1)
85 /* non-existent Dalvik register */
86 #define vNone   (-1)
87 /* non-existant physical register */
88 #define rNone   (-1)
89 
90 #ifdef HAVE_LITTLE_ENDIAN
91 #define LOWORD_OFFSET 0
92 #define HIWORD_OFFSET 4
93 #define r_ARG0 r_A0
94 #define r_ARG1 r_A1
95 #define r_ARG2 r_A2
96 #define r_ARG3 r_A3
97 #define r_RESULT0 r_V0
98 #define r_RESULT1 r_V1
99 #else
100 #define LOWORD_OFFSET 4
101 #define HIWORD_OFFSET 0
102 #define r_ARG0 r_A1
103 #define r_ARG1 r_A0
104 #define r_ARG2 r_A3
105 #define r_ARG3 r_A2
106 #define r_RESULT0 r_V1
107 #define r_RESULT1 r_V0
108 #endif
109 
110 /* These are the same for both big and little endian. */
111 #define r_FARG0 r_F12
112 #define r_FARG1 r_F13
113 #define r_FRESULT0 r_F0
114 #define r_FRESULT1 r_F1
115 
116 /* RegisterLocation templates return values (r_V0, or r_V0/r_V1) */
117 #define LOC_C_RETURN {kLocPhysReg, 0, 0, r_V0, 0, -1}
118 #define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, r_RESULT0, r_RESULT1, -1}
119 #define LOC_C_RETURN_ALT {kLocPhysReg, 0, 1, r_F0, 0, -1}
120 #define LOC_C_RETURN_WIDE_ALT {kLocPhysReg, 1, 1, r_FRESULT0, r_FRESULT1, -1}
121 /* RegisterLocation templates for interpState->retVal; */
122 #define LOC_DALVIK_RETURN_VAL {kLocRetval, 0, 0, 0, 0, -1}
123 #define LOC_DALVIK_RETURN_VAL_WIDE {kLocRetval, 1, 0, 0, 0, -1}
124 
125  /*
126  * Data structure tracking the mapping between a Dalvik register (pair) and a
127  * native register (pair). The idea is to reuse the previously loaded value
128  * if possible, otherwise to keep the value in a native register as long as
129  * possible.
130  */
131 typedef struct RegisterInfo {
132     int reg;                    // Reg number
133     bool inUse;                 // Has it been allocated?
134     bool pair;                  // Part of a register pair?
135     int partner;                // If pair, other reg of pair
136     bool live;                  // Is there an associated SSA name?
137     bool dirty;                 // If live, is it dirty?
138     int sReg;                   // Name of live value
139     struct LIR *defStart;       // Starting inst in last def sequence
140     struct LIR *defEnd;         // Ending inst in last def sequence
141 } RegisterInfo;
142 
143 typedef struct RegisterPool {
144     BitVector *nullCheckedRegs; // Track which registers have been null-checked
145     int numCoreTemps;
146     RegisterInfo *coreTemps;
147     int nextCoreTemp;
148     int numFPTemps;
149     RegisterInfo *FPTemps;
150     int nextFPTemp;
151 } RegisterPool;
152 
153 typedef enum ResourceEncodingPos {
154     kGPReg0     = 0,
155     kRegSP      = 29,
156     kRegLR      = 31,
157     kFPReg0     = 32, /* only 16 fp regs supported currently */
158     kFPRegEnd   = 48,
159     kRegHI      = kFPRegEnd,
160     kRegLO,
161     kRegPC,
162     kRegEnd     = 51,
163     kCCode      = kRegEnd,
164     kFPStatus,          // FP status word
165     // The following four bits are for memory disambiguation
166     kDalvikReg,         // 1 Dalvik Frame (can be fully disambiguated)
167     kLiteral,           // 2 Literal pool (can be fully disambiguated)
168     kHeapRef,           // 3 Somewhere on the heap (alias with any other heap)
169     kMustNotAlias,      // 4 Guaranteed to be non-alias (eg *(r6+x))
170 } ResourceEncodingPos;
171 
172 #define ENCODE_REG_LIST(N)      ((u8) N)
173 #define ENCODE_REG_SP           (1ULL << kRegSP)
174 #define ENCODE_REG_LR           (1ULL << kRegLR)
175 #define ENCODE_REG_PC           (1ULL << kRegPC)
176 #define ENCODE_CCODE            (1ULL << kCCode)
177 #define ENCODE_FP_STATUS        (1ULL << kFPStatus)
178 
179 /* Abstract memory locations */
180 #define ENCODE_DALVIK_REG       (1ULL << kDalvikReg)
181 #define ENCODE_LITERAL          (1ULL << kLiteral)
182 #define ENCODE_HEAP_REF         (1ULL << kHeapRef)
183 #define ENCODE_MUST_NOT_ALIAS   (1ULL << kMustNotAlias)
184 
185 #define ENCODE_ALL              (~0ULL)
186 #define ENCODE_MEM              (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
187                                  ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
188 
189 #define DECODE_ALIAS_INFO_REG(X)        (X & 0xffff)
190 #define DECODE_ALIAS_INFO_WIDE(X)       ((X & 0x80000000) ? 1 : 0)
191 
192 typedef enum OpSize {
193     kWord,
194     kLong,
195     kSingle,
196     kDouble,
197     kUnsignedHalf,
198     kSignedHalf,
199     kUnsignedByte,
200     kSignedByte,
201 } OpSize;
202 
203 typedef enum OpKind {
204     kOpMov,
205     kOpMvn,
206     kOpCmp,
207     kOpLsl,
208     kOpLsr,
209     kOpAsr,
210     kOpRor,
211     kOpNot,
212     kOpAnd,
213     kOpOr,
214     kOpXor,
215     kOpNeg,
216     kOpAdd,
217     kOpAdc,
218     kOpSub,
219     kOpSbc,
220     kOpRsub,
221     kOpMul,
222     kOpDiv,
223     kOpRem,
224     kOpBic,
225     kOpCmn,
226     kOpTst,
227     kOpBkpt,
228     kOpBlx,
229     kOpPush,
230     kOpPop,
231     kOp2Char,
232     kOp2Short,
233     kOp2Byte,
234     kOpCondBr,
235     kOpUncondBr,
236 } OpKind;
237 
238 /*
239  * Annotate special-purpose core registers:
240  *
241  * rPC, rFP, and rSELF are for architecture-independent code to use.
242  */
243 typedef enum NativeRegisterPool {
244     r_ZERO = 0,
245     r_AT = 1,
246     r_V0 = 2,
247     r_V1 = 3,
248     r_A0 = 4,
249     r_A1 = 5,
250     r_A2 = 6,
251     r_A3 = 7,
252     r_T0 = 8,
253     r_T1 = 9,
254     r_T2 = 10,
255     r_T3 = 11,
256     r_T4 = 12,
257     r_T5 = 13,
258     r_T6 = 14,
259     r_T7 = 15,
260     r_S0 = 16,
261     r_S1 = 17,
262     r_S2 = 18,
263     r_S3 = 19,
264     r_S4 = 20,
265     r_S5 = 21,
266     r_S6 = 22,
267     r_S7 = 23,
268     r_T8 = 24,
269     r_T9 = 25,
270     r_K0 = 26,
271     r_K1 = 27,
272     r_GP = 28,
273     r_SP = 29,
274     r_FP = 30,
275     r_RA = 31,
276 
277     r_F0 = 0 + FP_REG_OFFSET,
278     r_F1,
279     r_F2,
280     r_F3,
281     r_F4,
282     r_F5,
283     r_F6,
284     r_F7,
285     r_F8,
286     r_F9,
287     r_F10,
288     r_F11,
289     r_F12,
290     r_F13,
291     r_F14,
292     r_F15,
293 #if 0 /* only 16 fp regs supported currently */
294     r_F16,
295     r_F17,
296     r_F18,
297     r_F19,
298     r_F20,
299     r_F21,
300     r_F22,
301     r_F23,
302     r_F24,
303     r_F25,
304     r_F26,
305     r_F27,
306     r_F28,
307     r_F29,
308     r_F30,
309     r_F31,
310 #endif
311     r_DF0 = r_F0 + FP_DOUBLE,
312     r_DF1 = r_F2 + FP_DOUBLE,
313     r_DF2 = r_F4 + FP_DOUBLE,
314     r_DF3 = r_F6 + FP_DOUBLE,
315     r_DF4 = r_F8 + FP_DOUBLE,
316     r_DF5 = r_F10 + FP_DOUBLE,
317     r_DF6 = r_F12 + FP_DOUBLE,
318     r_DF7 = r_F14 + FP_DOUBLE,
319 #if 0 /* only 16 fp regs supported currently */
320     r_DF8 = r_F16 + FP_DOUBLE,
321     r_DF9 = r_F18 + FP_DOUBLE,
322     r_DF10 = r_F20 + FP_DOUBLE,
323     r_DF11 = r_F22 + FP_DOUBLE,
324     r_DF12 = r_F24 + FP_DOUBLE,
325     r_DF13 = r_F26 + FP_DOUBLE,
326     r_DF14 = r_F28 + FP_DOUBLE,
327     r_DF15 = r_F30 + FP_DOUBLE,
328 #endif
329     r_HI = EXTRA_REG_OFFSET,
330     r_LO,
331     r_PC,
332 } NativeRegisterPool;
333 
334 
335 /* must match gp offset used mterp/mips files */
336 #define STACK_OFFSET_GP 84
337 
338 /* MIPSTODO: properly remap arm regs (dPC, dFP, dGLUE) and remove these mappings */
339 #define r4PC r_S0
340 #define rFP r_S1
341 #define rSELF r_S2
342 #define rINST r_S4
343 
344 /* Shift encodings */
345 typedef enum MipsShiftEncodings {
346     kMipsLsl = 0x0,
347     kMipsLsr = 0x1,
348     kMipsAsr = 0x2,
349     kMipsRor = 0x3
350 } MipsShiftEncodings;
351 
352 /* condition encodings */
353 typedef enum MipsConditionCode {
354     kMipsCondEq = 0x0,    /* 0000 */
355     kMipsCondNe = 0x1,    /* 0001 */
356     kMipsCondCs = 0x2,    /* 0010 */
357     kMipsCondCc = 0x3,    /* 0011 */
358     kMipsCondMi = 0x4,    /* 0100 */
359     kMipsCondPl = 0x5,    /* 0101 */
360     kMipsCondVs = 0x6,    /* 0110 */
361     kMipsCondVc = 0x7,    /* 0111 */
362     kMipsCondHi = 0x8,    /* 1000 */
363     kMipsCondLs = 0x9,    /* 1001 */
364     kMipsCondGe = 0xa,    /* 1010 */
365     kMipsCondLt = 0xb,    /* 1011 */
366     kMipsCondGt = 0xc,    /* 1100 */
367     kMipsCondLe = 0xd,    /* 1101 */
368     kMipsCondAl = 0xe,    /* 1110 */
369     kMipsCondNv = 0xf,    /* 1111 */
370 } MipsConditionCode;
371 
372 #define isPseudoOpCode(opCode) ((int)(opCode) < 0)
373 
374 /*
375  * The following enum defines the list of supported Thumb instructions by the
376  * assembler. Their corresponding snippet positions will be defined in
377  * Assemble.c.
378  */
379 typedef enum MipsOpCode {
380     kMipsChainingCellBottom = -18,
381     kMipsPseudoBarrier = -17,
382     kMipsPseudoExtended = -16,
383     kMipsPseudoSSARep = -15,
384     kMipsPseudoEntryBlock = -14,
385     kMipsPseudoExitBlock = -13,
386     kMipsPseudoTargetLabel = -12,
387     kMipsPseudoChainingCellBackwardBranch = -11,
388     kMipsPseudoChainingCellHot = -10,
389     kMipsPseudoChainingCellInvokePredicted = -9,
390     kMipsPseudoChainingCellInvokeSingleton = -8,
391     kMipsPseudoChainingCellNormal = -7,
392     kMipsPseudoDalvikByteCodeBoundary = -6,
393     kMipsPseudoPseudoAlign4 = -5,
394     kMipsPseudoPCReconstructionCell = -4,
395     kMipsPseudoPCReconstructionBlockLabel = -3,
396     kMipsPseudoEHBlockLabel = -2,
397     kMipsPseudoNormalBlockLabel = -1,
398 
399     kMipsFirst,
400     kMips32BitData = kMipsFirst, /* data [31..0] */
401     kMipsAddiu,   /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
402     kMipsAddu,    /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
403     kMipsAnd,     /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
404     kMipsAndi,    /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
405     kMipsB,       /* b o   [0001000000000000] o[15..0] */
406     kMipsBal,     /* bal o [0000010000010001] o[15..0] */
407     /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
408              adding an instruction in this range may require updates */
409     kMipsBeq,     /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
410     kMipsBeqz,    /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
411     kMipsBgez,    /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
412     kMipsBgtz,    /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
413     kMipsBlez,    /* blez s,o [000110] s[25..21] [00000] o[15..0] */
414     kMipsBltz,    /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
415     kMipsBnez,    /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
416     kMipsBne,     /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
417     kMipsDiv,     /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
418 #if __mips_isa_rev>=2
419     kMipsExt,     /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */
420 #endif
421     kMipsJal,     /* jal t [000011] t[25..0] */
422     kMipsJalr,    /* jalr d,s [000000] s[25..21] [00000] d[15..11]
423                                   hint[10..6] [001001] */
424     kMipsJr,      /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
425     kMipsLahi,    /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
426     kMipsLalo,    /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
427     kMipsLui,     /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
428     kMipsLb,      /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
429     kMipsLbu,     /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
430     kMipsLh,      /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
431     kMipsLhu,     /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
432     kMipsLw,      /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
433     kMipsMfhi,    /* mfhi d [0000000000000000] d[15..11] [00000010000] */
434     kMipsMflo,    /* mflo d [0000000000000000] d[15..11] [00000010010] */
435     kMipsMove,    /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
436     kMipsMovz,    /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
437     kMipsMul,     /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
438     kMipsNop,     /* nop [00000000000000000000000000000000] */
439     kMipsNor,     /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
440     kMipsOr,      /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
441     kMipsOri,     /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
442     kMipsPref,    /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
443     kMipsSb,      /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
444 #if __mips_isa_rev>=2
445     kMipsSeb,     /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
446     kMipsSeh,     /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
447 #endif
448     kMipsSh,      /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
449     kMipsSll,     /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
450     kMipsSllv,    /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
451     kMipsSlt,     /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
452     kMipsSlti,    /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
453     kMipsSltu,    /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
454     kMipsSra,     /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
455     kMipsSrav,    /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
456     kMipsSrl,     /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
457     kMipsSrlv,    /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
458     kMipsSubu,    /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
459     kMipsSw,      /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
460     kMipsXor,     /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
461     kMipsXori,    /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
462 #ifdef __mips_hard_float
463     kMipsFadds,   /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
464     kMipsFsubs,   /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
465     kMipsFmuls,   /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
466     kMipsFdivs,   /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
467     kMipsFaddd,   /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
468     kMipsFsubd,   /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
469     kMipsFmuld,   /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
470     kMipsFdivd,   /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
471     kMipsFcvtsd,  /* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
472     kMipsFcvtsw,  /* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
473     kMipsFcvtds,  /* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
474     kMipsFcvtdw,  /* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
475     kMipsFcvtws,  /* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
476     kMipsFcvtwd,  /* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
477     kMipsFmovs,   /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
478     kMipsFmovd,   /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
479     kMipsFlwc1,   /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
480     kMipsFldc1,   /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
481     kMipsFswc1,   /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
482     kMipsFsdc1,   /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
483     kMipsMfc1,    /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
484     kMipsMtc1,    /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
485 #endif
486     kMipsUndefined,  /* undefined [011001xxxxxxxxxxxxxxxx] */
487     kMipsLast
488 } MipsOpCode;
489 
490 /* Bit flags describing the behavior of each native opcode */
491 typedef enum MipsOpFeatureFlags {
492     kIsBranch = 0,
493     kRegDef0,
494     kRegDef1,
495     kRegDefSP,
496     kRegDefLR,
497     kRegDefList0,
498     kRegDefList1,
499     kRegUse0,
500     kRegUse1,
501     kRegUse2,
502     kRegUse3,
503     kRegUseSP,
504     kRegUsePC,
505     kRegUseList0,
506     kRegUseList1,
507     kNoOperand,
508     kIsUnaryOp,
509     kIsBinaryOp,
510     kIsTertiaryOp,
511     kIsQuadOp,
512     kIsIT,
513     kSetsCCodes,
514     kUsesCCodes,
515     kMemLoad,
516     kMemStore,
517 } MipsOpFeatureFlags;
518 
519 #define IS_LOAD         (1 << kMemLoad)
520 #define IS_STORE        (1 << kMemStore)
521 #define IS_BRANCH       (1 << kIsBranch)
522 #define REG_DEF0        (1 << kRegDef0)
523 #define REG_DEF1        (1 << kRegDef1)
524 #define REG_DEF_SP      (1 << kRegDefSP)
525 #define REG_DEF_LR      (1 << kRegDefLR)
526 #define REG_DEF_LIST0   (1 << kRegDefList0)
527 #define REG_DEF_LIST1   (1 << kRegDefList1)
528 #define REG_USE0        (1 << kRegUse0)
529 #define REG_USE1        (1 << kRegUse1)
530 #define REG_USE2        (1 << kRegUse2)
531 #define REG_USE3        (1 << kRegUse3)
532 #define REG_USE_SP      (1 << kRegUseSP)
533 #define REG_USE_PC      (1 << kRegUsePC)
534 #define REG_USE_LIST0   (1 << kRegUseList0)
535 #define REG_USE_LIST1   (1 << kRegUseList1)
536 #define NO_OPERAND      (1 << kNoOperand)
537 #define IS_UNARY_OP     (1 << kIsUnaryOp)
538 #define IS_BINARY_OP    (1 << kIsBinaryOp)
539 #define IS_TERTIARY_OP  (1 << kIsTertiaryOp)
540 #define IS_QUAD_OP      (1 << kIsQuadOp)
541 #define IS_IT           (1 << kIsIT)
542 #define SETS_CCODES     (1 << kSetsCCodes)
543 #define USES_CCODES     (1 << kUsesCCodes)
544 
545 /* Common combo register usage patterns */
546 #define REG_USE01       (REG_USE0 | REG_USE1)
547 #define REG_USE02       (REG_USE0 | REG_USE2)
548 #define REG_USE012      (REG_USE01 | REG_USE2)
549 #define REG_USE12       (REG_USE1 | REG_USE2)
550 #define REG_USE23       (REG_USE2 | REG_USE3)
551 #define REG_DEF01       (REG_DEF0 | REG_DEF1)
552 #define REG_DEF0_USE0   (REG_DEF0 | REG_USE0)
553 #define REG_DEF0_USE1   (REG_DEF0 | REG_USE1)
554 #define REG_DEF0_USE2   (REG_DEF0 | REG_USE2)
555 #define REG_DEF0_USE01  (REG_DEF0 | REG_USE01)
556 #define REG_DEF0_USE12  (REG_DEF0 | REG_USE12)
557 #define REG_DEF01_USE2  (REG_DEF0 | REG_DEF1 | REG_USE2)
558 
559 /* Instruction assembly fieldLoc kind */
560 typedef enum MipsEncodingKind {
561     kFmtUnused,
562     kFmtBitBlt,        /* Bit string using end/start */
563     kFmtDfp,           /* Double FP reg */
564     kFmtSfp,           /* Single FP reg */
565 } MipsEncodingKind;
566 
567 /* Struct used to define the snippet positions for each Thumb opcode */
568 typedef struct MipsEncodingMap {
569     u4 skeleton;
570     struct {
571         MipsEncodingKind kind;
572         int end;   /* end for kFmtBitBlt, 1-bit slice end for FP regs */
573         int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
574     } fieldLoc[4];
575     MipsOpCode opcode;
576     int flags;
577     const char *name;
578     const char* fmt;
579     int size;
580 } MipsEncodingMap;
581 
582 /* Keys for target-specific scheduling and other optimization hints */
583 typedef enum MipsTargetOptHints {
584     kMaxHoistDistance,
585 } MipsTargetOptHints;
586 
587 extern MipsEncodingMap EncodingMap[kMipsLast];
588 
589 /*
590  * Each instance of this struct holds a pseudo or real LIR instruction:
591  * - pseudo ones (eg labels and marks) and will be discarded by the assembler.
592  * - real ones will be assembled into Thumb instructions.
593  *
594  * Machine resources are encoded into a 64-bit vector, where the encodings are
595  * as following:
596  * - [ 0..15]: general purpose registers including PC, SP, and LR
597  * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0
598  *   starts at bit 16
599  * - [48]: IT block
600  * - [49]: integer condition code
601  * - [50]: floatint-point status word
602  */
603 typedef struct MipsLIR {
604     LIR generic;
605     MipsOpCode opcode;
606     int operands[4];            // [0..3] = [dest, src1, src2, extra]
607     struct {
608         bool isNop:1;           // LIR is optimized away
609         bool insertWrapper:1;   // insert branch to emulate memory accesses
610         unsigned int age:4;     // default is 0, set lazily by the optimizer
611         unsigned int size:3;    // bytes (2 for thumb, 2/4 for thumb2)
612         unsigned int unused:23;
613     } flags;
614     int aliasInfo;              // For Dalvik register access & litpool disambiguation
615     u8 useMask;                 // Resource mask for use
616     u8 defMask;                 // Resource mask for def
617 } MipsLIR;
618 
619 /* Init values when a predicted chain is initially assembled */
620 /* E7FE is branch to self */
621 #define PREDICTED_CHAIN_BX_PAIR_INIT     0xe7fe
622 #define PREDICTED_CHAIN_DELAY_SLOT_INIT  0
623 #define PREDICTED_CHAIN_CLAZZ_INIT       0
624 #define PREDICTED_CHAIN_METHOD_INIT      0
625 #define PREDICTED_CHAIN_COUNTER_INIT     0
626 
627 /* Utility macros to traverse the LIR/MipsLIR list */
628 #define NEXT_LIR(lir) ((MipsLIR *) lir->generic.next)
629 #define PREV_LIR(lir) ((MipsLIR *) lir->generic.prev)
630 
631 #define NEXT_LIR_LVALUE(lir) (lir)->generic.next
632 #define PREV_LIR_LVALUE(lir) (lir)->generic.prev
633 
634 #define CHAIN_CELL_OFFSET_TAG   0xcdabcdabL
635 
636 #define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
637 #define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
638 #define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
639 
640 #define CHAIN_CELL_NORMAL_SIZE    16
641 #define CHAIN_CELL_PREDICTED_SIZE 20
642 
643 
644 #endif  // DALVIK_VM_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
645