blob: 5e59b565865fb75acbddb6761fcda5e7bd522486 [file] [log] [blame]
buzbeee88dfbf2012-03-05 11:19:57 -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
19bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
20 RegLocation rlSrc1, RegLocation rlSrc2)
21{
22 UNIMPLEMENTED(WARNING) << "genArithOpFloat";
23 return false;
24#if 0
buzbeea7678db2012-03-05 15:35:46 -080025 int op = kX86Nop;
buzbeee88dfbf2012-03-05 11:19:57 -080026 RegLocation rlResult;
27
28 /*
29 * Don't attempt to optimize register usage since these opcodes call out to
30 * the handlers.
31 */
32 switch (mir->dalvikInsn.opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -080033 case Instruction::ADD_FLOAT_2ADDR:
34 case Instruction::ADD_FLOAT:
buzbeea7678db2012-03-05 15:35:46 -080035 op = kX86Fadds;
buzbeee88dfbf2012-03-05 11:19:57 -080036 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -080037 case Instruction::SUB_FLOAT_2ADDR:
38 case Instruction::SUB_FLOAT:
buzbeea7678db2012-03-05 15:35:46 -080039 op = kX86Fsubs;
buzbeee88dfbf2012-03-05 11:19:57 -080040 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -080041 case Instruction::DIV_FLOAT_2ADDR:
42 case Instruction::DIV_FLOAT:
buzbeea7678db2012-03-05 15:35:46 -080043 op = kX86Fdivs;
buzbeee88dfbf2012-03-05 11:19:57 -080044 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -080045 case Instruction::MUL_FLOAT_2ADDR:
46 case Instruction::MUL_FLOAT:
buzbeea7678db2012-03-05 15:35:46 -080047 op = kX86Fmuls;
buzbeee88dfbf2012-03-05 11:19:57 -080048 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -080049 case Instruction::REM_FLOAT_2ADDR:
50 case Instruction::REM_FLOAT:
51 case Instruction::NEG_FLOAT: {
buzbeee88dfbf2012-03-05 11:19:57 -080052 return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
53 }
54 default:
55 return true;
56 }
57 rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
58 rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
59 rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
buzbeea7678db2012-03-05 15:35:46 -080060 newLIR3(cUnit, (X86OpCode)op, rlResult.lowReg, rlSrc1.lowReg,
buzbeee88dfbf2012-03-05 11:19:57 -080061 rlSrc2.lowReg);
62 storeValue(cUnit, rlDest, rlResult);
63
64 return false;
buzbeee88dfbf2012-03-05 11:19:57 -080065#endif
66}
67
68static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir,
69 RegLocation rlDest, RegLocation rlSrc1,
70 RegLocation rlSrc2)
71{
72 UNIMPLEMENTED(WARNING) << "genArithOpDouble";
73 return false;
74#if 0
buzbeea7678db2012-03-05 15:35:46 -080075 int op = kX86Nop;
buzbeee88dfbf2012-03-05 11:19:57 -080076 RegLocation rlResult;
77
78 switch (mir->dalvikInsn.opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -080079 case Instruction::ADD_DOUBLE_2ADDR:
80 case Instruction::ADD_DOUBLE:
buzbeea7678db2012-03-05 15:35:46 -080081 op = kX86Faddd;
buzbeee88dfbf2012-03-05 11:19:57 -080082 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -080083 case Instruction::SUB_DOUBLE_2ADDR:
84 case Instruction::SUB_DOUBLE:
buzbeea7678db2012-03-05 15:35:46 -080085 op = kX86Fsubd;
buzbeee88dfbf2012-03-05 11:19:57 -080086 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -080087 case Instruction::DIV_DOUBLE_2ADDR:
88 case Instruction::DIV_DOUBLE:
buzbeea7678db2012-03-05 15:35:46 -080089 op = kX86Fdivd;
buzbeee88dfbf2012-03-05 11:19:57 -080090 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -080091 case Instruction::MUL_DOUBLE_2ADDR:
92 case Instruction::MUL_DOUBLE:
buzbeea7678db2012-03-05 15:35:46 -080093 op = kX86Fmuld;
buzbeee88dfbf2012-03-05 11:19:57 -080094 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -080095 case Instruction::REM_DOUBLE_2ADDR:
96 case Instruction::REM_DOUBLE:
97 case Instruction::NEG_DOUBLE: {
buzbeee88dfbf2012-03-05 11:19:57 -080098 return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
99 }
100 default:
101 return true;
102 }
103 rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg);
104 DCHECK(rlSrc1.wide);
105 rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg);
106 DCHECK(rlSrc2.wide);
107 rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
108 DCHECK(rlDest.wide);
109 DCHECK(rlResult.wide);
buzbeea7678db2012-03-05 15:35:46 -0800110 newLIR3(cUnit, (X86OpCode)op, S2D(rlResult.lowReg, rlResult.highReg),
buzbeee88dfbf2012-03-05 11:19:57 -0800111 S2D(rlSrc1.lowReg, rlSrc1.highReg),
112 S2D(rlSrc2.lowReg, rlSrc2.highReg));
113 storeValueWide(cUnit, rlDest, rlResult);
114 return false;
buzbeee88dfbf2012-03-05 11:19:57 -0800115#endif
116}
117
118static bool genConversion(CompilationUnit *cUnit, MIR *mir)
119{
120 UNIMPLEMENTED(WARNING) << "genConversion";
121 return false;
122#if 0
Elliott Hughesadb8c672012-03-06 16:49:32 -0800123 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeee88dfbf2012-03-05 11:19:57 -0800124 bool longSrc = false;
125 bool longDest = false;
126 RegLocation rlSrc;
127 RegLocation rlDest;
buzbeea7678db2012-03-05 15:35:46 -0800128 int op = kX86Nop;
buzbeee88dfbf2012-03-05 11:19:57 -0800129 int srcReg;
130 RegLocation rlResult;
131 switch (opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800132 case Instruction::INT_TO_FLOAT:
buzbeee88dfbf2012-03-05 11:19:57 -0800133 longSrc = false;
134 longDest = false;
buzbeea7678db2012-03-05 15:35:46 -0800135 op = kX86Fcvtsw;
buzbeee88dfbf2012-03-05 11:19:57 -0800136 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800137 case Instruction::DOUBLE_TO_FLOAT:
buzbeee88dfbf2012-03-05 11:19:57 -0800138 longSrc = true;
139 longDest = false;
buzbeea7678db2012-03-05 15:35:46 -0800140 op = kX86Fcvtsd;
buzbeee88dfbf2012-03-05 11:19:57 -0800141 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800142 case Instruction::FLOAT_TO_DOUBLE:
buzbeee88dfbf2012-03-05 11:19:57 -0800143 longSrc = false;
144 longDest = true;
buzbeea7678db2012-03-05 15:35:46 -0800145 op = kX86Fcvtds;
buzbeee88dfbf2012-03-05 11:19:57 -0800146 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800147 case Instruction::INT_TO_DOUBLE:
buzbeee88dfbf2012-03-05 11:19:57 -0800148 longSrc = false;
149 longDest = true;
buzbeea7678db2012-03-05 15:35:46 -0800150 op = kX86Fcvtdw;
buzbeee88dfbf2012-03-05 11:19:57 -0800151 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800152 case Instruction::FLOAT_TO_INT:
153 case Instruction::DOUBLE_TO_INT:
154 case Instruction::LONG_TO_DOUBLE:
155 case Instruction::FLOAT_TO_LONG:
156 case Instruction::LONG_TO_FLOAT:
157 case Instruction::DOUBLE_TO_LONG:
buzbeee88dfbf2012-03-05 11:19:57 -0800158 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);
buzbeea7678db2012-03-05 15:35:46 -0800174 newLIR2(cUnit, (X86OpCode)op, S2D(rlResult.lowReg, rlResult.highReg), srcReg);
buzbeee88dfbf2012-03-05 11:19:57 -0800175 storeValueWide(cUnit, rlDest, rlResult);
176 } else {
177 rlDest = oatGetDest(cUnit, mir, 0);
178 rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
buzbeea7678db2012-03-05 15:35:46 -0800179 newLIR2(cUnit, (X86OpCode)op, rlResult.lowReg, srcReg);
buzbeee88dfbf2012-03-05 11:19:57 -0800180 storeValue(cUnit, rlDest, rlResult);
181 }
182 return false;
buzbeee88dfbf2012-03-05 11:19:57 -0800183#endif
184}
185
186static bool genCmpFP(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
187 RegLocation rlSrc1, RegLocation rlSrc2)
188{
189 UNIMPLEMENTED(WARNING) << "genCmpFP";
190#if 0
191 bool wide = true;
192 int offset;
193
194 switch(mir->dalvikInsn.opcode) {
Elliott Hughesadb8c672012-03-06 16:49:32 -0800195 case Instruction::CMPL_FLOAT:
buzbeee88dfbf2012-03-05 11:19:57 -0800196 offset = OFFSETOF_MEMBER(Thread, pCmplFloat);
197 wide = false;
198 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800199 case Instruction::CMPG_FLOAT:
buzbeee88dfbf2012-03-05 11:19:57 -0800200 offset = OFFSETOF_MEMBER(Thread, pCmpgFloat);
201 wide = false;
202 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800203 case Instruction::CMPL_DOUBLE:
buzbeee88dfbf2012-03-05 11:19:57 -0800204 offset = OFFSETOF_MEMBER(Thread, pCmplDouble);
205 break;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800206 case Instruction::CMPG_DOUBLE:
buzbeee88dfbf2012-03-05 11:19:57 -0800207 offset = OFFSETOF_MEMBER(Thread, pCmpgDouble);
208 break;
209 default:
210 return true;
211 }
212 oatFlushAllRegs(cUnit);
213 oatLockCallTemps(cUnit);
214 if (wide) {
215 loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1);
216 loadValueDirectWideFixed(cUnit, rlSrc2, rARG2, rARG3);
217 } else {
218 loadValueDirectFixed(cUnit, rlSrc1, rARG0);
219 loadValueDirectFixed(cUnit, rlSrc2, rARG1);
220 }
221 int rTgt = loadHelper(cUnit, offset);
222 opReg(cUnit, kOpBlx, rTgt);
223 RegLocation rlResult = oatGetReturn(cUnit);
224 storeValue(cUnit, rlDest, rlResult);
225#endif
226 return false;
227}
228
229} // namespace art