blob: acbac7f6d930c5ec0834427b31561cce3dba50f6 [file] [log] [blame]
buzbeee3acd072012-02-25 17:03:10 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17namespace art {
18
buzbee5de34942012-03-01 14:51:57 -080019bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
20 RegLocation rlSrc1, RegLocation rlSrc2)
buzbeee3acd072012-02-25 17:03:10 -080021{
22#ifdef __mips_hard_float
23 int op = kMipsNop;
24 RegLocation rlResult;
25
26 /*
27 * Don't attempt to optimize register usage since these opcodes call out to
28 * the handlers.
29 */
30 switch (mir->dalvikInsn.opcode) {
31 case OP_ADD_FLOAT_2ADDR:
32 case OP_ADD_FLOAT:
33 op = kMipsFadds;
34 break;
35 case OP_SUB_FLOAT_2ADDR:
36 case OP_SUB_FLOAT:
37 op = kMipsFsubs;
38 break;
39 case OP_DIV_FLOAT_2ADDR:
40 case OP_DIV_FLOAT:
41 op = kMipsFdivs;
42 break;
43 case OP_MUL_FLOAT_2ADDR:
44 case OP_MUL_FLOAT:
45 op = kMipsFmuls;
46 break;
47 case OP_REM_FLOAT_2ADDR:
48 case OP_REM_FLOAT:
49 case OP_NEG_FLOAT: {
50 return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
51 }
52 default:
53 return true;
54 }
55 rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
56 rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
57 rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
buzbee5de34942012-03-01 14:51:57 -080058 newLIR3(cUnit, (MipsOpCode)op, rlResult.lowReg, rlSrc1.lowReg,
59 rlSrc2.lowReg);
buzbeee3acd072012-02-25 17:03:10 -080060 storeValue(cUnit, rlDest, rlResult);
61
62 return false;
63#else
buzbee5de34942012-03-01 14:51:57 -080064 UNIMPLEMENTED(FATAL) << "Need Mips soft float implementation";
buzbeee3acd072012-02-25 17:03:10 -080065 return false;
buzbeee3acd072012-02-25 17:03:10 -080066#endif
67}
68
69static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir,
70 RegLocation rlDest, RegLocation rlSrc1,
71 RegLocation rlSrc2)
72{
73#ifdef __mips_hard_float
74 int op = kMipsNop;
75 RegLocation rlResult;
76
77 switch (mir->dalvikInsn.opcode) {
78 case OP_ADD_DOUBLE_2ADDR:
79 case OP_ADD_DOUBLE:
80 op = kMipsFaddd;
81 break;
82 case OP_SUB_DOUBLE_2ADDR:
83 case OP_SUB_DOUBLE:
84 op = kMipsFsubd;
85 break;
86 case OP_DIV_DOUBLE_2ADDR:
87 case OP_DIV_DOUBLE:
88 op = kMipsFdivd;
89 break;
90 case OP_MUL_DOUBLE_2ADDR:
91 case OP_MUL_DOUBLE:
92 op = kMipsFmuld;
93 break;
94 case OP_REM_DOUBLE_2ADDR:
95 case OP_REM_DOUBLE:
96 case OP_NEG_DOUBLE: {
97 return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
98 }
99 default:
100 return true;
101 }
102 rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
103 DCHECK(rlSrc1.wide);
104 rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
105 DCHECK(rlSrc2.wide);
106 rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
107 DCHECK(rlDest.wide);
108 DCHECK(rlResult.wide);
109 newLIR3(cUnit, (MipsOpCode)op, S2D(rlResult.lowReg, rlResult.highReg),
110 S2D(rlSrc1.lowReg, rlSrc1.highReg),
111 S2D(rlSrc2.lowReg, rlSrc2.highReg));
112 storeValueWide(cUnit, rlDest, rlResult);
113 return false;
114#else
buzbee5de34942012-03-01 14:51:57 -0800115 UNIMPLEMENTED(FATAL) << "Need Mips soft float implementation";
buzbeee3acd072012-02-25 17:03:10 -0800116 return false;
buzbeee3acd072012-02-25 17:03:10 -0800117#endif
118}
119
120static bool genConversion(CompilationUnit *cUnit, MIR *mir)
121{
buzbee5de34942012-03-01 14:51:57 -0800122#ifdef __mips_hard_float
buzbeee3acd072012-02-25 17:03:10 -0800123 Opcode opcode = mir->dalvikInsn.opcode;
124 bool longSrc = false;
125 bool longDest = false;
126 RegLocation rlSrc;
127 RegLocation rlDest;
buzbeee3acd072012-02-25 17:03:10 -0800128 int op = kMipsNop;
129 int srcReg;
130 RegLocation rlResult;
buzbeee3acd072012-02-25 17:03:10 -0800131 switch (opcode) {
132 case OP_INT_TO_FLOAT:
133 longSrc = false;
134 longDest = false;
135 op = kMipsFcvtsw;
136 break;
137 case OP_DOUBLE_TO_FLOAT:
138 longSrc = true;
139 longDest = false;
140 op = kMipsFcvtsd;
141 break;
142 case OP_FLOAT_TO_DOUBLE:
143 longSrc = false;
144 longDest = true;
145 op = kMipsFcvtds;
146 break;
147 case OP_INT_TO_DOUBLE:
148 longSrc = false;
149 longDest = true;
150 op = kMipsFcvtdw;
151 break;
152 case OP_FLOAT_TO_INT:
153 case OP_DOUBLE_TO_INT:
154 case OP_LONG_TO_DOUBLE:
155 case OP_FLOAT_TO_LONG:
156 case OP_LONG_TO_FLOAT:
157 case OP_DOUBLE_TO_LONG:
158 return genConversionPortable(cUnit, mir);
159 default:
160 return true;
161 }
162 if (longSrc) {
163 rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
164 rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
165 srcReg = S2D(rlSrc.lowReg, rlSrc.highReg);
166 } else {
167 rlSrc = oatGetSrc(cUnit, mir, 0);
168 rlSrc = loadValue(cUnit, rlSrc, kFPReg);
169 srcReg = rlSrc.lowReg;
170 }
171 if (longDest) {
172 rlDest = oatGetDestWide(cUnit, mir, 0, 1);
173 rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
174 newLIR2(cUnit, (MipsOpCode)op, S2D(rlResult.lowReg, rlResult.highReg), srcReg);
175 storeValueWide(cUnit, rlDest, rlResult);
176 } else {
177 rlDest = oatGetDest(cUnit, mir, 0);
178 rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
179 newLIR2(cUnit, (MipsOpCode)op, rlResult.lowReg, srcReg);
180 storeValue(cUnit, rlDest, rlResult);
181 }
182 return false;
183#else
buzbee5de34942012-03-01 14:51:57 -0800184 UNIMPLEMENTED(FATAL) << "Need Mips soft float implementation";
buzbeee3acd072012-02-25 17:03:10 -0800185 return false;
buzbeee3acd072012-02-25 17:03:10 -0800186#endif
187}
188
189static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
190 RegLocation rlSrc1, RegLocation rlSrc2)
191{
192 UNIMPLEMENTED(FATAL) << "Need Mips implementation";
193 return false;
194#if 0
195 TemplateOpcode templateOpcode;
196 RegLocation rlResult = oatGetReturn(cUnit);
197 bool wide = true;
198
199 switch(mir->dalvikInsn.opcode) {
200 case OP_CMPL_FLOAT:
201 templateOpcode = TEMPLATE_CMPL_FLOAT_VFP;
202 wide = false;
203 break;
204 case OP_CMPG_FLOAT:
205 templateOpcode = TEMPLATE_CMPG_FLOAT_VFP;
206 wide = false;
207 break;
208 case OP_CMPL_DOUBLE:
209 templateOpcode = TEMPLATE_CMPL_DOUBLE_VFP;
210 break;
211 case OP_CMPG_DOUBLE:
212 templateOpcode = TEMPLATE_CMPG_DOUBLE_VFP;
213 break;
214 default:
215 return true;
216 }
217 loadValueAddress(cUnit, rlSrc1, r_A0);
218 oatClobber(cUnit, r_A0);
219 loadValueAddress(cUnit, rlSrc2, r_A1);
220 UNIMP(FATAL) << "Need callout to handler";
221#if 0
222 genDispatchToHandler(cUnit, templateOpcode);
223#endif
224 storeValue(cUnit, rlDest, rlResult);
225 return false;
226#endif
227}
228
229} // namespace art