buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2011 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 | |
Elliott Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 17 | namespace art { |
| 18 | |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 19 | bool genArithOpFloat(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, |
buzbee | 31a4a6f | 2012-02-28 15:36:15 -0800 | [diff] [blame] | 20 | RegLocation rlSrc1, RegLocation rlSrc2) |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 21 | { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 22 | int op = kThumbBkpt; |
| 23 | RegLocation rlResult; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 24 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 25 | /* |
| 26 | * Don't attempt to optimize register usage since these opcodes call out to |
| 27 | * the handlers. |
| 28 | */ |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 29 | switch (opcode) { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 30 | case Instruction::ADD_FLOAT_2ADDR: |
| 31 | case Instruction::ADD_FLOAT: |
| 32 | op = kThumb2Vadds; |
| 33 | break; |
| 34 | case Instruction::SUB_FLOAT_2ADDR: |
| 35 | case Instruction::SUB_FLOAT: |
| 36 | op = kThumb2Vsubs; |
| 37 | break; |
| 38 | case Instruction::DIV_FLOAT_2ADDR: |
| 39 | case Instruction::DIV_FLOAT: |
| 40 | op = kThumb2Vdivs; |
| 41 | break; |
| 42 | case Instruction::MUL_FLOAT_2ADDR: |
| 43 | case Instruction::MUL_FLOAT: |
| 44 | op = kThumb2Vmuls; |
| 45 | break; |
| 46 | case Instruction::REM_FLOAT_2ADDR: |
| 47 | case Instruction::REM_FLOAT: |
| 48 | case Instruction::NEG_FLOAT: { |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 49 | return genArithOpFloatPortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2); |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 50 | } |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 51 | default: |
| 52 | return true; |
| 53 | } |
| 54 | rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); |
| 55 | rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); |
| 56 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
buzbee | cbd6d44 | 2012-11-17 14:11:25 -0800 | [diff] [blame] | 57 | newLIR3(cUnit, op, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 58 | storeValue(cUnit, rlDest, rlResult); |
| 59 | return false; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 60 | } |
| 61 | |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 62 | bool genArithOpDouble(CompilationUnit* cUnit, Instruction::Code opcode, |
| 63 | RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 64 | { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 65 | int op = kThumbBkpt; |
| 66 | RegLocation rlResult; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 67 | |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 68 | switch (opcode) { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 69 | case Instruction::ADD_DOUBLE_2ADDR: |
| 70 | case Instruction::ADD_DOUBLE: |
| 71 | op = kThumb2Vaddd; |
| 72 | break; |
| 73 | case Instruction::SUB_DOUBLE_2ADDR: |
| 74 | case Instruction::SUB_DOUBLE: |
| 75 | op = kThumb2Vsubd; |
| 76 | break; |
| 77 | case Instruction::DIV_DOUBLE_2ADDR: |
| 78 | case Instruction::DIV_DOUBLE: |
| 79 | op = kThumb2Vdivd; |
| 80 | break; |
| 81 | case Instruction::MUL_DOUBLE_2ADDR: |
| 82 | case Instruction::MUL_DOUBLE: |
| 83 | op = kThumb2Vmuld; |
| 84 | break; |
| 85 | case Instruction::REM_DOUBLE_2ADDR: |
| 86 | case Instruction::REM_DOUBLE: |
| 87 | case Instruction::NEG_DOUBLE: { |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 88 | return genArithOpDoublePortable(cUnit, opcode, rlDest, rlSrc1, rlSrc2); |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 89 | } |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 90 | default: |
| 91 | return true; |
| 92 | } |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 93 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 94 | rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); |
| 95 | DCHECK(rlSrc1.wide); |
| 96 | rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); |
| 97 | DCHECK(rlSrc2.wide); |
| 98 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
| 99 | DCHECK(rlDest.wide); |
| 100 | DCHECK(rlResult.wide); |
buzbee | cbd6d44 | 2012-11-17 14:11:25 -0800 | [diff] [blame] | 101 | newLIR3(cUnit, op, s2d(rlResult.lowReg, rlResult.highReg), s2d(rlSrc1.lowReg, rlSrc1.highReg), |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 102 | s2d(rlSrc2.lowReg, rlSrc2.highReg)); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 103 | storeValueWide(cUnit, rlDest, rlResult); |
| 104 | return false; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 105 | } |
| 106 | |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 107 | bool genConversion(CompilationUnit* cUnit, Instruction::Code opcode, |
| 108 | RegLocation rlDest, RegLocation rlSrc) |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 109 | { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 110 | int op = kThumbBkpt; |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 111 | int srcReg; |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 112 | RegLocation rlResult; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 113 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 114 | switch (opcode) { |
| 115 | case Instruction::INT_TO_FLOAT: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 116 | op = kThumb2VcvtIF; |
| 117 | break; |
| 118 | case Instruction::FLOAT_TO_INT: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 119 | op = kThumb2VcvtFI; |
| 120 | break; |
| 121 | case Instruction::DOUBLE_TO_FLOAT: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 122 | op = kThumb2VcvtDF; |
| 123 | break; |
| 124 | case Instruction::FLOAT_TO_DOUBLE: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 125 | op = kThumb2VcvtFd; |
| 126 | break; |
| 127 | case Instruction::INT_TO_DOUBLE: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 128 | op = kThumb2VcvtID; |
| 129 | break; |
| 130 | case Instruction::DOUBLE_TO_INT: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 131 | op = kThumb2VcvtDI; |
| 132 | break; |
| 133 | case Instruction::LONG_TO_DOUBLE: |
| 134 | case Instruction::FLOAT_TO_LONG: |
| 135 | case Instruction::LONG_TO_FLOAT: |
| 136 | case Instruction::DOUBLE_TO_LONG: |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 137 | return genConversionPortable(cUnit, opcode, rlDest, rlSrc); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 138 | default: |
| 139 | return true; |
| 140 | } |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 141 | if (rlSrc.wide) { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 142 | rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 143 | srcReg = s2d(rlSrc.lowReg, rlSrc.highReg); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 144 | } else { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 145 | rlSrc = loadValue(cUnit, rlSrc, kFPReg); |
| 146 | srcReg = rlSrc.lowReg; |
| 147 | } |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 148 | if (rlDest.wide) { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 149 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
buzbee | cbd6d44 | 2012-11-17 14:11:25 -0800 | [diff] [blame] | 150 | newLIR2(cUnit, op, s2d(rlResult.lowReg, rlResult.highReg), srcReg); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 151 | storeValueWide(cUnit, rlDest, rlResult); |
| 152 | } else { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 153 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
buzbee | cbd6d44 | 2012-11-17 14:11:25 -0800 | [diff] [blame] | 154 | newLIR2(cUnit, op, rlResult.lowReg, srcReg); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 155 | storeValue(cUnit, rlDest, rlResult); |
| 156 | } |
| 157 | return false; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 158 | } |
| 159 | |
buzbee | 84fd693 | 2012-03-29 16:44:16 -0700 | [diff] [blame] | 160 | void genFusedFPCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, |
| 161 | bool gtBias, bool isDouble) |
| 162 | { |
buzbee | a1da8a5 | 2012-07-09 14:00:21 -0700 | [diff] [blame] | 163 | LIR* labelList = cUnit->blockLabelList; |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 164 | LIR* target = &labelList[bb->taken->id]; |
| 165 | RegLocation rlSrc1; |
| 166 | RegLocation rlSrc2; |
| 167 | if (isDouble) { |
buzbee | 15bf980 | 2012-06-12 17:49:27 -0700 | [diff] [blame] | 168 | rlSrc1 = oatGetSrcWide(cUnit, mir, 0); |
| 169 | rlSrc2 = oatGetSrcWide(cUnit, mir, 2); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 170 | rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); |
| 171 | rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 172 | newLIR2(cUnit, kThumb2Vcmpd, s2d(rlSrc1.lowReg, rlSrc2.highReg), |
| 173 | s2d(rlSrc2.lowReg, rlSrc2.highReg)); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 174 | } else { |
| 175 | rlSrc1 = oatGetSrc(cUnit, mir, 0); |
| 176 | rlSrc2 = oatGetSrc(cUnit, mir, 1); |
| 177 | rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); |
| 178 | rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); |
| 179 | newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg); |
| 180 | } |
| 181 | newLIR0(cUnit, kThumb2Fmstat); |
| 182 | ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]); |
| 183 | switch(ccode) { |
| 184 | case kCondEq: |
| 185 | case kCondNe: |
| 186 | break; |
| 187 | case kCondLt: |
| 188 | if (gtBias) { |
| 189 | ccode = kCondMi; |
| 190 | } |
| 191 | break; |
| 192 | case kCondLe: |
| 193 | if (gtBias) { |
| 194 | ccode = kCondLs; |
| 195 | } |
| 196 | break; |
| 197 | case kCondGt: |
| 198 | if (gtBias) { |
| 199 | ccode = kCondHi; |
| 200 | } |
| 201 | break; |
| 202 | case kCondGe: |
| 203 | if (gtBias) { |
| 204 | ccode = kCondCs; |
| 205 | } |
| 206 | break; |
| 207 | default: |
buzbee | cbd6d44 | 2012-11-17 14:11:25 -0800 | [diff] [blame] | 208 | LOG(FATAL) << "Unexpected ccode: " << ccode; |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 209 | } |
| 210 | opCondBranch(cUnit, ccode, target); |
buzbee | 84fd693 | 2012-03-29 16:44:16 -0700 | [diff] [blame] | 211 | } |
| 212 | |
| 213 | |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 214 | bool genCmpFP(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 215 | RegLocation rlSrc1, RegLocation rlSrc2) |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 216 | { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 217 | bool isDouble; |
| 218 | int defaultResult; |
| 219 | RegLocation rlResult; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 220 | |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 221 | switch (opcode) { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 222 | case Instruction::CMPL_FLOAT: |
| 223 | isDouble = false; |
| 224 | defaultResult = -1; |
| 225 | break; |
| 226 | case Instruction::CMPG_FLOAT: |
| 227 | isDouble = false; |
| 228 | defaultResult = 1; |
| 229 | break; |
| 230 | case Instruction::CMPL_DOUBLE: |
| 231 | isDouble = true; |
| 232 | defaultResult = -1; |
| 233 | break; |
| 234 | case Instruction::CMPG_DOUBLE: |
| 235 | isDouble = true; |
| 236 | defaultResult = 1; |
| 237 | break; |
| 238 | default: |
| 239 | return true; |
| 240 | } |
| 241 | if (isDouble) { |
| 242 | rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); |
| 243 | rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); |
| 244 | oatClobberSReg(cUnit, rlDest.sRegLow); |
| 245 | rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); |
| 246 | loadConstant(cUnit, rlResult.lowReg, defaultResult); |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 247 | newLIR2(cUnit, kThumb2Vcmpd, s2d(rlSrc1.lowReg, rlSrc2.highReg), |
| 248 | s2d(rlSrc2.lowReg, rlSrc2.highReg)); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 249 | } else { |
| 250 | rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); |
| 251 | rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); |
| 252 | oatClobberSReg(cUnit, rlDest.sRegLow); |
| 253 | rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); |
| 254 | loadConstant(cUnit, rlResult.lowReg, defaultResult); |
| 255 | newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg); |
| 256 | } |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 257 | DCHECK(!ARM_FPREG(rlResult.lowReg)); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 258 | newLIR0(cUnit, kThumb2Fmstat); |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 259 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 260 | opIT(cUnit, (defaultResult == -1) ? kArmCondGt : kArmCondMi, ""); |
| 261 | newLIR2(cUnit, kThumb2MovImmShift, rlResult.lowReg, |
| 262 | modifiedImmediate(-defaultResult)); // Must not alter ccodes |
| 263 | genBarrier(cUnit); |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 264 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 265 | opIT(cUnit, kArmCondEq, ""); |
| 266 | loadConstant(cUnit, rlResult.lowReg, 0); |
| 267 | genBarrier(cUnit); |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 268 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 269 | storeValue(cUnit, rlDest, rlResult); |
| 270 | return false; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 271 | } |
Elliott Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 272 | |
buzbee | efc6369 | 2012-11-14 16:31:52 -0800 | [diff] [blame] | 273 | void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc) |
| 274 | { |
| 275 | RegLocation rlResult; |
| 276 | rlSrc = loadValue(cUnit, rlSrc, kFPReg); |
| 277 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
| 278 | newLIR2(cUnit, kThumb2Vnegs, rlResult.lowReg, rlSrc.lowReg); |
| 279 | storeValue(cUnit, rlDest, rlResult); |
| 280 | } |
| 281 | |
| 282 | void genNegDouble(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc) |
| 283 | { |
| 284 | RegLocation rlResult; |
| 285 | rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); |
| 286 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
| 287 | newLIR2(cUnit, kThumb2Vnegd, s2d(rlResult.lowReg, rlResult.highReg), |
| 288 | s2d(rlSrc.lowReg, rlSrc.highReg)); |
| 289 | storeValueWide(cUnit, rlDest, rlResult); |
| 290 | } |
| 291 | |
| 292 | bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) { |
| 293 | DCHECK_EQ(cUnit->instructionSet, kThumb2); |
| 294 | LIR *branch; |
| 295 | RegLocation rlSrc = info->args[0]; |
| 296 | RegLocation rlDest = inlineTargetWide(cUnit, info); // double place for result |
| 297 | rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); |
| 298 | RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
| 299 | newLIR2(cUnit, kThumb2Vsqrtd, s2d(rlResult.lowReg, rlResult.highReg), |
| 300 | s2d(rlSrc.lowReg, rlSrc.highReg)); |
| 301 | newLIR2(cUnit, kThumb2Vcmpd, s2d(rlResult.lowReg, rlResult.highReg), |
| 302 | s2d(rlResult.lowReg, rlResult.highReg)); |
| 303 | newLIR0(cUnit, kThumb2Fmstat); |
| 304 | branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq); |
| 305 | oatClobberCalleeSave(cUnit); |
| 306 | oatLockCallTemps(cUnit); // Using fixed registers |
| 307 | int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pSqrt)); |
| 308 | newLIR3(cUnit, kThumb2Fmrrd, r0, r1, s2d(rlSrc.lowReg, rlSrc.highReg)); |
| 309 | newLIR1(cUnit, kThumbBlxR, rTgt); |
| 310 | newLIR3(cUnit, kThumb2Fmdrr, s2d(rlResult.lowReg, rlResult.highReg), r0, r1); |
| 311 | branch->target = newLIR0(cUnit, kPseudoTargetLabel); |
| 312 | storeValueWide(cUnit, rlDest, rlResult); |
| 313 | return true; |
| 314 | } |
| 315 | |
| 316 | |
Elliott Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 317 | } // namespace art |