assembler_arm32.cc revision 19a19cffd197a28ae4c9c3e59eff6352fd392241
1/* 2 * Copyright (C) 2014 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 17#include "assembler_arm32.h" 18 19#include "base/logging.h" 20#include "entrypoints/quick/quick_entrypoints.h" 21#include "offsets.h" 22#include "thread.h" 23#include "utils.h" 24 25namespace art { 26namespace arm { 27 28void Arm32Assembler::and_(Register rd, Register rn, const ShifterOperand& so, 29 Condition cond) { 30 EmitType01(cond, so.type(), AND, 0, rn, rd, so); 31} 32 33 34void Arm32Assembler::eor(Register rd, Register rn, const ShifterOperand& so, 35 Condition cond) { 36 EmitType01(cond, so.type(), EOR, 0, rn, rd, so); 37} 38 39 40void Arm32Assembler::sub(Register rd, Register rn, const ShifterOperand& so, 41 Condition cond) { 42 EmitType01(cond, so.type(), SUB, 0, rn, rd, so); 43} 44 45void Arm32Assembler::rsb(Register rd, Register rn, const ShifterOperand& so, 46 Condition cond) { 47 EmitType01(cond, so.type(), RSB, 0, rn, rd, so); 48} 49 50void Arm32Assembler::rsbs(Register rd, Register rn, const ShifterOperand& so, 51 Condition cond) { 52 EmitType01(cond, so.type(), RSB, 1, rn, rd, so); 53} 54 55 56void Arm32Assembler::add(Register rd, Register rn, const ShifterOperand& so, 57 Condition cond) { 58 EmitType01(cond, so.type(), ADD, 0, rn, rd, so); 59} 60 61 62void Arm32Assembler::adds(Register rd, Register rn, const ShifterOperand& so, 63 Condition cond) { 64 EmitType01(cond, so.type(), ADD, 1, rn, rd, so); 65} 66 67 68void Arm32Assembler::subs(Register rd, Register rn, const ShifterOperand& so, 69 Condition cond) { 70 EmitType01(cond, so.type(), SUB, 1, rn, rd, so); 71} 72 73 74void Arm32Assembler::adc(Register rd, Register rn, const ShifterOperand& so, 75 Condition cond) { 76 EmitType01(cond, so.type(), ADC, 0, rn, rd, so); 77} 78 79 80void Arm32Assembler::sbc(Register rd, Register rn, const ShifterOperand& so, 81 Condition cond) { 82 EmitType01(cond, so.type(), SBC, 0, rn, rd, so); 83} 84 85 86void Arm32Assembler::rsc(Register rd, Register rn, const ShifterOperand& so, 87 Condition cond) { 88 EmitType01(cond, so.type(), RSC, 0, rn, rd, so); 89} 90 91 92void Arm32Assembler::tst(Register rn, const ShifterOperand& so, Condition cond) { 93 CHECK_NE(rn, PC); // Reserve tst pc instruction for exception handler marker. 94 EmitType01(cond, so.type(), TST, 1, rn, R0, so); 95} 96 97 98void Arm32Assembler::teq(Register rn, const ShifterOperand& so, Condition cond) { 99 CHECK_NE(rn, PC); // Reserve teq pc instruction for exception handler marker. 100 EmitType01(cond, so.type(), TEQ, 1, rn, R0, so); 101} 102 103 104void Arm32Assembler::cmp(Register rn, const ShifterOperand& so, Condition cond) { 105 EmitType01(cond, so.type(), CMP, 1, rn, R0, so); 106} 107 108 109void Arm32Assembler::cmn(Register rn, const ShifterOperand& so, Condition cond) { 110 EmitType01(cond, so.type(), CMN, 1, rn, R0, so); 111} 112 113 114void Arm32Assembler::orr(Register rd, Register rn, 115 const ShifterOperand& so, Condition cond) { 116 EmitType01(cond, so.type(), ORR, 0, rn, rd, so); 117} 118 119 120void Arm32Assembler::orrs(Register rd, Register rn, 121 const ShifterOperand& so, Condition cond) { 122 EmitType01(cond, so.type(), ORR, 1, rn, rd, so); 123} 124 125 126void Arm32Assembler::mov(Register rd, const ShifterOperand& so, Condition cond) { 127 EmitType01(cond, so.type(), MOV, 0, R0, rd, so); 128} 129 130 131void Arm32Assembler::movs(Register rd, const ShifterOperand& so, Condition cond) { 132 EmitType01(cond, so.type(), MOV, 1, R0, rd, so); 133} 134 135 136void Arm32Assembler::bic(Register rd, Register rn, const ShifterOperand& so, 137 Condition cond) { 138 EmitType01(cond, so.type(), BIC, 0, rn, rd, so); 139} 140 141 142void Arm32Assembler::mvn(Register rd, const ShifterOperand& so, Condition cond) { 143 EmitType01(cond, so.type(), MVN, 0, R0, rd, so); 144} 145 146 147void Arm32Assembler::mvns(Register rd, const ShifterOperand& so, Condition cond) { 148 EmitType01(cond, so.type(), MVN, 1, R0, rd, so); 149} 150 151 152void Arm32Assembler::mul(Register rd, Register rn, Register rm, Condition cond) { 153 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 154 EmitMulOp(cond, 0, R0, rd, rn, rm); 155} 156 157 158void Arm32Assembler::mla(Register rd, Register rn, Register rm, Register ra, 159 Condition cond) { 160 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 161 EmitMulOp(cond, B21, ra, rd, rn, rm); 162} 163 164 165void Arm32Assembler::mls(Register rd, Register rn, Register rm, Register ra, 166 Condition cond) { 167 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 168 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); 169} 170 171 172void Arm32Assembler::umull(Register rd_lo, Register rd_hi, Register rn, 173 Register rm, Condition cond) { 174 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 175 EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); 176} 177 178 179void Arm32Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) { 180 CHECK_NE(rd, kNoRegister); 181 CHECK_NE(rn, kNoRegister); 182 CHECK_NE(rm, kNoRegister); 183 CHECK_NE(cond, kNoCondition); 184 int32_t encoding = B26 | B25 | B24 | B20 | 185 B15 | B14 | B13 | B12 | 186 (static_cast<int32_t>(cond) << kConditionShift) | 187 (static_cast<int32_t>(rn) << 0) | 188 (static_cast<int32_t>(rd) << 16) | 189 (static_cast<int32_t>(rm) << 8) | 190 B4; 191 Emit(encoding); 192} 193 194 195void Arm32Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) { 196 CHECK_NE(rd, kNoRegister); 197 CHECK_NE(rn, kNoRegister); 198 CHECK_NE(rm, kNoRegister); 199 CHECK_NE(cond, kNoCondition); 200 int32_t encoding = B26 | B25 | B24 | B21 | B20 | 201 B15 | B14 | B13 | B12 | 202 (static_cast<int32_t>(cond) << kConditionShift) | 203 (static_cast<int32_t>(rn) << 0) | 204 (static_cast<int32_t>(rd) << 16) | 205 (static_cast<int32_t>(rm) << 8) | 206 B4; 207 Emit(encoding); 208} 209 210 211void Arm32Assembler::ldr(Register rd, const Address& ad, Condition cond) { 212 EmitMemOp(cond, true, false, rd, ad); 213} 214 215 216void Arm32Assembler::str(Register rd, const Address& ad, Condition cond) { 217 EmitMemOp(cond, false, false, rd, ad); 218} 219 220 221void Arm32Assembler::ldrb(Register rd, const Address& ad, Condition cond) { 222 EmitMemOp(cond, true, true, rd, ad); 223} 224 225 226void Arm32Assembler::strb(Register rd, const Address& ad, Condition cond) { 227 EmitMemOp(cond, false, true, rd, ad); 228} 229 230 231void Arm32Assembler::ldrh(Register rd, const Address& ad, Condition cond) { 232 EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad); 233} 234 235 236void Arm32Assembler::strh(Register rd, const Address& ad, Condition cond) { 237 EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad); 238} 239 240 241void Arm32Assembler::ldrsb(Register rd, const Address& ad, Condition cond) { 242 EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad); 243} 244 245 246void Arm32Assembler::ldrsh(Register rd, const Address& ad, Condition cond) { 247 EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad); 248} 249 250 251void Arm32Assembler::ldrd(Register rd, const Address& ad, Condition cond) { 252 CHECK_EQ(rd % 2, 0); 253 EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad); 254} 255 256 257void Arm32Assembler::strd(Register rd, const Address& ad, Condition cond) { 258 CHECK_EQ(rd % 2, 0); 259 EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad); 260} 261 262 263void Arm32Assembler::ldm(BlockAddressMode am, 264 Register base, 265 RegList regs, 266 Condition cond) { 267 EmitMultiMemOp(cond, am, true, base, regs); 268} 269 270 271void Arm32Assembler::stm(BlockAddressMode am, 272 Register base, 273 RegList regs, 274 Condition cond) { 275 EmitMultiMemOp(cond, am, false, base, regs); 276} 277 278 279void Arm32Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) { 280 EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm); 281} 282 283 284void Arm32Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) { 285 EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm); 286} 287 288 289bool Arm32Assembler::vmovs(SRegister sd, float s_imm, Condition cond) { 290 uint32_t imm32 = bit_cast<uint32_t, float>(s_imm); 291 if (((imm32 & ((1 << 19) - 1)) == 0) && 292 ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) || 293 (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) { 294 uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) | 295 ((imm32 >> 19) & ((1 << 6) -1)); 296 EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf), 297 sd, S0, S0); 298 return true; 299 } 300 return false; 301} 302 303 304bool Arm32Assembler::vmovd(DRegister dd, double d_imm, Condition cond) { 305 uint64_t imm64 = bit_cast<uint64_t, double>(d_imm); 306 if (((imm64 & ((1LL << 48) - 1)) == 0) && 307 ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) || 308 (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) { 309 uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) | 310 ((imm64 >> 48) & ((1 << 6) -1)); 311 EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf), 312 dd, D0, D0); 313 return true; 314 } 315 return false; 316} 317 318 319void Arm32Assembler::vadds(SRegister sd, SRegister sn, SRegister sm, 320 Condition cond) { 321 EmitVFPsss(cond, B21 | B20, sd, sn, sm); 322} 323 324 325void Arm32Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm, 326 Condition cond) { 327 EmitVFPddd(cond, B21 | B20, dd, dn, dm); 328} 329 330 331void Arm32Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm, 332 Condition cond) { 333 EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm); 334} 335 336 337void Arm32Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm, 338 Condition cond) { 339 EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm); 340} 341 342 343void Arm32Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm, 344 Condition cond) { 345 EmitVFPsss(cond, B21, sd, sn, sm); 346} 347 348 349void Arm32Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm, 350 Condition cond) { 351 EmitVFPddd(cond, B21, dd, dn, dm); 352} 353 354 355void Arm32Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm, 356 Condition cond) { 357 EmitVFPsss(cond, 0, sd, sn, sm); 358} 359 360 361void Arm32Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm, 362 Condition cond) { 363 EmitVFPddd(cond, 0, dd, dn, dm); 364} 365 366 367void Arm32Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm, 368 Condition cond) { 369 EmitVFPsss(cond, B6, sd, sn, sm); 370} 371 372 373void Arm32Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm, 374 Condition cond) { 375 EmitVFPddd(cond, B6, dd, dn, dm); 376} 377 378 379void Arm32Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm, 380 Condition cond) { 381 EmitVFPsss(cond, B23, sd, sn, sm); 382} 383 384 385void Arm32Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm, 386 Condition cond) { 387 EmitVFPddd(cond, B23, dd, dn, dm); 388} 389 390 391void Arm32Assembler::vabss(SRegister sd, SRegister sm, Condition cond) { 392 EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm); 393} 394 395 396void Arm32Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) { 397 EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm); 398} 399 400 401void Arm32Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) { 402 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm); 403} 404 405 406void Arm32Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) { 407 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm); 408} 409 410 411void Arm32Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) { 412 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm); 413} 414 415void Arm32Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) { 416 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm); 417} 418 419 420void Arm32Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) { 421 EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm); 422} 423 424 425void Arm32Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) { 426 EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm); 427} 428 429 430void Arm32Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) { 431 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm); 432} 433 434 435void Arm32Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) { 436 EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm); 437} 438 439 440void Arm32Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) { 441 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm); 442} 443 444 445void Arm32Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) { 446 EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm); 447} 448 449 450void Arm32Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) { 451 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm); 452} 453 454 455void Arm32Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) { 456 EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm); 457} 458 459 460void Arm32Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) { 461 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm); 462} 463 464 465void Arm32Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) { 466 EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm); 467} 468 469 470void Arm32Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) { 471 EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm); 472} 473 474 475void Arm32Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) { 476 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm); 477} 478 479 480void Arm32Assembler::vcmpsz(SRegister sd, Condition cond) { 481 EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0); 482} 483 484 485void Arm32Assembler::vcmpdz(DRegister dd, Condition cond) { 486 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0); 487} 488 489void Arm32Assembler::b(Label* label, Condition cond) { 490 EmitBranch(cond, label, false); 491} 492 493 494void Arm32Assembler::bl(Label* label, Condition cond) { 495 EmitBranch(cond, label, true); 496} 497 498 499void Arm32Assembler::MarkExceptionHandler(Label* label) { 500 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); 501 Label l; 502 b(&l); 503 EmitBranch(AL, label, false); 504 Bind(&l); 505} 506 507 508void Arm32Assembler::Emit(int32_t value) { 509 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 510 buffer_.Emit<int32_t>(value); 511} 512 513 514void Arm32Assembler::EmitType01(Condition cond, 515 int type, 516 Opcode opcode, 517 int set_cc, 518 Register rn, 519 Register rd, 520 const ShifterOperand& so) { 521 CHECK_NE(rd, kNoRegister); 522 CHECK_NE(cond, kNoCondition); 523 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 524 type << kTypeShift | 525 static_cast<int32_t>(opcode) << kOpcodeShift | 526 set_cc << kSShift | 527 static_cast<int32_t>(rn) << kRnShift | 528 static_cast<int32_t>(rd) << kRdShift | 529 so.encodingArm(); 530 Emit(encoding); 531} 532 533 534void Arm32Assembler::EmitType5(Condition cond, int offset, bool link) { 535 CHECK_NE(cond, kNoCondition); 536 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 537 5 << kTypeShift | 538 (link ? 1 : 0) << kLinkShift; 539 Emit(Arm32Assembler::EncodeBranchOffset(offset, encoding)); 540} 541 542 543void Arm32Assembler::EmitMemOp(Condition cond, 544 bool load, 545 bool byte, 546 Register rd, 547 const Address& ad) { 548 CHECK_NE(rd, kNoRegister); 549 CHECK_NE(cond, kNoCondition); 550 const Address& addr = static_cast<const Address&>(ad); 551 552 int32_t encoding = 0; 553 if (!ad.IsImmediate() && ad.GetRegisterOffset() == PC) { 554 // PC relative LDR(literal) 555 int32_t offset = ad.GetOffset(); 556 int32_t u = B23; 557 if (offset < 0) { 558 offset = -offset; 559 u = 0; 560 } 561 CHECK_LT(offset, (1 << 12)); 562 encoding = (static_cast<int32_t>(cond) << kConditionShift) | 563 B26 | B24 | u | B20 | 564 (load ? L : 0) | 565 (byte ? B : 0) | 566 (static_cast<int32_t>(rd) << kRdShift) | 567 0xf << 16 | 568 (offset & 0xfff); 569 570 } else { 571 encoding = (static_cast<int32_t>(cond) << kConditionShift) | 572 B26 | 573 (load ? L : 0) | 574 (byte ? B : 0) | 575 (static_cast<int32_t>(rd) << kRdShift) | 576 addr.encodingArm(); 577 } 578 Emit(encoding); 579} 580 581 582void Arm32Assembler::EmitMemOpAddressMode3(Condition cond, 583 int32_t mode, 584 Register rd, 585 const Address& ad) { 586 CHECK_NE(rd, kNoRegister); 587 CHECK_NE(cond, kNoCondition); 588 const Address& addr = static_cast<const Address&>(ad); 589 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 590 B22 | 591 mode | 592 (static_cast<int32_t>(rd) << kRdShift) | 593 addr.encoding3(); 594 Emit(encoding); 595} 596 597 598void Arm32Assembler::EmitMultiMemOp(Condition cond, 599 BlockAddressMode am, 600 bool load, 601 Register base, 602 RegList regs) { 603 CHECK_NE(base, kNoRegister); 604 CHECK_NE(cond, kNoCondition); 605 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 606 B27 | 607 am | 608 (load ? L : 0) | 609 (static_cast<int32_t>(base) << kRnShift) | 610 regs; 611 Emit(encoding); 612} 613 614 615void Arm32Assembler::EmitShiftImmediate(Condition cond, 616 Shift opcode, 617 Register rd, 618 Register rm, 619 const ShifterOperand& so) { 620 CHECK_NE(cond, kNoCondition); 621 CHECK(so.IsImmediate()); 622 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 623 static_cast<int32_t>(MOV) << kOpcodeShift | 624 static_cast<int32_t>(rd) << kRdShift | 625 so.encodingArm() << kShiftImmShift | 626 static_cast<int32_t>(opcode) << kShiftShift | 627 static_cast<int32_t>(rm); 628 Emit(encoding); 629} 630 631 632void Arm32Assembler::EmitShiftRegister(Condition cond, 633 Shift opcode, 634 Register rd, 635 Register rm, 636 const ShifterOperand& so) { 637 CHECK_NE(cond, kNoCondition); 638 CHECK(so.IsRegister()); 639 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 640 static_cast<int32_t>(MOV) << kOpcodeShift | 641 static_cast<int32_t>(rd) << kRdShift | 642 so.encodingArm() << kShiftRegisterShift | 643 static_cast<int32_t>(opcode) << kShiftShift | 644 B4 | 645 static_cast<int32_t>(rm); 646 Emit(encoding); 647} 648 649 650void Arm32Assembler::EmitBranch(Condition cond, Label* label, bool link) { 651 if (label->IsBound()) { 652 EmitType5(cond, label->Position() - buffer_.Size(), link); 653 } else { 654 int position = buffer_.Size(); 655 // Use the offset field of the branch instruction for linking the sites. 656 EmitType5(cond, label->position_, link); 657 label->LinkTo(position); 658 } 659} 660 661 662void Arm32Assembler::clz(Register rd, Register rm, Condition cond) { 663 CHECK_NE(rd, kNoRegister); 664 CHECK_NE(rm, kNoRegister); 665 CHECK_NE(cond, kNoCondition); 666 CHECK_NE(rd, PC); 667 CHECK_NE(rm, PC); 668 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 669 B24 | B22 | B21 | (0xf << 16) | 670 (static_cast<int32_t>(rd) << kRdShift) | 671 (0xf << 8) | B4 | static_cast<int32_t>(rm); 672 Emit(encoding); 673} 674 675 676void Arm32Assembler::movw(Register rd, uint16_t imm16, Condition cond) { 677 CHECK_NE(cond, kNoCondition); 678 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 679 B25 | B24 | ((imm16 >> 12) << 16) | 680 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 681 Emit(encoding); 682} 683 684 685void Arm32Assembler::movt(Register rd, uint16_t imm16, Condition cond) { 686 CHECK_NE(cond, kNoCondition); 687 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 688 B25 | B24 | B22 | ((imm16 >> 12) << 16) | 689 static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 690 Emit(encoding); 691} 692 693 694void Arm32Assembler::EmitMulOp(Condition cond, int32_t opcode, 695 Register rd, Register rn, 696 Register rm, Register rs) { 697 CHECK_NE(rd, kNoRegister); 698 CHECK_NE(rn, kNoRegister); 699 CHECK_NE(rm, kNoRegister); 700 CHECK_NE(rs, kNoRegister); 701 CHECK_NE(cond, kNoCondition); 702 int32_t encoding = opcode | 703 (static_cast<int32_t>(cond) << kConditionShift) | 704 (static_cast<int32_t>(rn) << kRnShift) | 705 (static_cast<int32_t>(rd) << kRdShift) | 706 (static_cast<int32_t>(rs) << kRsShift) | 707 B7 | B4 | 708 (static_cast<int32_t>(rm) << kRmShift); 709 Emit(encoding); 710} 711 712void Arm32Assembler::ldrex(Register rt, Register rn, Condition cond) { 713 CHECK_NE(rn, kNoRegister); 714 CHECK_NE(rt, kNoRegister); 715 CHECK_NE(cond, kNoCondition); 716 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 717 B24 | 718 B23 | 719 L | 720 (static_cast<int32_t>(rn) << kLdExRnShift) | 721 (static_cast<int32_t>(rt) << kLdExRtShift) | 722 B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0; 723 Emit(encoding); 724} 725 726 727void Arm32Assembler::strex(Register rd, 728 Register rt, 729 Register rn, 730 Condition cond) { 731 CHECK_NE(rn, kNoRegister); 732 CHECK_NE(rd, kNoRegister); 733 CHECK_NE(rt, kNoRegister); 734 CHECK_NE(cond, kNoCondition); 735 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 736 B24 | 737 B23 | 738 (static_cast<int32_t>(rn) << kStrExRnShift) | 739 (static_cast<int32_t>(rd) << kStrExRdShift) | 740 B11 | B10 | B9 | B8 | B7 | B4 | 741 (static_cast<int32_t>(rt) << kStrExRtShift); 742 Emit(encoding); 743} 744 745 746void Arm32Assembler::clrex(Condition cond) { 747 CHECK_EQ(cond, AL); // This cannot be conditional on ARM. 748 int32_t encoding = (kSpecialCondition << kConditionShift) | 749 B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf; 750 Emit(encoding); 751} 752 753 754void Arm32Assembler::nop(Condition cond) { 755 CHECK_NE(cond, kNoCondition); 756 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 757 B25 | B24 | B21 | (0xf << 12); 758 Emit(encoding); 759} 760 761 762void Arm32Assembler::vmovsr(SRegister sn, Register rt, Condition cond) { 763 CHECK_NE(sn, kNoSRegister); 764 CHECK_NE(rt, kNoRegister); 765 CHECK_NE(rt, SP); 766 CHECK_NE(rt, PC); 767 CHECK_NE(cond, kNoCondition); 768 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 769 B27 | B26 | B25 | 770 ((static_cast<int32_t>(sn) >> 1)*B16) | 771 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 772 ((static_cast<int32_t>(sn) & 1)*B7) | B4; 773 Emit(encoding); 774} 775 776 777void Arm32Assembler::vmovrs(Register rt, SRegister sn, Condition cond) { 778 CHECK_NE(sn, kNoSRegister); 779 CHECK_NE(rt, kNoRegister); 780 CHECK_NE(rt, SP); 781 CHECK_NE(rt, PC); 782 CHECK_NE(cond, kNoCondition); 783 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 784 B27 | B26 | B25 | B20 | 785 ((static_cast<int32_t>(sn) >> 1)*B16) | 786 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 787 ((static_cast<int32_t>(sn) & 1)*B7) | B4; 788 Emit(encoding); 789} 790 791 792void Arm32Assembler::vmovsrr(SRegister sm, Register rt, Register rt2, 793 Condition cond) { 794 CHECK_NE(sm, kNoSRegister); 795 CHECK_NE(sm, S31); 796 CHECK_NE(rt, kNoRegister); 797 CHECK_NE(rt, SP); 798 CHECK_NE(rt, PC); 799 CHECK_NE(rt2, kNoRegister); 800 CHECK_NE(rt2, SP); 801 CHECK_NE(rt2, PC); 802 CHECK_NE(cond, kNoCondition); 803 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 804 B27 | B26 | B22 | 805 (static_cast<int32_t>(rt2)*B16) | 806 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 807 ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 808 (static_cast<int32_t>(sm) >> 1); 809 Emit(encoding); 810} 811 812 813void Arm32Assembler::vmovrrs(Register rt, Register rt2, SRegister sm, 814 Condition cond) { 815 CHECK_NE(sm, kNoSRegister); 816 CHECK_NE(sm, S31); 817 CHECK_NE(rt, kNoRegister); 818 CHECK_NE(rt, SP); 819 CHECK_NE(rt, PC); 820 CHECK_NE(rt2, kNoRegister); 821 CHECK_NE(rt2, SP); 822 CHECK_NE(rt2, PC); 823 CHECK_NE(rt, rt2); 824 CHECK_NE(cond, kNoCondition); 825 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 826 B27 | B26 | B22 | B20 | 827 (static_cast<int32_t>(rt2)*B16) | 828 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 829 ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 830 (static_cast<int32_t>(sm) >> 1); 831 Emit(encoding); 832} 833 834 835void Arm32Assembler::vmovdrr(DRegister dm, Register rt, Register rt2, 836 Condition cond) { 837 CHECK_NE(dm, kNoDRegister); 838 CHECK_NE(rt, kNoRegister); 839 CHECK_NE(rt, SP); 840 CHECK_NE(rt, PC); 841 CHECK_NE(rt2, kNoRegister); 842 CHECK_NE(rt2, SP); 843 CHECK_NE(rt2, PC); 844 CHECK_NE(cond, kNoCondition); 845 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 846 B27 | B26 | B22 | 847 (static_cast<int32_t>(rt2)*B16) | 848 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 849 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 850 (static_cast<int32_t>(dm) & 0xf); 851 Emit(encoding); 852} 853 854 855void Arm32Assembler::vmovrrd(Register rt, Register rt2, DRegister dm, 856 Condition cond) { 857 CHECK_NE(dm, kNoDRegister); 858 CHECK_NE(rt, kNoRegister); 859 CHECK_NE(rt, SP); 860 CHECK_NE(rt, PC); 861 CHECK_NE(rt2, kNoRegister); 862 CHECK_NE(rt2, SP); 863 CHECK_NE(rt2, PC); 864 CHECK_NE(rt, rt2); 865 CHECK_NE(cond, kNoCondition); 866 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 867 B27 | B26 | B22 | B20 | 868 (static_cast<int32_t>(rt2)*B16) | 869 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 870 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 871 (static_cast<int32_t>(dm) & 0xf); 872 Emit(encoding); 873} 874 875 876void Arm32Assembler::vldrs(SRegister sd, const Address& ad, Condition cond) { 877 const Address& addr = static_cast<const Address&>(ad); 878 CHECK_NE(sd, kNoSRegister); 879 CHECK_NE(cond, kNoCondition); 880 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 881 B27 | B26 | B24 | B20 | 882 ((static_cast<int32_t>(sd) & 1)*B22) | 883 ((static_cast<int32_t>(sd) >> 1)*B12) | 884 B11 | B9 | addr.vencoding(); 885 Emit(encoding); 886} 887 888 889void Arm32Assembler::vstrs(SRegister sd, const Address& ad, Condition cond) { 890 const Address& addr = static_cast<const Address&>(ad); 891 CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC); 892 CHECK_NE(sd, kNoSRegister); 893 CHECK_NE(cond, kNoCondition); 894 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 895 B27 | B26 | B24 | 896 ((static_cast<int32_t>(sd) & 1)*B22) | 897 ((static_cast<int32_t>(sd) >> 1)*B12) | 898 B11 | B9 | addr.vencoding(); 899 Emit(encoding); 900} 901 902 903void Arm32Assembler::vldrd(DRegister dd, const Address& ad, Condition cond) { 904 const Address& addr = static_cast<const Address&>(ad); 905 CHECK_NE(dd, kNoDRegister); 906 CHECK_NE(cond, kNoCondition); 907 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 908 B27 | B26 | B24 | B20 | 909 ((static_cast<int32_t>(dd) >> 4)*B22) | 910 ((static_cast<int32_t>(dd) & 0xf)*B12) | 911 B11 | B9 | B8 | addr.vencoding(); 912 Emit(encoding); 913} 914 915 916void Arm32Assembler::vstrd(DRegister dd, const Address& ad, Condition cond) { 917 const Address& addr = static_cast<const Address&>(ad); 918 CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC); 919 CHECK_NE(dd, kNoDRegister); 920 CHECK_NE(cond, kNoCondition); 921 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 922 B27 | B26 | B24 | 923 ((static_cast<int32_t>(dd) >> 4)*B22) | 924 ((static_cast<int32_t>(dd) & 0xf)*B12) | 925 B11 | B9 | B8 | addr.vencoding(); 926 Emit(encoding); 927} 928 929 930void Arm32Assembler::vpushs(SRegister reg, int nregs, Condition cond) { 931 EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, false, cond); 932} 933 934 935void Arm32Assembler::vpushd(DRegister reg, int nregs, Condition cond) { 936 EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, true, cond); 937} 938 939 940void Arm32Assembler::vpops(SRegister reg, int nregs, Condition cond) { 941 EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, false, cond); 942} 943 944 945void Arm32Assembler::vpopd(DRegister reg, int nregs, Condition cond) { 946 EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, true, cond); 947} 948 949 950void Arm32Assembler::EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond) { 951 CHECK_NE(cond, kNoCondition); 952 CHECK_GT(nregs, 0); 953 uint32_t D; 954 uint32_t Vd; 955 if (dbl) { 956 // Encoded as D:Vd. 957 D = (reg >> 4) & 1; 958 Vd = reg & 15U /* 0b1111 */; 959 } else { 960 // Encoded as Vd:D. 961 D = reg & 1; 962 Vd = (reg >> 1) & 15U /* 0b1111 */; 963 } 964 int32_t encoding = B27 | B26 | B21 | B19 | B18 | B16 | 965 B11 | B9 | 966 (dbl ? B8 : 0) | 967 (push ? B24 : (B23 | B20)) | 968 static_cast<int32_t>(cond) << kConditionShift | 969 nregs << (dbl ? 1 : 0) | 970 D << 22 | 971 Vd << 12; 972 Emit(encoding); 973} 974 975 976void Arm32Assembler::EmitVFPsss(Condition cond, int32_t opcode, 977 SRegister sd, SRegister sn, SRegister sm) { 978 CHECK_NE(sd, kNoSRegister); 979 CHECK_NE(sn, kNoSRegister); 980 CHECK_NE(sm, kNoSRegister); 981 CHECK_NE(cond, kNoCondition); 982 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 983 B27 | B26 | B25 | B11 | B9 | opcode | 984 ((static_cast<int32_t>(sd) & 1)*B22) | 985 ((static_cast<int32_t>(sn) >> 1)*B16) | 986 ((static_cast<int32_t>(sd) >> 1)*B12) | 987 ((static_cast<int32_t>(sn) & 1)*B7) | 988 ((static_cast<int32_t>(sm) & 1)*B5) | 989 (static_cast<int32_t>(sm) >> 1); 990 Emit(encoding); 991} 992 993 994void Arm32Assembler::EmitVFPddd(Condition cond, int32_t opcode, 995 DRegister dd, DRegister dn, DRegister dm) { 996 CHECK_NE(dd, kNoDRegister); 997 CHECK_NE(dn, kNoDRegister); 998 CHECK_NE(dm, kNoDRegister); 999 CHECK_NE(cond, kNoCondition); 1000 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1001 B27 | B26 | B25 | B11 | B9 | B8 | opcode | 1002 ((static_cast<int32_t>(dd) >> 4)*B22) | 1003 ((static_cast<int32_t>(dn) & 0xf)*B16) | 1004 ((static_cast<int32_t>(dd) & 0xf)*B12) | 1005 ((static_cast<int32_t>(dn) >> 4)*B7) | 1006 ((static_cast<int32_t>(dm) >> 4)*B5) | 1007 (static_cast<int32_t>(dm) & 0xf); 1008 Emit(encoding); 1009} 1010 1011 1012void Arm32Assembler::EmitVFPsd(Condition cond, int32_t opcode, 1013 SRegister sd, DRegister dm) { 1014 CHECK_NE(sd, kNoSRegister); 1015 CHECK_NE(dm, kNoDRegister); 1016 CHECK_NE(cond, kNoCondition); 1017 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1018 B27 | B26 | B25 | B11 | B9 | opcode | 1019 ((static_cast<int32_t>(sd) & 1)*B22) | 1020 ((static_cast<int32_t>(sd) >> 1)*B12) | 1021 ((static_cast<int32_t>(dm) >> 4)*B5) | 1022 (static_cast<int32_t>(dm) & 0xf); 1023 Emit(encoding); 1024} 1025 1026 1027void Arm32Assembler::EmitVFPds(Condition cond, int32_t opcode, 1028 DRegister dd, SRegister sm) { 1029 CHECK_NE(dd, kNoDRegister); 1030 CHECK_NE(sm, kNoSRegister); 1031 CHECK_NE(cond, kNoCondition); 1032 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1033 B27 | B26 | B25 | B11 | B9 | opcode | 1034 ((static_cast<int32_t>(dd) >> 4)*B22) | 1035 ((static_cast<int32_t>(dd) & 0xf)*B12) | 1036 ((static_cast<int32_t>(sm) & 1)*B5) | 1037 (static_cast<int32_t>(sm) >> 1); 1038 Emit(encoding); 1039} 1040 1041 1042void Arm32Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm, 1043 bool setcc, Condition cond) { 1044 CHECK_NE(shift_imm, 0u); // Do not use Lsl if no shift is wanted. 1045 if (setcc) { 1046 movs(rd, ShifterOperand(rm, LSL, shift_imm), cond); 1047 } else { 1048 mov(rd, ShifterOperand(rm, LSL, shift_imm), cond); 1049 } 1050} 1051 1052 1053void Arm32Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm, 1054 bool setcc, Condition cond) { 1055 CHECK_NE(shift_imm, 0u); // Do not use Lsr if no shift is wanted. 1056 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 1057 if (setcc) { 1058 movs(rd, ShifterOperand(rm, LSR, shift_imm), cond); 1059 } else { 1060 mov(rd, ShifterOperand(rm, LSR, shift_imm), cond); 1061 } 1062} 1063 1064 1065void Arm32Assembler::Asr(Register rd, Register rm, uint32_t shift_imm, 1066 bool setcc, Condition cond) { 1067 CHECK_NE(shift_imm, 0u); // Do not use Asr if no shift is wanted. 1068 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 1069 if (setcc) { 1070 movs(rd, ShifterOperand(rm, ASR, shift_imm), cond); 1071 } else { 1072 mov(rd, ShifterOperand(rm, ASR, shift_imm), cond); 1073 } 1074} 1075 1076 1077void Arm32Assembler::Ror(Register rd, Register rm, uint32_t shift_imm, 1078 bool setcc, Condition cond) { 1079 CHECK_NE(shift_imm, 0u); // Use Rrx instruction. 1080 if (setcc) { 1081 movs(rd, ShifterOperand(rm, ROR, shift_imm), cond); 1082 } else { 1083 mov(rd, ShifterOperand(rm, ROR, shift_imm), cond); 1084 } 1085} 1086 1087void Arm32Assembler::Rrx(Register rd, Register rm, bool setcc, Condition cond) { 1088 if (setcc) { 1089 movs(rd, ShifterOperand(rm, ROR, 0), cond); 1090 } else { 1091 mov(rd, ShifterOperand(rm, ROR, 0), cond); 1092 } 1093} 1094 1095 1096void Arm32Assembler::Lsl(Register rd, Register rm, Register rn, 1097 bool setcc, Condition cond) { 1098 if (setcc) { 1099 movs(rd, ShifterOperand(rm, LSL, rn), cond); 1100 } else { 1101 mov(rd, ShifterOperand(rm, LSL, rn), cond); 1102 } 1103} 1104 1105 1106void Arm32Assembler::Lsr(Register rd, Register rm, Register rn, 1107 bool setcc, Condition cond) { 1108 if (setcc) { 1109 movs(rd, ShifterOperand(rm, LSR, rn), cond); 1110 } else { 1111 mov(rd, ShifterOperand(rm, LSR, rn), cond); 1112 } 1113} 1114 1115 1116void Arm32Assembler::Asr(Register rd, Register rm, Register rn, 1117 bool setcc, Condition cond) { 1118 if (setcc) { 1119 movs(rd, ShifterOperand(rm, ASR, rn), cond); 1120 } else { 1121 mov(rd, ShifterOperand(rm, ASR, rn), cond); 1122 } 1123} 1124 1125 1126void Arm32Assembler::Ror(Register rd, Register rm, Register rn, 1127 bool setcc, Condition cond) { 1128 if (setcc) { 1129 movs(rd, ShifterOperand(rm, ROR, rn), cond); 1130 } else { 1131 mov(rd, ShifterOperand(rm, ROR, rn), cond); 1132 } 1133} 1134 1135void Arm32Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR 1136 CHECK_NE(cond, kNoCondition); 1137 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1138 B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | 1139 (static_cast<int32_t>(PC)*B12) | 1140 B11 | B9 | B4; 1141 Emit(encoding); 1142} 1143 1144 1145void Arm32Assembler::svc(uint32_t imm24) { 1146 CHECK(IsUint(24, imm24)) << imm24; 1147 int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24; 1148 Emit(encoding); 1149} 1150 1151 1152void Arm32Assembler::bkpt(uint16_t imm16) { 1153 int32_t encoding = (AL << kConditionShift) | B24 | B21 | 1154 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); 1155 Emit(encoding); 1156} 1157 1158 1159void Arm32Assembler::blx(Register rm, Condition cond) { 1160 CHECK_NE(rm, kNoRegister); 1161 CHECK_NE(cond, kNoCondition); 1162 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1163 B24 | B21 | (0xfff << 8) | B5 | B4 | 1164 (static_cast<int32_t>(rm) << kRmShift); 1165 Emit(encoding); 1166} 1167 1168 1169void Arm32Assembler::bx(Register rm, Condition cond) { 1170 CHECK_NE(rm, kNoRegister); 1171 CHECK_NE(cond, kNoCondition); 1172 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1173 B24 | B21 | (0xfff << 8) | B4 | 1174 (static_cast<int32_t>(rm) << kRmShift); 1175 Emit(encoding); 1176} 1177 1178 1179void Arm32Assembler::Push(Register rd, Condition cond) { 1180 str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond); 1181} 1182 1183 1184void Arm32Assembler::Pop(Register rd, Condition cond) { 1185 ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond); 1186} 1187 1188 1189void Arm32Assembler::PushList(RegList regs, Condition cond) { 1190 stm(DB_W, SP, regs, cond); 1191} 1192 1193 1194void Arm32Assembler::PopList(RegList regs, Condition cond) { 1195 ldm(IA_W, SP, regs, cond); 1196} 1197 1198 1199void Arm32Assembler::Mov(Register rd, Register rm, Condition cond) { 1200 if (rd != rm) { 1201 mov(rd, ShifterOperand(rm), cond); 1202 } 1203} 1204 1205 1206void Arm32Assembler::Bind(Label* label) { 1207 CHECK(!label->IsBound()); 1208 int bound_pc = buffer_.Size(); 1209 while (label->IsLinked()) { 1210 int32_t position = label->Position(); 1211 int32_t next = buffer_.Load<int32_t>(position); 1212 int32_t encoded = Arm32Assembler::EncodeBranchOffset(bound_pc - position, next); 1213 buffer_.Store<int32_t>(position, encoded); 1214 label->position_ = Arm32Assembler::DecodeBranchOffset(next); 1215 } 1216 label->BindTo(bound_pc); 1217} 1218 1219 1220int32_t Arm32Assembler::EncodeBranchOffset(int offset, int32_t inst) { 1221 // The offset is off by 8 due to the way the ARM CPUs read PC. 1222 offset -= 8; 1223 CHECK_ALIGNED(offset, 4); 1224 CHECK(IsInt(POPCOUNT(kBranchOffsetMask), offset)) << offset; 1225 1226 // Properly preserve only the bits supported in the instruction. 1227 offset >>= 2; 1228 offset &= kBranchOffsetMask; 1229 return (inst & ~kBranchOffsetMask) | offset; 1230} 1231 1232 1233int Arm32Assembler::DecodeBranchOffset(int32_t inst) { 1234 // Sign-extend, left-shift by 2, then add 8. 1235 return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8); 1236} 1237 1238 1239void Arm32Assembler::AddConstant(Register rd, int32_t value, Condition cond) { 1240 AddConstant(rd, rd, value, cond); 1241} 1242 1243 1244void Arm32Assembler::AddConstant(Register rd, Register rn, int32_t value, 1245 Condition cond) { 1246 if (value == 0) { 1247 if (rd != rn) { 1248 mov(rd, ShifterOperand(rn), cond); 1249 } 1250 return; 1251 } 1252 // We prefer to select the shorter code sequence rather than selecting add for 1253 // positive values and sub for negatives ones, which would slightly improve 1254 // the readability of generated code for some constants. 1255 ShifterOperand shifter_op; 1256 if (ShifterOperand::CanHoldArm(value, &shifter_op)) { 1257 add(rd, rn, shifter_op, cond); 1258 } else if (ShifterOperand::CanHoldArm(-value, &shifter_op)) { 1259 sub(rd, rn, shifter_op, cond); 1260 } else { 1261 CHECK(rn != IP); 1262 if (ShifterOperand::CanHoldArm(~value, &shifter_op)) { 1263 mvn(IP, shifter_op, cond); 1264 add(rd, rn, ShifterOperand(IP), cond); 1265 } else if (ShifterOperand::CanHoldArm(~(-value), &shifter_op)) { 1266 mvn(IP, shifter_op, cond); 1267 sub(rd, rn, ShifterOperand(IP), cond); 1268 } else { 1269 movw(IP, Low16Bits(value), cond); 1270 uint16_t value_high = High16Bits(value); 1271 if (value_high != 0) { 1272 movt(IP, value_high, cond); 1273 } 1274 add(rd, rn, ShifterOperand(IP), cond); 1275 } 1276 } 1277} 1278 1279 1280void Arm32Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value, 1281 Condition cond) { 1282 ShifterOperand shifter_op; 1283 if (ShifterOperand::CanHoldArm(value, &shifter_op)) { 1284 adds(rd, rn, shifter_op, cond); 1285 } else if (ShifterOperand::CanHoldArm(-value, &shifter_op)) { 1286 subs(rd, rn, shifter_op, cond); 1287 } else { 1288 CHECK(rn != IP); 1289 if (ShifterOperand::CanHoldArm(~value, &shifter_op)) { 1290 mvn(IP, shifter_op, cond); 1291 adds(rd, rn, ShifterOperand(IP), cond); 1292 } else if (ShifterOperand::CanHoldArm(~(-value), &shifter_op)) { 1293 mvn(IP, shifter_op, cond); 1294 subs(rd, rn, ShifterOperand(IP), cond); 1295 } else { 1296 movw(IP, Low16Bits(value), cond); 1297 uint16_t value_high = High16Bits(value); 1298 if (value_high != 0) { 1299 movt(IP, value_high, cond); 1300 } 1301 adds(rd, rn, ShifterOperand(IP), cond); 1302 } 1303 } 1304} 1305 1306 1307void Arm32Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { 1308 ShifterOperand shifter_op; 1309 if (ShifterOperand::CanHoldArm(value, &shifter_op)) { 1310 mov(rd, shifter_op, cond); 1311 } else if (ShifterOperand::CanHoldArm(~value, &shifter_op)) { 1312 mvn(rd, shifter_op, cond); 1313 } else { 1314 movw(rd, Low16Bits(value), cond); 1315 uint16_t value_high = High16Bits(value); 1316 if (value_high != 0) { 1317 movt(rd, value_high, cond); 1318 } 1319 } 1320} 1321 1322 1323// Implementation note: this method must emit at most one instruction when 1324// Address::CanHoldLoadOffsetArm. 1325void Arm32Assembler::LoadFromOffset(LoadOperandType type, 1326 Register reg, 1327 Register base, 1328 int32_t offset, 1329 Condition cond) { 1330 if (!Address::CanHoldLoadOffsetArm(type, offset)) { 1331 CHECK(base != IP); 1332 LoadImmediate(IP, offset, cond); 1333 add(IP, IP, ShifterOperand(base), cond); 1334 base = IP; 1335 offset = 0; 1336 } 1337 CHECK(Address::CanHoldLoadOffsetArm(type, offset)); 1338 switch (type) { 1339 case kLoadSignedByte: 1340 ldrsb(reg, Address(base, offset), cond); 1341 break; 1342 case kLoadUnsignedByte: 1343 ldrb(reg, Address(base, offset), cond); 1344 break; 1345 case kLoadSignedHalfword: 1346 ldrsh(reg, Address(base, offset), cond); 1347 break; 1348 case kLoadUnsignedHalfword: 1349 ldrh(reg, Address(base, offset), cond); 1350 break; 1351 case kLoadWord: 1352 ldr(reg, Address(base, offset), cond); 1353 break; 1354 case kLoadWordPair: 1355 ldrd(reg, Address(base, offset), cond); 1356 break; 1357 default: 1358 LOG(FATAL) << "UNREACHABLE"; 1359 UNREACHABLE(); 1360 } 1361} 1362 1363 1364// Implementation note: this method must emit at most one instruction when 1365// Address::CanHoldLoadOffsetArm, as expected by JIT::GuardedLoadFromOffset. 1366void Arm32Assembler::LoadSFromOffset(SRegister reg, 1367 Register base, 1368 int32_t offset, 1369 Condition cond) { 1370 if (!Address::CanHoldLoadOffsetArm(kLoadSWord, offset)) { 1371 CHECK_NE(base, IP); 1372 LoadImmediate(IP, offset, cond); 1373 add(IP, IP, ShifterOperand(base), cond); 1374 base = IP; 1375 offset = 0; 1376 } 1377 CHECK(Address::CanHoldLoadOffsetArm(kLoadSWord, offset)); 1378 vldrs(reg, Address(base, offset), cond); 1379} 1380 1381 1382// Implementation note: this method must emit at most one instruction when 1383// Address::CanHoldLoadOffsetArm, as expected by JIT::GuardedLoadFromOffset. 1384void Arm32Assembler::LoadDFromOffset(DRegister reg, 1385 Register base, 1386 int32_t offset, 1387 Condition cond) { 1388 if (!Address::CanHoldLoadOffsetArm(kLoadDWord, offset)) { 1389 CHECK_NE(base, IP); 1390 LoadImmediate(IP, offset, cond); 1391 add(IP, IP, ShifterOperand(base), cond); 1392 base = IP; 1393 offset = 0; 1394 } 1395 CHECK(Address::CanHoldLoadOffsetArm(kLoadDWord, offset)); 1396 vldrd(reg, Address(base, offset), cond); 1397} 1398 1399 1400// Implementation note: this method must emit at most one instruction when 1401// Address::CanHoldStoreOffsetArm. 1402void Arm32Assembler::StoreToOffset(StoreOperandType type, 1403 Register reg, 1404 Register base, 1405 int32_t offset, 1406 Condition cond) { 1407 if (!Address::CanHoldStoreOffsetArm(type, offset)) { 1408 CHECK(reg != IP); 1409 CHECK(base != IP); 1410 LoadImmediate(IP, offset, cond); 1411 add(IP, IP, ShifterOperand(base), cond); 1412 base = IP; 1413 offset = 0; 1414 } 1415 CHECK(Address::CanHoldStoreOffsetArm(type, offset)); 1416 switch (type) { 1417 case kStoreByte: 1418 strb(reg, Address(base, offset), cond); 1419 break; 1420 case kStoreHalfword: 1421 strh(reg, Address(base, offset), cond); 1422 break; 1423 case kStoreWord: 1424 str(reg, Address(base, offset), cond); 1425 break; 1426 case kStoreWordPair: 1427 strd(reg, Address(base, offset), cond); 1428 break; 1429 default: 1430 LOG(FATAL) << "UNREACHABLE"; 1431 UNREACHABLE(); 1432 } 1433} 1434 1435 1436// Implementation note: this method must emit at most one instruction when 1437// Address::CanHoldStoreOffsetArm, as expected by JIT::GuardedStoreToOffset. 1438void Arm32Assembler::StoreSToOffset(SRegister reg, 1439 Register base, 1440 int32_t offset, 1441 Condition cond) { 1442 if (!Address::CanHoldStoreOffsetArm(kStoreSWord, offset)) { 1443 CHECK_NE(base, IP); 1444 LoadImmediate(IP, offset, cond); 1445 add(IP, IP, ShifterOperand(base), cond); 1446 base = IP; 1447 offset = 0; 1448 } 1449 CHECK(Address::CanHoldStoreOffsetArm(kStoreSWord, offset)); 1450 vstrs(reg, Address(base, offset), cond); 1451} 1452 1453 1454// Implementation note: this method must emit at most one instruction when 1455// Address::CanHoldStoreOffsetArm, as expected by JIT::GuardedStoreSToOffset. 1456void Arm32Assembler::StoreDToOffset(DRegister reg, 1457 Register base, 1458 int32_t offset, 1459 Condition cond) { 1460 if (!Address::CanHoldStoreOffsetArm(kStoreDWord, offset)) { 1461 CHECK_NE(base, IP); 1462 LoadImmediate(IP, offset, cond); 1463 add(IP, IP, ShifterOperand(base), cond); 1464 base = IP; 1465 offset = 0; 1466 } 1467 CHECK(Address::CanHoldStoreOffsetArm(kStoreDWord, offset)); 1468 vstrd(reg, Address(base, offset), cond); 1469} 1470 1471 1472void Arm32Assembler::MemoryBarrier(ManagedRegister mscratch) { 1473 CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12); 1474 dmb(SY); 1475} 1476 1477 1478void Arm32Assembler::dmb(DmbOptions flavor) { 1479#if ANDROID_SMP != 0 1480 int32_t encoding = 0xf57ff05f; // dmb 1481 Emit(encoding | flavor); 1482#endif 1483} 1484 1485 1486void Arm32Assembler::cbz(Register rn, Label* target) { 1487 LOG(FATAL) << "cbz is not supported on ARM32"; 1488} 1489 1490 1491void Arm32Assembler::cbnz(Register rn, Label* target) { 1492 LOG(FATAL) << "cbnz is not supported on ARM32"; 1493} 1494 1495 1496void Arm32Assembler::CompareAndBranchIfZero(Register r, Label* label) { 1497 cmp(r, ShifterOperand(0)); 1498 b(label, EQ); 1499} 1500 1501 1502void Arm32Assembler::CompareAndBranchIfNonZero(Register r, Label* label) { 1503 cmp(r, ShifterOperand(0)); 1504 b(label, NE); 1505} 1506 1507 1508} // namespace arm 1509} // namespace art 1510