1a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/*
2a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Copyright (C) 2009 The Android Open Source Project
3a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *
4a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Licensed under the Apache License, Version 2.0 (the "License");
5a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * you may not use this file except in compliance with the License.
6a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * You may obtain a copy of the License at
7a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *
8a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *      http://www.apache.org/licenses/LICENSE-2.0
9a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *
10a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Unless required by applicable law or agreed to in writing, software
11a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * distributed under the License is distributed on an "AS IS" BASIS,
12a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * See the License for the specific language governing permissions and
14a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * limitations under the License.
15a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */
16a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
17a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/*
18a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * This file contains codegen for the Thumb ISA and is intended to be
19a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * includes by:
20a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *
21a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *        Codegen-$(TARGET_ARCH_VARIANT).c
22a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *
23a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */
24a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
25a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic int coreTemps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2,
26a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                          r_T3, r_T4, r_T5, r_T6, r_T7, r_T8, r_T9, r_S0, r_S4};
27a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
28a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic int fpTemps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
29a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                        r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
30a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
31a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
32a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void storePair(CompilationUnit *cUnit, int base, int lowReg,
33a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                      int highReg);
34a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg);
35a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadWordDisp(CompilationUnit *cUnit, int rBase, int displacement,
36a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                            int rDest);
37a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeWordDisp(CompilationUnit *cUnit, int rBase,
38a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                             int displacement, int rSrc);
39a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *genRegRegCheck(CompilationUnit *cUnit,
40a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                              MipsConditionCode cond,
41a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                              int reg1, int reg2, int dOffset,
42a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                              MipsLIR *pcrLabel);
43a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value);
44a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
45a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
46a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
47a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
48a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR* res = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true);
49a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res->operands[0] = rDest;
50a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res->operands[1] = rSrc;
51a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (rDest == rSrc) {
52a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res->flags.isNop = true;
53a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
54a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        /* must be both DOUBLE or both not DOUBLE */
55a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        assert(DOUBLEREG(rDest) == DOUBLEREG(rSrc));
56a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (DOUBLEREG(rDest)) {
57a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            res->opcode = kMipsFmovd;
58a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
59a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (SINGLEREG(rDest)) {
60a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                if (SINGLEREG(rSrc)) {
61a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    res->opcode = kMipsFmovs;
62a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                } else {
63a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    /* note the operands are swapped for the mtc1 instr */
64a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    res->opcode = kMipsMtc1;
65a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    res->operands[0] = rSrc;
66a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    res->operands[1] = rDest;
67a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                }
68a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            } else {
69a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                assert(SINGLEREG(rSrc));
70a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                res->opcode = kMipsMfc1;
71a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
72a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
73a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
74a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    setupResourceMasks(res);
75a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
76a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
77a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
78a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
79a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/*
80a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Load a immediate using a shortcut if possible; otherwise
81a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * grab from the per-translation literal pool.  If target is
82a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a high register, build constant into a low register and copy.
83a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *
84a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * No additional register clobbering operation performed. Use this version when
85a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 1) rDest is freshly returned from dvmCompilerAllocTemp or
86a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 2) The codegen is under fixed register usage
87a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */
88a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest,
89a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                     int value)
90a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
91a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
92a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
93a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
94a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int rDestSave = rDest;
95a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int isFpReg = FPREG(rDest);
96a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (isFpReg) {
97a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        assert(SINGLEREG(rDest));
98a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        rDest = dvmCompilerAllocTemp(cUnit);
99a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
100a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
101a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
102a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* See if the value can be constructed cheaply */
103a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (value == 0) {
104a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res = newLIR2(cUnit, kMipsMove, rDest, r_ZERO);
105a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else if ((value > 0) && (value <= 65535)) {
106a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res = newLIR3(cUnit, kMipsOri, rDest, r_ZERO, value);
107a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else if ((value < 0) && (value >= -32768)) {
108a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res = newLIR3(cUnit, kMipsAddiu, rDest, r_ZERO, value);
109a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
110a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res = newLIR2(cUnit, kMipsLui, rDest, value>>16);
111a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (value & 0xffff)
112a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham	    newLIR3(cUnit, kMipsOri, rDest, rDest, value);
113a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
114a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
115a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
116a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (isFpReg) {
117a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        newLIR2(cUnit, kMipsMtc1, rDest, rDestSave);
118a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        dvmCompilerFreeTemp(cUnit, rDest);
119a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
120a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
121a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
122a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
123a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
124a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
125a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/*
126a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Load an immediate value into a fixed or temp register.  Target
127a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * register is clobbered, and marked inUse.
128a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */
129a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value)
130a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
131a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (dvmCompilerIsTemp(cUnit, rDest)) {
132a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        dvmCompilerClobber(cUnit, rDest);
133a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        dvmCompilerMarkInUse(cUnit, rDest);
134a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
135a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return loadConstantNoClobber(cUnit, rDest, value);
136a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
137a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
138a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/*
139a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Load a class pointer value into a fixed or temp register.  Target
140a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * register is clobbered, and marked inUse.
141a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */
142a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadClassPointer(CompilationUnit *cUnit, int rDest, int value)
143a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
144a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
145a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (dvmCompilerIsTemp(cUnit, rDest)) {
146a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        dvmCompilerClobber(cUnit, rDest);
147a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        dvmCompilerMarkInUse(cUnit, rDest);
148a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
149a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res = newLIR2(cUnit, kMipsLui, rDest, value>>16);
150a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (value & 0xffff)
151a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        newLIR3(cUnit, kMipsOri, rDest, rDest, value);
152a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
153a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
154a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
155a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opNone(CompilationUnit *cUnit, OpKind op)
156a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
157a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
158a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
159a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch (op) {
160a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpUncondBr:
161a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsB;
162a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
163a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
164fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in opNone");
165a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
166a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
167a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res = newLIR0(cUnit, opcode);
168a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
169a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
170a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
171a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opCompareBranch(CompilationUnit *cUnit, MipsOpCode opc, int rs, int rt)
172a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
173a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
174a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (rt < 0) {
175a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham      assert(opc >= kMipsBeqz && opc <= kMipsBnez);
176a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham      res = newLIR1(cUnit, opc, rs);
177a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else  {
178a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham      assert(opc == kMipsBeq || opc == kMipsBne);
179a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham      res = newLIR2(cUnit, opc, rs, rt);
180a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
181a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
182a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
183a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
184a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask);
185a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
186a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc)
187a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
188a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
189a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch (op) {
190a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpBlx:
191a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsJalr;
192a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
193a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
194a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            assert(0);
195a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
196a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return newLIR2(cUnit, opcode, r_RA, rDestSrc);
197a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
198a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
199a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
200a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                           int rSrc1, int value);
201a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
202a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                        int value)
203a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
204a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
205a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bool neg = (value < 0);
206a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int absValue = (neg) ? -value : value;
207a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bool shortForm = (absValue & 0xff) == absValue;
208a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
209a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch (op) {
210a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpAdd:
211a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value);
212a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
213a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpSub:
214a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            return opRegRegImm(cUnit, op, rDestSrc1, rDestSrc1, value);
215a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
216a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
217fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in opRegImm");
218a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
219a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
220a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
221a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (shortForm)
222a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res = newLIR2(cUnit, opcode, rDestSrc1, absValue);
223a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    else {
224a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        int rScratch = dvmCompilerAllocTemp(cUnit);
225a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res = loadConstant(cUnit, rScratch, value);
226a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (op == kOpCmp)
227a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR2(cUnit, opcode, rDestSrc1, rScratch);
228a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        else
229a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR3(cUnit, opcode, rDestSrc1, rDestSrc1, rScratch);
230a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
231a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
232a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
233a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
234a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest,
235a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                           int rSrc1, int rSrc2)
236a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
237a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
238a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch (op) {
239a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpAdd:
240a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsAddu;
241a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
242a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpSub:
243a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSubu;
244a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
245a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpAnd:
246a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsAnd;
247a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
248a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpMul:
249a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsMul;
250a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
251a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpOr:
252a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsOr;
253a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
254a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpXor:
255a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsXor;
256a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
257a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpLsl:
258a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSllv;
259a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
260a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpLsr:
261a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSrlv;
262a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
263a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpAsr:
264a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSrav;
265a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
266a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
267fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in opRegRegReg");
268a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
269a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
270a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
271a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2);
272a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
273a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
274a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
275a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                           int rSrc1, int value)
276a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
277a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
278a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
279a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bool shortForm = true;
280a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
281a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch(op) {
282a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpAdd:
283a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (IS_SIMM16(value)) {
284a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsAddiu;
285a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
286a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            else {
287a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                shortForm = false;
288a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsAddu;
289a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
290a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
291a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpSub:
292a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (IS_SIMM16((-value))) {
293a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                value = -value;
294a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsAddiu;
295a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
296a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            else {
297a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                shortForm = false;
298a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsSubu;
299a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
300a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
301a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpLsl:
302a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                assert(value >= 0 && value <= 31);
303a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsSll;
304a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                break;
305a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpLsr:
306a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                assert(value >= 0 && value <= 31);
307a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsSrl;
308a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                break;
309a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpAsr:
310a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                assert(value >= 0 && value <= 31);
311a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsSra;
312a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                break;
313a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpAnd:
314a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (IS_UIMM16((value))) {
315a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsAndi;
316a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
317a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            else {
318a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                shortForm = false;
319a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsAnd;
320a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
321a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
322a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpOr:
323a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (IS_UIMM16((value))) {
324a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsOri;
325a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
326a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            else {
327a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                shortForm = false;
328a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsOr;
329a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
330a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
331a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpXor:
332a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (IS_UIMM16((value))) {
333a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsXori;
334a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
335a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            else {
336a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                shortForm = false;
337a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsXor;
338a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
339a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
340a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpMul:
341a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            shortForm = false;
342a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsMul;
343a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
344a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
345fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in opRegRegImm");
346a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
347a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
348a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
349a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
350a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (shortForm)
351a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res = newLIR3(cUnit, opcode, rDest, rSrc1, value);
352a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    else {
353a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (rDest != rSrc1) {
354a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            res = loadConstant(cUnit, rDest, value);
355a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR3(cUnit, opcode, rDest, rSrc1, rDest);
356a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
357a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            int rScratch = dvmCompilerAllocTemp(cUnit);
358a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            res = loadConstant(cUnit, rScratch, value);
359a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR3(cUnit, opcode, rDest, rSrc1, rScratch);
360a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
361a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
362a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
363a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
364a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
365a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
366a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                        int rSrc2)
367a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
368a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
369a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
370a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch (op) {
371a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpMov:
372a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsMove;
373a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
374a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpMvn:
375a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            return newLIR3(cUnit, kMipsNor, rDestSrc1, rSrc2, r_ZERO);
376a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpNeg:
377a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            return newLIR3(cUnit, kMipsSubu, rDestSrc1, r_ZERO, rSrc2);
378a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpAdd:
379a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpAnd:
380a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpMul:
381a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpOr:
382a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpSub:
383a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOpXor:
384a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            return opRegRegReg(cUnit, op, rDestSrc1, rDestSrc1, rSrc2);
385a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOp2Byte:
386a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if __mips_isa_rev>=2
387a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            res = newLIR2(cUnit, kMipsSeb, rDestSrc1, rSrc2);
388a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#else
389a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            res = opRegRegImm(cUnit, kOpLsl, rDestSrc1, rSrc2, 24);
390a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opRegRegImm(cUnit, kOpAsr, rDestSrc1, rDestSrc1, 24);
391a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
392a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            return res;
393a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOp2Short:
394a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if __mips_isa_rev>=2
395a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            res = newLIR2(cUnit, kMipsSeh, rDestSrc1, rSrc2);
396a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#else
397a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            res = opRegRegImm(cUnit, kOpLsl, rDestSrc1, rSrc2, 16);
398a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opRegRegImm(cUnit, kOpAsr, rDestSrc1, rDestSrc1, 16);
399a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
400a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            return res;
401a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kOp2Char:
402a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham             return newLIR3(cUnit, kMipsAndi, rDestSrc1, rSrc2, 0xFFFF);
403a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
404fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in opRegReg");
405a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
406a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
407a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
408a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return newLIR2(cUnit, opcode, rDestSrc1, rSrc2);
409a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
410a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
411a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo,
412a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                     int rDestHi, int valLo, int valHi)
413a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
414a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
415a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res = loadConstantNoClobber(cUnit, rDestLo, valLo);
416a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    loadConstantNoClobber(cUnit, rDestHi, valHi);
417a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
418a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
419a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
420a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* Load value from base + scaled index. */
421a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase,
422a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                               int rIndex, int rDest, int scale, OpSize size)
423a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
424a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *first = NULL;
425a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
426a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
427a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int tReg = dvmCompilerAllocTemp(cUnit);
428a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
429a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
430a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (FPREG(rDest)) {
431a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        assert(SINGLEREG(rDest));
432a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        assert((size == kWord) || (size == kSingle));
433a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        size = kSingle;
434a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
435a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (size == kSingle)
436a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            size = kWord;
437a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
438a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
439a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
440a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (!scale) {
441a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        first = newLIR3(cUnit, kMipsAddu, tReg , rBase, rIndex);
442a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
443a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        first = opRegRegImm(cUnit, kOpLsl, tReg, rIndex, scale);
444a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        newLIR3(cUnit, kMipsAddu, tReg , rBase, tReg);
445a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
446a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
447a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch (size) {
448a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
449a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSingle:
450a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsFlwc1;
451a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
452a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
453a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kWord:
454a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLw;
455a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
456a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kUnsignedHalf:
457a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLhu;
458a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
459a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSignedHalf:
460a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLh;
461a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
462a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kUnsignedByte:
463a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLbu;
464a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
465a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSignedByte:
466a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLb;
467a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
468a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
469fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in loadBaseIndexed");
470a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
471a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
472a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
473a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res = newLIR3(cUnit, opcode, rDest, 0, tReg);
474a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION)
475a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (cUnit->heapMemOp)
476a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res->flags.insertWrapper = true;
477a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
478a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    dvmCompilerFreeTemp(cUnit, tReg);
479a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return (first) ? first : res;
480a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
481a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
482a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* store value base base + scaled index. */
483a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase,
484a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                int rIndex, int rSrc, int scale, OpSize size)
485a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
486a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *first = NULL;
487a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
488a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
489a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int rNewIndex = rIndex;
490a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int tReg = dvmCompilerAllocTemp(cUnit);
491a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
492a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
493a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (FPREG(rSrc)) {
494a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        assert(SINGLEREG(rSrc));
495a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        assert((size == kWord) || (size == kSingle));
496a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        size = kSingle;
497a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
498a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (size == kSingle)
499a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            size = kWord;
500a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
501a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
502a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
503a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (!scale) {
504a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        first = newLIR3(cUnit, kMipsAddu, tReg , rBase, rIndex);
505a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
506a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        first = opRegRegImm(cUnit, kOpLsl, tReg, rIndex, scale);
507a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        newLIR3(cUnit, kMipsAddu, tReg , rBase, tReg);
508a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
509a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
510a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch (size) {
511a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
512a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSingle:
513a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsFswc1;
514a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
515a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
516a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kWord:
517a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSw;
518a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
519a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kUnsignedHalf:
520a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSignedHalf:
521a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSh;
522a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
523a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kUnsignedByte:
524a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSignedByte:
525a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSb;
526a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
527a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
528fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in storeBaseIndexed");
529a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
530a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
531a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res = newLIR3(cUnit, opcode, rSrc, 0, tReg);
532a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION)
533a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (cUnit->heapMemOp)
534a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res->flags.insertWrapper = true;
535a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
536a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    dvmCompilerFreeTemp(cUnit, rNewIndex);
537a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return first;
538a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
539a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
540a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask)
541a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
542a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int i;
543a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int loadCnt = 0;
544a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res = NULL ;
545a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    genBarrier(cUnit);
546a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
547a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    for (i = 0; i < 8; i++, rMask >>= 1) {
548a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (rMask & 0x1) { /* map r0 to MIPS r_A0 */
549a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR3(cUnit, kMipsLw, i+r_A0, loadCnt*4, rBase);
550a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            loadCnt++;
551a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
552a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
553a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
554a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (loadCnt) {/* increment after */
555a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        newLIR3(cUnit, kMipsAddiu, rBase, rBase, loadCnt*4);
556a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
557a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
558a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION)
559a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (cUnit->heapMemOp)
560a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res->flags.insertWrapper = true;
561a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
562a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    genBarrier(cUnit);
563a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res; /* NULL always returned which should be ok since no callers use it */
564a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
565a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
566a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask)
567a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
568a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int i;
569a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    int storeCnt = 0;
570a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res = NULL ;
571a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    genBarrier(cUnit);
572a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
573a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    for (i = 0; i < 8; i++, rMask >>= 1) {
574a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (rMask & 0x1) { /* map r0 to MIPS r_A0 */
575a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR3(cUnit, kMipsSw, i+r_A0, storeCnt*4, rBase);
576a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            storeCnt++;
577a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
578a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
579a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
580a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (storeCnt) { /* increment after */
581a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        newLIR3(cUnit, kMipsAddiu, rBase, rBase, storeCnt*4);
582a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
583a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
584a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION)
585a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (cUnit->heapMemOp)
586a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res->flags.insertWrapper = true;
587a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
588a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    genBarrier(cUnit);
589a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res; /* NULL always returned which should be ok since no callers use it */
590a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
591a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
592a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
593a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                int displacement, int rDest, int rDestHi,
594a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                OpSize size, int sReg)
595a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/*
596a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Load value from base + displacement.  Optionally perform null check
597a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * on base (which must have an associated sReg and MIR).  If not
598a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * performing null check, incoming MIR can be null. IMPORTANT: this
599a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * code must not allocate any new temps.  If a new register is needed
600a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * and base and dest are the same, spill some other register to
601a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * rlp and then restore.
602a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */
603a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
604a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
605a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *load = NULL;
606a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *load2 = NULL;
607a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
608a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bool shortForm = IS_SIMM16(displacement);
609a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bool pair = false;
610a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
611a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch (size) {
612a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kLong:
613a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kDouble:
614a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            pair = true;
615a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLw;
616a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
617a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (FPREG(rDest)) {
618a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsFlwc1;
619a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                if (DOUBLEREG(rDest)) {
620a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    rDest = rDest - FP_DOUBLE;
621a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                } else {
622a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    assert(FPREG(rDestHi));
623a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    assert(rDest == (rDestHi - 1));
624a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                }
625a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                rDestHi = rDest + 1;
626a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
627a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
628a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            shortForm = IS_SIMM16_2WORD(displacement);
629a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            assert((displacement & 0x3) == 0);
630a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
631a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kWord:
632a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSingle:
633a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLw;
634a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
635a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (FPREG(rDest)) {
636a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsFlwc1;
637a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                assert(SINGLEREG(rDest));
638a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
639a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
640a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            assert((displacement & 0x3) == 0);
641a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
642a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kUnsignedHalf:
643a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLhu;
644a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            assert((displacement & 0x1) == 0);
645a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
646a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSignedHalf:
647a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLh;
648a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            assert((displacement & 0x1) == 0);
649a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
650a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kUnsignedByte:
651a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLbu;
652a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
653a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSignedByte:
654a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsLb;
655a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
656a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
657fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in loadBaseIndexedBody");
658a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
659a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
660a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
661a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (shortForm) {
662a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (!pair) {
663a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            load = res = newLIR3(cUnit, opcode, rDest, displacement, rBase);
664a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
665a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            load = res = newLIR3(cUnit, opcode, rDest, displacement + LOWORD_OFFSET, rBase);
666a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            load2 = newLIR3(cUnit, opcode, rDestHi, displacement + HIWORD_OFFSET, rBase);
667a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
668a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
669a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (pair) {
670a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            int rTmp = dvmCompilerAllocFreeTemp(cUnit);
671a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            res = opRegRegImm(cUnit, kOpAdd, rTmp, rBase, displacement);
672a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            load = newLIR3(cUnit, opcode, rDest, LOWORD_OFFSET, rTmp);
673a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            load2 = newLIR3(cUnit, opcode, rDestHi, HIWORD_OFFSET, rTmp);
674a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerFreeTemp(cUnit, rTmp);
675a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
676a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            int rTmp = (rBase == rDest) ? dvmCompilerAllocFreeTemp(cUnit)
677a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                        : rDest;
678a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            res = loadConstant(cUnit, rTmp, displacement);
679a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            load = newLIR3(cUnit, opcode, rDest, rBase, rTmp);
680a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (rTmp != rDest)
681a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                dvmCompilerFreeTemp(cUnit, rTmp);
682a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
683a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
684a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
685a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (rBase == rFP) {
686a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (load != NULL)
687a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            annotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
688a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                    true /* isLoad */);
689a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (load2 != NULL)
690a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            annotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2,
691a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                    true /* isLoad */);
692a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
693a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION)
694a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (load != NULL && cUnit->heapMemOp)
695a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        load->flags.insertWrapper = true;
696a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (load2 != NULL && cUnit->heapMemOp)
697a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        load2->flags.insertWrapper = true;
698a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
699a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return load;
700a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
701a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
702a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase,
703a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                            int displacement, int rDest, OpSize size,
704a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                            int sReg)
705a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
706a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1,
707a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                            size, sReg);
708a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
709a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
710a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase,
711a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                int displacement, int rDestLo, int rDestHi,
712a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                int sReg)
713a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
714a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi,
715a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                            kLong, sReg);
716a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
717a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
718a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
719a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                 int displacement, int rSrc, int rSrcHi,
720a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                 OpSize size)
721a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
722a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res;
723a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *store = NULL;
724a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *store2 = NULL;
725a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode = kMipsNop;
726a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bool shortForm = IS_SIMM16(displacement);
727a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bool pair = false;
728a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
729a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    switch (size) {
730a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kLong:
731a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kDouble:
732a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            pair = true;
733a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSw;
734a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
735a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (FPREG(rSrc)) {
736a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsFswc1;
737a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                if (DOUBLEREG(rSrc)) {
738a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    rSrc = rSrc - FP_DOUBLE;
739a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                } else {
740a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    assert(FPREG(rSrcHi));
741a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                    assert(rSrc == (rSrcHi - 1));
742a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                }
743a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                rSrcHi = rSrc + 1;
744a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
745a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
746a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            shortForm = IS_SIMM16_2WORD(displacement);
747a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            assert((displacement & 0x3) == 0);
748a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
749a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kWord:
750a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSingle:
751a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSw;
752a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
753a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (FPREG(rSrc)) {
754a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                opcode = kMipsFswc1;
755a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                assert(SINGLEREG(rSrc));
756a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
757a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
758a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            assert((displacement & 0x3) == 0);
759a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
760a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kUnsignedHalf:
761a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSignedHalf:
762a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSh;
763a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            assert((displacement & 0x1) == 0);
764a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
765a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kUnsignedByte:
766a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        case kSignedByte:
767a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opcode = kMipsSb;
768a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            break;
769a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        default:
770fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in storeBaseIndexedBody");
771a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
772a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
773a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
774a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (shortForm) {
775a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (!pair) {
776a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            store = res = newLIR3(cUnit, opcode, rSrc, displacement, rBase);
777a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
778a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            store = res = newLIR3(cUnit, opcode, rSrc, displacement + LOWORD_OFFSET, rBase);
779a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            store2 = newLIR3(cUnit, opcode, rSrcHi, displacement + HIWORD_OFFSET, rBase);
780a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
781a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
782a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        int rScratch = dvmCompilerAllocTemp(cUnit);
783a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res = opRegRegImm(cUnit, kOpAdd, rScratch, rBase, displacement);
784a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (!pair) {
785a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            store =  newLIR3(cUnit, opcode, rSrc, 0, rScratch);
786a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
787a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            store =  newLIR3(cUnit, opcode, rSrc, LOWORD_OFFSET, rScratch);
788a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            store2 = newLIR3(cUnit, opcode, rSrcHi, HIWORD_OFFSET, rScratch);
789a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
790a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        dvmCompilerFreeTemp(cUnit, rScratch);
791a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
792a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
793a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (rBase == rFP) {
794a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (store != NULL)
795a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            annotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
796a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                    false /* isLoad */);
797a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (store2 != NULL)
798a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            annotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2,
799a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                    false /* isLoad */);
800a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
801a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
802a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION)
803a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (store != NULL && cUnit->heapMemOp)
804a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        store->flags.insertWrapper = true;
805a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (store2 != NULL && cUnit->heapMemOp)
806a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        store2->flags.insertWrapper = true;
807a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
808a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
809a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
810a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
811a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase,
812a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                             int displacement, int rSrc, OpSize size)
813a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
814a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size);
815a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
816a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
817a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase,
818a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                 int displacement, int rSrcLo, int rSrcHi)
819a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
820a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
821a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
822a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
823a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
824a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
825a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    storeWordDisp(cUnit, base, LOWORD_OFFSET, lowReg);
826a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    storeWordDisp(cUnit, base, HIWORD_OFFSET, highReg);
827a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
828a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
829a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
830a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
831a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    loadWordDisp(cUnit, base, LOWORD_OFFSET , lowReg);
832a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    loadWordDisp(cUnit, base, HIWORD_OFFSET , highReg);
833a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
834a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
835a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
836a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
837a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR* res;
838a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsOpCode opcode;
839a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
840a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (FPREG(rDest) || FPREG(rSrc))
841a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        return fpRegCopy(cUnit, rDest, rSrc);
842a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
843a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true);
844a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    opcode = kMipsMove;
845a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    assert(LOWREG(rDest) && LOWREG(rSrc));
846a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res->operands[0] = rDest;
847a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res->operands[1] = rSrc;
848a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    res->opcode = opcode;
849a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    setupResourceMasks(res);
850a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (rDest == rSrc) {
851a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        res->flags.isNop = true;
852a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
853a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
854a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
855a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
856a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
857a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
858a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc);
859a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    dvmCompilerAppendLIR(cUnit, (LIR*)res);
860a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    return res;
861a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
862a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
863a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
864a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                           int srcLo, int srcHi)
865a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
866a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float
867a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bool destFP = FPREG(destLo) && FPREG(destHi);
868a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    bool srcFP = FPREG(srcLo) && FPREG(srcHi);
869a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    assert(FPREG(srcLo) == FPREG(srcHi));
870a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    assert(FPREG(destLo) == FPREG(destHi));
871a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (destFP) {
872a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (srcFP) {
873a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
874a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
875a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham           /* note the operands are swapped for the mtc1 instr */
876a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR2(cUnit, kMipsMtc1, srcLo, destLo);
877a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR2(cUnit, kMipsMtc1, srcHi, destHi);
878a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
879a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
880a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (srcFP) {
881a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR2(cUnit, kMipsMfc1, destLo, srcLo);
882a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR2(cUnit, kMipsMfc1, destHi, srcHi);
883a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
884a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            // Handle overlap
885a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            if (srcHi == destLo) {
886a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                genRegCopy(cUnit, destHi, srcHi);
887a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                genRegCopy(cUnit, destLo, srcLo);
888a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            } else {
889a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                genRegCopy(cUnit, destLo, srcLo);
890a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                genRegCopy(cUnit, destHi, srcHi);
891a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            }
892a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
893a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
894a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#else
895a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    // Handle overlap
896a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (srcHi == destLo) {
897a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        genRegCopy(cUnit, destHi, srcHi);
898a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        genRegCopy(cUnit, destLo, srcLo);
899a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
900a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        genRegCopy(cUnit, destLo, srcLo);
901a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        genRegCopy(cUnit, destHi, srcHi);
902a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
903a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
904a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
905a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
906a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic inline MipsLIR *genRegImmCheck(CompilationUnit *cUnit,
907a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                     MipsConditionCode cond, int reg,
908a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                     int checkValue, int dOffset,
909a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                     MipsLIR *pcrLabel)
910a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{
911a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *branch = NULL;
912a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
913a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (checkValue == 0) {
914a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        MipsOpCode opc = kMipsNop;
915a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (cond == kMipsCondEq) {
916a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opc = kMipsBeqz;
917a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham	} else if (cond == kMipsCondNe) {
918a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opc = kMipsBnez;
919a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else if (cond == kMipsCondLt || cond == kMipsCondMi) {
920a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opc = kMipsBltz;
921a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else if (cond == kMipsCondLe) {
922a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opc = kMipsBlez;
923a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else if (cond == kMipsCondGt) {
924a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opc = kMipsBgtz;
925a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else if (cond == kMipsCondGe) {
926a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            opc = kMipsBgez;
927a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
928fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in genRegImmCheck");
929a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
930a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
931a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        branch = opCompareBranch(cUnit, opc, reg, -1);
932a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else if (IS_SIMM16(checkValue)) {
933a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (cond == kMipsCondLt) {
934a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            int tReg = dvmCompilerAllocTemp(cUnit);
935a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            newLIR3(cUnit, kMipsSlti, tReg, reg, checkValue);
936a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            branch = opCompareBranch(cUnit, kMipsBne, tReg, r_ZERO);
937a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerFreeTemp(cUnit, tReg);
938a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
939fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Jit: bad case in genRegImmCheck");
940a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmCompilerAbort(cUnit);
941a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
942a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
943fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham        ALOGE("Jit: bad case in genRegImmCheck");
944a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        dvmCompilerAbort(cUnit);
945a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
946a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
947a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    if (cUnit->jitMode == kJitMethod) {
948a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        BasicBlock *bb = cUnit->curBlock;
949a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        if (bb->taken) {
950a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            MipsLIR  *exceptionLabel = (MipsLIR *) cUnit->blockLabelList;
951a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            exceptionLabel += bb->taken->id;
952a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            branch->generic.target = (LIR *) exceptionLabel;
953a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            return exceptionLabel;
954a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        } else {
955fc3b0c4ba9e0ecabb0f6df1ceb6a3eb69da07c7bRaghu Gandham            ALOGE("Catch blocks not handled yet");
956a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            dvmAbort();
957a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham            return NULL;
958a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        }
959a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    } else {
960a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham        return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
961a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    }
962a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
963a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
964a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if defined(WITH_SELF_VERIFICATION)
965a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void genSelfVerificationPreBranch(CompilationUnit *cUnit,
966a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                         MipsLIR *origLIR) {
967a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham// DOUGLAS - this still needs to be implemented for MIPS.
968a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if 0
969a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /*
970a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * We need two separate pushes, since we want r5 to be pushed first.
971a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * Store multiple will push LR first.
972a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     */
973a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *pushFP = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true);
974a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    pushFP->opcode = kThumbPush;
975a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    pushFP->operands[0] = 1 << r5FP;
976a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    setupResourceMasks(pushFP);
977a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    dvmCompilerInsertLIRBefore((LIR *) origLIR, (LIR *) pushFP);
978a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
979a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *pushLR = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true);
980a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    pushLR->opcode = kThumbPush;
981a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* Thumb push can handle LR, but is encoded differently at bit 8 */
982a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    pushLR->operands[0] = 1 << 8;
983a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    setupResourceMasks(pushLR);
984a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    dvmCompilerInsertLIRBefore((LIR *) origLIR, (LIR *) pushLR);
985a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
986a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
987a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
988a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void genSelfVerificationPostBranch(CompilationUnit *cUnit,
989a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham                                         MipsLIR *origLIR) {
990a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham// DOUGLAS - this still needs to be implemented for MIPS.
991a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if 0
992a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /*
993a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * Since Thumb cannot pop memory content into LR, we have to pop LR
994a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * to a temp first (r5 in this case). Then we move r5 to LR, then pop the
995a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     * original r5 from stack.
996a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham     */
997a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* Pop memory content(LR) into r5 first */
998a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *popForLR = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true);
999a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    popForLR->opcode = kThumbPop;
1000a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    popForLR->operands[0] = 1 << r5FP;
1001a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    setupResourceMasks(popForLR);
1002a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    dvmCompilerInsertLIRAfter((LIR *) origLIR, (LIR *) popForLR);
1003a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
1004a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *copy = genRegCopyNoInsert(cUnit, r14lr, r5FP);
1005a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    dvmCompilerInsertLIRAfter((LIR *) popForLR, (LIR *) copy);
1006a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham
1007a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    /* Now restore the original r5 */
1008a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    MipsLIR *popFP = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true);
1009a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    popFP->opcode = kThumbPop;
1010a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    popFP->operands[0] = 1 << r5FP;
1011a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    setupResourceMasks(popFP);
1012a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham    dvmCompilerInsertLIRAfter((LIR *) copy, (LIR *) popFP);
1013a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
1014a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham}
1015a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif
1016