| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 buffer_.Emit<int32_t>(value); | 108 buffer_.Emit<int32_t>(value); |
| 109 } | 109 } |
| 110 | 110 |
| 111 | 111 |
| 112 void Assembler::EmitType01(Condition cond, | 112 void Assembler::EmitType01(Condition cond, |
| 113 int type, | 113 int type, |
| 114 Opcode opcode, | 114 Opcode opcode, |
| 115 int set_cc, | 115 int set_cc, |
| 116 Register rn, | 116 Register rn, |
| 117 Register rd, | 117 Register rd, |
| 118 ShifterOperand so) { | 118 Operand o) { |
| 119 ASSERT(rd != kNoRegister); | 119 ASSERT(rd != kNoRegister); |
| 120 ASSERT(cond != kNoCondition); | 120 ASSERT(cond != kNoCondition); |
| 121 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | | 121 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | |
| 122 type << kTypeShift | | 122 type << kTypeShift | |
| 123 static_cast<int32_t>(opcode) << kOpcodeShift | | 123 static_cast<int32_t>(opcode) << kOpcodeShift | |
| 124 set_cc << kSShift | | 124 set_cc << kSShift | |
| 125 static_cast<int32_t>(rn) << kRnShift | | 125 static_cast<int32_t>(rn) << kRnShift | |
| 126 static_cast<int32_t>(rd) << kRdShift | | 126 static_cast<int32_t>(rd) << kRdShift | |
| 127 so.encoding(); | 127 o.encoding(); |
| 128 Emit(encoding); | 128 Emit(encoding); |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 void Assembler::EmitType5(Condition cond, int32_t offset, bool link) { | 132 void Assembler::EmitType5(Condition cond, int32_t offset, bool link) { |
| 133 ASSERT(cond != kNoCondition); | 133 ASSERT(cond != kNoCondition); |
| 134 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | | 134 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | |
| 135 5 << kTypeShift | | 135 5 << kTypeShift | |
| 136 (link ? 1 : 0) << kLinkShift; | 136 (link ? 1 : 0) << kLinkShift; |
| 137 Emit(Assembler::EncodeBranchOffset(offset, encoding)); | 137 Emit(Assembler::EncodeBranchOffset(offset, encoding)); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 (static_cast<int32_t>(base) << kRnShift) | | 183 (static_cast<int32_t>(base) << kRnShift) | |
| 184 regs; | 184 regs; |
| 185 Emit(encoding); | 185 Emit(encoding); |
| 186 } | 186 } |
| 187 | 187 |
| 188 | 188 |
| 189 void Assembler::EmitShiftImmediate(Condition cond, | 189 void Assembler::EmitShiftImmediate(Condition cond, |
| 190 Shift opcode, | 190 Shift opcode, |
| 191 Register rd, | 191 Register rd, |
| 192 Register rm, | 192 Register rm, |
| 193 ShifterOperand so) { | 193 Operand o) { |
| 194 ASSERT(cond != kNoCondition); | 194 ASSERT(cond != kNoCondition); |
| 195 ASSERT(so.type() == 1); | 195 ASSERT(o.type() == 1); |
| 196 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | | 196 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | |
| 197 static_cast<int32_t>(MOV) << kOpcodeShift | | 197 static_cast<int32_t>(MOV) << kOpcodeShift | |
| 198 static_cast<int32_t>(rd) << kRdShift | | 198 static_cast<int32_t>(rd) << kRdShift | |
| 199 so.encoding() << kShiftImmShift | | 199 o.encoding() << kShiftImmShift | |
| 200 static_cast<int32_t>(opcode) << kShiftShift | | 200 static_cast<int32_t>(opcode) << kShiftShift | |
| 201 static_cast<int32_t>(rm); | 201 static_cast<int32_t>(rm); |
| 202 Emit(encoding); | 202 Emit(encoding); |
| 203 } | 203 } |
| 204 | 204 |
| 205 | 205 |
| 206 void Assembler::EmitShiftRegister(Condition cond, | 206 void Assembler::EmitShiftRegister(Condition cond, |
| 207 Shift opcode, | 207 Shift opcode, |
| 208 Register rd, | 208 Register rd, |
| 209 Register rm, | 209 Register rm, |
| 210 ShifterOperand so) { | 210 Operand o) { |
| 211 ASSERT(cond != kNoCondition); | 211 ASSERT(cond != kNoCondition); |
| 212 ASSERT(so.type() == 0); | 212 ASSERT(o.type() == 0); |
| 213 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | | 213 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | |
| 214 static_cast<int32_t>(MOV) << kOpcodeShift | | 214 static_cast<int32_t>(MOV) << kOpcodeShift | |
| 215 static_cast<int32_t>(rd) << kRdShift | | 215 static_cast<int32_t>(rd) << kRdShift | |
| 216 so.encoding() << kShiftRegisterShift | | 216 o.encoding() << kShiftRegisterShift | |
| 217 static_cast<int32_t>(opcode) << kShiftShift | | 217 static_cast<int32_t>(opcode) << kShiftShift | |
| 218 B4 | | 218 B4 | |
| 219 static_cast<int32_t>(rm); | 219 static_cast<int32_t>(rm); |
| 220 Emit(encoding); | 220 Emit(encoding); |
| 221 } | 221 } |
| 222 | 222 |
| 223 | 223 |
| 224 void Assembler::and_(Register rd, Register rn, ShifterOperand so, | 224 void Assembler::and_(Register rd, Register rn, Operand o, Condition cond) { |
| 225 Condition cond) { | 225 EmitType01(cond, o.type(), AND, 0, rn, rd, o); |
| 226 EmitType01(cond, so.type(), AND, 0, rn, rd, so); | |
| 227 } | 226 } |
| 228 | 227 |
| 229 | 228 |
| 230 void Assembler::eor(Register rd, Register rn, ShifterOperand so, | 229 void Assembler::eor(Register rd, Register rn, Operand o, Condition cond) { |
| 231 Condition cond) { | 230 EmitType01(cond, o.type(), EOR, 0, rn, rd, o); |
| 232 EmitType01(cond, so.type(), EOR, 0, rn, rd, so); | |
| 233 } | 231 } |
| 234 | 232 |
| 235 | 233 |
| 236 void Assembler::sub(Register rd, Register rn, ShifterOperand so, | 234 void Assembler::sub(Register rd, Register rn, Operand o, Condition cond) { |
| 237 Condition cond) { | 235 EmitType01(cond, o.type(), SUB, 0, rn, rd, o); |
| 238 EmitType01(cond, so.type(), SUB, 0, rn, rd, so); | |
| 239 } | 236 } |
| 240 | 237 |
| 241 void Assembler::rsb(Register rd, Register rn, ShifterOperand so, | 238 void Assembler::rsb(Register rd, Register rn, Operand o, Condition cond) { |
| 242 Condition cond) { | 239 EmitType01(cond, o.type(), RSB, 0, rn, rd, o); |
| 243 EmitType01(cond, so.type(), RSB, 0, rn, rd, so); | |
| 244 } | 240 } |
| 245 | 241 |
| 246 void Assembler::rsbs(Register rd, Register rn, ShifterOperand so, | 242 void Assembler::rsbs(Register rd, Register rn, Operand o, Condition cond) { |
| 247 Condition cond) { | 243 EmitType01(cond, o.type(), RSB, 1, rn, rd, o); |
| 248 EmitType01(cond, so.type(), RSB, 1, rn, rd, so); | |
| 249 } | 244 } |
| 250 | 245 |
| 251 | 246 |
| 252 void Assembler::add(Register rd, Register rn, ShifterOperand so, | 247 void Assembler::add(Register rd, Register rn, Operand o, Condition cond) { |
| 253 Condition cond) { | 248 EmitType01(cond, o.type(), ADD, 0, rn, rd, o); |
| 254 EmitType01(cond, so.type(), ADD, 0, rn, rd, so); | |
| 255 } | 249 } |
| 256 | 250 |
| 257 | 251 |
| 258 void Assembler::adds(Register rd, Register rn, ShifterOperand so, | 252 void Assembler::adds(Register rd, Register rn, Operand o, Condition cond) { |
| 259 Condition cond) { | 253 EmitType01(cond, o.type(), ADD, 1, rn, rd, o); |
| 260 EmitType01(cond, so.type(), ADD, 1, rn, rd, so); | |
| 261 } | 254 } |
| 262 | 255 |
| 263 | 256 |
| 264 void Assembler::subs(Register rd, Register rn, ShifterOperand so, | 257 void Assembler::subs(Register rd, Register rn, Operand o, Condition cond) { |
| 265 Condition cond) { | 258 EmitType01(cond, o.type(), SUB, 1, rn, rd, o); |
| 266 EmitType01(cond, so.type(), SUB, 1, rn, rd, so); | |
| 267 } | 259 } |
| 268 | 260 |
| 269 | 261 |
| 270 void Assembler::adc(Register rd, Register rn, ShifterOperand so, | 262 void Assembler::adc(Register rd, Register rn, Operand o, Condition cond) { |
| 271 Condition cond) { | 263 EmitType01(cond, o.type(), ADC, 0, rn, rd, o); |
| 272 EmitType01(cond, so.type(), ADC, 0, rn, rd, so); | |
| 273 } | 264 } |
| 274 | 265 |
| 275 | 266 |
| 276 void Assembler::adcs(Register rd, Register rn, ShifterOperand so, | 267 void Assembler::adcs(Register rd, Register rn, Operand o, Condition cond) { |
| 277 Condition cond) { | 268 EmitType01(cond, o.type(), ADC, 1, rn, rd, o); |
| 278 EmitType01(cond, so.type(), ADC, 1, rn, rd, so); | |
| 279 } | 269 } |
| 280 | 270 |
| 281 | 271 |
| 282 void Assembler::sbc(Register rd, Register rn, ShifterOperand so, | 272 void Assembler::sbc(Register rd, Register rn, Operand o, Condition cond) { |
| 283 Condition cond) { | 273 EmitType01(cond, o.type(), SBC, 0, rn, rd, o); |
| 284 EmitType01(cond, so.type(), SBC, 0, rn, rd, so); | |
| 285 } | 274 } |
| 286 | 275 |
| 287 | 276 |
| 288 void Assembler::sbcs(Register rd, Register rn, ShifterOperand so, | 277 void Assembler::sbcs(Register rd, Register rn, Operand o, Condition cond) { |
| 289 Condition cond) { | 278 EmitType01(cond, o.type(), SBC, 1, rn, rd, o); |
| 290 EmitType01(cond, so.type(), SBC, 1, rn, rd, so); | |
| 291 } | 279 } |
| 292 | 280 |
| 293 | 281 |
| 294 void Assembler::rsc(Register rd, Register rn, ShifterOperand so, | 282 void Assembler::rsc(Register rd, Register rn, Operand o, Condition cond) { |
| 295 Condition cond) { | 283 EmitType01(cond, o.type(), RSC, 0, rn, rd, o); |
| 296 EmitType01(cond, so.type(), RSC, 0, rn, rd, so); | |
| 297 } | 284 } |
| 298 | 285 |
| 299 | 286 |
| 300 void Assembler::tst(Register rn, ShifterOperand so, Condition cond) { | 287 void Assembler::tst(Register rn, Operand o, Condition cond) { |
| 301 EmitType01(cond, so.type(), TST, 1, rn, R0, so); | 288 EmitType01(cond, o.type(), TST, 1, rn, R0, o); |
| 302 } | 289 } |
| 303 | 290 |
| 304 | 291 |
| 305 void Assembler::teq(Register rn, ShifterOperand so, Condition cond) { | 292 void Assembler::teq(Register rn, Operand o, Condition cond) { |
| 306 EmitType01(cond, so.type(), TEQ, 1, rn, R0, so); | 293 EmitType01(cond, o.type(), TEQ, 1, rn, R0, o); |
| 307 } | 294 } |
| 308 | 295 |
| 309 | 296 |
| 310 void Assembler::cmp(Register rn, ShifterOperand so, Condition cond) { | 297 void Assembler::cmp(Register rn, Operand o, Condition cond) { |
| 311 EmitType01(cond, so.type(), CMP, 1, rn, R0, so); | 298 EmitType01(cond, o.type(), CMP, 1, rn, R0, o); |
| 312 } | 299 } |
| 313 | 300 |
| 314 | 301 |
| 315 void Assembler::cmn(Register rn, ShifterOperand so, Condition cond) { | 302 void Assembler::cmn(Register rn, Operand o, Condition cond) { |
| 316 EmitType01(cond, so.type(), CMN, 1, rn, R0, so); | 303 EmitType01(cond, o.type(), CMN, 1, rn, R0, o); |
| 317 } | 304 } |
| 318 | 305 |
| 319 | 306 |
| 320 void Assembler::orr(Register rd, Register rn, ShifterOperand so, | 307 void Assembler::orr(Register rd, Register rn, Operand o, Condition cond) { |
| 321 Condition cond) { | 308 EmitType01(cond, o.type(), ORR, 0, rn, rd, o); |
| 322 EmitType01(cond, so.type(), ORR, 0, rn, rd, so); | |
| 323 } | 309 } |
| 324 | 310 |
| 325 | 311 |
| 326 void Assembler::orrs(Register rd, Register rn, ShifterOperand so, | 312 void Assembler::orrs(Register rd, Register rn, Operand o, Condition cond) { |
| 327 Condition cond) { | 313 EmitType01(cond, o.type(), ORR, 1, rn, rd, o); |
| 328 EmitType01(cond, so.type(), ORR, 1, rn, rd, so); | |
| 329 } | 314 } |
| 330 | 315 |
| 331 | 316 |
| 332 void Assembler::mov(Register rd, ShifterOperand so, Condition cond) { | 317 void Assembler::mov(Register rd, Operand o, Condition cond) { |
| 333 EmitType01(cond, so.type(), MOV, 0, R0, rd, so); | 318 EmitType01(cond, o.type(), MOV, 0, R0, rd, o); |
| 334 } | 319 } |
| 335 | 320 |
| 336 | 321 |
| 337 void Assembler::movs(Register rd, ShifterOperand so, Condition cond) { | 322 void Assembler::movs(Register rd, Operand o, Condition cond) { |
| 338 EmitType01(cond, so.type(), MOV, 1, R0, rd, so); | 323 EmitType01(cond, o.type(), MOV, 1, R0, rd, o); |
| 339 } | 324 } |
| 340 | 325 |
| 341 | 326 |
| 342 void Assembler::bic(Register rd, Register rn, ShifterOperand so, | 327 void Assembler::bic(Register rd, Register rn, Operand o, Condition cond) { |
| 343 Condition cond) { | 328 EmitType01(cond, o.type(), BIC, 0, rn, rd, o); |
| 344 EmitType01(cond, so.type(), BIC, 0, rn, rd, so); | |
| 345 } | 329 } |
| 346 | 330 |
| 347 | 331 |
| 348 void Assembler::bics(Register rd, Register rn, ShifterOperand so, | 332 void Assembler::bics(Register rd, Register rn, Operand o, Condition cond) { |
| 349 Condition cond) { | 333 EmitType01(cond, o.type(), BIC, 1, rn, rd, o); |
| 350 EmitType01(cond, so.type(), BIC, 1, rn, rd, so); | |
| 351 } | 334 } |
| 352 | 335 |
| 353 | 336 |
| 354 void Assembler::mvn(Register rd, ShifterOperand so, Condition cond) { | 337 void Assembler::mvn(Register rd, Operand o, Condition cond) { |
| 355 EmitType01(cond, so.type(), MVN, 0, R0, rd, so); | 338 EmitType01(cond, o.type(), MVN, 0, R0, rd, o); |
| 356 } | 339 } |
| 357 | 340 |
| 358 | 341 |
| 359 void Assembler::mvns(Register rd, ShifterOperand so, Condition cond) { | 342 void Assembler::mvns(Register rd, Operand o, Condition cond) { |
| 360 EmitType01(cond, so.type(), MVN, 1, R0, rd, so); | 343 EmitType01(cond, o.type(), MVN, 1, R0, rd, o); |
| 361 } | 344 } |
| 362 | 345 |
| 363 | 346 |
| 364 void Assembler::clz(Register rd, Register rm, Condition cond) { | 347 void Assembler::clz(Register rd, Register rm, Condition cond) { |
| 365 ASSERT(rd != kNoRegister); | 348 ASSERT(rd != kNoRegister); |
| 366 ASSERT(rm != kNoRegister); | 349 ASSERT(rm != kNoRegister); |
| 367 ASSERT(cond != kNoCondition); | 350 ASSERT(cond != kNoCondition); |
| 368 ASSERT(rd != PC); | 351 ASSERT(rd != PC); |
| 369 ASSERT(rm != PC); | 352 ASSERT(rm != PC); |
| 370 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | | 353 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 (static_cast<int32_t>(cond) << kConditionShift) | | 388 (static_cast<int32_t>(cond) << kConditionShift) | |
| 406 (static_cast<int32_t>(rn) << kRnShift) | | 389 (static_cast<int32_t>(rn) << kRnShift) | |
| 407 (static_cast<int32_t>(rd) << kRdShift) | | 390 (static_cast<int32_t>(rd) << kRdShift) | |
| 408 (static_cast<int32_t>(rs) << kRsShift) | | 391 (static_cast<int32_t>(rs) << kRsShift) | |
| 409 B7 | B4 | | 392 B7 | B4 | |
| 410 (static_cast<int32_t>(rm) << kRmShift); | 393 (static_cast<int32_t>(rm) << kRmShift); |
| 411 Emit(encoding); | 394 Emit(encoding); |
| 412 } | 395 } |
| 413 | 396 |
| 414 | 397 |
| 415 void Assembler::mul(Register rd, Register rn, | 398 void Assembler::mul(Register rd, Register rn, Register rm, Condition cond) { |
| 416 Register rm, Condition cond) { | |
| 417 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | 399 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. |
| 418 EmitMulOp(cond, 0, R0, rd, rn, rm); | 400 EmitMulOp(cond, 0, R0, rd, rn, rm); |
| 419 } | 401 } |
| 420 | 402 |
| 421 | 403 |
| 422 // Like mul, but sets condition flags. | 404 // Like mul, but sets condition flags. |
| 423 void Assembler::muls(Register rd, Register rn, | 405 void Assembler::muls(Register rd, Register rn, Register rm, Condition cond) { |
| 424 Register rm, Condition cond) { | |
| 425 EmitMulOp(cond, B20, R0, rd, rn, rm); | 406 EmitMulOp(cond, B20, R0, rd, rn, rm); |
| 426 } | 407 } |
| 427 | 408 |
| 428 | 409 |
| 429 void Assembler::mla(Register rd, Register rn, | 410 void Assembler::mla(Register rd, Register rn, |
| 430 Register rm, Register ra, Condition cond) { | 411 Register rm, Register ra, Condition cond) { |
| 431 // rd <- ra + rn * rm. | 412 // rd <- ra + rn * rm. |
| 432 if (TargetCPUFeatures::arm_version() == ARMv7) { | 413 if (TargetCPUFeatures::arm_version() == ARMv7) { |
| 433 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. | 414 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. |
| 434 EmitMulOp(cond, B21, ra, rd, rn, rm); | 415 EmitMulOp(cond, B21, ra, rd, rn, rm); |
| 435 } else { | 416 } else { |
| 436 mul(IP, rn, rm, cond); | 417 mul(IP, rn, rm, cond); |
| 437 add(rd, ra, ShifterOperand(IP), cond); | 418 add(rd, ra, Operand(IP), cond); |
| 438 } | 419 } |
| 439 } | 420 } |
| 440 | 421 |
| 441 | 422 |
| 442 void Assembler::mls(Register rd, Register rn, | 423 void Assembler::mls(Register rd, Register rn, |
| 443 Register rm, Register ra, Condition cond) { | 424 Register rm, Register ra, Condition cond) { |
| 444 // rd <- ra - rn * rm. | 425 // rd <- ra - rn * rm. |
| 445 if (TargetCPUFeatures::arm_version() == ARMv7) { | 426 if (TargetCPUFeatures::arm_version() == ARMv7) { |
| 446 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. | 427 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. |
| 447 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); | 428 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); |
| 448 } else { | 429 } else { |
| 449 mul(IP, rn, rm, cond); | 430 mul(IP, rn, rm, cond); |
| 450 sub(rd, ra, ShifterOperand(IP), cond); | 431 sub(rd, ra, Operand(IP), cond); |
| 451 } | 432 } |
| 452 } | 433 } |
| 453 | 434 |
| 454 | 435 |
| 455 void Assembler::smull(Register rd_lo, Register rd_hi, | 436 void Assembler::smull(Register rd_lo, Register rd_hi, |
| 456 Register rn, Register rm, Condition cond) { | 437 Register rn, Register rm, Condition cond) { |
| 457 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); | 438 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); |
| 458 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 439 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
| 459 EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm); | 440 EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm); |
| 460 } | 441 } |
| (...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 ASSERT(rm != kNoRegister); | 1473 ASSERT(rm != kNoRegister); |
| 1493 ASSERT(cond != kNoCondition); | 1474 ASSERT(cond != kNoCondition); |
| 1494 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | | 1475 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 1495 B24 | B21 | (0xfff << 8) | B5 | B4 | | 1476 B24 | B21 | (0xfff << 8) | B5 | B4 | |
| 1496 (static_cast<int32_t>(rm) << kRmShift); | 1477 (static_cast<int32_t>(rm) << kRmShift); |
| 1497 Emit(encoding); | 1478 Emit(encoding); |
| 1498 } | 1479 } |
| 1499 | 1480 |
| 1500 | 1481 |
| 1501 void Assembler::MarkExceptionHandler(Label* label) { | 1482 void Assembler::MarkExceptionHandler(Label* label) { |
| 1502 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); | 1483 EmitType01(AL, 1, TST, 1, PC, R0, Operand(0)); |
| 1503 Label l; | 1484 Label l; |
| 1504 b(&l); | 1485 b(&l); |
| 1505 EmitBranch(AL, label, false); | 1486 EmitBranch(AL, label, false); |
| 1506 Bind(&l); | 1487 Bind(&l); |
| 1507 } | 1488 } |
| 1508 | 1489 |
| 1509 | 1490 |
| 1510 void Assembler::Drop(intptr_t stack_elements) { | 1491 void Assembler::Drop(intptr_t stack_elements) { |
| 1511 ASSERT(stack_elements >= 0); | 1492 ASSERT(stack_elements >= 0); |
| 1512 if (stack_elements > 0) { | 1493 if (stack_elements > 0) { |
| 1513 AddImmediate(SP, SP, stack_elements * kWordSize); | 1494 AddImmediate(SP, SP, stack_elements * kWordSize); |
| 1514 } | 1495 } |
| 1515 } | 1496 } |
| 1516 | 1497 |
| 1517 | 1498 |
| 1518 // Uses a code sequence that can easily be decoded. | 1499 // Uses a code sequence that can easily be decoded. |
| 1519 void Assembler::LoadWordFromPoolOffset(Register rd, | 1500 void Assembler::LoadWordFromPoolOffset(Register rd, |
| 1520 int32_t offset, | 1501 int32_t offset, |
| 1521 Condition cond) { | 1502 Condition cond) { |
| 1522 ASSERT(rd != PP); | 1503 ASSERT(rd != PP); |
| 1523 int32_t offset_mask = 0; | 1504 int32_t offset_mask = 0; |
| 1524 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { | 1505 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { |
| 1525 ldr(rd, Address(PP, offset), cond); | 1506 ldr(rd, Address(PP, offset), cond); |
| 1526 } else { | 1507 } else { |
| 1527 int32_t offset_hi = offset & ~offset_mask; // signed | 1508 int32_t offset_hi = offset & ~offset_mask; // signed |
| 1528 uint32_t offset_lo = offset & offset_mask; // unsigned | 1509 uint32_t offset_lo = offset & offset_mask; // unsigned |
| 1529 // Inline a simplified version of AddImmediate(rd, PP, offset_hi). | 1510 // Inline a simplified version of AddImmediate(rd, PP, offset_hi). |
| 1530 ShifterOperand shifter_op; | 1511 Operand o; |
| 1531 if (ShifterOperand::CanHold(offset_hi, &shifter_op)) { | 1512 if (Operand::CanHold(offset_hi, &o)) { |
| 1532 add(rd, PP, shifter_op, cond); | 1513 add(rd, PP, o, cond); |
| 1533 } else { | 1514 } else { |
| 1534 LoadImmediate(rd, offset_hi, cond); | 1515 LoadImmediate(rd, offset_hi, cond); |
| 1535 add(rd, PP, ShifterOperand(LR), cond); | 1516 add(rd, PP, Operand(LR), cond); |
| 1536 } | 1517 } |
| 1537 ldr(rd, Address(rd, offset_lo), cond); | 1518 ldr(rd, Address(rd, offset_lo), cond); |
| 1538 } | 1519 } |
| 1539 } | 1520 } |
| 1540 | 1521 |
| 1541 | 1522 |
| 1542 void Assembler::LoadPoolPointer() { | 1523 void Assembler::LoadPoolPointer() { |
| 1543 const intptr_t object_pool_pc_dist = | 1524 const intptr_t object_pool_pc_dist = |
| 1544 Instructions::HeaderSize() - Instructions::object_pool_offset() + | 1525 Instructions::HeaderSize() - Instructions::object_pool_offset() + |
| 1545 CodeSize() + Instr::kPCReadOffset; | 1526 CodeSize() + Instr::kPCReadOffset; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1570 Push(IP); | 1551 Push(IP); |
| 1571 } | 1552 } |
| 1572 | 1553 |
| 1573 | 1554 |
| 1574 void Assembler::CompareObject(Register rn, const Object& object) { | 1555 void Assembler::CompareObject(Register rn, const Object& object) { |
| 1575 ASSERT(rn != IP); | 1556 ASSERT(rn != IP); |
| 1576 if (object.IsSmi()) { | 1557 if (object.IsSmi()) { |
| 1577 CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw())); | 1558 CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw())); |
| 1578 } else { | 1559 } else { |
| 1579 LoadObject(IP, object); | 1560 LoadObject(IP, object); |
| 1580 cmp(rn, ShifterOperand(IP)); | 1561 cmp(rn, Operand(IP)); |
| 1581 } | 1562 } |
| 1582 } | 1563 } |
| 1583 | 1564 |
| 1584 | 1565 |
| 1585 // Preserves object and value registers. | 1566 // Preserves object and value registers. |
| 1586 void Assembler::StoreIntoObjectFilterNoSmi(Register object, | 1567 void Assembler::StoreIntoObjectFilterNoSmi(Register object, |
| 1587 Register value, | 1568 Register value, |
| 1588 Label* no_update) { | 1569 Label* no_update) { |
| 1589 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && | 1570 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && |
| 1590 (kOldObjectAlignmentOffset == 0)); | 1571 (kOldObjectAlignmentOffset == 0)); |
| 1591 | 1572 |
| 1592 // Write-barrier triggers if the value is in the new space (has bit set) and | 1573 // Write-barrier triggers if the value is in the new space (has bit set) and |
| 1593 // the object is in the old space (has bit cleared). | 1574 // the object is in the old space (has bit cleared). |
| 1594 // To check that, we compute value & ~object and skip the write barrier | 1575 // To check that, we compute value & ~object and skip the write barrier |
| 1595 // if the bit is not set. We can't destroy the object. | 1576 // if the bit is not set. We can't destroy the object. |
| 1596 bic(IP, value, ShifterOperand(object)); | 1577 bic(IP, value, Operand(object)); |
| 1597 tst(IP, ShifterOperand(kNewObjectAlignmentOffset)); | 1578 tst(IP, Operand(kNewObjectAlignmentOffset)); |
| 1598 b(no_update, EQ); | 1579 b(no_update, EQ); |
| 1599 } | 1580 } |
| 1600 | 1581 |
| 1601 | 1582 |
| 1602 // Preserves object and value registers. | 1583 // Preserves object and value registers. |
| 1603 void Assembler::StoreIntoObjectFilter(Register object, | 1584 void Assembler::StoreIntoObjectFilter(Register object, |
| 1604 Register value, | 1585 Register value, |
| 1605 Label* no_update) { | 1586 Label* no_update) { |
| 1606 // For the value we are only interested in the new/old bit and the tag bit. | 1587 // For the value we are only interested in the new/old bit and the tag bit. |
| 1607 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi. | 1588 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi. |
| 1608 and_(IP, value, ShifterOperand(value, LSL, kObjectAlignmentLog2 - 1)); | 1589 and_(IP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1)); |
| 1609 // And the result with the negated space bit of the object. | 1590 // And the result with the negated space bit of the object. |
| 1610 bic(IP, IP, ShifterOperand(object)); | 1591 bic(IP, IP, Operand(object)); |
| 1611 tst(IP, ShifterOperand(kNewObjectAlignmentOffset)); | 1592 tst(IP, Operand(kNewObjectAlignmentOffset)); |
| 1612 b(no_update, EQ); | 1593 b(no_update, EQ); |
| 1613 } | 1594 } |
| 1614 | 1595 |
| 1615 | 1596 |
| 1616 void Assembler::StoreIntoObject(Register object, | 1597 void Assembler::StoreIntoObject(Register object, |
| 1617 const Address& dest, | 1598 const Address& dest, |
| 1618 Register value, | 1599 Register value, |
| 1619 bool can_value_be_smi) { | 1600 bool can_value_be_smi) { |
| 1620 ASSERT(object != value); | 1601 ASSERT(object != value); |
| 1621 str(value, dest); | 1602 str(value, dest); |
| 1622 Label done; | 1603 Label done; |
| 1623 if (can_value_be_smi) { | 1604 if (can_value_be_smi) { |
| 1624 StoreIntoObjectFilter(object, value, &done); | 1605 StoreIntoObjectFilter(object, value, &done); |
| 1625 } else { | 1606 } else { |
| 1626 StoreIntoObjectFilterNoSmi(object, value, &done); | 1607 StoreIntoObjectFilterNoSmi(object, value, &done); |
| 1627 } | 1608 } |
| 1628 // A store buffer update is required. | 1609 // A store buffer update is required. |
| 1629 RegList regs = (1 << LR); | 1610 RegList regs = (1 << LR); |
| 1630 if (value != R0) { | 1611 if (value != R0) { |
| 1631 regs |= (1 << R0); // Preserve R0. | 1612 regs |= (1 << R0); // Preserve R0. |
| 1632 } | 1613 } |
| 1633 PushList(regs); | 1614 PushList(regs); |
| 1634 if (object != R0) { | 1615 if (object != R0) { |
| 1635 mov(R0, ShifterOperand(object)); | 1616 mov(R0, Operand(object)); |
| 1636 } | 1617 } |
| 1637 BranchLink(&StubCode::UpdateStoreBufferLabel()); | 1618 BranchLink(&StubCode::UpdateStoreBufferLabel()); |
| 1638 PopList(regs); | 1619 PopList(regs); |
| 1639 Bind(&done); | 1620 Bind(&done); |
| 1640 } | 1621 } |
| 1641 | 1622 |
| 1642 | 1623 |
| 1643 void Assembler::StoreIntoObjectNoBarrier(Register object, | 1624 void Assembler::StoreIntoObjectNoBarrier(Register object, |
| 1644 const Address& dest, | 1625 const Address& dest, |
| 1645 Register value) { | 1626 Register value) { |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2164 } | 2145 } |
| 2165 | 2146 |
| 2166 | 2147 |
| 2167 void Assembler::PopList(RegList regs, Condition cond) { | 2148 void Assembler::PopList(RegList regs, Condition cond) { |
| 2168 ldm(IA_W, SP, regs, cond); | 2149 ldm(IA_W, SP, regs, cond); |
| 2169 } | 2150 } |
| 2170 | 2151 |
| 2171 | 2152 |
| 2172 void Assembler::MoveRegister(Register rd, Register rm, Condition cond) { | 2153 void Assembler::MoveRegister(Register rd, Register rm, Condition cond) { |
| 2173 if (rd != rm) { | 2154 if (rd != rm) { |
| 2174 mov(rd, ShifterOperand(rm), cond); | 2155 mov(rd, Operand(rm), cond); |
| 2175 } | 2156 } |
| 2176 } | 2157 } |
| 2177 | 2158 |
| 2178 | 2159 |
| 2179 void Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm, | 2160 void Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm, |
| 2180 Condition cond) { | 2161 Condition cond) { |
| 2181 ASSERT(shift_imm != 0); // Do not use Lsl if no shift is wanted. | 2162 ASSERT(shift_imm != 0); // Do not use Lsl if no shift is wanted. |
| 2182 mov(rd, ShifterOperand(rm, LSL, shift_imm), cond); | 2163 mov(rd, Operand(rm, LSL, shift_imm), cond); |
| 2183 } | 2164 } |
| 2184 | 2165 |
| 2185 | 2166 |
| 2186 void Assembler::Lsl(Register rd, Register rm, Register rs, Condition cond) { | 2167 void Assembler::Lsl(Register rd, Register rm, Register rs, Condition cond) { |
| 2187 mov(rd, ShifterOperand(rm, LSL, rs), cond); | 2168 mov(rd, Operand(rm, LSL, rs), cond); |
| 2188 } | 2169 } |
| 2189 | 2170 |
| 2190 | 2171 |
| 2191 void Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm, | 2172 void Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm, |
| 2192 Condition cond) { | 2173 Condition cond) { |
| 2193 ASSERT(shift_imm != 0); // Do not use Lsr if no shift is wanted. | 2174 ASSERT(shift_imm != 0); // Do not use Lsr if no shift is wanted. |
| 2194 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. | 2175 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. |
| 2195 mov(rd, ShifterOperand(rm, LSR, shift_imm), cond); | 2176 mov(rd, Operand(rm, LSR, shift_imm), cond); |
| 2196 } | 2177 } |
| 2197 | 2178 |
| 2198 | 2179 |
| 2199 void Assembler::Lsr(Register rd, Register rm, Register rs, Condition cond) { | 2180 void Assembler::Lsr(Register rd, Register rm, Register rs, Condition cond) { |
| 2200 mov(rd, ShifterOperand(rm, LSR, rs), cond); | 2181 mov(rd, Operand(rm, LSR, rs), cond); |
| 2201 } | 2182 } |
| 2202 | 2183 |
| 2203 | 2184 |
| 2204 void Assembler::Asr(Register rd, Register rm, uint32_t shift_imm, | 2185 void Assembler::Asr(Register rd, Register rm, uint32_t shift_imm, |
| 2205 Condition cond) { | 2186 Condition cond) { |
| 2206 ASSERT(shift_imm != 0); // Do not use Asr if no shift is wanted. | 2187 ASSERT(shift_imm != 0); // Do not use Asr if no shift is wanted. |
| 2207 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. | 2188 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. |
| 2208 mov(rd, ShifterOperand(rm, ASR, shift_imm), cond); | 2189 mov(rd, Operand(rm, ASR, shift_imm), cond); |
| 2209 } | 2190 } |
| 2210 | 2191 |
| 2211 | 2192 |
| 2212 void Assembler::Asr(Register rd, Register rm, Register rs, Condition cond) { | 2193 void Assembler::Asr(Register rd, Register rm, Register rs, Condition cond) { |
| 2213 mov(rd, ShifterOperand(rm, ASR, rs), cond); | 2194 mov(rd, Operand(rm, ASR, rs), cond); |
| 2214 } | 2195 } |
| 2215 | 2196 |
| 2216 | 2197 |
| 2217 void Assembler::Ror(Register rd, Register rm, uint32_t shift_imm, | 2198 void Assembler::Ror(Register rd, Register rm, uint32_t shift_imm, |
| 2218 Condition cond) { | 2199 Condition cond) { |
| 2219 ASSERT(shift_imm != 0); // Use Rrx instruction. | 2200 ASSERT(shift_imm != 0); // Use Rrx instruction. |
| 2220 mov(rd, ShifterOperand(rm, ROR, shift_imm), cond); | 2201 mov(rd, Operand(rm, ROR, shift_imm), cond); |
| 2221 } | 2202 } |
| 2222 | 2203 |
| 2223 | 2204 |
| 2224 void Assembler::Ror(Register rd, Register rm, Register rs, Condition cond) { | 2205 void Assembler::Ror(Register rd, Register rm, Register rs, Condition cond) { |
| 2225 mov(rd, ShifterOperand(rm, ROR, rs), cond); | 2206 mov(rd, Operand(rm, ROR, rs), cond); |
| 2226 } | 2207 } |
| 2227 | 2208 |
| 2228 | 2209 |
| 2229 void Assembler::Rrx(Register rd, Register rm, Condition cond) { | 2210 void Assembler::Rrx(Register rd, Register rm, Condition cond) { |
| 2230 mov(rd, ShifterOperand(rm, ROR, 0), cond); | 2211 mov(rd, Operand(rm, ROR, 0), cond); |
| 2231 } | 2212 } |
| 2232 | 2213 |
| 2233 | 2214 |
| 2234 void Assembler::SignFill(Register rd, Register rm, Condition cond) { | 2215 void Assembler::SignFill(Register rd, Register rm, Condition cond) { |
| 2235 Asr(rd, rm, 31, cond); | 2216 Asr(rd, rm, 31, cond); |
| 2236 } | 2217 } |
| 2237 | 2218 |
| 2238 | 2219 |
| 2239 void Assembler::Vreciprocalqs(QRegister qd, QRegister qm) { | 2220 void Assembler::Vreciprocalqs(QRegister qd, QRegister qm) { |
| 2240 ASSERT(qm != QTMP); | 2221 ASSERT(qm != QTMP); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2338 | 2319 |
| 2339 void Assembler::LoadPatchableImmediate( | 2320 void Assembler::LoadPatchableImmediate( |
| 2340 Register rd, int32_t value, Condition cond) { | 2321 Register rd, int32_t value, Condition cond) { |
| 2341 const ARMVersion version = TargetCPUFeatures::arm_version(); | 2322 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 2342 if ((version == ARMv5TE) || (version == ARMv6)) { | 2323 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 2343 // This sequence is patched in a few places, and should remain fixed. | 2324 // This sequence is patched in a few places, and should remain fixed. |
| 2344 const uint32_t byte0 = (value & 0x000000ff); | 2325 const uint32_t byte0 = (value & 0x000000ff); |
| 2345 const uint32_t byte1 = (value & 0x0000ff00) >> 8; | 2326 const uint32_t byte1 = (value & 0x0000ff00) >> 8; |
| 2346 const uint32_t byte2 = (value & 0x00ff0000) >> 16; | 2327 const uint32_t byte2 = (value & 0x00ff0000) >> 16; |
| 2347 const uint32_t byte3 = (value & 0xff000000) >> 24; | 2328 const uint32_t byte3 = (value & 0xff000000) >> 24; |
| 2348 mov(rd, ShifterOperand(4, byte3), cond); | 2329 mov(rd, Operand(4, byte3), cond); |
| 2349 orr(rd, rd, ShifterOperand(8, byte2), cond); | 2330 orr(rd, rd, Operand(8, byte2), cond); |
| 2350 orr(rd, rd, ShifterOperand(12, byte1), cond); | 2331 orr(rd, rd, Operand(12, byte1), cond); |
| 2351 orr(rd, rd, ShifterOperand(byte0), cond); | 2332 orr(rd, rd, Operand(byte0), cond); |
| 2352 } else { | 2333 } else { |
| 2353 ASSERT(version == ARMv7); | 2334 ASSERT(version == ARMv7); |
| 2354 const uint16_t value_low = Utils::Low16Bits(value); | 2335 const uint16_t value_low = Utils::Low16Bits(value); |
| 2355 const uint16_t value_high = Utils::High16Bits(value); | 2336 const uint16_t value_high = Utils::High16Bits(value); |
| 2356 movw(rd, value_low, cond); | 2337 movw(rd, value_low, cond); |
| 2357 movt(rd, value_high, cond); | 2338 movt(rd, value_high, cond); |
| 2358 } | 2339 } |
| 2359 } | 2340 } |
| 2360 | 2341 |
| 2361 | 2342 |
| 2362 void Assembler::LoadDecodableImmediate( | 2343 void Assembler::LoadDecodableImmediate( |
| 2363 Register rd, int32_t value, Condition cond) { | 2344 Register rd, int32_t value, Condition cond) { |
| 2364 const ARMVersion version = TargetCPUFeatures::arm_version(); | 2345 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 2365 if ((version == ARMv5TE) || (version == ARMv6)) { | 2346 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 2366 LoadPatchableImmediate(rd, value, cond); | 2347 LoadPatchableImmediate(rd, value, cond); |
| 2367 } else { | 2348 } else { |
| 2368 ASSERT(version == ARMv7); | 2349 ASSERT(version == ARMv7); |
| 2369 movw(rd, Utils::Low16Bits(value), cond); | 2350 movw(rd, Utils::Low16Bits(value), cond); |
| 2370 const uint16_t value_high = Utils::High16Bits(value); | 2351 const uint16_t value_high = Utils::High16Bits(value); |
| 2371 if (value_high != 0) { | 2352 if (value_high != 0) { |
| 2372 movt(rd, value_high, cond); | 2353 movt(rd, value_high, cond); |
| 2373 } | 2354 } |
| 2374 } | 2355 } |
| 2375 } | 2356 } |
| 2376 | 2357 |
| 2377 | 2358 |
| 2378 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { | 2359 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { |
| 2379 ShifterOperand shifter_op; | 2360 Operand o; |
| 2380 if (ShifterOperand::CanHold(value, &shifter_op)) { | 2361 if (Operand::CanHold(value, &o)) { |
| 2381 mov(rd, shifter_op, cond); | 2362 mov(rd, o, cond); |
| 2382 } else if (ShifterOperand::CanHold(~value, &shifter_op)) { | 2363 } else if (Operand::CanHold(~value, &o)) { |
| 2383 mvn(rd, shifter_op, cond); | 2364 mvn(rd, o, cond); |
| 2384 } else { | 2365 } else { |
| 2385 LoadDecodableImmediate(rd, value, cond); | 2366 LoadDecodableImmediate(rd, value, cond); |
| 2386 } | 2367 } |
| 2387 } | 2368 } |
| 2388 | 2369 |
| 2389 | 2370 |
| 2390 void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) { | 2371 void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) { |
| 2391 if (!vmovs(sd, value, cond)) { | 2372 if (!vmovs(sd, value, cond)) { |
| 2392 LoadImmediate(IP, bit_cast<int32_t, float>(value), cond); | 2373 LoadImmediate(IP, bit_cast<int32_t, float>(value), cond); |
| 2393 vmovsr(sd, IP, cond); | 2374 vmovsr(sd, IP, cond); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2638 | 2619 |
| 2639 void Assembler::AddImmediate(Register rd, int32_t value, Condition cond) { | 2620 void Assembler::AddImmediate(Register rd, int32_t value, Condition cond) { |
| 2640 AddImmediate(rd, rd, value, cond); | 2621 AddImmediate(rd, rd, value, cond); |
| 2641 } | 2622 } |
| 2642 | 2623 |
| 2643 | 2624 |
| 2644 void Assembler::AddImmediate(Register rd, Register rn, int32_t value, | 2625 void Assembler::AddImmediate(Register rd, Register rn, int32_t value, |
| 2645 Condition cond) { | 2626 Condition cond) { |
| 2646 if (value == 0) { | 2627 if (value == 0) { |
| 2647 if (rd != rn) { | 2628 if (rd != rn) { |
| 2648 mov(rd, ShifterOperand(rn), cond); | 2629 mov(rd, Operand(rn), cond); |
| 2649 } | 2630 } |
| 2650 return; | 2631 return; |
| 2651 } | 2632 } |
| 2652 // We prefer to select the shorter code sequence rather than selecting add for | 2633 // We prefer to select the shorter code sequence rather than selecting add for |
| 2653 // positive values and sub for negatives ones, which would slightly improve | 2634 // positive values and sub for negatives ones, which would slightly improve |
| 2654 // the readability of generated code for some constants. | 2635 // the readability of generated code for some constants. |
| 2655 ShifterOperand shifter_op; | 2636 Operand o; |
| 2656 if (ShifterOperand::CanHold(value, &shifter_op)) { | 2637 if (Operand::CanHold(value, &o)) { |
| 2657 add(rd, rn, shifter_op, cond); | 2638 add(rd, rn, o, cond); |
| 2658 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { | 2639 } else if (Operand::CanHold(-value, &o)) { |
| 2659 sub(rd, rn, shifter_op, cond); | 2640 sub(rd, rn, o, cond); |
| 2660 } else { | 2641 } else { |
| 2661 ASSERT(rn != IP); | 2642 ASSERT(rn != IP); |
| 2662 if (ShifterOperand::CanHold(~value, &shifter_op)) { | 2643 if (Operand::CanHold(~value, &o)) { |
| 2663 mvn(IP, shifter_op, cond); | 2644 mvn(IP, o, cond); |
| 2664 add(rd, rn, ShifterOperand(IP), cond); | 2645 add(rd, rn, Operand(IP), cond); |
| 2665 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { | 2646 } else if (Operand::CanHold(~(-value), &o)) { |
| 2666 mvn(IP, shifter_op, cond); | 2647 mvn(IP, o, cond); |
| 2667 sub(rd, rn, ShifterOperand(IP), cond); | 2648 sub(rd, rn, Operand(IP), cond); |
| 2668 } else { | 2649 } else { |
| 2669 LoadDecodableImmediate(IP, value, cond); | 2650 LoadDecodableImmediate(IP, value, cond); |
| 2670 add(rd, rn, ShifterOperand(IP), cond); | 2651 add(rd, rn, Operand(IP), cond); |
| 2671 } | 2652 } |
| 2672 } | 2653 } |
| 2673 } | 2654 } |
| 2674 | 2655 |
| 2675 | 2656 |
| 2676 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, | 2657 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, |
| 2677 Condition cond) { | 2658 Condition cond) { |
| 2678 ShifterOperand shifter_op; | 2659 Operand o; |
| 2679 if (ShifterOperand::CanHold(value, &shifter_op)) { | 2660 if (Operand::CanHold(value, &o)) { |
| 2680 // Handles value == kMinInt32. | 2661 // Handles value == kMinInt32. |
| 2681 adds(rd, rn, shifter_op, cond); | 2662 adds(rd, rn, o, cond); |
| 2682 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { | 2663 } else if (Operand::CanHold(-value, &o)) { |
| 2683 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. | 2664 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. |
| 2684 subs(rd, rn, shifter_op, cond); | 2665 subs(rd, rn, o, cond); |
| 2685 } else { | 2666 } else { |
| 2686 ASSERT(rn != IP); | 2667 ASSERT(rn != IP); |
| 2687 if (ShifterOperand::CanHold(~value, &shifter_op)) { | 2668 if (Operand::CanHold(~value, &o)) { |
| 2688 mvn(IP, shifter_op, cond); | 2669 mvn(IP, o, cond); |
| 2689 adds(rd, rn, ShifterOperand(IP), cond); | 2670 adds(rd, rn, Operand(IP), cond); |
| 2690 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { | 2671 } else if (Operand::CanHold(~(-value), &o)) { |
| 2691 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. | 2672 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. |
| 2692 mvn(IP, shifter_op, cond); | 2673 mvn(IP, o, cond); |
| 2693 subs(rd, rn, ShifterOperand(IP), cond); | 2674 subs(rd, rn, Operand(IP), cond); |
| 2694 } else { | 2675 } else { |
| 2695 LoadDecodableImmediate(IP, value, cond); | 2676 LoadDecodableImmediate(IP, value, cond); |
| 2696 adds(rd, rn, ShifterOperand(IP), cond); | 2677 adds(rd, rn, Operand(IP), cond); |
| 2697 } | 2678 } |
| 2698 } | 2679 } |
| 2699 } | 2680 } |
| 2700 | 2681 |
| 2701 | 2682 |
| 2702 void Assembler::SubImmediateSetFlags(Register rd, Register rn, int32_t value, | 2683 void Assembler::SubImmediateSetFlags(Register rd, Register rn, int32_t value, |
| 2703 Condition cond) { | 2684 Condition cond) { |
| 2704 ShifterOperand shifter_op; | 2685 Operand o; |
| 2705 if (ShifterOperand::CanHold(value, &shifter_op)) { | 2686 if (Operand::CanHold(value, &o)) { |
| 2706 // Handles value == kMinInt32. | 2687 // Handles value == kMinInt32. |
| 2707 subs(rd, rn, shifter_op, cond); | 2688 subs(rd, rn, o, cond); |
| 2708 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { | 2689 } else if (Operand::CanHold(-value, &o)) { |
| 2709 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. | 2690 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. |
| 2710 adds(rd, rn, shifter_op, cond); | 2691 adds(rd, rn, o, cond); |
| 2711 } else { | 2692 } else { |
| 2712 ASSERT(rn != IP); | 2693 ASSERT(rn != IP); |
| 2713 if (ShifterOperand::CanHold(~value, &shifter_op)) { | 2694 if (Operand::CanHold(~value, &o)) { |
| 2714 mvn(IP, shifter_op, cond); | 2695 mvn(IP, o, cond); |
| 2715 subs(rd, rn, ShifterOperand(IP), cond); | 2696 subs(rd, rn, Operand(IP), cond); |
| 2716 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { | 2697 } else if (Operand::CanHold(~(-value), &o)) { |
| 2717 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. | 2698 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. |
| 2718 mvn(IP, shifter_op, cond); | 2699 mvn(IP, o, cond); |
| 2719 adds(rd, rn, ShifterOperand(IP), cond); | 2700 adds(rd, rn, Operand(IP), cond); |
| 2720 } else { | 2701 } else { |
| 2721 LoadDecodableImmediate(IP, value, cond); | 2702 LoadDecodableImmediate(IP, value, cond); |
| 2722 subs(rd, rn, ShifterOperand(IP), cond); | 2703 subs(rd, rn, Operand(IP), cond); |
| 2723 } | 2704 } |
| 2724 } | 2705 } |
| 2725 } | 2706 } |
| 2726 | 2707 |
| 2727 | 2708 |
| 2728 void Assembler::AndImmediate(Register rd, Register rs, int32_t imm, | 2709 void Assembler::AndImmediate(Register rd, Register rs, int32_t imm, |
| 2729 Condition cond) { | 2710 Condition cond) { |
| 2730 ShifterOperand op; | 2711 Operand o; |
| 2731 if (ShifterOperand::CanHold(imm, &op)) { | 2712 if (Operand::CanHold(imm, &o)) { |
| 2732 and_(rd, rs, ShifterOperand(op), cond); | 2713 and_(rd, rs, Operand(o), cond); |
| 2733 } else { | 2714 } else { |
| 2734 LoadImmediate(TMP, imm, cond); | 2715 LoadImmediate(TMP, imm, cond); |
| 2735 and_(rd, rs, ShifterOperand(TMP), cond); | 2716 and_(rd, rs, Operand(TMP), cond); |
| 2736 } | 2717 } |
| 2737 } | 2718 } |
| 2738 | 2719 |
| 2739 | 2720 |
| 2740 void Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) { | 2721 void Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) { |
| 2741 ShifterOperand shifter_op; | 2722 Operand o; |
| 2742 if (ShifterOperand::CanHold(value, &shifter_op)) { | 2723 if (Operand::CanHold(value, &o)) { |
| 2743 cmp(rn, shifter_op, cond); | 2724 cmp(rn, o, cond); |
| 2744 } else { | 2725 } else { |
| 2745 ASSERT(rn != IP); | 2726 ASSERT(rn != IP); |
| 2746 LoadImmediate(IP, value, cond); | 2727 LoadImmediate(IP, value, cond); |
| 2747 cmp(rn, ShifterOperand(IP), cond); | 2728 cmp(rn, Operand(IP), cond); |
| 2748 } | 2729 } |
| 2749 } | 2730 } |
| 2750 | 2731 |
| 2751 | 2732 |
| 2752 void Assembler::TestImmediate(Register rn, int32_t imm, Condition cond) { | 2733 void Assembler::TestImmediate(Register rn, int32_t imm, Condition cond) { |
| 2753 ShifterOperand shifter_op; | 2734 Operand o; |
| 2754 if (ShifterOperand::CanHold(imm, &shifter_op)) { | 2735 if (Operand::CanHold(imm, &o)) { |
| 2755 tst(rn, shifter_op, cond); | 2736 tst(rn, o, cond); |
| 2756 } else { | 2737 } else { |
| 2757 LoadImmediate(IP, imm); | 2738 LoadImmediate(IP, imm); |
| 2758 tst(rn, ShifterOperand(IP), cond); | 2739 tst(rn, Operand(IP), cond); |
| 2759 } | 2740 } |
| 2760 } | 2741 } |
| 2761 | 2742 |
| 2762 void Assembler::IntegerDivide(Register result, Register left, Register right, | 2743 void Assembler::IntegerDivide(Register result, Register left, Register right, |
| 2763 DRegister tmpl, DRegister tmpr) { | 2744 DRegister tmpl, DRegister tmpr) { |
| 2764 ASSERT(tmpl != tmpr); | 2745 ASSERT(tmpl != tmpr); |
| 2765 if (TargetCPUFeatures::integer_division_supported()) { | 2746 if (TargetCPUFeatures::integer_division_supported()) { |
| 2766 sdiv(result, left, right); | 2747 sdiv(result, left, right); |
| 2767 } else { | 2748 } else { |
| 2768 SRegister stmpl = static_cast<SRegister>(2 * tmpl); | 2749 SRegister stmpl = static_cast<SRegister>(2 * tmpl); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2790 CompareImmediate(left, 0); | 2771 CompareImmediate(left, 0); |
| 2791 b(&left_neg, LT); | 2772 b(&left_neg, LT); |
| 2792 b(&done, EQ); | 2773 b(&done, EQ); |
| 2793 CompareImmediate(right, 0); | 2774 CompareImmediate(right, 0); |
| 2794 b(&left_pos_right_neg, LT); | 2775 b(&left_pos_right_neg, LT); |
| 2795 b(&done, EQ); | 2776 b(&done, EQ); |
| 2796 | 2777 |
| 2797 // Both positive. | 2778 // Both positive. |
| 2798 LoadImmediate(tmp, INT_MAX); | 2779 LoadImmediate(tmp, INT_MAX); |
| 2799 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); | 2780 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); |
| 2800 cmp(tmp, ShifterOperand(right)); | 2781 cmp(tmp, Operand(right)); |
| 2801 b(overflow, LT); | 2782 b(overflow, LT); |
| 2802 b(&done); | 2783 b(&done); |
| 2803 | 2784 |
| 2804 // left positive, right non-positive. | 2785 // left positive, right non-positive. |
| 2805 Bind(&left_pos_right_neg); | 2786 Bind(&left_pos_right_neg); |
| 2806 LoadImmediate(tmp, INT_MIN); | 2787 LoadImmediate(tmp, INT_MIN); |
| 2807 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); | 2788 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); |
| 2808 cmp(tmp, ShifterOperand(right)); | 2789 cmp(tmp, Operand(right)); |
| 2809 b(overflow, GT); | 2790 b(overflow, GT); |
| 2810 b(&done); | 2791 b(&done); |
| 2811 | 2792 |
| 2812 Bind(&left_neg); | 2793 Bind(&left_neg); |
| 2813 CompareImmediate(right, 0); | 2794 CompareImmediate(right, 0); |
| 2814 b(&left_neg_right_pos, GT); | 2795 b(&left_neg_right_pos, GT); |
| 2815 b(&done, EQ); | 2796 b(&done, EQ); |
| 2816 | 2797 |
| 2817 // both negative. | 2798 // both negative. |
| 2818 LoadImmediate(tmp, INT_MAX); | 2799 LoadImmediate(tmp, INT_MAX); |
| 2819 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); | 2800 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); |
| 2820 cmp(tmp, ShifterOperand(right)); | 2801 cmp(tmp, Operand(right)); |
| 2821 b(overflow, GT); | 2802 b(overflow, GT); |
| 2822 b(&done); | 2803 b(&done); |
| 2823 | 2804 |
| 2824 // left non-positive, right positive. | 2805 // left non-positive, right positive. |
| 2825 Bind(&left_neg_right_pos); | 2806 Bind(&left_neg_right_pos); |
| 2826 LoadImmediate(tmp, INT_MIN); | 2807 LoadImmediate(tmp, INT_MIN); |
| 2827 IntegerDivide(tmp, tmp, right, dtmp0, dtmp1); | 2808 IntegerDivide(tmp, tmp, right, dtmp0, dtmp1); |
| 2828 cmp(tmp, ShifterOperand(left)); | 2809 cmp(tmp, Operand(left)); |
| 2829 b(overflow, GT); | 2810 b(overflow, GT); |
| 2830 | 2811 |
| 2831 Bind(&done); | 2812 Bind(&done); |
| 2832 } | 2813 } |
| 2833 | 2814 |
| 2834 | 2815 |
| 2835 static int NumRegsBelowFP(RegList regs) { | 2816 static int NumRegsBelowFP(RegList regs) { |
| 2836 int count = 0; | 2817 int count = 0; |
| 2837 for (int i = 0; i < FP; i++) { | 2818 for (int i = 0; i < FP; i++) { |
| 2838 if ((regs & (1 << i)) != 0) { | 2819 if ((regs & (1 << i)) != 0) { |
| 2839 count++; | 2820 count++; |
| 2840 } | 2821 } |
| 2841 } | 2822 } |
| 2842 return count; | 2823 return count; |
| 2843 } | 2824 } |
| 2844 | 2825 |
| 2845 | 2826 |
| 2846 void Assembler::EnterFrame(RegList regs, intptr_t frame_size) { | 2827 void Assembler::EnterFrame(RegList regs, intptr_t frame_size) { |
| 2847 if (prologue_offset_ == -1) { | 2828 if (prologue_offset_ == -1) { |
| 2848 prologue_offset_ = CodeSize(); | 2829 prologue_offset_ = CodeSize(); |
| 2849 } | 2830 } |
| 2850 PushList(regs); | 2831 PushList(regs); |
| 2851 if ((regs & (1 << FP)) != 0) { | 2832 if ((regs & (1 << FP)) != 0) { |
| 2852 // Set FP to the saved previous FP. | 2833 // Set FP to the saved previous FP. |
| 2853 add(FP, SP, ShifterOperand(4 * NumRegsBelowFP(regs))); | 2834 add(FP, SP, Operand(4 * NumRegsBelowFP(regs))); |
| 2854 } | 2835 } |
| 2855 AddImmediate(SP, -frame_size); | 2836 AddImmediate(SP, -frame_size); |
| 2856 } | 2837 } |
| 2857 | 2838 |
| 2858 | 2839 |
| 2859 void Assembler::LeaveFrame(RegList regs) { | 2840 void Assembler::LeaveFrame(RegList regs) { |
| 2860 ASSERT((regs & (1 << PC)) == 0); // Must not pop PC. | 2841 ASSERT((regs & (1 << PC)) == 0); // Must not pop PC. |
| 2861 if ((regs & (1 << FP)) != 0) { | 2842 if ((regs & (1 << FP)) != 0) { |
| 2862 // Use FP to set SP. | 2843 // Use FP to set SP. |
| 2863 sub(SP, FP, ShifterOperand(4 * NumRegsBelowFP(regs))); | 2844 sub(SP, FP, Operand(4 * NumRegsBelowFP(regs))); |
| 2864 } | 2845 } |
| 2865 PopList(regs); | 2846 PopList(regs); |
| 2866 } | 2847 } |
| 2867 | 2848 |
| 2868 | 2849 |
| 2869 void Assembler::Ret() { | 2850 void Assembler::Ret() { |
| 2870 bx(LR); | 2851 bx(LR); |
| 2871 } | 2852 } |
| 2872 | 2853 |
| 2873 | 2854 |
| 2874 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { | 2855 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { |
| 2875 // Reserve space for arguments and align frame before entering | 2856 // Reserve space for arguments and align frame before entering |
| 2876 // the C++ world. | 2857 // the C++ world. |
| 2877 AddImmediate(SP, -frame_space); | 2858 AddImmediate(SP, -frame_space); |
| 2878 if (OS::ActivationFrameAlignment() > 1) { | 2859 if (OS::ActivationFrameAlignment() > 1) { |
| 2879 bic(SP, SP, ShifterOperand(OS::ActivationFrameAlignment() - 1)); | 2860 bic(SP, SP, Operand(OS::ActivationFrameAlignment() - 1)); |
| 2880 } | 2861 } |
| 2881 } | 2862 } |
| 2882 | 2863 |
| 2883 | 2864 |
| 2884 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { | 2865 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { |
| 2885 // Preserve volatile CPU registers. | 2866 // Preserve volatile CPU registers. |
| 2886 EnterFrame(kDartVolatileCpuRegs | (1 << FP) | (1 << LR), 0); | 2867 EnterFrame(kDartVolatileCpuRegs | (1 << FP) | (1 << LR), 0); |
| 2887 | 2868 |
| 2888 // Preserve all volatile FPU registers. | 2869 // Preserve all volatile FPU registers. |
| 2889 if (TargetCPUFeatures::vfp_supported()) { | 2870 if (TargetCPUFeatures::vfp_supported()) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2963 | 2944 |
| 2964 // On entry to a function compiled for OSR, the caller's frame pointer, the | 2945 // On entry to a function compiled for OSR, the caller's frame pointer, the |
| 2965 // stack locals, and any copied parameters are already in place. The frame | 2946 // stack locals, and any copied parameters are already in place. The frame |
| 2966 // pointer is already set up. The PC marker is not correct for the | 2947 // pointer is already set up. The PC marker is not correct for the |
| 2967 // optimized function and there may be extra space for spill slots to | 2948 // optimized function and there may be extra space for spill slots to |
| 2968 // allocate. We must also set up the pool pointer for the function. | 2949 // allocate. We must also set up the pool pointer for the function. |
| 2969 void Assembler::EnterOsrFrame(intptr_t extra_size) { | 2950 void Assembler::EnterOsrFrame(intptr_t extra_size) { |
| 2970 const intptr_t offset = CodeSize(); | 2951 const intptr_t offset = CodeSize(); |
| 2971 | 2952 |
| 2972 Comment("EnterOsrFrame"); | 2953 Comment("EnterOsrFrame"); |
| 2973 mov(IP, ShifterOperand(PC)); | 2954 mov(IP, Operand(PC)); |
| 2974 | 2955 |
| 2975 AddImmediate(IP, -offset); | 2956 AddImmediate(IP, -offset); |
| 2976 str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize)); | 2957 str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize)); |
| 2977 | 2958 |
| 2978 // Setup pool pointer for this dart function. | 2959 // Setup pool pointer for this dart function. |
| 2979 LoadPoolPointer(); | 2960 LoadPoolPointer(); |
| 2980 | 2961 |
| 2981 AddImmediate(SP, -extra_size); | 2962 AddImmediate(SP, -extra_size); |
| 2982 } | 2963 } |
| 2983 | 2964 |
| 2984 | 2965 |
| 2985 void Assembler::LeaveDartFrame() { | 2966 void Assembler::LeaveDartFrame() { |
| 2986 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); | 2967 LeaveFrame((1 << PP) | (1 << FP) | (1 << LR)); |
| 2987 // Adjust SP for PC pushed in EnterDartFrame. | 2968 // Adjust SP for PC pushed in EnterDartFrame. |
| 2988 AddImmediate(SP, kWordSize); | 2969 AddImmediate(SP, kWordSize); |
| 2989 } | 2970 } |
| 2990 | 2971 |
| 2991 | 2972 |
| 2992 void Assembler::EnterStubFrame(bool load_pp) { | 2973 void Assembler::EnterStubFrame(bool load_pp) { |
| 2993 // Push 0 as saved PC for stub frames. | 2974 // Push 0 as saved PC for stub frames. |
| 2994 mov(IP, ShifterOperand(LR)); | 2975 mov(IP, Operand(LR)); |
| 2995 mov(LR, ShifterOperand(0)); | 2976 mov(LR, Operand(0)); |
| 2996 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR); | 2977 RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR); |
| 2997 EnterFrame(regs, 0); | 2978 EnterFrame(regs, 0); |
| 2998 if (load_pp) { | 2979 if (load_pp) { |
| 2999 // Setup pool pointer for this stub. | 2980 // Setup pool pointer for this stub. |
| 3000 LoadPoolPointer(); | 2981 LoadPoolPointer(); |
| 3001 } | 2982 } |
| 3002 } | 2983 } |
| 3003 | 2984 |
| 3004 | 2985 |
| 3005 void Assembler::LeaveStubFrame() { | 2986 void Assembler::LeaveStubFrame() { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3064 const uword size_field_offset = (space == Heap::kNew) ? | 3045 const uword size_field_offset = (space == Heap::kNew) ? |
| 3065 ClassHeapStats::allocated_size_since_gc_new_space_offset() : | 3046 ClassHeapStats::allocated_size_since_gc_new_space_offset() : |
| 3066 ClassHeapStats::allocated_size_since_gc_old_space_offset(); | 3047 ClassHeapStats::allocated_size_since_gc_old_space_offset(); |
| 3067 LoadImmediate(temp_reg, class_heap_stats_table_address + class_offset); | 3048 LoadImmediate(temp_reg, class_heap_stats_table_address + class_offset); |
| 3068 const Address& count_address = Address(temp_reg, count_field_offset); | 3049 const Address& count_address = Address(temp_reg, count_field_offset); |
| 3069 const Address& size_address = Address(temp_reg, size_field_offset); | 3050 const Address& size_address = Address(temp_reg, size_field_offset); |
| 3070 ldr(TMP, count_address); | 3051 ldr(TMP, count_address); |
| 3071 AddImmediate(TMP, 1); | 3052 AddImmediate(TMP, 1); |
| 3072 str(TMP, count_address); | 3053 str(TMP, count_address); |
| 3073 ldr(TMP, size_address); | 3054 ldr(TMP, size_address); |
| 3074 add(TMP, TMP, ShifterOperand(size_reg)); | 3055 add(TMP, TMP, Operand(size_reg)); |
| 3075 str(TMP, size_address); | 3056 str(TMP, size_address); |
| 3076 } else { | 3057 } else { |
| 3077 ASSERT(temp_reg != kNoRegister); | 3058 ASSERT(temp_reg != kNoRegister); |
| 3078 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 3059 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| 3079 const uword count_field_offset = (space == Heap::kNew) ? | 3060 const uword count_field_offset = (space == Heap::kNew) ? |
| 3080 ClassHeapStats::allocated_since_gc_new_space_offset() : | 3061 ClassHeapStats::allocated_since_gc_new_space_offset() : |
| 3081 ClassHeapStats::allocated_since_gc_old_space_offset(); | 3062 ClassHeapStats::allocated_since_gc_old_space_offset(); |
| 3082 const uword size_field_offset = (space == Heap::kNew) ? | 3063 const uword size_field_offset = (space == Heap::kNew) ? |
| 3083 ClassHeapStats::allocated_size_since_gc_new_space_offset() : | 3064 ClassHeapStats::allocated_size_since_gc_new_space_offset() : |
| 3084 ClassHeapStats::allocated_size_since_gc_old_space_offset(); | 3065 ClassHeapStats::allocated_size_since_gc_old_space_offset(); |
| 3085 LoadImmediate(temp_reg, class_table->ClassStatsTableAddress()); | 3066 LoadImmediate(temp_reg, class_table->ClassStatsTableAddress()); |
| 3086 ldr(temp_reg, Address(temp_reg, 0)); | 3067 ldr(temp_reg, Address(temp_reg, 0)); |
| 3087 AddImmediate(temp_reg, class_offset); | 3068 AddImmediate(temp_reg, class_offset); |
| 3088 ldr(TMP, Address(temp_reg, count_field_offset)); | 3069 ldr(TMP, Address(temp_reg, count_field_offset)); |
| 3089 AddImmediate(TMP, 1); | 3070 AddImmediate(TMP, 1); |
| 3090 str(TMP, Address(temp_reg, count_field_offset)); | 3071 str(TMP, Address(temp_reg, count_field_offset)); |
| 3091 ldr(TMP, Address(temp_reg, size_field_offset)); | 3072 ldr(TMP, Address(temp_reg, size_field_offset)); |
| 3092 add(TMP, TMP, ShifterOperand(size_reg)); | 3073 add(TMP, TMP, Operand(size_reg)); |
| 3093 str(TMP, Address(temp_reg, size_field_offset)); | 3074 str(TMP, Address(temp_reg, size_field_offset)); |
| 3094 } | 3075 } |
| 3095 } | 3076 } |
| 3096 | 3077 |
| 3097 | 3078 |
| 3098 void Assembler::TryAllocate(const Class& cls, | 3079 void Assembler::TryAllocate(const Class& cls, |
| 3099 Label* failure, | 3080 Label* failure, |
| 3100 Register instance_reg, | 3081 Register instance_reg, |
| 3101 Register temp_reg) { | 3082 Register temp_reg) { |
| 3102 ASSERT(failure != NULL); | 3083 ASSERT(failure != NULL); |
| 3103 if (FLAG_inline_alloc) { | 3084 if (FLAG_inline_alloc) { |
| 3104 Heap* heap = Isolate::Current()->heap(); | 3085 Heap* heap = Isolate::Current()->heap(); |
| 3105 const intptr_t instance_size = cls.instance_size(); | 3086 const intptr_t instance_size = cls.instance_size(); |
| 3106 LoadImmediate(instance_reg, heap->TopAddress()); | 3087 LoadImmediate(instance_reg, heap->TopAddress()); |
| 3107 ldr(instance_reg, Address(instance_reg, 0)); | 3088 ldr(instance_reg, Address(instance_reg, 0)); |
| 3108 AddImmediate(instance_reg, instance_size); | 3089 AddImmediate(instance_reg, instance_size); |
| 3109 | 3090 |
| 3110 // instance_reg: potential next object start. | 3091 // instance_reg: potential next object start. |
| 3111 LoadImmediate(IP, heap->EndAddress()); | 3092 LoadImmediate(IP, heap->EndAddress()); |
| 3112 ldr(IP, Address(IP, 0)); | 3093 ldr(IP, Address(IP, 0)); |
| 3113 cmp(IP, ShifterOperand(instance_reg)); | 3094 cmp(IP, Operand(instance_reg)); |
| 3114 // fail if heap end unsigned less than or equal to instance_reg. | 3095 // fail if heap end unsigned less than or equal to instance_reg. |
| 3115 b(failure, LS); | 3096 b(failure, LS); |
| 3116 | 3097 |
| 3117 // Successfully allocated the object, now update top to point to | 3098 // Successfully allocated the object, now update top to point to |
| 3118 // next object start and store the class in the class field of object. | 3099 // next object start and store the class in the class field of object. |
| 3119 LoadImmediate(IP, heap->TopAddress()); | 3100 LoadImmediate(IP, heap->TopAddress()); |
| 3120 str(instance_reg, Address(IP, 0)); | 3101 str(instance_reg, Address(IP, 0)); |
| 3121 | 3102 |
| 3122 ASSERT(instance_size >= kHeapObjectTag); | 3103 ASSERT(instance_size >= kHeapObjectTag); |
| 3123 AddImmediate(instance_reg, -instance_size + kHeapObjectTag); | 3104 AddImmediate(instance_reg, -instance_size + kHeapObjectTag); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3210 | 3191 |
| 3211 | 3192 |
| 3212 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3193 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3213 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3194 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 3214 return fpu_reg_names[reg]; | 3195 return fpu_reg_names[reg]; |
| 3215 } | 3196 } |
| 3216 | 3197 |
| 3217 } // namespace dart | 3198 } // namespace dart |
| 3218 | 3199 |
| 3219 #endif // defined TARGET_ARCH_ARM | 3200 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |