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); |
| 57 | newLIR3(cUnit, (ArmOpcode)op, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg); |
| 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 | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 101 | newLIR3(cUnit, (ArmOpcode)op, s2d(rlResult.lowReg, rlResult.highReg), |
| 102 | s2d(rlSrc1.lowReg, rlSrc1.highReg), |
| 103 | s2d(rlSrc2.lowReg, rlSrc2.highReg)); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 104 | storeValueWide(cUnit, rlDest, rlResult); |
| 105 | return false; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 106 | } |
| 107 | |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 108 | bool genConversion(CompilationUnit* cUnit, Instruction::Code opcode, |
| 109 | RegLocation rlDest, RegLocation rlSrc) |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 110 | { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 111 | int op = kThumbBkpt; |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 112 | int srcReg; |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 113 | RegLocation rlResult; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 114 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 115 | switch (opcode) { |
| 116 | case Instruction::INT_TO_FLOAT: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 117 | op = kThumb2VcvtIF; |
| 118 | break; |
| 119 | case Instruction::FLOAT_TO_INT: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 120 | op = kThumb2VcvtFI; |
| 121 | break; |
| 122 | case Instruction::DOUBLE_TO_FLOAT: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 123 | op = kThumb2VcvtDF; |
| 124 | break; |
| 125 | case Instruction::FLOAT_TO_DOUBLE: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 126 | op = kThumb2VcvtFd; |
| 127 | break; |
| 128 | case Instruction::INT_TO_DOUBLE: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 129 | op = kThumb2VcvtID; |
| 130 | break; |
| 131 | case Instruction::DOUBLE_TO_INT: |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 132 | op = kThumb2VcvtDI; |
| 133 | break; |
| 134 | case Instruction::LONG_TO_DOUBLE: |
| 135 | case Instruction::FLOAT_TO_LONG: |
| 136 | case Instruction::LONG_TO_FLOAT: |
| 137 | case Instruction::DOUBLE_TO_LONG: |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 138 | return genConversionPortable(cUnit, opcode, rlDest, rlSrc); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 139 | default: |
| 140 | return true; |
| 141 | } |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 142 | if (rlSrc.wide) { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 143 | rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 144 | srcReg = s2d(rlSrc.lowReg, rlSrc.highReg); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 145 | } else { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 146 | rlSrc = loadValue(cUnit, rlSrc, kFPReg); |
| 147 | srcReg = rlSrc.lowReg; |
| 148 | } |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 149 | if (rlDest.wide) { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 150 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 151 | newLIR2(cUnit, (ArmOpcode)op, s2d(rlResult.lowReg, rlResult.highReg), |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 152 | srcReg); |
| 153 | storeValueWide(cUnit, rlDest, rlResult); |
| 154 | } else { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 155 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
| 156 | newLIR2(cUnit, (ArmOpcode)op, rlResult.lowReg, srcReg); |
| 157 | storeValue(cUnit, rlDest, rlResult); |
| 158 | } |
| 159 | return false; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 160 | } |
| 161 | |
buzbee | 84fd693 | 2012-03-29 16:44:16 -0700 | [diff] [blame] | 162 | void genFusedFPCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, |
| 163 | bool gtBias, bool isDouble) |
| 164 | { |
buzbee | a1da8a5 | 2012-07-09 14:00:21 -0700 | [diff] [blame] | 165 | LIR* labelList = cUnit->blockLabelList; |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 166 | LIR* target = &labelList[bb->taken->id]; |
| 167 | RegLocation rlSrc1; |
| 168 | RegLocation rlSrc2; |
| 169 | if (isDouble) { |
buzbee | 15bf980 | 2012-06-12 17:49:27 -0700 | [diff] [blame] | 170 | rlSrc1 = oatGetSrcWide(cUnit, mir, 0); |
| 171 | rlSrc2 = oatGetSrcWide(cUnit, mir, 2); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 172 | rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); |
| 173 | rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 174 | newLIR2(cUnit, kThumb2Vcmpd, s2d(rlSrc1.lowReg, rlSrc2.highReg), |
| 175 | s2d(rlSrc2.lowReg, rlSrc2.highReg)); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 176 | } else { |
| 177 | rlSrc1 = oatGetSrc(cUnit, mir, 0); |
| 178 | rlSrc2 = oatGetSrc(cUnit, mir, 1); |
| 179 | rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); |
| 180 | rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); |
| 181 | newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg); |
| 182 | } |
| 183 | newLIR0(cUnit, kThumb2Fmstat); |
| 184 | ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]); |
| 185 | switch(ccode) { |
| 186 | case kCondEq: |
| 187 | case kCondNe: |
| 188 | break; |
| 189 | case kCondLt: |
| 190 | if (gtBias) { |
| 191 | ccode = kCondMi; |
| 192 | } |
| 193 | break; |
| 194 | case kCondLe: |
| 195 | if (gtBias) { |
| 196 | ccode = kCondLs; |
| 197 | } |
| 198 | break; |
| 199 | case kCondGt: |
| 200 | if (gtBias) { |
| 201 | ccode = kCondHi; |
| 202 | } |
| 203 | break; |
| 204 | case kCondGe: |
| 205 | if (gtBias) { |
| 206 | ccode = kCondCs; |
| 207 | } |
| 208 | break; |
| 209 | default: |
| 210 | LOG(FATAL) << "Unexpected ccode: " << (int)ccode; |
| 211 | } |
| 212 | opCondBranch(cUnit, ccode, target); |
buzbee | 84fd693 | 2012-03-29 16:44:16 -0700 | [diff] [blame] | 213 | } |
| 214 | |
| 215 | |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 216 | bool genCmpFP(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 217 | RegLocation rlSrc1, RegLocation rlSrc2) |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 218 | { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 219 | bool isDouble; |
| 220 | int defaultResult; |
| 221 | RegLocation rlResult; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 222 | |
buzbee | 408ad16 | 2012-06-06 16:45:18 -0700 | [diff] [blame] | 223 | switch (opcode) { |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 224 | case Instruction::CMPL_FLOAT: |
| 225 | isDouble = false; |
| 226 | defaultResult = -1; |
| 227 | break; |
| 228 | case Instruction::CMPG_FLOAT: |
| 229 | isDouble = false; |
| 230 | defaultResult = 1; |
| 231 | break; |
| 232 | case Instruction::CMPL_DOUBLE: |
| 233 | isDouble = true; |
| 234 | defaultResult = -1; |
| 235 | break; |
| 236 | case Instruction::CMPG_DOUBLE: |
| 237 | isDouble = true; |
| 238 | defaultResult = 1; |
| 239 | break; |
| 240 | default: |
| 241 | return true; |
| 242 | } |
| 243 | if (isDouble) { |
| 244 | rlSrc1 = loadValueWide(cUnit, rlSrc1, kFPReg); |
| 245 | rlSrc2 = loadValueWide(cUnit, rlSrc2, kFPReg); |
| 246 | oatClobberSReg(cUnit, rlDest.sRegLow); |
| 247 | rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); |
| 248 | loadConstant(cUnit, rlResult.lowReg, defaultResult); |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 249 | newLIR2(cUnit, kThumb2Vcmpd, s2d(rlSrc1.lowReg, rlSrc2.highReg), |
| 250 | s2d(rlSrc2.lowReg, rlSrc2.highReg)); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 251 | } else { |
| 252 | rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg); |
| 253 | rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg); |
| 254 | oatClobberSReg(cUnit, rlDest.sRegLow); |
| 255 | rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true); |
| 256 | loadConstant(cUnit, rlResult.lowReg, defaultResult); |
| 257 | newLIR2(cUnit, kThumb2Vcmps, rlSrc1.lowReg, rlSrc2.lowReg); |
| 258 | } |
buzbee | f0504cd | 2012-11-13 16:31:10 -0800 | [diff] [blame] | 259 | DCHECK(!ARM_FPREG(rlResult.lowReg)); |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 260 | newLIR0(cUnit, kThumb2Fmstat); |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 261 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 262 | opIT(cUnit, (defaultResult == -1) ? kArmCondGt : kArmCondMi, ""); |
| 263 | newLIR2(cUnit, kThumb2MovImmShift, rlResult.lowReg, |
| 264 | modifiedImmediate(-defaultResult)); // Must not alter ccodes |
| 265 | genBarrier(cUnit); |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 266 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 267 | opIT(cUnit, kArmCondEq, ""); |
| 268 | loadConstant(cUnit, rlResult.lowReg, 0); |
| 269 | genBarrier(cUnit); |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 270 | |
Bill Buzbee | a114add | 2012-05-03 15:00:40 -0700 | [diff] [blame] | 271 | storeValue(cUnit, rlDest, rlResult); |
| 272 | return false; |
buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 273 | } |
Elliott Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 274 | |
buzbee | efc6369 | 2012-11-14 16:31:52 -0800 | [diff] [blame^] | 275 | void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc) |
| 276 | { |
| 277 | RegLocation rlResult; |
| 278 | rlSrc = loadValue(cUnit, rlSrc, kFPReg); |
| 279 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
| 280 | newLIR2(cUnit, kThumb2Vnegs, rlResult.lowReg, rlSrc.lowReg); |
| 281 | storeValue(cUnit, rlDest, rlResult); |
| 282 | } |
| 283 | |
| 284 | void genNegDouble(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc) |
| 285 | { |
| 286 | RegLocation rlResult; |
| 287 | rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); |
| 288 | rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
| 289 | newLIR2(cUnit, kThumb2Vnegd, s2d(rlResult.lowReg, rlResult.highReg), |
| 290 | s2d(rlSrc.lowReg, rlSrc.highReg)); |
| 291 | storeValueWide(cUnit, rlDest, rlResult); |
| 292 | } |
| 293 | |
| 294 | bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) { |
| 295 | DCHECK_EQ(cUnit->instructionSet, kThumb2); |
| 296 | LIR *branch; |
| 297 | RegLocation rlSrc = info->args[0]; |
| 298 | RegLocation rlDest = inlineTargetWide(cUnit, info); // double place for result |
| 299 | rlSrc = loadValueWide(cUnit, rlSrc, kFPReg); |
| 300 | RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true); |
| 301 | newLIR2(cUnit, kThumb2Vsqrtd, s2d(rlResult.lowReg, rlResult.highReg), |
| 302 | s2d(rlSrc.lowReg, rlSrc.highReg)); |
| 303 | newLIR2(cUnit, kThumb2Vcmpd, s2d(rlResult.lowReg, rlResult.highReg), |
| 304 | s2d(rlResult.lowReg, rlResult.highReg)); |
| 305 | newLIR0(cUnit, kThumb2Fmstat); |
| 306 | branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq); |
| 307 | oatClobberCalleeSave(cUnit); |
| 308 | oatLockCallTemps(cUnit); // Using fixed registers |
| 309 | int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pSqrt)); |
| 310 | newLIR3(cUnit, kThumb2Fmrrd, r0, r1, s2d(rlSrc.lowReg, rlSrc.highReg)); |
| 311 | newLIR1(cUnit, kThumbBlxR, rTgt); |
| 312 | newLIR3(cUnit, kThumb2Fmdrr, s2d(rlResult.lowReg, rlResult.highReg), r0, r1); |
| 313 | branch->target = newLIR0(cUnit, kPseudoTargetLabel); |
| 314 | storeValueWide(cUnit, rlDest, rlResult); |
| 315 | return true; |
| 316 | } |
| 317 | |
| 318 | |
Elliott Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 319 | } // namespace art |