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 <type_traits> 18 19 #include "assembler_thumb2.h" 20 21 #include "base/bit_utils.h" 22 #include "base/logging.h" 23 #include "entrypoints/quick/quick_entrypoints.h" 24 #include "offsets.h" 25 #include "thread.h" 26 27 namespace art { 28 namespace arm { 29 30 template <typename Function> 31 void Thumb2Assembler::Fixup::ForExpandableDependencies(Thumb2Assembler* assembler, Function fn) { 32 static_assert( 33 std::is_same<typename std::result_of<Function(FixupId, FixupId)>::type, void>::value, 34 "Incorrect signature for argument `fn`: expected (FixupId, FixupId) -> void"); 35 Fixup* fixups = assembler->fixups_.data(); 36 for (FixupId fixup_id = 0u, end_id = assembler->fixups_.size(); fixup_id != end_id; ++fixup_id) { 37 uint32_t target = fixups[fixup_id].target_; 38 if (target > fixups[fixup_id].location_) { 39 for (FixupId id = fixup_id + 1u; id != end_id && fixups[id].location_ < target; ++id) { 40 if (fixups[id].CanExpand()) { 41 fn(id, fixup_id); 42 } 43 } 44 } else { 45 for (FixupId id = fixup_id; id != 0u && fixups[id - 1u].location_ >= target; --id) { 46 if (fixups[id - 1u].CanExpand()) { 47 fn(id - 1u, fixup_id); 48 } 49 } 50 } 51 } 52 } 53 54 void Thumb2Assembler::Fixup::PrepareDependents(Thumb2Assembler* assembler) { 55 // For each Fixup, it's easy to find the Fixups that it depends on as they are either 56 // the following or the preceding Fixups until we find the target. However, for fixup 57 // adjustment we need the reverse lookup, i.e. what Fixups depend on a given Fixup. 58 // This function creates a compact representation of this relationship, where we have 59 // all the dependents in a single array and Fixups reference their ranges by start 60 // index and count. (Instead of having a per-fixup vector.) 61 62 // Count the number of dependents of each Fixup. 63 Fixup* fixups = assembler->fixups_.data(); 64 ForExpandableDependencies( 65 assembler, 66 [fixups](FixupId dependency, FixupId dependent ATTRIBUTE_UNUSED) { 67 fixups[dependency].dependents_count_ += 1u; 68 }); 69 // Assign index ranges in fixup_dependents_ to individual fixups. Record the end of the 70 // range in dependents_start_, we shall later decrement it as we fill in fixup_dependents_. 71 uint32_t number_of_dependents = 0u; 72 for (FixupId fixup_id = 0u, end_id = assembler->fixups_.size(); fixup_id != end_id; ++fixup_id) { 73 number_of_dependents += fixups[fixup_id].dependents_count_; 74 fixups[fixup_id].dependents_start_ = number_of_dependents; 75 } 76 if (number_of_dependents == 0u) { 77 return; 78 } 79 // Create and fill in the fixup_dependents_. 80 assembler->fixup_dependents_.resize(number_of_dependents); 81 FixupId* dependents = assembler->fixup_dependents_.data(); 82 ForExpandableDependencies( 83 assembler, 84 [fixups, dependents](FixupId dependency, FixupId dependent) { 85 fixups[dependency].dependents_start_ -= 1u; 86 dependents[fixups[dependency].dependents_start_] = dependent; 87 }); 88 } 89 90 void Thumb2Assembler::BindLabel(Label* label, uint32_t bound_pc) { 91 CHECK(!label->IsBound()); 92 93 while (label->IsLinked()) { 94 FixupId fixup_id = label->Position(); // The id for linked Fixup. 95 Fixup* fixup = GetFixup(fixup_id); // Get the Fixup at this id. 96 fixup->Resolve(bound_pc); // Fixup can be resolved now. 97 uint32_t fixup_location = fixup->GetLocation(); 98 uint16_t next = buffer_.Load<uint16_t>(fixup_location); // Get next in chain. 99 buffer_.Store<int16_t>(fixup_location, 0); 100 label->position_ = next; // Move to next. 101 } 102 label->BindTo(bound_pc); 103 } 104 105 uint32_t Thumb2Assembler::BindLiterals() { 106 // We don't add the padding here, that's done only after adjusting the Fixup sizes. 107 uint32_t code_size = buffer_.Size(); 108 for (Literal& lit : literals_) { 109 Label* label = lit.GetLabel(); 110 BindLabel(label, code_size); 111 code_size += lit.GetSize(); 112 } 113 return code_size; 114 } 115 116 void Thumb2Assembler::BindJumpTables(uint32_t code_size) { 117 for (JumpTable& table : jump_tables_) { 118 Label* label = table.GetLabel(); 119 BindLabel(label, code_size); 120 code_size += table.GetSize(); 121 } 122 } 123 124 void Thumb2Assembler::AdjustFixupIfNeeded(Fixup* fixup, uint32_t* current_code_size, 125 std::deque<FixupId>* fixups_to_recalculate) { 126 uint32_t adjustment = fixup->AdjustSizeIfNeeded(*current_code_size); 127 if (adjustment != 0u) { 128 DCHECK(fixup->CanExpand()); 129 *current_code_size += adjustment; 130 for (FixupId dependent_id : fixup->Dependents(*this)) { 131 Fixup* dependent = GetFixup(dependent_id); 132 dependent->IncreaseAdjustment(adjustment); 133 if (buffer_.Load<int16_t>(dependent->GetLocation()) == 0) { 134 buffer_.Store<int16_t>(dependent->GetLocation(), 1); 135 fixups_to_recalculate->push_back(dependent_id); 136 } 137 } 138 } 139 } 140 141 uint32_t Thumb2Assembler::AdjustFixups() { 142 Fixup::PrepareDependents(this); 143 uint32_t current_code_size = buffer_.Size(); 144 std::deque<FixupId> fixups_to_recalculate; 145 if (kIsDebugBuild) { 146 // We will use the placeholders in the buffer_ to mark whether the fixup has 147 // been added to the fixups_to_recalculate. Make sure we start with zeros. 148 for (Fixup& fixup : fixups_) { 149 CHECK_EQ(buffer_.Load<int16_t>(fixup.GetLocation()), 0); 150 } 151 } 152 for (Fixup& fixup : fixups_) { 153 AdjustFixupIfNeeded(&fixup, ¤t_code_size, &fixups_to_recalculate); 154 } 155 while (!fixups_to_recalculate.empty()) { 156 do { 157 // Pop the fixup. 158 FixupId fixup_id = fixups_to_recalculate.front(); 159 fixups_to_recalculate.pop_front(); 160 Fixup* fixup = GetFixup(fixup_id); 161 DCHECK_NE(buffer_.Load<int16_t>(fixup->GetLocation()), 0); 162 buffer_.Store<int16_t>(fixup->GetLocation(), 0); 163 // See if it needs adjustment. 164 AdjustFixupIfNeeded(fixup, ¤t_code_size, &fixups_to_recalculate); 165 } while (!fixups_to_recalculate.empty()); 166 167 if ((current_code_size & 2) != 0 && (!literals_.empty() || !jump_tables_.empty())) { 168 // If we need to add padding before literals, this may just push some out of range, 169 // so recalculate all load literals. This makes up for the fact that we don't mark 170 // load literal as a dependency of all previous Fixups even though it actually is. 171 for (Fixup& fixup : fixups_) { 172 if (fixup.IsLoadLiteral()) { 173 AdjustFixupIfNeeded(&fixup, ¤t_code_size, &fixups_to_recalculate); 174 } 175 } 176 } 177 } 178 if (kIsDebugBuild) { 179 // Check that no fixup is marked as being in fixups_to_recalculate anymore. 180 for (Fixup& fixup : fixups_) { 181 CHECK_EQ(buffer_.Load<int16_t>(fixup.GetLocation()), 0); 182 } 183 } 184 185 // Adjust literal pool labels for padding. 186 DCHECK_ALIGNED(current_code_size, 2); 187 uint32_t literals_adjustment = current_code_size + (current_code_size & 2) - buffer_.Size(); 188 if (literals_adjustment != 0u) { 189 for (Literal& literal : literals_) { 190 Label* label = literal.GetLabel(); 191 DCHECK(label->IsBound()); 192 int old_position = label->Position(); 193 label->Reinitialize(); 194 label->BindTo(old_position + literals_adjustment); 195 } 196 for (JumpTable& table : jump_tables_) { 197 Label* label = table.GetLabel(); 198 DCHECK(label->IsBound()); 199 int old_position = label->Position(); 200 label->Reinitialize(); 201 label->BindTo(old_position + literals_adjustment); 202 } 203 } 204 205 return current_code_size; 206 } 207 208 void Thumb2Assembler::EmitFixups(uint32_t adjusted_code_size) { 209 // Move non-fixup code to its final place and emit fixups. 210 // Process fixups in reverse order so that we don't repeatedly move the same data. 211 size_t src_end = buffer_.Size(); 212 size_t dest_end = adjusted_code_size; 213 buffer_.Resize(dest_end); 214 DCHECK_GE(dest_end, src_end); 215 for (auto i = fixups_.rbegin(), end = fixups_.rend(); i != end; ++i) { 216 Fixup* fixup = &*i; 217 if (fixup->GetOriginalSize() == fixup->GetSize()) { 218 // The size of this Fixup didn't change. To avoid moving the data 219 // in small chunks, emit the code to its original position. 220 fixup->Emit(&buffer_, adjusted_code_size); 221 fixup->Finalize(dest_end - src_end); 222 } else { 223 // Move the data between the end of the fixup and src_end to its final location. 224 size_t old_fixup_location = fixup->GetLocation(); 225 size_t src_begin = old_fixup_location + fixup->GetOriginalSizeInBytes(); 226 size_t data_size = src_end - src_begin; 227 size_t dest_begin = dest_end - data_size; 228 buffer_.Move(dest_begin, src_begin, data_size); 229 src_end = old_fixup_location; 230 dest_end = dest_begin - fixup->GetSizeInBytes(); 231 // Finalize the Fixup and emit the data to the new location. 232 fixup->Finalize(dest_end - src_end); 233 fixup->Emit(&buffer_, adjusted_code_size); 234 } 235 } 236 CHECK_EQ(src_end, dest_end); 237 } 238 239 void Thumb2Assembler::EmitLiterals() { 240 if (!literals_.empty()) { 241 // Load literal instructions (LDR, LDRD, VLDR) require 4-byte alignment. 242 // We don't support byte and half-word literals. 243 uint32_t code_size = buffer_.Size(); 244 DCHECK_ALIGNED(code_size, 2); 245 if ((code_size & 2u) != 0u) { 246 Emit16(0); 247 } 248 for (Literal& literal : literals_) { 249 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 250 DCHECK_EQ(static_cast<size_t>(literal.GetLabel()->Position()), buffer_.Size()); 251 DCHECK(literal.GetSize() == 4u || literal.GetSize() == 8u); 252 for (size_t i = 0, size = literal.GetSize(); i != size; ++i) { 253 buffer_.Emit<uint8_t>(literal.GetData()[i]); 254 } 255 } 256 } 257 } 258 259 void Thumb2Assembler::EmitJumpTables() { 260 if (!jump_tables_.empty()) { 261 // Jump tables require 4 byte alignment. (We don't support byte and half-word jump tables.) 262 uint32_t code_size = buffer_.Size(); 263 DCHECK_ALIGNED(code_size, 2); 264 if ((code_size & 2u) != 0u) { 265 Emit16(0); 266 } 267 for (JumpTable& table : jump_tables_) { 268 // Bulk ensure capacity, as this may be large. 269 size_t orig_size = buffer_.Size(); 270 size_t required_capacity = orig_size + table.GetSize(); 271 if (required_capacity > buffer_.Capacity()) { 272 buffer_.ExtendCapacity(required_capacity); 273 } 274 #ifndef NDEBUG 275 buffer_.has_ensured_capacity_ = true; 276 #endif 277 278 DCHECK_EQ(static_cast<size_t>(table.GetLabel()->Position()), buffer_.Size()); 279 int32_t anchor_position = table.GetAnchorLabel()->Position() + 4; 280 281 for (Label* target : table.GetData()) { 282 // Ensure that the label was tracked, so that it will have the right position. 283 DCHECK(std::find(tracked_labels_.begin(), tracked_labels_.end(), target) != 284 tracked_labels_.end()); 285 286 int32_t offset = target->Position() - anchor_position; 287 buffer_.Emit<int32_t>(offset); 288 } 289 290 #ifndef NDEBUG 291 buffer_.has_ensured_capacity_ = false; 292 #endif 293 size_t new_size = buffer_.Size(); 294 DCHECK_LE(new_size - orig_size, table.GetSize()); 295 } 296 } 297 } 298 299 void Thumb2Assembler::PatchCFI() { 300 if (cfi().NumberOfDelayedAdvancePCs() == 0u) { 301 return; 302 } 303 304 typedef DebugFrameOpCodeWriterForAssembler::DelayedAdvancePC DelayedAdvancePC; 305 const auto data = cfi().ReleaseStreamAndPrepareForDelayedAdvancePC(); 306 const std::vector<uint8_t>& old_stream = data.first; 307 const std::vector<DelayedAdvancePC>& advances = data.second; 308 309 // Refill our data buffer with patched opcodes. 310 cfi().ReserveCFIStream(old_stream.size() + advances.size() + 16); 311 size_t stream_pos = 0; 312 for (const DelayedAdvancePC& advance : advances) { 313 DCHECK_GE(advance.stream_pos, stream_pos); 314 // Copy old data up to the point where advance was issued. 315 cfi().AppendRawData(old_stream, stream_pos, advance.stream_pos); 316 stream_pos = advance.stream_pos; 317 // Insert the advance command with its final offset. 318 size_t final_pc = GetAdjustedPosition(advance.pc); 319 cfi().AdvancePC(final_pc); 320 } 321 // Copy the final segment if any. 322 cfi().AppendRawData(old_stream, stream_pos, old_stream.size()); 323 } 324 325 inline int16_t Thumb2Assembler::BEncoding16(int32_t offset, Condition cond) { 326 DCHECK_ALIGNED(offset, 2); 327 int16_t encoding = B15 | B14; 328 if (cond != AL) { 329 DCHECK(IsInt<9>(offset)); 330 encoding |= B12 | (static_cast<int32_t>(cond) << 8) | ((offset >> 1) & 0xff); 331 } else { 332 DCHECK(IsInt<12>(offset)); 333 encoding |= B13 | ((offset >> 1) & 0x7ff); 334 } 335 return encoding; 336 } 337 338 inline int32_t Thumb2Assembler::BEncoding32(int32_t offset, Condition cond) { 339 DCHECK_ALIGNED(offset, 2); 340 int32_t s = (offset >> 31) & 1; // Sign bit. 341 int32_t encoding = B31 | B30 | B29 | B28 | B15 | 342 (s << 26) | // Sign bit goes to bit 26. 343 ((offset >> 1) & 0x7ff); // imm11 goes to bits 0-10. 344 if (cond != AL) { 345 DCHECK(IsInt<21>(offset)); 346 // Encode cond, move imm6 from bits 12-17 to bits 16-21 and move J1 and J2. 347 encoding |= (static_cast<int32_t>(cond) << 22) | ((offset & 0x3f000) << (16 - 12)) | 348 ((offset & (1 << 19)) >> (19 - 13)) | // Extract J1 from bit 19 to bit 13. 349 ((offset & (1 << 18)) >> (18 - 11)); // Extract J2 from bit 18 to bit 11. 350 } else { 351 DCHECK(IsInt<25>(offset)); 352 int32_t j1 = ((offset >> 23) ^ s ^ 1) & 1; // Calculate J1 from I1 extracted from bit 23. 353 int32_t j2 = ((offset >> 22)^ s ^ 1) & 1; // Calculate J2 from I2 extracted from bit 22. 354 // Move imm10 from bits 12-21 to bits 16-25 and add J1 and J2. 355 encoding |= B12 | ((offset & 0x3ff000) << (16 - 12)) | 356 (j1 << 13) | (j2 << 11); 357 } 358 return encoding; 359 } 360 361 inline int16_t Thumb2Assembler::CbxzEncoding16(Register rn, int32_t offset, Condition cond) { 362 DCHECK(!IsHighRegister(rn)); 363 DCHECK_ALIGNED(offset, 2); 364 DCHECK(IsUint<7>(offset)); 365 DCHECK(cond == EQ || cond == NE); 366 return B15 | B13 | B12 | B8 | (cond == NE ? B11 : 0) | static_cast<int32_t>(rn) | 367 ((offset & 0x3e) << (3 - 1)) | // Move imm5 from bits 1-5 to bits 3-7. 368 ((offset & 0x40) << (9 - 6)); // Move i from bit 6 to bit 11 369 } 370 371 inline int16_t Thumb2Assembler::CmpRnImm8Encoding16(Register rn, int32_t value) { 372 DCHECK(!IsHighRegister(rn)); 373 DCHECK(IsUint<8>(value)); 374 return B13 | B11 | (rn << 8) | value; 375 } 376 377 inline int16_t Thumb2Assembler::AddRdnRmEncoding16(Register rdn, Register rm) { 378 // The high bit of rn is moved across 4-bit rm. 379 return B14 | B10 | (static_cast<int32_t>(rm) << 3) | 380 (static_cast<int32_t>(rdn) & 7) | ((static_cast<int32_t>(rdn) & 8) << 4); 381 } 382 383 inline int32_t Thumb2Assembler::MovwEncoding32(Register rd, int32_t value) { 384 DCHECK(IsUint<16>(value)); 385 return B31 | B30 | B29 | B28 | B25 | B22 | 386 (static_cast<int32_t>(rd) << 8) | 387 ((value & 0xf000) << (16 - 12)) | // Move imm4 from bits 12-15 to bits 16-19. 388 ((value & 0x0800) << (26 - 11)) | // Move i from bit 11 to bit 26. 389 ((value & 0x0700) << (12 - 8)) | // Move imm3 from bits 8-10 to bits 12-14. 390 (value & 0xff); // Keep imm8 in bits 0-7. 391 } 392 393 inline int32_t Thumb2Assembler::MovtEncoding32(Register rd, int32_t value) { 394 DCHECK_EQ(value & 0xffff, 0); 395 int32_t movw_encoding = MovwEncoding32(rd, (value >> 16) & 0xffff); 396 return movw_encoding | B25 | B23; 397 } 398 399 inline int32_t Thumb2Assembler::MovModImmEncoding32(Register rd, int32_t value) { 400 uint32_t mod_imm = ModifiedImmediate(value); 401 DCHECK_NE(mod_imm, kInvalidModifiedImmediate); 402 return B31 | B30 | B29 | B28 | B22 | B19 | B18 | B17 | B16 | 403 (static_cast<int32_t>(rd) << 8) | static_cast<int32_t>(mod_imm); 404 } 405 406 inline int16_t Thumb2Assembler::LdrLitEncoding16(Register rt, int32_t offset) { 407 DCHECK(!IsHighRegister(rt)); 408 DCHECK_ALIGNED(offset, 4); 409 DCHECK(IsUint<10>(offset)); 410 return B14 | B11 | (static_cast<int32_t>(rt) << 8) | (offset >> 2); 411 } 412 413 inline int32_t Thumb2Assembler::LdrLitEncoding32(Register rt, int32_t offset) { 414 // NOTE: We don't support negative offset, i.e. U=0 (B23). 415 return LdrRtRnImm12Encoding(rt, PC, offset); 416 } 417 418 inline int32_t Thumb2Assembler::LdrdEncoding32(Register rt, Register rt2, Register rn, int32_t offset) { 419 DCHECK_ALIGNED(offset, 4); 420 CHECK(IsUint<10>(offset)); 421 return B31 | B30 | B29 | B27 | 422 B24 /* P = 1 */ | B23 /* U = 1 */ | B22 | 0 /* W = 0 */ | B20 | 423 (static_cast<int32_t>(rn) << 16) | (static_cast<int32_t>(rt) << 12) | 424 (static_cast<int32_t>(rt2) << 8) | (offset >> 2); 425 } 426 427 inline int32_t Thumb2Assembler::VldrsEncoding32(SRegister sd, Register rn, int32_t offset) { 428 DCHECK_ALIGNED(offset, 4); 429 CHECK(IsUint<10>(offset)); 430 return B31 | B30 | B29 | B27 | B26 | B24 | 431 B23 /* U = 1 */ | B20 | B11 | B9 | 432 (static_cast<int32_t>(rn) << 16) | 433 ((static_cast<int32_t>(sd) & 0x01) << (22 - 0)) | // Move D from bit 0 to bit 22. 434 ((static_cast<int32_t>(sd) & 0x1e) << (12 - 1)) | // Move Vd from bits 1-4 to bits 12-15. 435 (offset >> 2); 436 } 437 438 inline int32_t Thumb2Assembler::VldrdEncoding32(DRegister dd, Register rn, int32_t offset) { 439 DCHECK_ALIGNED(offset, 4); 440 CHECK(IsUint<10>(offset)); 441 return B31 | B30 | B29 | B27 | B26 | B24 | 442 B23 /* U = 1 */ | B20 | B11 | B9 | B8 | 443 (rn << 16) | 444 ((static_cast<int32_t>(dd) & 0x10) << (22 - 4)) | // Move D from bit 4 to bit 22. 445 ((static_cast<int32_t>(dd) & 0x0f) << (12 - 0)) | // Move Vd from bits 0-3 to bits 12-15. 446 (offset >> 2); 447 } 448 449 inline int16_t Thumb2Assembler::LdrRtRnImm5Encoding16(Register rt, Register rn, int32_t offset) { 450 DCHECK(!IsHighRegister(rt)); 451 DCHECK(!IsHighRegister(rn)); 452 DCHECK_ALIGNED(offset, 4); 453 DCHECK(IsUint<7>(offset)); 454 return B14 | B13 | B11 | 455 (static_cast<int32_t>(rn) << 3) | static_cast<int32_t>(rt) | 456 (offset << (6 - 2)); // Move imm5 from bits 2-6 to bits 6-10. 457 } 458 459 int32_t Thumb2Assembler::Fixup::LoadWideOrFpEncoding(Register rbase, int32_t offset) const { 460 switch (type_) { 461 case kLoadLiteralWide: 462 return LdrdEncoding32(rn_, rt2_, rbase, offset); 463 case kLoadFPLiteralSingle: 464 return VldrsEncoding32(sd_, rbase, offset); 465 case kLoadFPLiteralDouble: 466 return VldrdEncoding32(dd_, rbase, offset); 467 default: 468 LOG(FATAL) << "Unexpected type: " << static_cast<int>(type_); 469 UNREACHABLE(); 470 } 471 } 472 473 inline int32_t Thumb2Assembler::LdrRtRnImm12Encoding(Register rt, Register rn, int32_t offset) { 474 DCHECK(IsUint<12>(offset)); 475 return B31 | B30 | B29 | B28 | B27 | B23 | B22 | B20 | (rn << 16) | (rt << 12) | offset; 476 } 477 478 inline int16_t Thumb2Assembler::AdrEncoding16(Register rd, int32_t offset) { 479 DCHECK(IsUint<10>(offset)); 480 DCHECK(IsAligned<4>(offset)); 481 DCHECK(!IsHighRegister(rd)); 482 return B15 | B13 | (rd << 8) | (offset >> 2); 483 } 484 485 inline int32_t Thumb2Assembler::AdrEncoding32(Register rd, int32_t offset) { 486 DCHECK(IsUint<12>(offset)); 487 // Bit 26: offset[11] 488 // Bits 14-12: offset[10-8] 489 // Bits 7-0: offset[7-0] 490 int32_t immediate_mask = 491 ((offset & (1 << 11)) << (26 - 11)) | 492 ((offset & (7 << 8)) << (12 - 8)) | 493 (offset & 0xFF); 494 return B31 | B30 | B29 | B28 | B25 | B19 | B18 | B17 | B16 | (rd << 8) | immediate_mask; 495 } 496 497 void Thumb2Assembler::FinalizeCode() { 498 ArmAssembler::FinalizeCode(); 499 uint32_t size_after_literals = BindLiterals(); 500 BindJumpTables(size_after_literals); 501 uint32_t adjusted_code_size = AdjustFixups(); 502 EmitFixups(adjusted_code_size); 503 EmitLiterals(); 504 FinalizeTrackedLabels(); 505 EmitJumpTables(); 506 PatchCFI(); 507 } 508 509 bool Thumb2Assembler::ShifterOperandCanAlwaysHold(uint32_t immediate) { 510 return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate; 511 } 512 513 bool Thumb2Assembler::ShifterOperandCanHold(Register rd ATTRIBUTE_UNUSED, 514 Register rn ATTRIBUTE_UNUSED, 515 Opcode opcode, 516 uint32_t immediate, 517 SetCc set_cc, 518 ShifterOperand* shifter_op) { 519 shifter_op->type_ = ShifterOperand::kImmediate; 520 shifter_op->immed_ = immediate; 521 shifter_op->is_shift_ = false; 522 shifter_op->is_rotate_ = false; 523 switch (opcode) { 524 case ADD: 525 case SUB: 526 // Less than (or equal to) 12 bits can be done if we don't need to set condition codes. 527 if (immediate < (1 << 12) && set_cc != kCcSet) { 528 return true; 529 } 530 return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate; 531 532 case MOV: 533 // TODO: Support less than or equal to 12bits. 534 return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate; 535 536 case MVN: 537 default: 538 return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate; 539 } 540 } 541 542 void Thumb2Assembler::and_(Register rd, Register rn, const ShifterOperand& so, 543 Condition cond, SetCc set_cc) { 544 EmitDataProcessing(cond, AND, set_cc, rn, rd, so); 545 } 546 547 548 void Thumb2Assembler::eor(Register rd, Register rn, const ShifterOperand& so, 549 Condition cond, SetCc set_cc) { 550 EmitDataProcessing(cond, EOR, set_cc, rn, rd, so); 551 } 552 553 554 void Thumb2Assembler::sub(Register rd, Register rn, const ShifterOperand& so, 555 Condition cond, SetCc set_cc) { 556 EmitDataProcessing(cond, SUB, set_cc, rn, rd, so); 557 } 558 559 560 void Thumb2Assembler::rsb(Register rd, Register rn, const ShifterOperand& so, 561 Condition cond, SetCc set_cc) { 562 EmitDataProcessing(cond, RSB, set_cc, rn, rd, so); 563 } 564 565 566 void Thumb2Assembler::add(Register rd, Register rn, const ShifterOperand& so, 567 Condition cond, SetCc set_cc) { 568 EmitDataProcessing(cond, ADD, set_cc, rn, rd, so); 569 } 570 571 572 void Thumb2Assembler::adc(Register rd, Register rn, const ShifterOperand& so, 573 Condition cond, SetCc set_cc) { 574 EmitDataProcessing(cond, ADC, set_cc, rn, rd, so); 575 } 576 577 578 void Thumb2Assembler::sbc(Register rd, Register rn, const ShifterOperand& so, 579 Condition cond, SetCc set_cc) { 580 EmitDataProcessing(cond, SBC, set_cc, rn, rd, so); 581 } 582 583 584 void Thumb2Assembler::rsc(Register rd, Register rn, const ShifterOperand& so, 585 Condition cond, SetCc set_cc) { 586 EmitDataProcessing(cond, RSC, set_cc, rn, rd, so); 587 } 588 589 590 void Thumb2Assembler::tst(Register rn, const ShifterOperand& so, Condition cond) { 591 CHECK_NE(rn, PC); // Reserve tst pc instruction for exception handler marker. 592 EmitDataProcessing(cond, TST, kCcSet, rn, R0, so); 593 } 594 595 596 void Thumb2Assembler::teq(Register rn, const ShifterOperand& so, Condition cond) { 597 CHECK_NE(rn, PC); // Reserve teq pc instruction for exception handler marker. 598 EmitDataProcessing(cond, TEQ, kCcSet, rn, R0, so); 599 } 600 601 602 void Thumb2Assembler::cmp(Register rn, const ShifterOperand& so, Condition cond) { 603 EmitDataProcessing(cond, CMP, kCcSet, rn, R0, so); 604 } 605 606 607 void Thumb2Assembler::cmn(Register rn, const ShifterOperand& so, Condition cond) { 608 EmitDataProcessing(cond, CMN, kCcSet, rn, R0, so); 609 } 610 611 612 void Thumb2Assembler::orr(Register rd, Register rn, const ShifterOperand& so, 613 Condition cond, SetCc set_cc) { 614 EmitDataProcessing(cond, ORR, set_cc, rn, rd, so); 615 } 616 617 618 void Thumb2Assembler::orn(Register rd, Register rn, const ShifterOperand& so, 619 Condition cond, SetCc set_cc) { 620 EmitDataProcessing(cond, ORN, set_cc, rn, rd, so); 621 } 622 623 624 void Thumb2Assembler::mov(Register rd, const ShifterOperand& so, 625 Condition cond, SetCc set_cc) { 626 EmitDataProcessing(cond, MOV, set_cc, R0, rd, so); 627 } 628 629 630 void Thumb2Assembler::bic(Register rd, Register rn, const ShifterOperand& so, 631 Condition cond, SetCc set_cc) { 632 EmitDataProcessing(cond, BIC, set_cc, rn, rd, so); 633 } 634 635 636 void Thumb2Assembler::mvn(Register rd, const ShifterOperand& so, 637 Condition cond, SetCc set_cc) { 638 EmitDataProcessing(cond, MVN, set_cc, R0, rd, so); 639 } 640 641 642 void Thumb2Assembler::mul(Register rd, Register rn, Register rm, Condition cond) { 643 CheckCondition(cond); 644 645 if (rd == rm && !IsHighRegister(rd) && !IsHighRegister(rn) && !force_32bit_) { 646 // 16 bit. 647 int16_t encoding = B14 | B9 | B8 | B6 | 648 rn << 3 | rd; 649 Emit16(encoding); 650 } else { 651 // 32 bit. 652 uint32_t op1 = 0U /* 0b000 */; 653 uint32_t op2 = 0U /* 0b00 */; 654 int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | 655 op1 << 20 | 656 B15 | B14 | B13 | B12 | 657 op2 << 4 | 658 static_cast<uint32_t>(rd) << 8 | 659 static_cast<uint32_t>(rn) << 16 | 660 static_cast<uint32_t>(rm); 661 662 Emit32(encoding); 663 } 664 } 665 666 667 void Thumb2Assembler::mla(Register rd, Register rn, Register rm, Register ra, 668 Condition cond) { 669 CheckCondition(cond); 670 671 uint32_t op1 = 0U /* 0b000 */; 672 uint32_t op2 = 0U /* 0b00 */; 673 int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | 674 op1 << 20 | 675 op2 << 4 | 676 static_cast<uint32_t>(rd) << 8 | 677 static_cast<uint32_t>(ra) << 12 | 678 static_cast<uint32_t>(rn) << 16 | 679 static_cast<uint32_t>(rm); 680 681 Emit32(encoding); 682 } 683 684 685 void Thumb2Assembler::mls(Register rd, Register rn, Register rm, Register ra, 686 Condition cond) { 687 CheckCondition(cond); 688 689 uint32_t op1 = 0U /* 0b000 */; 690 uint32_t op2 = 01 /* 0b01 */; 691 int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | 692 op1 << 20 | 693 op2 << 4 | 694 static_cast<uint32_t>(rd) << 8 | 695 static_cast<uint32_t>(ra) << 12 | 696 static_cast<uint32_t>(rn) << 16 | 697 static_cast<uint32_t>(rm); 698 699 Emit32(encoding); 700 } 701 702 703 void Thumb2Assembler::smull(Register rd_lo, Register rd_hi, Register rn, 704 Register rm, Condition cond) { 705 CheckCondition(cond); 706 707 uint32_t op1 = 0U /* 0b000; */; 708 uint32_t op2 = 0U /* 0b0000 */; 709 int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | 710 op1 << 20 | 711 op2 << 4 | 712 static_cast<uint32_t>(rd_lo) << 12 | 713 static_cast<uint32_t>(rd_hi) << 8 | 714 static_cast<uint32_t>(rn) << 16 | 715 static_cast<uint32_t>(rm); 716 717 Emit32(encoding); 718 } 719 720 721 void Thumb2Assembler::umull(Register rd_lo, Register rd_hi, Register rn, 722 Register rm, Condition cond) { 723 CheckCondition(cond); 724 725 uint32_t op1 = 2U /* 0b010; */; 726 uint32_t op2 = 0U /* 0b0000 */; 727 int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | 728 op1 << 20 | 729 op2 << 4 | 730 static_cast<uint32_t>(rd_lo) << 12 | 731 static_cast<uint32_t>(rd_hi) << 8 | 732 static_cast<uint32_t>(rn) << 16 | 733 static_cast<uint32_t>(rm); 734 735 Emit32(encoding); 736 } 737 738 739 void Thumb2Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) { 740 CheckCondition(cond); 741 742 uint32_t op1 = 1U /* 0b001 */; 743 uint32_t op2 = 15U /* 0b1111 */; 744 int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | B20 | 745 op1 << 20 | 746 op2 << 4 | 747 0xf << 12 | 748 static_cast<uint32_t>(rd) << 8 | 749 static_cast<uint32_t>(rn) << 16 | 750 static_cast<uint32_t>(rm); 751 752 Emit32(encoding); 753 } 754 755 756 void Thumb2Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) { 757 CheckCondition(cond); 758 759 uint32_t op1 = 1U /* 0b001 */; 760 uint32_t op2 = 15U /* 0b1111 */; 761 int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | B21 | B20 | 762 op1 << 20 | 763 op2 << 4 | 764 0xf << 12 | 765 static_cast<uint32_t>(rd) << 8 | 766 static_cast<uint32_t>(rn) << 16 | 767 static_cast<uint32_t>(rm); 768 769 Emit32(encoding); 770 } 771 772 773 void Thumb2Assembler::sbfx(Register rd, Register rn, uint32_t lsb, uint32_t width, Condition cond) { 774 CheckCondition(cond); 775 CHECK_LE(lsb, 31U); 776 CHECK(1U <= width && width <= 32U) << width; 777 uint32_t widthminus1 = width - 1; 778 uint32_t imm2 = lsb & (B1 | B0); // Bits 0-1 of `lsb`. 779 uint32_t imm3 = (lsb & (B4 | B3 | B2)) >> 2; // Bits 2-4 of `lsb`. 780 781 uint32_t op = 20U /* 0b10100 */; 782 int32_t encoding = B31 | B30 | B29 | B28 | B25 | 783 op << 20 | 784 static_cast<uint32_t>(rn) << 16 | 785 imm3 << 12 | 786 static_cast<uint32_t>(rd) << 8 | 787 imm2 << 6 | 788 widthminus1; 789 790 Emit32(encoding); 791 } 792 793 794 void Thumb2Assembler::ubfx(Register rd, Register rn, uint32_t lsb, uint32_t width, Condition cond) { 795 CheckCondition(cond); 796 CHECK_LE(lsb, 31U); 797 CHECK(1U <= width && width <= 32U) << width; 798 uint32_t widthminus1 = width - 1; 799 uint32_t imm2 = lsb & (B1 | B0); // Bits 0-1 of `lsb`. 800 uint32_t imm3 = (lsb & (B4 | B3 | B2)) >> 2; // Bits 2-4 of `lsb`. 801 802 uint32_t op = 28U /* 0b11100 */; 803 int32_t encoding = B31 | B30 | B29 | B28 | B25 | 804 op << 20 | 805 static_cast<uint32_t>(rn) << 16 | 806 imm3 << 12 | 807 static_cast<uint32_t>(rd) << 8 | 808 imm2 << 6 | 809 widthminus1; 810 811 Emit32(encoding); 812 } 813 814 815 void Thumb2Assembler::ldr(Register rd, const Address& ad, Condition cond) { 816 EmitLoadStore(cond, true, false, false, false, rd, ad); 817 } 818 819 820 void Thumb2Assembler::str(Register rd, const Address& ad, Condition cond) { 821 EmitLoadStore(cond, false, false, false, false, rd, ad); 822 } 823 824 825 void Thumb2Assembler::ldrb(Register rd, const Address& ad, Condition cond) { 826 EmitLoadStore(cond, true, true, false, false, rd, ad); 827 } 828 829 830 void Thumb2Assembler::strb(Register rd, const Address& ad, Condition cond) { 831 EmitLoadStore(cond, false, true, false, false, rd, ad); 832 } 833 834 835 void Thumb2Assembler::ldrh(Register rd, const Address& ad, Condition cond) { 836 EmitLoadStore(cond, true, false, true, false, rd, ad); 837 } 838 839 840 void Thumb2Assembler::strh(Register rd, const Address& ad, Condition cond) { 841 EmitLoadStore(cond, false, false, true, false, rd, ad); 842 } 843 844 845 void Thumb2Assembler::ldrsb(Register rd, const Address& ad, Condition cond) { 846 EmitLoadStore(cond, true, true, false, true, rd, ad); 847 } 848 849 850 void Thumb2Assembler::ldrsh(Register rd, const Address& ad, Condition cond) { 851 EmitLoadStore(cond, true, false, true, true, rd, ad); 852 } 853 854 855 void Thumb2Assembler::ldrd(Register rd, const Address& ad, Condition cond) { 856 ldrd(rd, Register(rd + 1), ad, cond); 857 } 858 859 860 void Thumb2Assembler::ldrd(Register rd, Register rd2, const Address& ad, Condition cond) { 861 CheckCondition(cond); 862 // Encoding T1. 863 // This is different from other loads. The encoding is like ARM. 864 int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 | 865 static_cast<int32_t>(rd) << 12 | 866 static_cast<int32_t>(rd2) << 8 | 867 ad.encodingThumbLdrdStrd(); 868 Emit32(encoding); 869 } 870 871 872 void Thumb2Assembler::strd(Register rd, const Address& ad, Condition cond) { 873 strd(rd, Register(rd + 1), ad, cond); 874 } 875 876 877 void Thumb2Assembler::strd(Register rd, Register rd2, const Address& ad, Condition cond) { 878 CheckCondition(cond); 879 // Encoding T1. 880 // This is different from other loads. The encoding is like ARM. 881 int32_t encoding = B31 | B30 | B29 | B27 | B22 | 882 static_cast<int32_t>(rd) << 12 | 883 static_cast<int32_t>(rd2) << 8 | 884 ad.encodingThumbLdrdStrd(); 885 Emit32(encoding); 886 } 887 888 889 void Thumb2Assembler::ldm(BlockAddressMode am, 890 Register base, 891 RegList regs, 892 Condition cond) { 893 CHECK_NE(regs, 0u); // Do not use ldm if there's nothing to load. 894 if (IsPowerOfTwo(regs)) { 895 // Thumb doesn't support one reg in the list. 896 // Find the register number. 897 int reg = CTZ(static_cast<uint32_t>(regs)); 898 CHECK_LT(reg, 16); 899 CHECK(am == DB_W); // Only writeback is supported. 900 ldr(static_cast<Register>(reg), Address(base, kRegisterSize, Address::PostIndex), cond); 901 } else { 902 EmitMultiMemOp(cond, am, true, base, regs); 903 } 904 } 905 906 907 void Thumb2Assembler::stm(BlockAddressMode am, 908 Register base, 909 RegList regs, 910 Condition cond) { 911 CHECK_NE(regs, 0u); // Do not use stm if there's nothing to store. 912 if (IsPowerOfTwo(regs)) { 913 // Thumb doesn't support one reg in the list. 914 // Find the register number. 915 int reg = CTZ(static_cast<uint32_t>(regs)); 916 CHECK_LT(reg, 16); 917 CHECK(am == IA || am == IA_W); 918 Address::Mode strmode = am == IA ? Address::PreIndex : Address::Offset; 919 str(static_cast<Register>(reg), Address(base, -kRegisterSize, strmode), cond); 920 } else { 921 EmitMultiMemOp(cond, am, false, base, regs); 922 } 923 } 924 925 926 bool Thumb2Assembler::vmovs(SRegister sd, float s_imm, Condition cond) { 927 uint32_t imm32 = bit_cast<uint32_t, float>(s_imm); 928 if (((imm32 & ((1 << 19) - 1)) == 0) && 929 ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) || 930 (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) { 931 uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) | 932 ((imm32 >> 19) & ((1 << 6) -1)); 933 EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf), 934 sd, S0, S0); 935 return true; 936 } 937 return false; 938 } 939 940 941 bool Thumb2Assembler::vmovd(DRegister dd, double d_imm, Condition cond) { 942 uint64_t imm64 = bit_cast<uint64_t, double>(d_imm); 943 if (((imm64 & ((1LL << 48) - 1)) == 0) && 944 ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) || 945 (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) { 946 uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) | 947 ((imm64 >> 48) & ((1 << 6) -1)); 948 EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf), 949 dd, D0, D0); 950 return true; 951 } 952 return false; 953 } 954 955 956 void Thumb2Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) { 957 EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm); 958 } 959 960 961 void Thumb2Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) { 962 EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm); 963 } 964 965 966 void Thumb2Assembler::vadds(SRegister sd, SRegister sn, SRegister sm, 967 Condition cond) { 968 EmitVFPsss(cond, B21 | B20, sd, sn, sm); 969 } 970 971 972 void Thumb2Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm, 973 Condition cond) { 974 EmitVFPddd(cond, B21 | B20, dd, dn, dm); 975 } 976 977 978 void Thumb2Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm, 979 Condition cond) { 980 EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm); 981 } 982 983 984 void Thumb2Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm, 985 Condition cond) { 986 EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm); 987 } 988 989 990 void Thumb2Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm, 991 Condition cond) { 992 EmitVFPsss(cond, B21, sd, sn, sm); 993 } 994 995 996 void Thumb2Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm, 997 Condition cond) { 998 EmitVFPddd(cond, B21, dd, dn, dm); 999 } 1000 1001 1002 void Thumb2Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm, 1003 Condition cond) { 1004 EmitVFPsss(cond, 0, sd, sn, sm); 1005 } 1006 1007 1008 void Thumb2Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm, 1009 Condition cond) { 1010 EmitVFPddd(cond, 0, dd, dn, dm); 1011 } 1012 1013 1014 void Thumb2Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm, 1015 Condition cond) { 1016 EmitVFPsss(cond, B6, sd, sn, sm); 1017 } 1018 1019 1020 void Thumb2Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm, 1021 Condition cond) { 1022 EmitVFPddd(cond, B6, dd, dn, dm); 1023 } 1024 1025 1026 void Thumb2Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm, 1027 Condition cond) { 1028 EmitVFPsss(cond, B23, sd, sn, sm); 1029 } 1030 1031 1032 void Thumb2Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm, 1033 Condition cond) { 1034 EmitVFPddd(cond, B23, dd, dn, dm); 1035 } 1036 1037 1038 void Thumb2Assembler::vabss(SRegister sd, SRegister sm, Condition cond) { 1039 EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm); 1040 } 1041 1042 1043 void Thumb2Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) { 1044 EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm); 1045 } 1046 1047 1048 void Thumb2Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) { 1049 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm); 1050 } 1051 1052 1053 void Thumb2Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) { 1054 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm); 1055 } 1056 1057 1058 void Thumb2Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) { 1059 EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm); 1060 } 1061 1062 void Thumb2Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) { 1063 EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm); 1064 } 1065 1066 1067 void Thumb2Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) { 1068 EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm); 1069 } 1070 1071 1072 void Thumb2Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) { 1073 EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm); 1074 } 1075 1076 1077 void Thumb2Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) { 1078 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm); 1079 } 1080 1081 1082 void Thumb2Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) { 1083 EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm); 1084 } 1085 1086 1087 void Thumb2Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) { 1088 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm); 1089 } 1090 1091 1092 void Thumb2Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) { 1093 EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm); 1094 } 1095 1096 1097 void Thumb2Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) { 1098 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm); 1099 } 1100 1101 1102 void Thumb2Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) { 1103 EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm); 1104 } 1105 1106 1107 void Thumb2Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) { 1108 EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm); 1109 } 1110 1111 1112 void Thumb2Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) { 1113 EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm); 1114 } 1115 1116 1117 void Thumb2Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) { 1118 EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm); 1119 } 1120 1121 1122 void Thumb2Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) { 1123 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm); 1124 } 1125 1126 1127 void Thumb2Assembler::vcmpsz(SRegister sd, Condition cond) { 1128 EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0); 1129 } 1130 1131 1132 void Thumb2Assembler::vcmpdz(DRegister dd, Condition cond) { 1133 EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0); 1134 } 1135 1136 void Thumb2Assembler::b(Label* label, Condition cond) { 1137 DCHECK_EQ(next_condition_, AL); 1138 EmitBranch(cond, label, false, false); 1139 } 1140 1141 1142 void Thumb2Assembler::bl(Label* label, Condition cond) { 1143 CheckCondition(cond); 1144 EmitBranch(cond, label, true, false); 1145 } 1146 1147 1148 void Thumb2Assembler::blx(Label* label) { 1149 EmitBranch(AL, label, true, true); 1150 } 1151 1152 1153 void Thumb2Assembler::MarkExceptionHandler(Label* label) { 1154 EmitDataProcessing(AL, TST, kCcSet, PC, R0, ShifterOperand(0)); 1155 Label l; 1156 b(&l); 1157 EmitBranch(AL, label, false, false); 1158 Bind(&l); 1159 } 1160 1161 1162 void Thumb2Assembler::Emit32(int32_t value) { 1163 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1164 buffer_.Emit<int16_t>(value >> 16); 1165 buffer_.Emit<int16_t>(value & 0xffff); 1166 } 1167 1168 1169 void Thumb2Assembler::Emit16(int16_t value) { 1170 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 1171 buffer_.Emit<int16_t>(value); 1172 } 1173 1174 1175 bool Thumb2Assembler::Is32BitDataProcessing(Condition cond, 1176 Opcode opcode, 1177 SetCc set_cc, 1178 Register rn, 1179 Register rd, 1180 const ShifterOperand& so) { 1181 if (force_32bit_) { 1182 return true; 1183 } 1184 1185 // Check special case for SP relative ADD and SUB immediate. 1186 if ((opcode == ADD || opcode == SUB) && rn == SP && so.IsImmediate() && set_cc != kCcSet) { 1187 // If the immediate is in range, use 16 bit. 1188 if (rd == SP) { 1189 if (so.GetImmediate() < (1 << 9)) { // 9 bit immediate. 1190 return false; 1191 } 1192 } else if (!IsHighRegister(rd) && opcode == ADD) { 1193 if (so.GetImmediate() < (1 << 10)) { // 10 bit immediate. 1194 return false; 1195 } 1196 } 1197 } 1198 1199 bool can_contain_high_register = 1200 (opcode == CMP) || 1201 (opcode == MOV && set_cc != kCcSet) || 1202 ((opcode == ADD) && (rn == rd) && set_cc != kCcSet); 1203 1204 if (IsHighRegister(rd) || IsHighRegister(rn)) { 1205 if (!can_contain_high_register) { 1206 return true; 1207 } 1208 1209 // There are high register instructions available for this opcode. 1210 // However, there is no actual shift available, neither for ADD nor for MOV (ASR/LSR/LSL/ROR). 1211 if (so.IsShift() && (so.GetShift() == RRX || so.GetImmediate() != 0u)) { 1212 return true; 1213 } 1214 1215 // The ADD and MOV instructions that work with high registers don't have 16-bit 1216 // immediate variants. 1217 if (so.IsImmediate()) { 1218 return true; 1219 } 1220 } 1221 1222 if (so.IsRegister() && IsHighRegister(so.GetRegister()) && !can_contain_high_register) { 1223 return true; 1224 } 1225 1226 bool rn_is_valid = true; 1227 1228 // Check for single operand instructions and ADD/SUB. 1229 switch (opcode) { 1230 case CMP: 1231 case MOV: 1232 case TST: 1233 case MVN: 1234 rn_is_valid = false; // There is no Rn for these instructions. 1235 break; 1236 case TEQ: 1237 case ORN: 1238 return true; 1239 case ADD: 1240 case SUB: 1241 break; 1242 default: 1243 if (so.IsRegister() && rd != rn) { 1244 return true; 1245 } 1246 } 1247 1248 if (so.IsImmediate()) { 1249 if (opcode == RSB) { 1250 DCHECK(rn_is_valid); 1251 if (so.GetImmediate() != 0u) { 1252 return true; 1253 } 1254 } else if (rn_is_valid && rn != rd) { 1255 // The only thumb1 instructions with a register and an immediate are ADD and SUB 1256 // with a 3-bit immediate, and RSB with zero immediate. 1257 if (opcode == ADD || opcode == SUB) { 1258 if ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet) { 1259 return true; // Cannot match "setflags". 1260 } 1261 if (!IsUint<3>(so.GetImmediate()) && !IsUint<3>(-so.GetImmediate())) { 1262 return true; 1263 } 1264 } else { 1265 return true; 1266 } 1267 } else { 1268 // ADD, SUB, CMP and MOV may be thumb1 only if the immediate is 8 bits. 1269 if (!(opcode == ADD || opcode == SUB || opcode == MOV || opcode == CMP)) { 1270 return true; 1271 } else if (opcode != CMP && ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet)) { 1272 return true; // Cannot match "setflags" for ADD, SUB or MOV. 1273 } else { 1274 // For ADD and SUB allow also negative 8-bit immediate as we will emit the oposite opcode. 1275 if (!IsUint<8>(so.GetImmediate()) && 1276 (opcode == MOV || opcode == CMP || !IsUint<8>(-so.GetImmediate()))) { 1277 return true; 1278 } 1279 } 1280 } 1281 } else { 1282 DCHECK(so.IsRegister()); 1283 if (so.IsShift()) { 1284 // Shift operand - check if it is a MOV convertible to a 16-bit shift instruction. 1285 if (opcode != MOV) { 1286 return true; 1287 } 1288 // Check for MOV with an ROR/RRX. There is no 16-bit ROR immediate and no 16-bit RRX. 1289 if (so.GetShift() == ROR || so.GetShift() == RRX) { 1290 return true; 1291 } 1292 // 16-bit shifts set condition codes if and only if outside IT block, 1293 // i.e. if and only if cond == AL. 1294 if ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet) { 1295 return true; 1296 } 1297 } else { 1298 // Register operand without shift. 1299 switch (opcode) { 1300 case ADD: 1301 // The 16-bit ADD that cannot contain high registers can set condition codes 1302 // if and only if outside IT block, i.e. if and only if cond == AL. 1303 if (!can_contain_high_register && 1304 ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet)) { 1305 return true; 1306 } 1307 break; 1308 case AND: 1309 case BIC: 1310 case EOR: 1311 case ORR: 1312 case MVN: 1313 case ADC: 1314 case SUB: 1315 case SBC: 1316 // These 16-bit opcodes set condition codes if and only if outside IT block, 1317 // i.e. if and only if cond == AL. 1318 if ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet) { 1319 return true; 1320 } 1321 break; 1322 case RSB: 1323 case RSC: 1324 // No 16-bit RSB/RSC Rd, Rm, Rn. It would be equivalent to SUB/SBC Rd, Rn, Rm. 1325 return true; 1326 case CMP: 1327 default: 1328 break; 1329 } 1330 } 1331 } 1332 1333 // The instruction can be encoded in 16 bits. 1334 return false; 1335 } 1336 1337 1338 void Thumb2Assembler::Emit32BitDataProcessing(Condition cond ATTRIBUTE_UNUSED, 1339 Opcode opcode, 1340 SetCc set_cc, 1341 Register rn, 1342 Register rd, 1343 const ShifterOperand& so) { 1344 uint8_t thumb_opcode = 255U /* 0b11111111 */; 1345 switch (opcode) { 1346 case AND: thumb_opcode = 0U /* 0b0000 */; break; 1347 case EOR: thumb_opcode = 4U /* 0b0100 */; break; 1348 case SUB: thumb_opcode = 13U /* 0b1101 */; break; 1349 case RSB: thumb_opcode = 14U /* 0b1110 */; break; 1350 case ADD: thumb_opcode = 8U /* 0b1000 */; break; 1351 case ADC: thumb_opcode = 10U /* 0b1010 */; break; 1352 case SBC: thumb_opcode = 11U /* 0b1011 */; break; 1353 case RSC: break; 1354 case TST: thumb_opcode = 0U /* 0b0000 */; DCHECK(set_cc == kCcSet); rd = PC; break; 1355 case TEQ: thumb_opcode = 4U /* 0b0100 */; DCHECK(set_cc == kCcSet); rd = PC; break; 1356 case CMP: thumb_opcode = 13U /* 0b1101 */; DCHECK(set_cc == kCcSet); rd = PC; break; 1357 case CMN: thumb_opcode = 8U /* 0b1000 */; DCHECK(set_cc == kCcSet); rd = PC; break; 1358 case ORR: thumb_opcode = 2U /* 0b0010 */; break; 1359 case MOV: thumb_opcode = 2U /* 0b0010 */; rn = PC; break; 1360 case BIC: thumb_opcode = 1U /* 0b0001 */; break; 1361 case MVN: thumb_opcode = 3U /* 0b0011 */; rn = PC; break; 1362 case ORN: thumb_opcode = 3U /* 0b0011 */; break; 1363 default: 1364 break; 1365 } 1366 1367 if (thumb_opcode == 255U /* 0b11111111 */) { 1368 LOG(FATAL) << "Invalid thumb2 opcode " << opcode; 1369 UNREACHABLE(); 1370 } 1371 1372 int32_t encoding = 0; 1373 if (so.IsImmediate()) { 1374 // Check special cases. 1375 if ((opcode == SUB || opcode == ADD) && (so.GetImmediate() < (1u << 12)) && 1376 /* Prefer T3 encoding to T4. */ !ShifterOperandCanAlwaysHold(so.GetImmediate())) { 1377 if (set_cc != kCcSet) { 1378 if (opcode == SUB) { 1379 thumb_opcode = 5U; 1380 } else if (opcode == ADD) { 1381 thumb_opcode = 0U; 1382 } 1383 } 1384 uint32_t imm = so.GetImmediate(); 1385 1386 uint32_t i = (imm >> 11) & 1; 1387 uint32_t imm3 = (imm >> 8) & 7U /* 0b111 */; 1388 uint32_t imm8 = imm & 0xff; 1389 1390 encoding = B31 | B30 | B29 | B28 | 1391 (set_cc == kCcSet ? B20 : B25) | 1392 thumb_opcode << 21 | 1393 rn << 16 | 1394 rd << 8 | 1395 i << 26 | 1396 imm3 << 12 | 1397 imm8; 1398 } else { 1399 // Modified immediate. 1400 uint32_t imm = ModifiedImmediate(so.encodingThumb()); 1401 if (imm == kInvalidModifiedImmediate) { 1402 LOG(FATAL) << "Immediate value cannot fit in thumb2 modified immediate"; 1403 UNREACHABLE(); 1404 } 1405 encoding = B31 | B30 | B29 | B28 | 1406 thumb_opcode << 21 | 1407 (set_cc == kCcSet ? B20 : 0) | 1408 rn << 16 | 1409 rd << 8 | 1410 imm; 1411 } 1412 } else if (so.IsRegister()) { 1413 // Register (possibly shifted) 1414 encoding = B31 | B30 | B29 | B27 | B25 | 1415 thumb_opcode << 21 | 1416 (set_cc == kCcSet ? B20 : 0) | 1417 rn << 16 | 1418 rd << 8 | 1419 so.encodingThumb(); 1420 } 1421 Emit32(encoding); 1422 } 1423 1424 1425 void Thumb2Assembler::Emit16BitDataProcessing(Condition cond, 1426 Opcode opcode, 1427 SetCc set_cc, 1428 Register rn, 1429 Register rd, 1430 const ShifterOperand& so) { 1431 if (opcode == ADD || opcode == SUB) { 1432 Emit16BitAddSub(cond, opcode, set_cc, rn, rd, so); 1433 return; 1434 } 1435 uint8_t thumb_opcode = 255U /* 0b11111111 */; 1436 // Thumb1. 1437 uint8_t dp_opcode = 1U /* 0b01 */; 1438 uint8_t opcode_shift = 6; 1439 uint8_t rd_shift = 0; 1440 uint8_t rn_shift = 3; 1441 uint8_t immediate_shift = 0; 1442 bool use_immediate = false; 1443 uint8_t immediate = 0; 1444 1445 if (opcode == MOV && so.IsRegister() && so.IsShift()) { 1446 // Convert shifted mov operand2 into 16 bit opcodes. 1447 dp_opcode = 0; 1448 opcode_shift = 11; 1449 1450 use_immediate = true; 1451 immediate = so.GetImmediate(); 1452 immediate_shift = 6; 1453 1454 rn = so.GetRegister(); 1455 1456 switch (so.GetShift()) { 1457 case LSL: 1458 DCHECK_LE(immediate, 31u); 1459 thumb_opcode = 0U /* 0b00 */; 1460 break; 1461 case LSR: 1462 DCHECK(1 <= immediate && immediate <= 32); 1463 immediate &= 31; // 32 is encoded as 0. 1464 thumb_opcode = 1U /* 0b01 */; 1465 break; 1466 case ASR: 1467 DCHECK(1 <= immediate && immediate <= 32); 1468 immediate &= 31; // 32 is encoded as 0. 1469 thumb_opcode = 2U /* 0b10 */; 1470 break; 1471 case ROR: // No 16-bit ROR immediate. 1472 case RRX: // No 16-bit RRX. 1473 default: 1474 LOG(FATAL) << "Unexpected shift: " << so.GetShift(); 1475 UNREACHABLE(); 1476 } 1477 } else { 1478 if (so.IsImmediate()) { 1479 use_immediate = true; 1480 immediate = so.GetImmediate(); 1481 } else { 1482 CHECK(!(so.IsRegister() && so.IsShift() && so.GetSecondRegister() != kNoRegister)) 1483 << "No register-shifted register instruction available in thumb"; 1484 // Adjust rn and rd: only two registers will be emitted. 1485 switch (opcode) { 1486 case AND: 1487 case ORR: 1488 case EOR: 1489 case RSB: 1490 case ADC: 1491 case SBC: 1492 case BIC: { 1493 // Sets condition codes if and only if outside IT block, 1494 // check that it complies with set_cc. 1495 DCHECK((cond == AL) ? set_cc != kCcKeep : set_cc != kCcSet); 1496 if (rn == rd) { 1497 rn = so.GetRegister(); 1498 } else { 1499 CHECK_EQ(rd, so.GetRegister()); 1500 } 1501 break; 1502 } 1503 case CMP: 1504 case CMN: { 1505 CHECK_EQ(rd, 0); 1506 rd = rn; 1507 rn = so.GetRegister(); 1508 break; 1509 } 1510 case MVN: { 1511 // Sets condition codes if and only if outside IT block, 1512 // check that it complies with set_cc. 1513 DCHECK((cond == AL) ? set_cc != kCcKeep : set_cc != kCcSet); 1514 CHECK_EQ(rn, 0); 1515 rn = so.GetRegister(); 1516 break; 1517 } 1518 case TST: 1519 case TEQ: { 1520 DCHECK(set_cc == kCcSet); 1521 CHECK_EQ(rn, 0); 1522 rn = so.GetRegister(); 1523 break; 1524 } 1525 default: 1526 break; 1527 } 1528 } 1529 1530 switch (opcode) { 1531 case AND: thumb_opcode = 0U /* 0b0000 */; break; 1532 case ORR: thumb_opcode = 12U /* 0b1100 */; break; 1533 case EOR: thumb_opcode = 1U /* 0b0001 */; break; 1534 case RSB: thumb_opcode = 9U /* 0b1001 */; break; 1535 case ADC: thumb_opcode = 5U /* 0b0101 */; break; 1536 case SBC: thumb_opcode = 6U /* 0b0110 */; break; 1537 case BIC: thumb_opcode = 14U /* 0b1110 */; break; 1538 case TST: thumb_opcode = 8U /* 0b1000 */; CHECK(!use_immediate); break; 1539 case MVN: thumb_opcode = 15U /* 0b1111 */; CHECK(!use_immediate); break; 1540 case CMP: { 1541 DCHECK(set_cc == kCcSet); 1542 if (use_immediate) { 1543 // T2 encoding. 1544 dp_opcode = 0; 1545 opcode_shift = 11; 1546 thumb_opcode = 5U /* 0b101 */; 1547 rd_shift = 8; 1548 rn_shift = 8; 1549 } else if (IsHighRegister(rd) || IsHighRegister(rn)) { 1550 // Special cmp for high registers. 1551 dp_opcode = 1U /* 0b01 */; 1552 opcode_shift = 7; 1553 // Put the top bit of rd into the bottom bit of the opcode. 1554 thumb_opcode = 10U /* 0b0001010 */ | static_cast<uint32_t>(rd) >> 3; 1555 rd = static_cast<Register>(static_cast<uint32_t>(rd) & 7U /* 0b111 */); 1556 } else { 1557 thumb_opcode = 10U /* 0b1010 */; 1558 } 1559 1560 break; 1561 } 1562 case CMN: { 1563 CHECK(!use_immediate); 1564 thumb_opcode = 11U /* 0b1011 */; 1565 break; 1566 } 1567 case MOV: 1568 dp_opcode = 0; 1569 if (use_immediate) { 1570 // T2 encoding. 1571 opcode_shift = 11; 1572 thumb_opcode = 4U /* 0b100 */; 1573 rd_shift = 8; 1574 rn_shift = 8; 1575 } else { 1576 rn = so.GetRegister(); 1577 if (set_cc != kCcSet) { 1578 // Special mov for high registers. 1579 dp_opcode = 1U /* 0b01 */; 1580 opcode_shift = 7; 1581 // Put the top bit of rd into the bottom bit of the opcode. 1582 thumb_opcode = 12U /* 0b0001100 */ | static_cast<uint32_t>(rd) >> 3; 1583 rd = static_cast<Register>(static_cast<uint32_t>(rd) & 7U /* 0b111 */); 1584 } else { 1585 DCHECK(!IsHighRegister(rn)); 1586 DCHECK(!IsHighRegister(rd)); 1587 thumb_opcode = 0; 1588 } 1589 } 1590 break; 1591 1592 case TEQ: 1593 case RSC: 1594 default: 1595 LOG(FATAL) << "Invalid thumb1 opcode " << opcode; 1596 break; 1597 } 1598 } 1599 1600 if (thumb_opcode == 255U /* 0b11111111 */) { 1601 LOG(FATAL) << "Invalid thumb1 opcode " << opcode; 1602 UNREACHABLE(); 1603 } 1604 1605 int16_t encoding = dp_opcode << 14 | 1606 (thumb_opcode << opcode_shift) | 1607 rd << rd_shift | 1608 rn << rn_shift | 1609 (use_immediate ? (immediate << immediate_shift) : 0); 1610 1611 Emit16(encoding); 1612 } 1613 1614 1615 // ADD and SUB are complex enough to warrant their own emitter. 1616 void Thumb2Assembler::Emit16BitAddSub(Condition cond, 1617 Opcode opcode, 1618 SetCc set_cc, 1619 Register rn, 1620 Register rd, 1621 const ShifterOperand& so) { 1622 uint8_t dp_opcode = 0; 1623 uint8_t opcode_shift = 6; 1624 uint8_t rd_shift = 0; 1625 uint8_t rn_shift = 3; 1626 uint8_t immediate_shift = 0; 1627 bool use_immediate = false; 1628 uint32_t immediate = 0; // Should be at most 10 bits but keep the full immediate for CHECKs. 1629 uint8_t thumb_opcode; 1630 1631 if (so.IsImmediate()) { 1632 use_immediate = true; 1633 immediate = so.GetImmediate(); 1634 if (!IsUint<10>(immediate)) { 1635 // Flip ADD/SUB. 1636 opcode = (opcode == ADD) ? SUB : ADD; 1637 immediate = -immediate; 1638 DCHECK(IsUint<10>(immediate)); // More stringent checks below. 1639 } 1640 } 1641 1642 switch (opcode) { 1643 case ADD: 1644 if (so.IsRegister()) { 1645 Register rm = so.GetRegister(); 1646 if (rn == rd && set_cc != kCcSet) { 1647 // Can use T2 encoding (allows 4 bit registers) 1648 dp_opcode = 1U /* 0b01 */; 1649 opcode_shift = 10; 1650 thumb_opcode = 1U /* 0b0001 */; 1651 // Make Rn also contain the top bit of rd. 1652 rn = static_cast<Register>(static_cast<uint32_t>(rm) | 1653 (static_cast<uint32_t>(rd) & 8U /* 0b1000 */) << 1); 1654 rd = static_cast<Register>(static_cast<uint32_t>(rd) & 7U /* 0b111 */); 1655 } else { 1656 // T1. 1657 DCHECK(!IsHighRegister(rd)); 1658 DCHECK(!IsHighRegister(rn)); 1659 DCHECK(!IsHighRegister(rm)); 1660 // Sets condition codes if and only if outside IT block, 1661 // check that it complies with set_cc. 1662 DCHECK((cond == AL) ? set_cc != kCcKeep : set_cc != kCcSet); 1663 opcode_shift = 9; 1664 thumb_opcode = 12U /* 0b01100 */; 1665 immediate = static_cast<uint32_t>(so.GetRegister()); 1666 use_immediate = true; 1667 immediate_shift = 6; 1668 } 1669 } else { 1670 // Immediate. 1671 if (rd == SP && rn == SP) { 1672 // ADD sp, sp, #imm 1673 dp_opcode = 2U /* 0b10 */; 1674 thumb_opcode = 3U /* 0b11 */; 1675 opcode_shift = 12; 1676 CHECK(IsUint<9>(immediate)); 1677 CHECK_ALIGNED(immediate, 4); 1678 1679 // Remove rd and rn from instruction by orring it with immed and clearing bits. 1680 rn = R0; 1681 rd = R0; 1682 rd_shift = 0; 1683 rn_shift = 0; 1684 immediate >>= 2; 1685 } else if (rd != SP && rn == SP) { 1686 // ADD rd, SP, #imm 1687 dp_opcode = 2U /* 0b10 */; 1688 thumb_opcode = 5U /* 0b101 */; 1689 opcode_shift = 11; 1690 CHECK(IsUint<10>(immediate)); 1691 CHECK_ALIGNED(immediate, 4); 1692 1693 // Remove rn from instruction. 1694 rn = R0; 1695 rn_shift = 0; 1696 rd_shift = 8; 1697 immediate >>= 2; 1698 } else if (rn != rd) { 1699 // Must use T1. 1700 CHECK(IsUint<3>(immediate)); 1701 opcode_shift = 9; 1702 thumb_opcode = 14U /* 0b01110 */; 1703 immediate_shift = 6; 1704 } else { 1705 // T2 encoding. 1706 CHECK(IsUint<8>(immediate)); 1707 opcode_shift = 11; 1708 thumb_opcode = 6U /* 0b110 */; 1709 rd_shift = 8; 1710 rn_shift = 8; 1711 } 1712 } 1713 break; 1714 1715 case SUB: 1716 if (so.IsRegister()) { 1717 // T1. 1718 Register rm = so.GetRegister(); 1719 DCHECK(!IsHighRegister(rd)); 1720 DCHECK(!IsHighRegister(rn)); 1721 DCHECK(!IsHighRegister(rm)); 1722 // Sets condition codes if and only if outside IT block, 1723 // check that it complies with set_cc. 1724 DCHECK((cond == AL) ? set_cc != kCcKeep : set_cc != kCcSet); 1725 opcode_shift = 9; 1726 thumb_opcode = 13U /* 0b01101 */; 1727 immediate = static_cast<uint32_t>(rm); 1728 use_immediate = true; 1729 immediate_shift = 6; 1730 } else { 1731 if (rd == SP && rn == SP) { 1732 // SUB sp, sp, #imm 1733 dp_opcode = 2U /* 0b10 */; 1734 thumb_opcode = 0x61 /* 0b1100001 */; 1735 opcode_shift = 7; 1736 CHECK(IsUint<9>(immediate)); 1737 CHECK_ALIGNED(immediate, 4); 1738 1739 // Remove rd and rn from instruction by orring it with immed and clearing bits. 1740 rn = R0; 1741 rd = R0; 1742 rd_shift = 0; 1743 rn_shift = 0; 1744 immediate >>= 2; 1745 } else if (rn != rd) { 1746 // Must use T1. 1747 CHECK(IsUint<3>(immediate)); 1748 opcode_shift = 9; 1749 thumb_opcode = 15U /* 0b01111 */; 1750 immediate_shift = 6; 1751 } else { 1752 // T2 encoding. 1753 CHECK(IsUint<8>(immediate)); 1754 opcode_shift = 11; 1755 thumb_opcode = 7U /* 0b111 */; 1756 rd_shift = 8; 1757 rn_shift = 8; 1758 } 1759 } 1760 break; 1761 default: 1762 LOG(FATAL) << "This opcode is not an ADD or SUB: " << opcode; 1763 UNREACHABLE(); 1764 } 1765 1766 int16_t encoding = dp_opcode << 14 | 1767 (thumb_opcode << opcode_shift) | 1768 rd << rd_shift | 1769 rn << rn_shift | 1770 (use_immediate ? (immediate << immediate_shift) : 0); 1771 1772 Emit16(encoding); 1773 } 1774 1775 1776 void Thumb2Assembler::EmitDataProcessing(Condition cond, 1777 Opcode opcode, 1778 SetCc set_cc, 1779 Register rn, 1780 Register rd, 1781 const ShifterOperand& so) { 1782 CHECK_NE(rd, kNoRegister); 1783 CheckCondition(cond); 1784 1785 if (Is32BitDataProcessing(cond, opcode, set_cc, rn, rd, so)) { 1786 Emit32BitDataProcessing(cond, opcode, set_cc, rn, rd, so); 1787 } else { 1788 Emit16BitDataProcessing(cond, opcode, set_cc, rn, rd, so); 1789 } 1790 } 1791 1792 void Thumb2Assembler::EmitShift(Register rd, 1793 Register rm, 1794 Shift shift, 1795 uint8_t amount, 1796 Condition cond, 1797 SetCc set_cc) { 1798 CHECK_LT(amount, (1 << 5)); 1799 if ((IsHighRegister(rd) || IsHighRegister(rm) || shift == ROR || shift == RRX) || 1800 ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet)) { 1801 uint16_t opcode = 0; 1802 switch (shift) { 1803 case LSL: opcode = 0U /* 0b00 */; break; 1804 case LSR: opcode = 1U /* 0b01 */; break; 1805 case ASR: opcode = 2U /* 0b10 */; break; 1806 case ROR: opcode = 3U /* 0b11 */; break; 1807 case RRX: opcode = 3U /* 0b11 */; amount = 0; break; 1808 default: 1809 LOG(FATAL) << "Unsupported thumb2 shift opcode"; 1810 UNREACHABLE(); 1811 } 1812 // 32 bit. 1813 int32_t encoding = B31 | B30 | B29 | B27 | B25 | B22 | 1814 0xf << 16 | (set_cc == kCcSet ? B20 : 0); 1815 uint32_t imm3 = amount >> 2; 1816 uint32_t imm2 = amount & 3U /* 0b11 */; 1817 encoding |= imm3 << 12 | imm2 << 6 | static_cast<int16_t>(rm) | 1818 static_cast<int16_t>(rd) << 8 | opcode << 4; 1819 Emit32(encoding); 1820 } else { 1821 // 16 bit shift 1822 uint16_t opcode = 0; 1823 switch (shift) { 1824 case LSL: opcode = 0U /* 0b00 */; break; 1825 case LSR: opcode = 1U /* 0b01 */; break; 1826 case ASR: opcode = 2U /* 0b10 */; break; 1827 default: 1828 LOG(FATAL) << "Unsupported thumb2 shift opcode"; 1829 UNREACHABLE(); 1830 } 1831 int16_t encoding = opcode << 11 | amount << 6 | static_cast<int16_t>(rm) << 3 | 1832 static_cast<int16_t>(rd); 1833 Emit16(encoding); 1834 } 1835 } 1836 1837 void Thumb2Assembler::EmitShift(Register rd, 1838 Register rn, 1839 Shift shift, 1840 Register rm, 1841 Condition cond, 1842 SetCc set_cc) { 1843 CHECK_NE(shift, RRX); 1844 bool must_be_32bit = false; 1845 if (IsHighRegister(rd) || IsHighRegister(rm) || IsHighRegister(rn) || rd != rn || 1846 ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet)) { 1847 must_be_32bit = true; 1848 } 1849 1850 if (must_be_32bit) { 1851 uint16_t opcode = 0; 1852 switch (shift) { 1853 case LSL: opcode = 0U /* 0b00 */; break; 1854 case LSR: opcode = 1U /* 0b01 */; break; 1855 case ASR: opcode = 2U /* 0b10 */; break; 1856 case ROR: opcode = 3U /* 0b11 */; break; 1857 default: 1858 LOG(FATAL) << "Unsupported thumb2 shift opcode"; 1859 UNREACHABLE(); 1860 } 1861 // 32 bit. 1862 int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | 1863 0xf << 12 | (set_cc == kCcSet ? B20 : 0); 1864 encoding |= static_cast<int16_t>(rn) << 16 | static_cast<int16_t>(rm) | 1865 static_cast<int16_t>(rd) << 8 | opcode << 21; 1866 Emit32(encoding); 1867 } else { 1868 uint16_t opcode = 0; 1869 switch (shift) { 1870 case LSL: opcode = 2U /* 0b0010 */; break; 1871 case LSR: opcode = 3U /* 0b0011 */; break; 1872 case ASR: opcode = 4U /* 0b0100 */; break; 1873 case ROR: opcode = 7U /* 0b0111 */; break; 1874 default: 1875 LOG(FATAL) << "Unsupported thumb2 shift opcode"; 1876 UNREACHABLE(); 1877 } 1878 int16_t encoding = B14 | opcode << 6 | static_cast<int16_t>(rm) << 3 | 1879 static_cast<int16_t>(rd); 1880 Emit16(encoding); 1881 } 1882 } 1883 1884 inline size_t Thumb2Assembler::Fixup::SizeInBytes(Size size) { 1885 switch (size) { 1886 case kBranch16Bit: 1887 return 2u; 1888 case kBranch32Bit: 1889 return 4u; 1890 1891 case kCbxz16Bit: 1892 return 2u; 1893 case kCbxz32Bit: 1894 return 4u; 1895 case kCbxz48Bit: 1896 return 6u; 1897 1898 case kLiteral1KiB: 1899 return 2u; 1900 case kLiteral4KiB: 1901 return 4u; 1902 case kLiteral64KiB: 1903 return 8u; 1904 case kLiteral1MiB: 1905 return 10u; 1906 case kLiteralFar: 1907 return 14u; 1908 1909 case kLiteralAddr1KiB: 1910 return 2u; 1911 case kLiteralAddr4KiB: 1912 return 4u; 1913 case kLiteralAddr64KiB: 1914 return 6u; 1915 case kLiteralAddrFar: 1916 return 10u; 1917 1918 case kLongOrFPLiteral1KiB: 1919 return 4u; 1920 case kLongOrFPLiteral256KiB: 1921 return 10u; 1922 case kLongOrFPLiteralFar: 1923 return 14u; 1924 } 1925 LOG(FATAL) << "Unexpected size: " << static_cast<int>(size); 1926 UNREACHABLE(); 1927 } 1928 1929 inline uint32_t Thumb2Assembler::Fixup::GetOriginalSizeInBytes() const { 1930 return SizeInBytes(original_size_); 1931 } 1932 1933 inline uint32_t Thumb2Assembler::Fixup::GetSizeInBytes() const { 1934 return SizeInBytes(size_); 1935 } 1936 1937 inline size_t Thumb2Assembler::Fixup::LiteralPoolPaddingSize(uint32_t current_code_size) { 1938 // The code size must be a multiple of 2. 1939 DCHECK_ALIGNED(current_code_size, 2); 1940 // If it isn't a multiple of 4, we need to add a 2-byte padding before the literal pool. 1941 return current_code_size & 2; 1942 } 1943 1944 inline int32_t Thumb2Assembler::Fixup::GetOffset(uint32_t current_code_size) const { 1945 static constexpr int32_t int32_min = std::numeric_limits<int32_t>::min(); 1946 static constexpr int32_t int32_max = std::numeric_limits<int32_t>::max(); 1947 DCHECK_LE(target_, static_cast<uint32_t>(int32_max)); 1948 DCHECK_LE(location_, static_cast<uint32_t>(int32_max)); 1949 DCHECK_LE(adjustment_, static_cast<uint32_t>(int32_max)); 1950 int32_t diff = static_cast<int32_t>(target_) - static_cast<int32_t>(location_); 1951 if (target_ > location_) { 1952 DCHECK_LE(adjustment_, static_cast<uint32_t>(int32_max - diff)); 1953 diff += static_cast<int32_t>(adjustment_); 1954 } else { 1955 DCHECK_LE(int32_min + static_cast<int32_t>(adjustment_), diff); 1956 diff -= static_cast<int32_t>(adjustment_); 1957 } 1958 // The default PC adjustment for Thumb2 is 4 bytes. 1959 DCHECK_GE(diff, int32_min + 4); 1960 diff -= 4; 1961 // Add additional adjustment for instructions preceding the PC usage, padding 1962 // before the literal pool and rounding down the PC for literal loads. 1963 switch (GetSize()) { 1964 case kBranch16Bit: 1965 case kBranch32Bit: 1966 break; 1967 1968 case kCbxz16Bit: 1969 break; 1970 case kCbxz32Bit: 1971 case kCbxz48Bit: 1972 DCHECK_GE(diff, int32_min + 2); 1973 diff -= 2; // Extra CMP Rn, #0, 16-bit. 1974 break; 1975 1976 case kLiteral1KiB: 1977 case kLiteral4KiB: 1978 case kLongOrFPLiteral1KiB: 1979 case kLiteralAddr1KiB: 1980 case kLiteralAddr4KiB: 1981 DCHECK(diff >= 0 || (GetSize() == kLiteral1KiB && diff == -2)); 1982 diff += LiteralPoolPaddingSize(current_code_size); 1983 // Load literal instructions round down the PC+4 to a multiple of 4, so if the PC 1984 // isn't a multiple of 2, we need to adjust. Since we already adjusted for the target 1985 // being aligned, current PC alignment can be inferred from diff. 1986 DCHECK_ALIGNED(diff, 2); 1987 diff = diff + (diff & 2); 1988 DCHECK_GE(diff, 0); 1989 break; 1990 case kLiteral1MiB: 1991 case kLiteral64KiB: 1992 case kLongOrFPLiteral256KiB: 1993 case kLiteralAddr64KiB: 1994 DCHECK_GE(diff, 4); // The target must be at least 4 bytes after the ADD rX, PC. 1995 diff -= 4; // One extra 32-bit MOV. 1996 diff += LiteralPoolPaddingSize(current_code_size); 1997 break; 1998 case kLiteralFar: 1999 case kLongOrFPLiteralFar: 2000 case kLiteralAddrFar: 2001 DCHECK_GE(diff, 8); // The target must be at least 4 bytes after the ADD rX, PC. 2002 diff -= 8; // Extra MOVW+MOVT; both 32-bit. 2003 diff += LiteralPoolPaddingSize(current_code_size); 2004 break; 2005 } 2006 return diff; 2007 } 2008 2009 inline size_t Thumb2Assembler::Fixup::IncreaseSize(Size new_size) { 2010 DCHECK_NE(target_, kUnresolved); 2011 Size old_size = size_; 2012 size_ = new_size; 2013 DCHECK_GT(SizeInBytes(new_size), SizeInBytes(old_size)); 2014 size_t adjustment = SizeInBytes(new_size) - SizeInBytes(old_size); 2015 if (target_ > location_) { 2016 adjustment_ += adjustment; 2017 } 2018 return adjustment; 2019 } 2020 2021 uint32_t Thumb2Assembler::Fixup::AdjustSizeIfNeeded(uint32_t current_code_size) { 2022 uint32_t old_code_size = current_code_size; 2023 switch (GetSize()) { 2024 case kBranch16Bit: 2025 if (IsInt(cond_ != AL ? 9 : 12, GetOffset(current_code_size))) { 2026 break; 2027 } 2028 current_code_size += IncreaseSize(kBranch32Bit); 2029 FALLTHROUGH_INTENDED; 2030 case kBranch32Bit: 2031 // We don't support conditional branches beyond +-1MiB 2032 // or unconditional branches beyond +-16MiB. 2033 break; 2034 2035 case kCbxz16Bit: 2036 if (IsUint<7>(GetOffset(current_code_size))) { 2037 break; 2038 } 2039 current_code_size += IncreaseSize(kCbxz32Bit); 2040 FALLTHROUGH_INTENDED; 2041 case kCbxz32Bit: 2042 if (IsInt<9>(GetOffset(current_code_size))) { 2043 break; 2044 } 2045 current_code_size += IncreaseSize(kCbxz48Bit); 2046 FALLTHROUGH_INTENDED; 2047 case kCbxz48Bit: 2048 // We don't support conditional branches beyond +-1MiB. 2049 break; 2050 2051 case kLiteral1KiB: 2052 DCHECK(!IsHighRegister(rn_)); 2053 if (IsUint<10>(GetOffset(current_code_size))) { 2054 break; 2055 } 2056 current_code_size += IncreaseSize(kLiteral4KiB); 2057 FALLTHROUGH_INTENDED; 2058 case kLiteral4KiB: 2059 if (IsUint<12>(GetOffset(current_code_size))) { 2060 break; 2061 } 2062 current_code_size += IncreaseSize(kLiteral64KiB); 2063 FALLTHROUGH_INTENDED; 2064 case kLiteral64KiB: 2065 // Can't handle high register which we can encounter by fall-through from kLiteral4KiB. 2066 if (!IsHighRegister(rn_) && IsUint<16>(GetOffset(current_code_size))) { 2067 break; 2068 } 2069 current_code_size += IncreaseSize(kLiteral1MiB); 2070 FALLTHROUGH_INTENDED; 2071 case kLiteral1MiB: 2072 if (IsUint<20>(GetOffset(current_code_size))) { 2073 break; 2074 } 2075 current_code_size += IncreaseSize(kLiteralFar); 2076 FALLTHROUGH_INTENDED; 2077 case kLiteralFar: 2078 // This encoding can reach any target. 2079 break; 2080 2081 case kLiteralAddr1KiB: 2082 DCHECK(!IsHighRegister(rn_)); 2083 if (IsUint<10>(GetOffset(current_code_size))) { 2084 break; 2085 } 2086 current_code_size += IncreaseSize(kLiteralAddr4KiB); 2087 FALLTHROUGH_INTENDED; 2088 case kLiteralAddr4KiB: 2089 if (IsUint<12>(GetOffset(current_code_size))) { 2090 break; 2091 } 2092 current_code_size += IncreaseSize(kLiteralAddr64KiB); 2093 FALLTHROUGH_INTENDED; 2094 case kLiteralAddr64KiB: 2095 if (IsUint<16>(GetOffset(current_code_size))) { 2096 break; 2097 } 2098 current_code_size += IncreaseSize(kLiteralAddrFar); 2099 FALLTHROUGH_INTENDED; 2100 case kLiteralAddrFar: 2101 // This encoding can reach any target. 2102 break; 2103 2104 case kLongOrFPLiteral1KiB: 2105 if (IsUint<10>(GetOffset(current_code_size))) { 2106 break; 2107 } 2108 current_code_size += IncreaseSize(kLongOrFPLiteral256KiB); 2109 FALLTHROUGH_INTENDED; 2110 case kLongOrFPLiteral256KiB: 2111 if (IsUint<18>(GetOffset(current_code_size))) { 2112 break; 2113 } 2114 current_code_size += IncreaseSize(kLongOrFPLiteralFar); 2115 FALLTHROUGH_INTENDED; 2116 case kLongOrFPLiteralFar: 2117 // This encoding can reach any target. 2118 break; 2119 } 2120 return current_code_size - old_code_size; 2121 } 2122 2123 void Thumb2Assembler::Fixup::Emit(AssemblerBuffer* buffer, uint32_t code_size) const { 2124 switch (GetSize()) { 2125 case kBranch16Bit: { 2126 DCHECK(type_ == kUnconditional || type_ == kConditional); 2127 DCHECK_EQ(type_ == kConditional, cond_ != AL); 2128 int16_t encoding = BEncoding16(GetOffset(code_size), cond_); 2129 buffer->Store<int16_t>(location_, encoding); 2130 break; 2131 } 2132 case kBranch32Bit: { 2133 DCHECK(type_ == kConditional || type_ == kUnconditional || 2134 type_ == kUnconditionalLink || type_ == kUnconditionalLinkX); 2135 DCHECK_EQ(type_ == kConditional, cond_ != AL); 2136 int32_t encoding = BEncoding32(GetOffset(code_size), cond_); 2137 if (type_ == kUnconditionalLink) { 2138 DCHECK_NE(encoding & B12, 0); 2139 encoding |= B14; 2140 } else if (type_ == kUnconditionalLinkX) { 2141 DCHECK_NE(encoding & B12, 0); 2142 encoding ^= B14 | B12; 2143 } 2144 buffer->Store<int16_t>(location_, encoding >> 16); 2145 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(encoding & 0xffff)); 2146 break; 2147 } 2148 2149 case kCbxz16Bit: { 2150 DCHECK(type_ == kCompareAndBranchXZero); 2151 int16_t encoding = CbxzEncoding16(rn_, GetOffset(code_size), cond_); 2152 buffer->Store<int16_t>(location_, encoding); 2153 break; 2154 } 2155 case kCbxz32Bit: { 2156 DCHECK(type_ == kCompareAndBranchXZero); 2157 DCHECK(cond_ == EQ || cond_ == NE); 2158 int16_t cmp_encoding = CmpRnImm8Encoding16(rn_, 0); 2159 int16_t b_encoding = BEncoding16(GetOffset(code_size), cond_); 2160 buffer->Store<int16_t>(location_, cmp_encoding); 2161 buffer->Store<int16_t>(location_ + 2, b_encoding); 2162 break; 2163 } 2164 case kCbxz48Bit: { 2165 DCHECK(type_ == kCompareAndBranchXZero); 2166 DCHECK(cond_ == EQ || cond_ == NE); 2167 int16_t cmp_encoding = CmpRnImm8Encoding16(rn_, 0); 2168 int32_t b_encoding = BEncoding32(GetOffset(code_size), cond_); 2169 buffer->Store<int16_t>(location_, cmp_encoding); 2170 buffer->Store<int16_t>(location_ + 2u, b_encoding >> 16); 2171 buffer->Store<int16_t>(location_ + 4u, static_cast<int16_t>(b_encoding & 0xffff)); 2172 break; 2173 } 2174 2175 case kLiteral1KiB: { 2176 DCHECK(type_ == kLoadLiteralNarrow); 2177 int16_t encoding = LdrLitEncoding16(rn_, GetOffset(code_size)); 2178 buffer->Store<int16_t>(location_, encoding); 2179 break; 2180 } 2181 case kLiteral4KiB: { 2182 DCHECK(type_ == kLoadLiteralNarrow); 2183 // GetOffset() uses PC+4 but load literal uses AlignDown(PC+4, 4). Adjust offset accordingly. 2184 int32_t encoding = LdrLitEncoding32(rn_, GetOffset(code_size)); 2185 buffer->Store<int16_t>(location_, encoding >> 16); 2186 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(encoding & 0xffff)); 2187 break; 2188 } 2189 case kLiteral64KiB: { 2190 DCHECK(type_ == kLoadLiteralNarrow); 2191 int32_t mov_encoding = MovwEncoding32(rn_, GetOffset(code_size)); 2192 int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC); 2193 int16_t ldr_encoding = LdrRtRnImm5Encoding16(rn_, rn_, 0); 2194 buffer->Store<int16_t>(location_, mov_encoding >> 16); 2195 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(mov_encoding & 0xffff)); 2196 buffer->Store<int16_t>(location_ + 4u, add_pc_encoding); 2197 buffer->Store<int16_t>(location_ + 6u, ldr_encoding); 2198 break; 2199 } 2200 case kLiteral1MiB: { 2201 DCHECK(type_ == kLoadLiteralNarrow); 2202 int32_t offset = GetOffset(code_size); 2203 int32_t mov_encoding = MovModImmEncoding32(rn_, offset & ~0xfff); 2204 int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC); 2205 int32_t ldr_encoding = LdrRtRnImm12Encoding(rn_, rn_, offset & 0xfff); 2206 buffer->Store<int16_t>(location_, mov_encoding >> 16); 2207 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(mov_encoding & 0xffff)); 2208 buffer->Store<int16_t>(location_ + 4u, add_pc_encoding); 2209 buffer->Store<int16_t>(location_ + 6u, ldr_encoding >> 16); 2210 buffer->Store<int16_t>(location_ + 8u, static_cast<int16_t>(ldr_encoding & 0xffff)); 2211 break; 2212 } 2213 case kLiteralFar: { 2214 DCHECK(type_ == kLoadLiteralNarrow); 2215 int32_t offset = GetOffset(code_size); 2216 int32_t movw_encoding = MovwEncoding32(rn_, offset & 0xffff); 2217 int32_t movt_encoding = MovtEncoding32(rn_, offset & ~0xffff); 2218 int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC); 2219 int32_t ldr_encoding = LdrRtRnImm12Encoding(rn_, rn_, 0); 2220 buffer->Store<int16_t>(location_, movw_encoding >> 16); 2221 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(movw_encoding & 0xffff)); 2222 buffer->Store<int16_t>(location_ + 4u, movt_encoding >> 16); 2223 buffer->Store<int16_t>(location_ + 6u, static_cast<int16_t>(movt_encoding & 0xffff)); 2224 buffer->Store<int16_t>(location_ + 8u, add_pc_encoding); 2225 buffer->Store<int16_t>(location_ + 10u, ldr_encoding >> 16); 2226 buffer->Store<int16_t>(location_ + 12u, static_cast<int16_t>(ldr_encoding & 0xffff)); 2227 break; 2228 } 2229 2230 case kLiteralAddr1KiB: { 2231 DCHECK(type_ == kLoadLiteralAddr); 2232 int16_t encoding = AdrEncoding16(rn_, GetOffset(code_size)); 2233 buffer->Store<int16_t>(location_, encoding); 2234 break; 2235 } 2236 case kLiteralAddr4KiB: { 2237 DCHECK(type_ == kLoadLiteralAddr); 2238 int32_t encoding = AdrEncoding32(rn_, GetOffset(code_size)); 2239 buffer->Store<int16_t>(location_, encoding >> 16); 2240 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(encoding & 0xffff)); 2241 break; 2242 } 2243 case kLiteralAddr64KiB: { 2244 DCHECK(type_ == kLoadLiteralAddr); 2245 int32_t mov_encoding = MovwEncoding32(rn_, GetOffset(code_size)); 2246 int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC); 2247 buffer->Store<int16_t>(location_, mov_encoding >> 16); 2248 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(mov_encoding & 0xffff)); 2249 buffer->Store<int16_t>(location_ + 4u, add_pc_encoding); 2250 break; 2251 } 2252 case kLiteralAddrFar: { 2253 DCHECK(type_ == kLoadLiteralAddr); 2254 int32_t offset = GetOffset(code_size); 2255 int32_t movw_encoding = MovwEncoding32(rn_, offset & 0xffff); 2256 int32_t movt_encoding = MovtEncoding32(rn_, offset & ~0xffff); 2257 int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC); 2258 buffer->Store<int16_t>(location_, movw_encoding >> 16); 2259 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(movw_encoding & 0xffff)); 2260 buffer->Store<int16_t>(location_ + 4u, movt_encoding >> 16); 2261 buffer->Store<int16_t>(location_ + 6u, static_cast<int16_t>(movt_encoding & 0xffff)); 2262 buffer->Store<int16_t>(location_ + 8u, add_pc_encoding); 2263 break; 2264 } 2265 2266 case kLongOrFPLiteral1KiB: { 2267 int32_t encoding = LoadWideOrFpEncoding(PC, GetOffset(code_size)); // DCHECKs type_. 2268 buffer->Store<int16_t>(location_, encoding >> 16); 2269 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(encoding & 0xffff)); 2270 break; 2271 } 2272 case kLongOrFPLiteral256KiB: { 2273 int32_t offset = GetOffset(code_size); 2274 int32_t mov_encoding = MovModImmEncoding32(IP, offset & ~0x3ff); 2275 int16_t add_pc_encoding = AddRdnRmEncoding16(IP, PC); 2276 int32_t ldr_encoding = LoadWideOrFpEncoding(IP, offset & 0x3ff); // DCHECKs type_. 2277 buffer->Store<int16_t>(location_, mov_encoding >> 16); 2278 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(mov_encoding & 0xffff)); 2279 buffer->Store<int16_t>(location_ + 4u, add_pc_encoding); 2280 buffer->Store<int16_t>(location_ + 6u, ldr_encoding >> 16); 2281 buffer->Store<int16_t>(location_ + 8u, static_cast<int16_t>(ldr_encoding & 0xffff)); 2282 break; 2283 } 2284 case kLongOrFPLiteralFar: { 2285 int32_t offset = GetOffset(code_size); 2286 int32_t movw_encoding = MovwEncoding32(IP, offset & 0xffff); 2287 int32_t movt_encoding = MovtEncoding32(IP, offset & ~0xffff); 2288 int16_t add_pc_encoding = AddRdnRmEncoding16(IP, PC); 2289 int32_t ldr_encoding = LoadWideOrFpEncoding(IP, 0); // DCHECKs type_. 2290 buffer->Store<int16_t>(location_, movw_encoding >> 16); 2291 buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(movw_encoding & 0xffff)); 2292 buffer->Store<int16_t>(location_ + 4u, movt_encoding >> 16); 2293 buffer->Store<int16_t>(location_ + 6u, static_cast<int16_t>(movt_encoding & 0xffff)); 2294 buffer->Store<int16_t>(location_ + 8u, add_pc_encoding); 2295 buffer->Store<int16_t>(location_ + 10u, ldr_encoding >> 16); 2296 buffer->Store<int16_t>(location_ + 12u, static_cast<int16_t>(ldr_encoding & 0xffff)); 2297 break; 2298 } 2299 } 2300 } 2301 2302 uint16_t Thumb2Assembler::EmitCompareAndBranch(Register rn, uint16_t prev, bool n) { 2303 CHECK(IsLowRegister(rn)); 2304 uint32_t location = buffer_.Size(); 2305 2306 // This is always unresolved as it must be a forward branch. 2307 Emit16(prev); // Previous link. 2308 return AddFixup(Fixup::CompareAndBranch(location, rn, n ? NE : EQ)); 2309 } 2310 2311 2312 // NOTE: this only support immediate offsets, not [rx,ry]. 2313 // TODO: support [rx,ry] instructions. 2314 void Thumb2Assembler::EmitLoadStore(Condition cond, 2315 bool load, 2316 bool byte, 2317 bool half, 2318 bool is_signed, 2319 Register rd, 2320 const Address& ad) { 2321 CHECK_NE(rd, kNoRegister); 2322 CheckCondition(cond); 2323 bool must_be_32bit = force_32bit_; 2324 if (IsHighRegister(rd)) { 2325 must_be_32bit = true; 2326 } 2327 2328 Register rn = ad.GetRegister(); 2329 if (IsHighRegister(rn) && rn != SP && rn != PC) { 2330 must_be_32bit = true; 2331 } 2332 2333 if (is_signed || ad.GetOffset() < 0 || ad.GetMode() != Address::Offset) { 2334 must_be_32bit = true; 2335 } 2336 2337 if (ad.IsImmediate()) { 2338 // Immediate offset 2339 int32_t offset = ad.GetOffset(); 2340 2341 // The 16 bit SP relative instruction can only have a 10 bit offset. 2342 if (rn == SP && offset >= (1 << 10)) { 2343 must_be_32bit = true; 2344 } 2345 2346 if (byte) { 2347 // 5 bit offset, no shift. 2348 if (offset >= (1 << 5)) { 2349 must_be_32bit = true; 2350 } 2351 } else if (half) { 2352 // 6 bit offset, shifted by 1. 2353 if (offset >= (1 << 6)) { 2354 must_be_32bit = true; 2355 } 2356 } else { 2357 // 7 bit offset, shifted by 2. 2358 if (offset >= (1 << 7)) { 2359 must_be_32bit = true; 2360 } 2361 } 2362 2363 if (must_be_32bit) { 2364 int32_t encoding = B31 | B30 | B29 | B28 | B27 | 2365 (load ? B20 : 0) | 2366 (is_signed ? B24 : 0) | 2367 static_cast<uint32_t>(rd) << 12 | 2368 ad.encodingThumb(true) | 2369 (byte ? 0 : half ? B21 : B22); 2370 Emit32(encoding); 2371 } else { 2372 // 16 bit thumb1. 2373 uint8_t opA = 0; 2374 bool sp_relative = false; 2375 2376 if (byte) { 2377 opA = 7U /* 0b0111 */; 2378 } else if (half) { 2379 opA = 8U /* 0b1000 */; 2380 } else { 2381 if (rn == SP) { 2382 opA = 9U /* 0b1001 */; 2383 sp_relative = true; 2384 } else { 2385 opA = 6U /* 0b0110 */; 2386 } 2387 } 2388 int16_t encoding = opA << 12 | 2389 (load ? B11 : 0); 2390 2391 CHECK_GE(offset, 0); 2392 if (sp_relative) { 2393 // SP relative, 10 bit offset. 2394 CHECK_LT(offset, (1 << 10)); 2395 CHECK_ALIGNED(offset, 4); 2396 encoding |= rd << 8 | offset >> 2; 2397 } else { 2398 // No SP relative. The offset is shifted right depending on 2399 // the size of the load/store. 2400 encoding |= static_cast<uint32_t>(rd); 2401 2402 if (byte) { 2403 // 5 bit offset, no shift. 2404 CHECK_LT(offset, (1 << 5)); 2405 } else if (half) { 2406 // 6 bit offset, shifted by 1. 2407 CHECK_LT(offset, (1 << 6)); 2408 CHECK_ALIGNED(offset, 2); 2409 offset >>= 1; 2410 } else { 2411 // 7 bit offset, shifted by 2. 2412 CHECK_LT(offset, (1 << 7)); 2413 CHECK_ALIGNED(offset, 4); 2414 offset >>= 2; 2415 } 2416 encoding |= rn << 3 | offset << 6; 2417 } 2418 2419 Emit16(encoding); 2420 } 2421 } else { 2422 // Register shift. 2423 if (ad.GetRegister() == PC) { 2424 // PC relative literal encoding. 2425 int32_t offset = ad.GetOffset(); 2426 if (must_be_32bit || offset < 0 || offset >= (1 << 10) || !load) { 2427 int32_t up = B23; 2428 if (offset < 0) { 2429 offset = -offset; 2430 up = 0; 2431 } 2432 CHECK_LT(offset, (1 << 12)); 2433 int32_t encoding = 0x1f << 27 | 0xf << 16 | B22 | (load ? B20 : 0) | 2434 offset | up | 2435 static_cast<uint32_t>(rd) << 12; 2436 Emit32(encoding); 2437 } else { 2438 // 16 bit literal load. 2439 CHECK_GE(offset, 0); 2440 CHECK_LT(offset, (1 << 10)); 2441 int32_t encoding = B14 | (load ? B11 : 0) | static_cast<uint32_t>(rd) << 8 | offset >> 2; 2442 Emit16(encoding); 2443 } 2444 } else { 2445 if (ad.GetShiftCount() != 0) { 2446 // If there is a shift count this must be 32 bit. 2447 must_be_32bit = true; 2448 } else if (IsHighRegister(ad.GetRegisterOffset())) { 2449 must_be_32bit = true; 2450 } 2451 2452 if (must_be_32bit) { 2453 int32_t encoding = 0x1f << 27 | (load ? B20 : 0) | static_cast<uint32_t>(rd) << 12 | 2454 ad.encodingThumb(true); 2455 if (half) { 2456 encoding |= B21; 2457 } else if (!byte) { 2458 encoding |= B22; 2459 } 2460 Emit32(encoding); 2461 } else { 2462 // 16 bit register offset. 2463 int32_t encoding = B14 | B12 | (load ? B11 : 0) | static_cast<uint32_t>(rd) | 2464 ad.encodingThumb(false); 2465 if (byte) { 2466 encoding |= B10; 2467 } else if (half) { 2468 encoding |= B9; 2469 } 2470 Emit16(encoding); 2471 } 2472 } 2473 } 2474 } 2475 2476 2477 void Thumb2Assembler::EmitMultiMemOp(Condition cond, 2478 BlockAddressMode bam, 2479 bool load, 2480 Register base, 2481 RegList regs) { 2482 CHECK_NE(base, kNoRegister); 2483 CheckCondition(cond); 2484 bool must_be_32bit = force_32bit_; 2485 2486 if (!must_be_32bit && base == SP && bam == (load ? IA_W : DB_W) && 2487 (regs & 0xff00 & ~(1 << (load ? PC : LR))) == 0) { 2488 // Use 16-bit PUSH/POP. 2489 int16_t encoding = B15 | B13 | B12 | (load ? B11 : 0) | B10 | 2490 ((regs & (1 << (load ? PC : LR))) != 0 ? B8 : 0) | (regs & 0x00ff); 2491 Emit16(encoding); 2492 return; 2493 } 2494 2495 if ((regs & 0xff00) != 0) { 2496 must_be_32bit = true; 2497 } 2498 2499 bool w_bit = bam == IA_W || bam == DB_W || bam == DA_W || bam == IB_W; 2500 // 16 bit always uses writeback. 2501 if (!w_bit) { 2502 must_be_32bit = true; 2503 } 2504 2505 if (must_be_32bit) { 2506 uint32_t op = 0; 2507 switch (bam) { 2508 case IA: 2509 case IA_W: 2510 op = 1U /* 0b01 */; 2511 break; 2512 case DB: 2513 case DB_W: 2514 op = 2U /* 0b10 */; 2515 break; 2516 case DA: 2517 case IB: 2518 case DA_W: 2519 case IB_W: 2520 LOG(FATAL) << "LDM/STM mode not supported on thumb: " << bam; 2521 UNREACHABLE(); 2522 } 2523 if (load) { 2524 // Cannot have SP in the list. 2525 CHECK_EQ((regs & (1 << SP)), 0); 2526 } else { 2527 // Cannot have PC or SP in the list. 2528 CHECK_EQ((regs & (1 << PC | 1 << SP)), 0); 2529 } 2530 int32_t encoding = B31 | B30 | B29 | B27 | 2531 (op << 23) | 2532 (load ? B20 : 0) | 2533 base << 16 | 2534 regs | 2535 (w_bit << 21); 2536 Emit32(encoding); 2537 } else { 2538 int16_t encoding = B15 | B14 | 2539 (load ? B11 : 0) | 2540 base << 8 | 2541 regs; 2542 Emit16(encoding); 2543 } 2544 } 2545 2546 void Thumb2Assembler::EmitBranch(Condition cond, Label* label, bool link, bool x) { 2547 bool use32bit = IsForced32Bit() || !CanRelocateBranches(); 2548 uint32_t pc = buffer_.Size(); 2549 Fixup::Type branch_type; 2550 if (cond == AL) { 2551 if (link) { 2552 use32bit = true; 2553 if (x) { 2554 branch_type = Fixup::kUnconditionalLinkX; // BLX. 2555 } else { 2556 branch_type = Fixup::kUnconditionalLink; // BX. 2557 } 2558 } else { 2559 branch_type = Fixup::kUnconditional; // B. 2560 // The T2 encoding offset is `SignExtend(imm11:'0', 32)` and there is a PC adjustment of 4. 2561 static constexpr size_t kMaxT2BackwardDistance = (1u << 11) - 4u; 2562 if (!use32bit && label->IsBound() && pc - label->Position() > kMaxT2BackwardDistance) { 2563 use32bit = true; 2564 } 2565 } 2566 } else { 2567 branch_type = Fixup::kConditional; // B<cond>. 2568 // The T1 encoding offset is `SignExtend(imm8:'0', 32)` and there is a PC adjustment of 4. 2569 static constexpr size_t kMaxT1BackwardDistance = (1u << 8) - 4u; 2570 if (!use32bit && label->IsBound() && pc - label->Position() > kMaxT1BackwardDistance) { 2571 use32bit = true; 2572 } 2573 } 2574 2575 Fixup::Size size = use32bit ? Fixup::kBranch32Bit : Fixup::kBranch16Bit; 2576 FixupId branch_id = AddFixup(Fixup::Branch(pc, branch_type, size, cond)); 2577 2578 if (label->IsBound()) { 2579 // The branch is to a bound label which means that it's a backwards branch. 2580 GetFixup(branch_id)->Resolve(label->Position()); 2581 Emit16(0); 2582 } else { 2583 // Branch target is an unbound label. Add it to a singly-linked list maintained within 2584 // the code with the label serving as the head. 2585 Emit16(static_cast<uint16_t>(label->position_)); 2586 label->LinkTo(branch_id); 2587 } 2588 2589 if (use32bit) { 2590 Emit16(0); 2591 } 2592 DCHECK_EQ(buffer_.Size() - pc, GetFixup(branch_id)->GetSizeInBytes()); 2593 } 2594 2595 2596 void Thumb2Assembler::Emit32Miscellaneous(uint8_t op1, 2597 uint8_t op2, 2598 uint32_t rest_encoding) { 2599 int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B23 | 2600 op1 << 20 | 2601 0xf << 12 | 2602 B7 | 2603 op2 << 4 | 2604 rest_encoding; 2605 Emit32(encoding); 2606 } 2607 2608 2609 void Thumb2Assembler::Emit16Miscellaneous(uint32_t rest_encoding) { 2610 int16_t encoding = B15 | B13 | B12 | 2611 rest_encoding; 2612 Emit16(encoding); 2613 } 2614 2615 void Thumb2Assembler::clz(Register rd, Register rm, Condition cond) { 2616 CHECK_NE(rd, kNoRegister); 2617 CHECK_NE(rm, kNoRegister); 2618 CheckCondition(cond); 2619 CHECK_NE(rd, PC); 2620 CHECK_NE(rm, PC); 2621 int32_t encoding = 2622 static_cast<uint32_t>(rm) << 16 | 2623 static_cast<uint32_t>(rd) << 8 | 2624 static_cast<uint32_t>(rm); 2625 Emit32Miscellaneous(0b11, 0b00, encoding); 2626 } 2627 2628 2629 void Thumb2Assembler::movw(Register rd, uint16_t imm16, Condition cond) { 2630 CheckCondition(cond); 2631 // Always 32 bits, encoding T3. (Other encondings are called MOV, not MOVW.) 2632 uint32_t imm4 = (imm16 >> 12) & 15U /* 0b1111 */; 2633 uint32_t i = (imm16 >> 11) & 1U /* 0b1 */; 2634 uint32_t imm3 = (imm16 >> 8) & 7U /* 0b111 */; 2635 uint32_t imm8 = imm16 & 0xff; 2636 int32_t encoding = B31 | B30 | B29 | B28 | 2637 B25 | B22 | 2638 static_cast<uint32_t>(rd) << 8 | 2639 i << 26 | 2640 imm4 << 16 | 2641 imm3 << 12 | 2642 imm8; 2643 Emit32(encoding); 2644 } 2645 2646 2647 void Thumb2Assembler::movt(Register rd, uint16_t imm16, Condition cond) { 2648 CheckCondition(cond); 2649 // Always 32 bits. 2650 uint32_t imm4 = (imm16 >> 12) & 15U /* 0b1111 */; 2651 uint32_t i = (imm16 >> 11) & 1U /* 0b1 */; 2652 uint32_t imm3 = (imm16 >> 8) & 7U /* 0b111 */; 2653 uint32_t imm8 = imm16 & 0xff; 2654 int32_t encoding = B31 | B30 | B29 | B28 | 2655 B25 | B23 | B22 | 2656 static_cast<uint32_t>(rd) << 8 | 2657 i << 26 | 2658 imm4 << 16 | 2659 imm3 << 12 | 2660 imm8; 2661 Emit32(encoding); 2662 } 2663 2664 2665 void Thumb2Assembler::rbit(Register rd, Register rm, Condition cond) { 2666 CHECK_NE(rd, kNoRegister); 2667 CHECK_NE(rm, kNoRegister); 2668 CheckCondition(cond); 2669 CHECK_NE(rd, PC); 2670 CHECK_NE(rm, PC); 2671 CHECK_NE(rd, SP); 2672 CHECK_NE(rm, SP); 2673 int32_t encoding = 2674 static_cast<uint32_t>(rm) << 16 | 2675 static_cast<uint32_t>(rd) << 8 | 2676 static_cast<uint32_t>(rm); 2677 2678 Emit32Miscellaneous(0b01, 0b10, encoding); 2679 } 2680 2681 2682 void Thumb2Assembler::EmitReverseBytes(Register rd, Register rm, 2683 uint32_t op) { 2684 CHECK_NE(rd, kNoRegister); 2685 CHECK_NE(rm, kNoRegister); 2686 CHECK_NE(rd, PC); 2687 CHECK_NE(rm, PC); 2688 CHECK_NE(rd, SP); 2689 CHECK_NE(rm, SP); 2690 2691 if (!IsHighRegister(rd) && !IsHighRegister(rm) && !force_32bit_) { 2692 uint16_t t1_op = B11 | B9 | (op << 6); 2693 int16_t encoding = t1_op | 2694 static_cast<uint16_t>(rm) << 3 | 2695 static_cast<uint16_t>(rd); 2696 Emit16Miscellaneous(encoding); 2697 } else { 2698 int32_t encoding = 2699 static_cast<uint32_t>(rm) << 16 | 2700 static_cast<uint32_t>(rd) << 8 | 2701 static_cast<uint32_t>(rm); 2702 Emit32Miscellaneous(0b01, op, encoding); 2703 } 2704 } 2705 2706 2707 void Thumb2Assembler::rev(Register rd, Register rm, Condition cond) { 2708 CheckCondition(cond); 2709 EmitReverseBytes(rd, rm, 0b00); 2710 } 2711 2712 2713 void Thumb2Assembler::rev16(Register rd, Register rm, Condition cond) { 2714 CheckCondition(cond); 2715 EmitReverseBytes(rd, rm, 0b01); 2716 } 2717 2718 2719 void Thumb2Assembler::revsh(Register rd, Register rm, Condition cond) { 2720 CheckCondition(cond); 2721 EmitReverseBytes(rd, rm, 0b11); 2722 } 2723 2724 2725 void Thumb2Assembler::ldrex(Register rt, Register rn, uint16_t imm, Condition cond) { 2726 CHECK_NE(rn, kNoRegister); 2727 CHECK_NE(rt, kNoRegister); 2728 CheckCondition(cond); 2729 CHECK_LT(imm, (1u << 10)); 2730 2731 int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 | 2732 static_cast<uint32_t>(rn) << 16 | 2733 static_cast<uint32_t>(rt) << 12 | 2734 0xf << 8 | 2735 imm >> 2; 2736 Emit32(encoding); 2737 } 2738 2739 2740 void Thumb2Assembler::ldrex(Register rt, Register rn, Condition cond) { 2741 ldrex(rt, rn, 0, cond); 2742 } 2743 2744 2745 void Thumb2Assembler::strex(Register rd, 2746 Register rt, 2747 Register rn, 2748 uint16_t imm, 2749 Condition cond) { 2750 CHECK_NE(rn, kNoRegister); 2751 CHECK_NE(rd, kNoRegister); 2752 CHECK_NE(rt, kNoRegister); 2753 CheckCondition(cond); 2754 CHECK_LT(imm, (1u << 10)); 2755 2756 int32_t encoding = B31 | B30 | B29 | B27 | B22 | 2757 static_cast<uint32_t>(rn) << 16 | 2758 static_cast<uint32_t>(rt) << 12 | 2759 static_cast<uint32_t>(rd) << 8 | 2760 imm >> 2; 2761 Emit32(encoding); 2762 } 2763 2764 2765 void Thumb2Assembler::ldrexd(Register rt, Register rt2, Register rn, Condition cond) { 2766 CHECK_NE(rn, kNoRegister); 2767 CHECK_NE(rt, kNoRegister); 2768 CHECK_NE(rt2, kNoRegister); 2769 CHECK_NE(rt, rt2); 2770 CheckCondition(cond); 2771 2772 int32_t encoding = B31 | B30 | B29 | B27 | B23 | B22 | B20 | 2773 static_cast<uint32_t>(rn) << 16 | 2774 static_cast<uint32_t>(rt) << 12 | 2775 static_cast<uint32_t>(rt2) << 8 | 2776 B6 | B5 | B4 | B3 | B2 | B1 | B0; 2777 Emit32(encoding); 2778 } 2779 2780 2781 void Thumb2Assembler::strex(Register rd, 2782 Register rt, 2783 Register rn, 2784 Condition cond) { 2785 strex(rd, rt, rn, 0, cond); 2786 } 2787 2788 2789 void Thumb2Assembler::strexd(Register rd, Register rt, Register rt2, Register rn, Condition cond) { 2790 CHECK_NE(rd, kNoRegister); 2791 CHECK_NE(rn, kNoRegister); 2792 CHECK_NE(rt, kNoRegister); 2793 CHECK_NE(rt2, kNoRegister); 2794 CHECK_NE(rt, rt2); 2795 CHECK_NE(rd, rt); 2796 CHECK_NE(rd, rt2); 2797 CheckCondition(cond); 2798 2799 int32_t encoding = B31 | B30 | B29 | B27 | B23 | B22 | 2800 static_cast<uint32_t>(rn) << 16 | 2801 static_cast<uint32_t>(rt) << 12 | 2802 static_cast<uint32_t>(rt2) << 8 | 2803 B6 | B5 | B4 | 2804 static_cast<uint32_t>(rd); 2805 Emit32(encoding); 2806 } 2807 2808 2809 void Thumb2Assembler::clrex(Condition cond) { 2810 CheckCondition(cond); 2811 int32_t encoding = B31 | B30 | B29 | B27 | B28 | B25 | B24 | B23 | 2812 B21 | B20 | 2813 0xf << 16 | 2814 B15 | 2815 0xf << 8 | 2816 B5 | 2817 0xf; 2818 Emit32(encoding); 2819 } 2820 2821 2822 void Thumb2Assembler::nop(Condition cond) { 2823 CheckCondition(cond); 2824 uint16_t encoding = B15 | B13 | B12 | 2825 B11 | B10 | B9 | B8; 2826 Emit16(static_cast<int16_t>(encoding)); 2827 } 2828 2829 2830 void Thumb2Assembler::vmovsr(SRegister sn, Register rt, Condition cond) { 2831 CHECK_NE(sn, kNoSRegister); 2832 CHECK_NE(rt, kNoRegister); 2833 CHECK_NE(rt, SP); 2834 CHECK_NE(rt, PC); 2835 CheckCondition(cond); 2836 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2837 B27 | B26 | B25 | 2838 ((static_cast<int32_t>(sn) >> 1)*B16) | 2839 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 2840 ((static_cast<int32_t>(sn) & 1)*B7) | B4; 2841 Emit32(encoding); 2842 } 2843 2844 2845 void Thumb2Assembler::vmovrs(Register rt, SRegister sn, Condition cond) { 2846 CHECK_NE(sn, kNoSRegister); 2847 CHECK_NE(rt, kNoRegister); 2848 CHECK_NE(rt, SP); 2849 CHECK_NE(rt, PC); 2850 CheckCondition(cond); 2851 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2852 B27 | B26 | B25 | B20 | 2853 ((static_cast<int32_t>(sn) >> 1)*B16) | 2854 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 2855 ((static_cast<int32_t>(sn) & 1)*B7) | B4; 2856 Emit32(encoding); 2857 } 2858 2859 2860 void Thumb2Assembler::vmovsrr(SRegister sm, Register rt, Register rt2, 2861 Condition cond) { 2862 CHECK_NE(sm, kNoSRegister); 2863 CHECK_NE(sm, S31); 2864 CHECK_NE(rt, kNoRegister); 2865 CHECK_NE(rt, SP); 2866 CHECK_NE(rt, PC); 2867 CHECK_NE(rt2, kNoRegister); 2868 CHECK_NE(rt2, SP); 2869 CHECK_NE(rt2, PC); 2870 CheckCondition(cond); 2871 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2872 B27 | B26 | B22 | 2873 (static_cast<int32_t>(rt2)*B16) | 2874 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 2875 ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 2876 (static_cast<int32_t>(sm) >> 1); 2877 Emit32(encoding); 2878 } 2879 2880 2881 void Thumb2Assembler::vmovrrs(Register rt, Register rt2, SRegister sm, 2882 Condition cond) { 2883 CHECK_NE(sm, kNoSRegister); 2884 CHECK_NE(sm, S31); 2885 CHECK_NE(rt, kNoRegister); 2886 CHECK_NE(rt, SP); 2887 CHECK_NE(rt, PC); 2888 CHECK_NE(rt2, kNoRegister); 2889 CHECK_NE(rt2, SP); 2890 CHECK_NE(rt2, PC); 2891 CHECK_NE(rt, rt2); 2892 CheckCondition(cond); 2893 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2894 B27 | B26 | B22 | B20 | 2895 (static_cast<int32_t>(rt2)*B16) | 2896 (static_cast<int32_t>(rt)*B12) | B11 | B9 | 2897 ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 2898 (static_cast<int32_t>(sm) >> 1); 2899 Emit32(encoding); 2900 } 2901 2902 2903 void Thumb2Assembler::vmovdrr(DRegister dm, Register rt, Register rt2, 2904 Condition cond) { 2905 CHECK_NE(dm, kNoDRegister); 2906 CHECK_NE(rt, kNoRegister); 2907 CHECK_NE(rt, SP); 2908 CHECK_NE(rt, PC); 2909 CHECK_NE(rt2, kNoRegister); 2910 CHECK_NE(rt2, SP); 2911 CHECK_NE(rt2, PC); 2912 CheckCondition(cond); 2913 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2914 B27 | B26 | B22 | 2915 (static_cast<int32_t>(rt2)*B16) | 2916 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 2917 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 2918 (static_cast<int32_t>(dm) & 0xf); 2919 Emit32(encoding); 2920 } 2921 2922 2923 void Thumb2Assembler::vmovrrd(Register rt, Register rt2, DRegister dm, 2924 Condition cond) { 2925 CHECK_NE(dm, kNoDRegister); 2926 CHECK_NE(rt, kNoRegister); 2927 CHECK_NE(rt, SP); 2928 CHECK_NE(rt, PC); 2929 CHECK_NE(rt2, kNoRegister); 2930 CHECK_NE(rt2, SP); 2931 CHECK_NE(rt2, PC); 2932 CHECK_NE(rt, rt2); 2933 CheckCondition(cond); 2934 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2935 B27 | B26 | B22 | B20 | 2936 (static_cast<int32_t>(rt2)*B16) | 2937 (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 2938 ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 2939 (static_cast<int32_t>(dm) & 0xf); 2940 Emit32(encoding); 2941 } 2942 2943 2944 void Thumb2Assembler::vldrs(SRegister sd, const Address& ad, Condition cond) { 2945 const Address& addr = static_cast<const Address&>(ad); 2946 CHECK_NE(sd, kNoSRegister); 2947 CheckCondition(cond); 2948 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2949 B27 | B26 | B24 | B20 | 2950 ((static_cast<int32_t>(sd) & 1)*B22) | 2951 ((static_cast<int32_t>(sd) >> 1)*B12) | 2952 B11 | B9 | addr.vencoding(); 2953 Emit32(encoding); 2954 } 2955 2956 2957 void Thumb2Assembler::vstrs(SRegister sd, const Address& ad, Condition cond) { 2958 const Address& addr = static_cast<const Address&>(ad); 2959 CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC); 2960 CHECK_NE(sd, kNoSRegister); 2961 CheckCondition(cond); 2962 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2963 B27 | B26 | B24 | 2964 ((static_cast<int32_t>(sd) & 1)*B22) | 2965 ((static_cast<int32_t>(sd) >> 1)*B12) | 2966 B11 | B9 | addr.vencoding(); 2967 Emit32(encoding); 2968 } 2969 2970 2971 void Thumb2Assembler::vldrd(DRegister dd, const Address& ad, Condition cond) { 2972 const Address& addr = static_cast<const Address&>(ad); 2973 CHECK_NE(dd, kNoDRegister); 2974 CheckCondition(cond); 2975 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2976 B27 | B26 | B24 | B20 | 2977 ((static_cast<int32_t>(dd) >> 4)*B22) | 2978 ((static_cast<int32_t>(dd) & 0xf)*B12) | 2979 B11 | B9 | B8 | addr.vencoding(); 2980 Emit32(encoding); 2981 } 2982 2983 2984 void Thumb2Assembler::vstrd(DRegister dd, const Address& ad, Condition cond) { 2985 const Address& addr = static_cast<const Address&>(ad); 2986 CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC); 2987 CHECK_NE(dd, kNoDRegister); 2988 CheckCondition(cond); 2989 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 2990 B27 | B26 | B24 | 2991 ((static_cast<int32_t>(dd) >> 4)*B22) | 2992 ((static_cast<int32_t>(dd) & 0xf)*B12) | 2993 B11 | B9 | B8 | addr.vencoding(); 2994 Emit32(encoding); 2995 } 2996 2997 2998 void Thumb2Assembler::vpushs(SRegister reg, int nregs, Condition cond) { 2999 EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, false, cond); 3000 } 3001 3002 3003 void Thumb2Assembler::vpushd(DRegister reg, int nregs, Condition cond) { 3004 EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, true, cond); 3005 } 3006 3007 3008 void Thumb2Assembler::vpops(SRegister reg, int nregs, Condition cond) { 3009 EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, false, cond); 3010 } 3011 3012 3013 void Thumb2Assembler::vpopd(DRegister reg, int nregs, Condition cond) { 3014 EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, true, cond); 3015 } 3016 3017 3018 void Thumb2Assembler::EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond) { 3019 CheckCondition(cond); 3020 3021 uint32_t D; 3022 uint32_t Vd; 3023 if (dbl) { 3024 // Encoded as D:Vd. 3025 D = (reg >> 4) & 1; 3026 Vd = reg & 15U /* 0b1111 */; 3027 } else { 3028 // Encoded as Vd:D. 3029 D = reg & 1; 3030 Vd = (reg >> 1) & 15U /* 0b1111 */; 3031 } 3032 int32_t encoding = B27 | B26 | B21 | B19 | B18 | B16 | 3033 B11 | B9 | 3034 (dbl ? B8 : 0) | 3035 (push ? B24 : (B23 | B20)) | 3036 14U /* 0b1110 */ << 28 | 3037 nregs << (dbl ? 1 : 0) | 3038 D << 22 | 3039 Vd << 12; 3040 Emit32(encoding); 3041 } 3042 3043 3044 void Thumb2Assembler::EmitVFPsss(Condition cond, int32_t opcode, 3045 SRegister sd, SRegister sn, SRegister sm) { 3046 CHECK_NE(sd, kNoSRegister); 3047 CHECK_NE(sn, kNoSRegister); 3048 CHECK_NE(sm, kNoSRegister); 3049 CheckCondition(cond); 3050 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 3051 B27 | B26 | B25 | B11 | B9 | opcode | 3052 ((static_cast<int32_t>(sd) & 1)*B22) | 3053 ((static_cast<int32_t>(sn) >> 1)*B16) | 3054 ((static_cast<int32_t>(sd) >> 1)*B12) | 3055 ((static_cast<int32_t>(sn) & 1)*B7) | 3056 ((static_cast<int32_t>(sm) & 1)*B5) | 3057 (static_cast<int32_t>(sm) >> 1); 3058 Emit32(encoding); 3059 } 3060 3061 3062 void Thumb2Assembler::EmitVFPddd(Condition cond, int32_t opcode, 3063 DRegister dd, DRegister dn, DRegister dm) { 3064 CHECK_NE(dd, kNoDRegister); 3065 CHECK_NE(dn, kNoDRegister); 3066 CHECK_NE(dm, kNoDRegister); 3067 CheckCondition(cond); 3068 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 3069 B27 | B26 | B25 | B11 | B9 | B8 | opcode | 3070 ((static_cast<int32_t>(dd) >> 4)*B22) | 3071 ((static_cast<int32_t>(dn) & 0xf)*B16) | 3072 ((static_cast<int32_t>(dd) & 0xf)*B12) | 3073 ((static_cast<int32_t>(dn) >> 4)*B7) | 3074 ((static_cast<int32_t>(dm) >> 4)*B5) | 3075 (static_cast<int32_t>(dm) & 0xf); 3076 Emit32(encoding); 3077 } 3078 3079 3080 void Thumb2Assembler::EmitVFPsd(Condition cond, int32_t opcode, 3081 SRegister sd, DRegister dm) { 3082 CHECK_NE(sd, kNoSRegister); 3083 CHECK_NE(dm, kNoDRegister); 3084 CheckCondition(cond); 3085 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 3086 B27 | B26 | B25 | B11 | B9 | opcode | 3087 ((static_cast<int32_t>(sd) & 1)*B22) | 3088 ((static_cast<int32_t>(sd) >> 1)*B12) | 3089 ((static_cast<int32_t>(dm) >> 4)*B5) | 3090 (static_cast<int32_t>(dm) & 0xf); 3091 Emit32(encoding); 3092 } 3093 3094 3095 void Thumb2Assembler::EmitVFPds(Condition cond, int32_t opcode, 3096 DRegister dd, SRegister sm) { 3097 CHECK_NE(dd, kNoDRegister); 3098 CHECK_NE(sm, kNoSRegister); 3099 CheckCondition(cond); 3100 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 3101 B27 | B26 | B25 | B11 | B9 | opcode | 3102 ((static_cast<int32_t>(dd) >> 4)*B22) | 3103 ((static_cast<int32_t>(dd) & 0xf)*B12) | 3104 ((static_cast<int32_t>(sm) & 1)*B5) | 3105 (static_cast<int32_t>(sm) >> 1); 3106 Emit32(encoding); 3107 } 3108 3109 3110 void Thumb2Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR. 3111 CHECK_NE(cond, kNoCondition); 3112 CheckCondition(cond); 3113 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 3114 B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | 3115 (static_cast<int32_t>(PC)*B12) | 3116 B11 | B9 | B4; 3117 Emit32(encoding); 3118 } 3119 3120 3121 void Thumb2Assembler::svc(uint32_t imm8) { 3122 CHECK(IsUint<8>(imm8)) << imm8; 3123 int16_t encoding = B15 | B14 | B12 | 3124 B11 | B10 | B9 | B8 | 3125 imm8; 3126 Emit16(encoding); 3127 } 3128 3129 3130 void Thumb2Assembler::bkpt(uint16_t imm8) { 3131 CHECK(IsUint<8>(imm8)) << imm8; 3132 int16_t encoding = B15 | B13 | B12 | 3133 B11 | B10 | B9 | 3134 imm8; 3135 Emit16(encoding); 3136 } 3137 3138 // Convert the given IT state to a mask bit given bit 0 of the first 3139 // condition and a shift position. 3140 static uint8_t ToItMask(ItState s, uint8_t firstcond0, uint8_t shift) { 3141 switch (s) { 3142 case kItOmitted: return 1 << shift; 3143 case kItThen: return firstcond0 << shift; 3144 case kItElse: return !firstcond0 << shift; 3145 } 3146 return 0; 3147 } 3148 3149 3150 // Set the IT condition in the given position for the given state. This is used 3151 // to check that conditional instructions match the preceding IT statement. 3152 void Thumb2Assembler::SetItCondition(ItState s, Condition cond, uint8_t index) { 3153 switch (s) { 3154 case kItOmitted: it_conditions_[index] = AL; break; 3155 case kItThen: it_conditions_[index] = cond; break; 3156 case kItElse: 3157 it_conditions_[index] = static_cast<Condition>(static_cast<uint8_t>(cond) ^ 1); 3158 break; 3159 } 3160 } 3161 3162 3163 void Thumb2Assembler::it(Condition firstcond, ItState i1, ItState i2, ItState i3) { 3164 CheckCondition(AL); // Not allowed in IT block. 3165 uint8_t firstcond0 = static_cast<uint8_t>(firstcond) & 1; 3166 3167 // All conditions to AL. 3168 for (uint8_t i = 0; i < 4; ++i) { 3169 it_conditions_[i] = AL; 3170 } 3171 3172 SetItCondition(kItThen, firstcond, 0); 3173 uint8_t mask = ToItMask(i1, firstcond0, 3); 3174 SetItCondition(i1, firstcond, 1); 3175 3176 if (i1 != kItOmitted) { 3177 mask |= ToItMask(i2, firstcond0, 2); 3178 SetItCondition(i2, firstcond, 2); 3179 if (i2 != kItOmitted) { 3180 mask |= ToItMask(i3, firstcond0, 1); 3181 SetItCondition(i3, firstcond, 3); 3182 if (i3 != kItOmitted) { 3183 mask |= 1U /* 0b0001 */; 3184 } 3185 } 3186 } 3187 3188 // Start at first condition. 3189 it_cond_index_ = 0; 3190 next_condition_ = it_conditions_[0]; 3191 uint16_t encoding = B15 | B13 | B12 | 3192 B11 | B10 | B9 | B8 | 3193 firstcond << 4 | 3194 mask; 3195 Emit16(encoding); 3196 } 3197 3198 3199 void Thumb2Assembler::cbz(Register rn, Label* label) { 3200 CheckCondition(AL); 3201 if (label->IsBound()) { 3202 LOG(FATAL) << "cbz can only be used to branch forwards"; 3203 UNREACHABLE(); 3204 } else if (IsHighRegister(rn)) { 3205 LOG(FATAL) << "cbz can only be used with low registers"; 3206 UNREACHABLE(); 3207 } else { 3208 uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), false); 3209 label->LinkTo(branchid); 3210 } 3211 } 3212 3213 3214 void Thumb2Assembler::cbnz(Register rn, Label* label) { 3215 CheckCondition(AL); 3216 if (label->IsBound()) { 3217 LOG(FATAL) << "cbnz can only be used to branch forwards"; 3218 UNREACHABLE(); 3219 } else if (IsHighRegister(rn)) { 3220 LOG(FATAL) << "cbnz can only be used with low registers"; 3221 UNREACHABLE(); 3222 } else { 3223 uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), true); 3224 label->LinkTo(branchid); 3225 } 3226 } 3227 3228 3229 void Thumb2Assembler::blx(Register rm, Condition cond) { 3230 CHECK_NE(rm, kNoRegister); 3231 CheckCondition(cond); 3232 int16_t encoding = B14 | B10 | B9 | B8 | B7 | static_cast<int16_t>(rm) << 3; 3233 Emit16(encoding); 3234 } 3235 3236 3237 void Thumb2Assembler::bx(Register rm, Condition cond) { 3238 CHECK_NE(rm, kNoRegister); 3239 CheckCondition(cond); 3240 int16_t encoding = B14 | B10 | B9 | B8 | static_cast<int16_t>(rm) << 3; 3241 Emit16(encoding); 3242 } 3243 3244 3245 void Thumb2Assembler::Push(Register rd, Condition cond) { 3246 str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond); 3247 } 3248 3249 3250 void Thumb2Assembler::Pop(Register rd, Condition cond) { 3251 ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond); 3252 } 3253 3254 3255 void Thumb2Assembler::PushList(RegList regs, Condition cond) { 3256 stm(DB_W, SP, regs, cond); 3257 } 3258 3259 3260 void Thumb2Assembler::PopList(RegList regs, Condition cond) { 3261 ldm(IA_W, SP, regs, cond); 3262 } 3263 3264 3265 void Thumb2Assembler::Mov(Register rd, Register rm, Condition cond) { 3266 if (cond != AL || rd != rm) { 3267 mov(rd, ShifterOperand(rm), cond); 3268 } 3269 } 3270 3271 3272 void Thumb2Assembler::Bind(Label* label) { 3273 BindLabel(label, buffer_.Size()); 3274 } 3275 3276 3277 void Thumb2Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm, 3278 Condition cond, SetCc set_cc) { 3279 CHECK_LE(shift_imm, 31u); 3280 CheckCondition(cond); 3281 EmitShift(rd, rm, LSL, shift_imm, cond, set_cc); 3282 } 3283 3284 3285 void Thumb2Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm, 3286 Condition cond, SetCc set_cc) { 3287 CHECK(1u <= shift_imm && shift_imm <= 32u); 3288 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 3289 CheckCondition(cond); 3290 EmitShift(rd, rm, LSR, shift_imm, cond, set_cc); 3291 } 3292 3293 3294 void Thumb2Assembler::Asr(Register rd, Register rm, uint32_t shift_imm, 3295 Condition cond, SetCc set_cc) { 3296 CHECK(1u <= shift_imm && shift_imm <= 32u); 3297 if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 3298 CheckCondition(cond); 3299 EmitShift(rd, rm, ASR, shift_imm, cond, set_cc); 3300 } 3301 3302 3303 void Thumb2Assembler::Ror(Register rd, Register rm, uint32_t shift_imm, 3304 Condition cond, SetCc set_cc) { 3305 CHECK(1u <= shift_imm && shift_imm <= 31u); 3306 CheckCondition(cond); 3307 EmitShift(rd, rm, ROR, shift_imm, cond, set_cc); 3308 } 3309 3310 3311 void Thumb2Assembler::Rrx(Register rd, Register rm, Condition cond, SetCc set_cc) { 3312 CheckCondition(cond); 3313 EmitShift(rd, rm, RRX, 0, cond, set_cc); 3314 } 3315 3316 3317 void Thumb2Assembler::Lsl(Register rd, Register rm, Register rn, 3318 Condition cond, SetCc set_cc) { 3319 CheckCondition(cond); 3320 EmitShift(rd, rm, LSL, rn, cond, set_cc); 3321 } 3322 3323 3324 void Thumb2Assembler::Lsr(Register rd, Register rm, Register rn, 3325 Condition cond, SetCc set_cc) { 3326 CheckCondition(cond); 3327 EmitShift(rd, rm, LSR, rn, cond, set_cc); 3328 } 3329 3330 3331 void Thumb2Assembler::Asr(Register rd, Register rm, Register rn, 3332 Condition cond, SetCc set_cc) { 3333 CheckCondition(cond); 3334 EmitShift(rd, rm, ASR, rn, cond, set_cc); 3335 } 3336 3337 3338 void Thumb2Assembler::Ror(Register rd, Register rm, Register rn, 3339 Condition cond, SetCc set_cc) { 3340 CheckCondition(cond); 3341 EmitShift(rd, rm, ROR, rn, cond, set_cc); 3342 } 3343 3344 3345 int32_t Thumb2Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) { 3346 // The offset is off by 4 due to the way the ARM CPUs read PC. 3347 offset -= 4; 3348 offset >>= 1; 3349 3350 uint32_t value = 0; 3351 // There are two different encodings depending on the value of bit 12. In one case 3352 // intermediate values are calculated using the sign bit. 3353 if ((inst & B12) == B12) { 3354 // 25 bits of offset. 3355 uint32_t signbit = (offset >> 31) & 0x1; 3356 uint32_t i1 = (offset >> 22) & 0x1; 3357 uint32_t i2 = (offset >> 21) & 0x1; 3358 uint32_t imm10 = (offset >> 11) & 0x03ff; 3359 uint32_t imm11 = offset & 0x07ff; 3360 uint32_t j1 = (i1 ^ signbit) ? 0 : 1; 3361 uint32_t j2 = (i2 ^ signbit) ? 0 : 1; 3362 value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm10 << 16) | 3363 imm11; 3364 // Remove the offset from the current encoding. 3365 inst &= ~(0x3ff << 16 | 0x7ff); 3366 } else { 3367 uint32_t signbit = (offset >> 31) & 0x1; 3368 uint32_t imm6 = (offset >> 11) & 0x03f; 3369 uint32_t imm11 = offset & 0x07ff; 3370 uint32_t j1 = (offset >> 19) & 1; 3371 uint32_t j2 = (offset >> 17) & 1; 3372 value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm6 << 16) | 3373 imm11; 3374 // Remove the offset from the current encoding. 3375 inst &= ~(0x3f << 16 | 0x7ff); 3376 } 3377 // Mask out offset bits in current instruction. 3378 inst &= ~(B26 | B13 | B11); 3379 inst |= value; 3380 return inst; 3381 } 3382 3383 3384 int Thumb2Assembler::DecodeBranchOffset(int32_t instr) { 3385 int32_t imm32; 3386 if ((instr & B12) == B12) { 3387 uint32_t S = (instr >> 26) & 1; 3388 uint32_t J2 = (instr >> 11) & 1; 3389 uint32_t J1 = (instr >> 13) & 1; 3390 uint32_t imm10 = (instr >> 16) & 0x3FF; 3391 uint32_t imm11 = instr & 0x7FF; 3392 3393 uint32_t I1 = ~(J1 ^ S) & 1; 3394 uint32_t I2 = ~(J2 ^ S) & 1; 3395 imm32 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 3396 imm32 = (imm32 << 8) >> 8; // sign extend 24 bit immediate. 3397 } else { 3398 uint32_t S = (instr >> 26) & 1; 3399 uint32_t J2 = (instr >> 11) & 1; 3400 uint32_t J1 = (instr >> 13) & 1; 3401 uint32_t imm6 = (instr >> 16) & 0x3F; 3402 uint32_t imm11 = instr & 0x7FF; 3403 3404 imm32 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 3405 imm32 = (imm32 << 11) >> 11; // sign extend 21 bit immediate. 3406 } 3407 imm32 += 4; 3408 return imm32; 3409 } 3410 3411 uint32_t Thumb2Assembler::GetAdjustedPosition(uint32_t old_position) { 3412 // We can reconstruct the adjustment by going through all the fixups from the beginning 3413 // up to the old_position. Since we expect AdjustedPosition() to be called in a loop 3414 // with increasing old_position, we can use the data from last AdjustedPosition() to 3415 // continue where we left off and the whole loop should be O(m+n) where m is the number 3416 // of positions to adjust and n is the number of fixups. 3417 if (old_position < last_old_position_) { 3418 last_position_adjustment_ = 0u; 3419 last_old_position_ = 0u; 3420 last_fixup_id_ = 0u; 3421 } 3422 while (last_fixup_id_ != fixups_.size()) { 3423 Fixup* fixup = GetFixup(last_fixup_id_); 3424 if (fixup->GetLocation() >= old_position + last_position_adjustment_) { 3425 break; 3426 } 3427 if (fixup->GetSize() != fixup->GetOriginalSize()) { 3428 last_position_adjustment_ += fixup->GetSizeInBytes() - fixup->GetOriginalSizeInBytes(); 3429 } 3430 ++last_fixup_id_; 3431 } 3432 last_old_position_ = old_position; 3433 return old_position + last_position_adjustment_; 3434 } 3435 3436 Literal* Thumb2Assembler::NewLiteral(size_t size, const uint8_t* data) { 3437 DCHECK(size == 4u || size == 8u) << size; 3438 literals_.emplace_back(size, data); 3439 return &literals_.back(); 3440 } 3441 3442 void Thumb2Assembler::LoadLiteral(Register rt, Literal* literal) { 3443 DCHECK_EQ(literal->GetSize(), 4u); 3444 DCHECK(!literal->GetLabel()->IsBound()); 3445 bool use32bit = IsForced32Bit() || IsHighRegister(rt); 3446 uint32_t location = buffer_.Size(); 3447 Fixup::Size size = use32bit ? Fixup::kLiteral4KiB : Fixup::kLiteral1KiB; 3448 FixupId fixup_id = AddFixup(Fixup::LoadNarrowLiteral(location, rt, size)); 3449 Emit16(static_cast<uint16_t>(literal->GetLabel()->position_)); 3450 literal->GetLabel()->LinkTo(fixup_id); 3451 if (use32bit) { 3452 Emit16(0); 3453 } 3454 DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size()); 3455 } 3456 3457 void Thumb2Assembler::LoadLiteral(Register rt, Register rt2, Literal* literal) { 3458 DCHECK_EQ(literal->GetSize(), 8u); 3459 DCHECK(!literal->GetLabel()->IsBound()); 3460 uint32_t location = buffer_.Size(); 3461 FixupId fixup_id = 3462 AddFixup(Fixup::LoadWideLiteral(location, rt, rt2, Fixup::kLongOrFPLiteral1KiB)); 3463 Emit16(static_cast<uint16_t>(literal->GetLabel()->position_)); 3464 literal->GetLabel()->LinkTo(fixup_id); 3465 Emit16(0); 3466 DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size()); 3467 } 3468 3469 void Thumb2Assembler::LoadLiteral(SRegister sd, Literal* literal) { 3470 DCHECK_EQ(literal->GetSize(), 4u); 3471 DCHECK(!literal->GetLabel()->IsBound()); 3472 uint32_t location = buffer_.Size(); 3473 FixupId fixup_id = AddFixup(Fixup::LoadSingleLiteral(location, sd, Fixup::kLongOrFPLiteral1KiB)); 3474 Emit16(static_cast<uint16_t>(literal->GetLabel()->position_)); 3475 literal->GetLabel()->LinkTo(fixup_id); 3476 Emit16(0); 3477 DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size()); 3478 } 3479 3480 void Thumb2Assembler::LoadLiteral(DRegister dd, Literal* literal) { 3481 DCHECK_EQ(literal->GetSize(), 8u); 3482 DCHECK(!literal->GetLabel()->IsBound()); 3483 uint32_t location = buffer_.Size(); 3484 FixupId fixup_id = AddFixup(Fixup::LoadDoubleLiteral(location, dd, Fixup::kLongOrFPLiteral1KiB)); 3485 Emit16(static_cast<uint16_t>(literal->GetLabel()->position_)); 3486 literal->GetLabel()->LinkTo(fixup_id); 3487 Emit16(0); 3488 DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size()); 3489 } 3490 3491 3492 void Thumb2Assembler::AddConstant(Register rd, Register rn, int32_t value, 3493 Condition cond, SetCc set_cc) { 3494 if (value == 0 && set_cc != kCcSet) { 3495 if (rd != rn) { 3496 mov(rd, ShifterOperand(rn), cond); 3497 } 3498 return; 3499 } 3500 // We prefer to select the shorter code sequence rather than selecting add for 3501 // positive values and sub for negatives ones, which would slightly improve 3502 // the readability of generated code for some constants. 3503 ShifterOperand shifter_op; 3504 if (ShifterOperandCanHold(rd, rn, ADD, value, set_cc, &shifter_op)) { 3505 add(rd, rn, shifter_op, cond, set_cc); 3506 } else if (ShifterOperandCanHold(rd, rn, SUB, -value, set_cc, &shifter_op)) { 3507 sub(rd, rn, shifter_op, cond, set_cc); 3508 } else { 3509 CHECK(rn != IP); 3510 // If rd != rn, use rd as temp. This alows 16-bit ADD/SUB in more situations than using IP. 3511 Register temp = (rd != rn) ? rd : IP; 3512 if (ShifterOperandCanHold(temp, kNoRegister, MVN, ~value, kCcKeep, &shifter_op)) { 3513 mvn(temp, shifter_op, cond, kCcKeep); 3514 add(rd, rn, ShifterOperand(temp), cond, set_cc); 3515 } else if (ShifterOperandCanHold(temp, kNoRegister, MVN, ~(-value), kCcKeep, &shifter_op)) { 3516 mvn(temp, shifter_op, cond, kCcKeep); 3517 sub(rd, rn, ShifterOperand(temp), cond, set_cc); 3518 } else if (High16Bits(-value) == 0) { 3519 movw(temp, Low16Bits(-value), cond); 3520 sub(rd, rn, ShifterOperand(temp), cond, set_cc); 3521 } else { 3522 movw(temp, Low16Bits(value), cond); 3523 uint16_t value_high = High16Bits(value); 3524 if (value_high != 0) { 3525 movt(temp, value_high, cond); 3526 } 3527 add(rd, rn, ShifterOperand(temp), cond, set_cc); 3528 } 3529 } 3530 } 3531 3532 void Thumb2Assembler::CmpConstant(Register rn, int32_t value, Condition cond) { 3533 // We prefer to select the shorter code sequence rather than using plain cmp and cmn 3534 // which would slightly improve the readability of generated code for some constants. 3535 ShifterOperand shifter_op; 3536 if (ShifterOperandCanHold(kNoRegister, rn, CMP, value, kCcSet, &shifter_op)) { 3537 cmp(rn, shifter_op, cond); 3538 } else if (ShifterOperandCanHold(kNoRegister, rn, CMN, -value, kCcSet, &shifter_op)) { 3539 cmn(rn, shifter_op, cond); 3540 } else { 3541 CHECK(rn != IP); 3542 if (ShifterOperandCanHold(IP, kNoRegister, MVN, ~value, kCcKeep, &shifter_op)) { 3543 mvn(IP, shifter_op, cond, kCcKeep); 3544 cmp(rn, ShifterOperand(IP), cond); 3545 } else if (ShifterOperandCanHold(IP, kNoRegister, MVN, ~(-value), kCcKeep, &shifter_op)) { 3546 mvn(IP, shifter_op, cond, kCcKeep); 3547 cmn(rn, ShifterOperand(IP), cond); 3548 } else if (High16Bits(-value) == 0) { 3549 movw(IP, Low16Bits(-value), cond); 3550 cmn(rn, ShifterOperand(IP), cond); 3551 } else { 3552 movw(IP, Low16Bits(value), cond); 3553 uint16_t value_high = High16Bits(value); 3554 if (value_high != 0) { 3555 movt(IP, value_high, cond); 3556 } 3557 cmp(rn, ShifterOperand(IP), cond); 3558 } 3559 } 3560 } 3561 3562 void Thumb2Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { 3563 ShifterOperand shifter_op; 3564 if (ShifterOperandCanHold(rd, R0, MOV, value, &shifter_op)) { 3565 mov(rd, shifter_op, cond); 3566 } else if (ShifterOperandCanHold(rd, R0, MVN, ~value, &shifter_op)) { 3567 mvn(rd, shifter_op, cond); 3568 } else { 3569 movw(rd, Low16Bits(value), cond); 3570 uint16_t value_high = High16Bits(value); 3571 if (value_high != 0) { 3572 movt(rd, value_high, cond); 3573 } 3574 } 3575 } 3576 3577 int32_t Thumb2Assembler::GetAllowedLoadOffsetBits(LoadOperandType type) { 3578 switch (type) { 3579 case kLoadSignedByte: 3580 case kLoadSignedHalfword: 3581 case kLoadUnsignedHalfword: 3582 case kLoadUnsignedByte: 3583 case kLoadWord: 3584 // We can encode imm12 offset. 3585 return 0xfffu; 3586 case kLoadSWord: 3587 case kLoadDWord: 3588 case kLoadWordPair: 3589 // We can encode imm8:'00' offset. 3590 return 0xff << 2; 3591 default: 3592 LOG(FATAL) << "UNREACHABLE"; 3593 UNREACHABLE(); 3594 } 3595 } 3596 3597 int32_t Thumb2Assembler::GetAllowedStoreOffsetBits(StoreOperandType type) { 3598 switch (type) { 3599 case kStoreHalfword: 3600 case kStoreByte: 3601 case kStoreWord: 3602 // We can encode imm12 offset. 3603 return 0xfff; 3604 case kStoreSWord: 3605 case kStoreDWord: 3606 case kStoreWordPair: 3607 // We can encode imm8:'00' offset. 3608 return 0xff << 2; 3609 default: 3610 LOG(FATAL) << "UNREACHABLE"; 3611 UNREACHABLE(); 3612 } 3613 } 3614 3615 bool Thumb2Assembler::CanSplitLoadStoreOffset(int32_t allowed_offset_bits, 3616 int32_t offset, 3617 /*out*/ int32_t* add_to_base, 3618 /*out*/ int32_t* offset_for_load_store) { 3619 int32_t other_bits = offset & ~allowed_offset_bits; 3620 if (ShifterOperandCanAlwaysHold(other_bits) || ShifterOperandCanAlwaysHold(-other_bits)) { 3621 *add_to_base = offset & ~allowed_offset_bits; 3622 *offset_for_load_store = offset & allowed_offset_bits; 3623 return true; 3624 } 3625 return false; 3626 } 3627 3628 int32_t Thumb2Assembler::AdjustLoadStoreOffset(int32_t allowed_offset_bits, 3629 Register temp, 3630 Register base, 3631 int32_t offset, 3632 Condition cond) { 3633 DCHECK_NE(offset & ~allowed_offset_bits, 0); 3634 int32_t add_to_base, offset_for_load; 3635 if (CanSplitLoadStoreOffset(allowed_offset_bits, offset, &add_to_base, &offset_for_load)) { 3636 AddConstant(temp, base, add_to_base, cond, kCcKeep); 3637 return offset_for_load; 3638 } else { 3639 LoadImmediate(temp, offset, cond); 3640 add(temp, temp, ShifterOperand(base), cond, kCcKeep); 3641 return 0; 3642 } 3643 } 3644 3645 // Implementation note: this method must emit at most one instruction when 3646 // Address::CanHoldLoadOffsetThumb. 3647 void Thumb2Assembler::LoadFromOffset(LoadOperandType type, 3648 Register reg, 3649 Register base, 3650 int32_t offset, 3651 Condition cond) { 3652 if (!Address::CanHoldLoadOffsetThumb(type, offset)) { 3653 CHECK_NE(base, IP); 3654 // Inlined AdjustLoadStoreOffset() allows us to pull a few more tricks. 3655 int32_t allowed_offset_bits = GetAllowedLoadOffsetBits(type); 3656 DCHECK_NE(offset & ~allowed_offset_bits, 0); 3657 int32_t add_to_base, offset_for_load; 3658 if (CanSplitLoadStoreOffset(allowed_offset_bits, offset, &add_to_base, &offset_for_load)) { 3659 // Use reg for the adjusted base. If it's low reg, we may end up using 16-bit load. 3660 AddConstant(reg, base, add_to_base, cond, kCcKeep); 3661 base = reg; 3662 offset = offset_for_load; 3663 } else { 3664 Register temp = (reg == base) ? IP : reg; 3665 LoadImmediate(temp, offset, cond); 3666 // TODO: Implement indexed load (not available for LDRD) and use it here to avoid the ADD. 3667 // Use reg for the adjusted base. If it's low reg, we may end up using 16-bit load. 3668 add(reg, reg, ShifterOperand((reg == base) ? IP : base), cond, kCcKeep); 3669 base = reg; 3670 offset = 0; 3671 } 3672 } 3673 DCHECK(Address::CanHoldLoadOffsetThumb(type, offset)); 3674 switch (type) { 3675 case kLoadSignedByte: 3676 ldrsb(reg, Address(base, offset), cond); 3677 break; 3678 case kLoadUnsignedByte: 3679 ldrb(reg, Address(base, offset), cond); 3680 break; 3681 case kLoadSignedHalfword: 3682 ldrsh(reg, Address(base, offset), cond); 3683 break; 3684 case kLoadUnsignedHalfword: 3685 ldrh(reg, Address(base, offset), cond); 3686 break; 3687 case kLoadWord: 3688 ldr(reg, Address(base, offset), cond); 3689 break; 3690 case kLoadWordPair: 3691 ldrd(reg, Address(base, offset), cond); 3692 break; 3693 default: 3694 LOG(FATAL) << "UNREACHABLE"; 3695 UNREACHABLE(); 3696 } 3697 } 3698 3699 // Implementation note: this method must emit at most one instruction when 3700 // Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset. 3701 void Thumb2Assembler::LoadSFromOffset(SRegister reg, 3702 Register base, 3703 int32_t offset, 3704 Condition cond) { 3705 if (!Address::CanHoldLoadOffsetThumb(kLoadSWord, offset)) { 3706 CHECK_NE(base, IP); 3707 offset = AdjustLoadStoreOffset(GetAllowedLoadOffsetBits(kLoadSWord), IP, base, offset, cond); 3708 base = IP; 3709 } 3710 DCHECK(Address::CanHoldLoadOffsetThumb(kLoadSWord, offset)); 3711 vldrs(reg, Address(base, offset), cond); 3712 } 3713 3714 3715 // Implementation note: this method must emit at most one instruction when 3716 // Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset. 3717 void Thumb2Assembler::LoadDFromOffset(DRegister reg, 3718 Register base, 3719 int32_t offset, 3720 Condition cond) { 3721 if (!Address::CanHoldLoadOffsetThumb(kLoadDWord, offset)) { 3722 CHECK_NE(base, IP); 3723 offset = AdjustLoadStoreOffset(GetAllowedLoadOffsetBits(kLoadDWord), IP, base, offset, cond); 3724 base = IP; 3725 } 3726 DCHECK(Address::CanHoldLoadOffsetThumb(kLoadDWord, offset)); 3727 vldrd(reg, Address(base, offset), cond); 3728 } 3729 3730 3731 // Implementation note: this method must emit at most one instruction when 3732 // Address::CanHoldStoreOffsetThumb. 3733 void Thumb2Assembler::StoreToOffset(StoreOperandType type, 3734 Register reg, 3735 Register base, 3736 int32_t offset, 3737 Condition cond) { 3738 Register tmp_reg = kNoRegister; 3739 if (!Address::CanHoldStoreOffsetThumb(type, offset)) { 3740 CHECK_NE(base, IP); 3741 if ((reg != IP) && 3742 ((type != kStoreWordPair) || (reg + 1 != IP))) { 3743 tmp_reg = IP; 3744 } else { 3745 // Be careful not to use IP twice (for `reg` (or `reg` + 1 in 3746 // the case of a word-pair store) and `base`) to build the 3747 // Address object used by the store instruction(s) below. 3748 // Instead, save R5 on the stack (or R6 if R5 is already used by 3749 // `base`), use it as secondary temporary register, and restore 3750 // it after the store instruction has been emitted. 3751 tmp_reg = (base != R5) ? R5 : R6; 3752 Push(tmp_reg); 3753 if (base == SP) { 3754 offset += kRegisterSize; 3755 } 3756 } 3757 // TODO: Implement indexed store (not available for STRD), inline AdjustLoadStoreOffset() 3758 // and in the "unsplittable" path get rid of the "add" by using the store indexed instead. 3759 offset = AdjustLoadStoreOffset(GetAllowedStoreOffsetBits(type), tmp_reg, base, offset, cond); 3760 base = tmp_reg; 3761 } 3762 DCHECK(Address::CanHoldStoreOffsetThumb(type, offset)); 3763 switch (type) { 3764 case kStoreByte: 3765 strb(reg, Address(base, offset), cond); 3766 break; 3767 case kStoreHalfword: 3768 strh(reg, Address(base, offset), cond); 3769 break; 3770 case kStoreWord: 3771 str(reg, Address(base, offset), cond); 3772 break; 3773 case kStoreWordPair: 3774 strd(reg, Address(base, offset), cond); 3775 break; 3776 default: 3777 LOG(FATAL) << "UNREACHABLE"; 3778 UNREACHABLE(); 3779 } 3780 if ((tmp_reg != kNoRegister) && (tmp_reg != IP)) { 3781 CHECK((tmp_reg == R5) || (tmp_reg == R6)); 3782 Pop(tmp_reg); 3783 } 3784 } 3785 3786 3787 // Implementation note: this method must emit at most one instruction when 3788 // Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreToOffset. 3789 void Thumb2Assembler::StoreSToOffset(SRegister reg, 3790 Register base, 3791 int32_t offset, 3792 Condition cond) { 3793 if (!Address::CanHoldStoreOffsetThumb(kStoreSWord, offset)) { 3794 CHECK_NE(base, IP); 3795 offset = AdjustLoadStoreOffset(GetAllowedStoreOffsetBits(kStoreSWord), IP, base, offset, cond); 3796 base = IP; 3797 } 3798 DCHECK(Address::CanHoldStoreOffsetThumb(kStoreSWord, offset)); 3799 vstrs(reg, Address(base, offset), cond); 3800 } 3801 3802 3803 // Implementation note: this method must emit at most one instruction when 3804 // Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreSToOffset. 3805 void Thumb2Assembler::StoreDToOffset(DRegister reg, 3806 Register base, 3807 int32_t offset, 3808 Condition cond) { 3809 if (!Address::CanHoldStoreOffsetThumb(kStoreDWord, offset)) { 3810 CHECK_NE(base, IP); 3811 offset = AdjustLoadStoreOffset(GetAllowedStoreOffsetBits(kStoreDWord), IP, base, offset, cond); 3812 base = IP; 3813 } 3814 DCHECK(Address::CanHoldStoreOffsetThumb(kStoreDWord, offset)); 3815 vstrd(reg, Address(base, offset), cond); 3816 } 3817 3818 3819 void Thumb2Assembler::MemoryBarrier(ManagedRegister mscratch) { 3820 CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12); 3821 dmb(SY); 3822 } 3823 3824 3825 void Thumb2Assembler::dmb(DmbOptions flavor) { 3826 int32_t encoding = 0xf3bf8f50; // dmb in T1 encoding. 3827 Emit32(encoding | flavor); 3828 } 3829 3830 3831 void Thumb2Assembler::CompareAndBranchIfZero(Register r, Label* label) { 3832 if (CanRelocateBranches() && IsLowRegister(r) && !label->IsBound()) { 3833 cbz(r, label); 3834 } else { 3835 cmp(r, ShifterOperand(0)); 3836 b(label, EQ); 3837 } 3838 } 3839 3840 3841 void Thumb2Assembler::CompareAndBranchIfNonZero(Register r, Label* label) { 3842 if (CanRelocateBranches() && IsLowRegister(r) && !label->IsBound()) { 3843 cbnz(r, label); 3844 } else { 3845 cmp(r, ShifterOperand(0)); 3846 b(label, NE); 3847 } 3848 } 3849 3850 JumpTable* Thumb2Assembler::CreateJumpTable(std::vector<Label*>&& labels, Register base_reg) { 3851 jump_tables_.emplace_back(std::move(labels)); 3852 JumpTable* table = &jump_tables_.back(); 3853 DCHECK(!table->GetLabel()->IsBound()); 3854 3855 bool use32bit = IsForced32Bit() || IsHighRegister(base_reg); 3856 uint32_t location = buffer_.Size(); 3857 Fixup::Size size = use32bit ? Fixup::kLiteralAddr4KiB : Fixup::kLiteralAddr1KiB; 3858 FixupId fixup_id = AddFixup(Fixup::LoadLiteralAddress(location, base_reg, size)); 3859 Emit16(static_cast<uint16_t>(table->GetLabel()->position_)); 3860 table->GetLabel()->LinkTo(fixup_id); 3861 if (use32bit) { 3862 Emit16(0); 3863 } 3864 DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size()); 3865 3866 return table; 3867 } 3868 3869 void Thumb2Assembler::EmitJumpTableDispatch(JumpTable* jump_table, Register displacement_reg) { 3870 CHECK(!IsForced32Bit()) << "Forced 32-bit dispatch not implemented yet"; 3871 // 32-bit ADD doesn't support PC as an input, so we need a two-instruction sequence: 3872 // SUB ip, ip, #0 3873 // ADD pc, ip, reg 3874 // TODO: Implement. 3875 3876 // The anchor's position needs to be fixed up before we can compute offsets - so make it a tracked 3877 // label. 3878 BindTrackedLabel(jump_table->GetAnchorLabel()); 3879 3880 add(PC, PC, ShifterOperand(displacement_reg)); 3881 } 3882 3883 } // namespace arm 3884 } // namespace art 3885