MipsLIR.h revision a8b91c52fd8a90b784835dfe1f8898035266c4dd
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 */
131typedef 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
143typedef 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
153typedef 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
192typedef enum OpSize {
193    kWord,
194    kLong,
195    kSingle,
196    kDouble,
197    kUnsignedHalf,
198    kSignedHalf,
199    kUnsignedByte,
200    kSignedByte,
201} OpSize;
202
203typedef 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 */
243typedef 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 */
345typedef enum MipsShiftEncodings {
346    kMipsLsl = 0x0,
347    kMipsLsr = 0x1,
348    kMipsAsr = 0x2,
349    kMipsRor = 0x3
350} MipsShiftEncodings;
351
352/* condition encodings */
353typedef 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 */
379typedef 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 */
491typedef 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 */
560typedef 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 */
568typedef 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 */
583typedef enum MipsTargetOptHints {
584    kMaxHoistDistance,
585} MipsTargetOptHints;
586
587extern 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 */
603typedef 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