1//=- AArch64/AArch64MCCodeEmitter.cpp - Convert AArch64 code to machine code-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the AArch64MCCodeEmitter class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "MCTargetDesc/AArch64AddressingModes.h" 15#include "MCTargetDesc/AArch64FixupKinds.h" 16#include "MCTargetDesc/AArch64MCExpr.h" 17#include "Utils/AArch64BaseInfo.h" 18#include "llvm/ADT/Statistic.h" 19#include "llvm/MC/MCCodeEmitter.h" 20#include "llvm/MC/MCContext.h" 21#include "llvm/MC/MCInst.h" 22#include "llvm/MC/MCInstrInfo.h" 23#include "llvm/MC/MCRegisterInfo.h" 24#include "llvm/MC/MCSubtargetInfo.h" 25#include "llvm/Support/EndianStream.h" 26#include "llvm/Support/raw_ostream.h" 27using namespace llvm; 28 29#define DEBUG_TYPE "mccodeemitter" 30 31STATISTIC(MCNumEmitted, "Number of MC instructions emitted."); 32STATISTIC(MCNumFixups, "Number of MC fixups created."); 33 34namespace { 35 36class AArch64MCCodeEmitter : public MCCodeEmitter { 37 MCContext &Ctx; 38 39 AArch64MCCodeEmitter(const AArch64MCCodeEmitter &); // DO NOT IMPLEMENT 40 void operator=(const AArch64MCCodeEmitter &); // DO NOT IMPLEMENT 41public: 42 AArch64MCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) : Ctx(ctx) {} 43 44 ~AArch64MCCodeEmitter() override {} 45 46 // getBinaryCodeForInstr - TableGen'erated function for getting the 47 // binary encoding for an instruction. 48 uint64_t getBinaryCodeForInstr(const MCInst &MI, 49 SmallVectorImpl<MCFixup> &Fixups, 50 const MCSubtargetInfo &STI) const; 51 52 /// getMachineOpValue - Return binary encoding of operand. If the machine 53 /// operand requires relocation, record the relocation and return zero. 54 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, 55 SmallVectorImpl<MCFixup> &Fixups, 56 const MCSubtargetInfo &STI) const; 57 58 /// getLdStUImm12OpValue - Return encoding info for 12-bit unsigned immediate 59 /// attached to a load, store or prfm instruction. If operand requires a 60 /// relocation, record it and return zero in that part of the encoding. 61 template <uint32_t FixupKind> 62 uint32_t getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx, 63 SmallVectorImpl<MCFixup> &Fixups, 64 const MCSubtargetInfo &STI) const; 65 66 /// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label 67 /// target. 68 uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 69 SmallVectorImpl<MCFixup> &Fixups, 70 const MCSubtargetInfo &STI) const; 71 72 /// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and 73 /// the 2-bit shift field. 74 uint32_t getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx, 75 SmallVectorImpl<MCFixup> &Fixups, 76 const MCSubtargetInfo &STI) const; 77 78 /// getCondBranchTargetOpValue - Return the encoded value for a conditional 79 /// branch target. 80 uint32_t getCondBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 81 SmallVectorImpl<MCFixup> &Fixups, 82 const MCSubtargetInfo &STI) const; 83 84 /// getLoadLiteralOpValue - Return the encoded value for a load-literal 85 /// pc-relative address. 86 uint32_t getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx, 87 SmallVectorImpl<MCFixup> &Fixups, 88 const MCSubtargetInfo &STI) const; 89 90 /// getMemExtendOpValue - Return the encoded value for a reg-extend load/store 91 /// instruction: bit 0 is whether a shift is present, bit 1 is whether the 92 /// operation is a sign extend (as opposed to a zero extend). 93 uint32_t getMemExtendOpValue(const MCInst &MI, unsigned OpIdx, 94 SmallVectorImpl<MCFixup> &Fixups, 95 const MCSubtargetInfo &STI) const; 96 97 /// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and- 98 /// branch target. 99 uint32_t getTestBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 100 SmallVectorImpl<MCFixup> &Fixups, 101 const MCSubtargetInfo &STI) const; 102 103 /// getBranchTargetOpValue - Return the encoded value for an unconditional 104 /// branch target. 105 uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 106 SmallVectorImpl<MCFixup> &Fixups, 107 const MCSubtargetInfo &STI) const; 108 109 /// getMoveWideImmOpValue - Return the encoded value for the immediate operand 110 /// of a MOVZ or MOVK instruction. 111 uint32_t getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx, 112 SmallVectorImpl<MCFixup> &Fixups, 113 const MCSubtargetInfo &STI) const; 114 115 /// getVecShifterOpValue - Return the encoded value for the vector shifter. 116 uint32_t getVecShifterOpValue(const MCInst &MI, unsigned OpIdx, 117 SmallVectorImpl<MCFixup> &Fixups, 118 const MCSubtargetInfo &STI) const; 119 120 /// getMoveVecShifterOpValue - Return the encoded value for the vector move 121 /// shifter (MSL). 122 uint32_t getMoveVecShifterOpValue(const MCInst &MI, unsigned OpIdx, 123 SmallVectorImpl<MCFixup> &Fixups, 124 const MCSubtargetInfo &STI) const; 125 126 /// getFixedPointScaleOpValue - Return the encoded value for the 127 // FP-to-fixed-point scale factor. 128 uint32_t getFixedPointScaleOpValue(const MCInst &MI, unsigned OpIdx, 129 SmallVectorImpl<MCFixup> &Fixups, 130 const MCSubtargetInfo &STI) const; 131 132 uint32_t getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx, 133 SmallVectorImpl<MCFixup> &Fixups, 134 const MCSubtargetInfo &STI) const; 135 uint32_t getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx, 136 SmallVectorImpl<MCFixup> &Fixups, 137 const MCSubtargetInfo &STI) const; 138 uint32_t getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx, 139 SmallVectorImpl<MCFixup> &Fixups, 140 const MCSubtargetInfo &STI) const; 141 uint32_t getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx, 142 SmallVectorImpl<MCFixup> &Fixups, 143 const MCSubtargetInfo &STI) const; 144 uint32_t getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx, 145 SmallVectorImpl<MCFixup> &Fixups, 146 const MCSubtargetInfo &STI) const; 147 uint32_t getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx, 148 SmallVectorImpl<MCFixup> &Fixups, 149 const MCSubtargetInfo &STI) const; 150 uint32_t getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx, 151 SmallVectorImpl<MCFixup> &Fixups, 152 const MCSubtargetInfo &STI) const; 153 uint32_t getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx, 154 SmallVectorImpl<MCFixup> &Fixups, 155 const MCSubtargetInfo &STI) const; 156 157 unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue, 158 const MCSubtargetInfo &STI) const; 159 160 void encodeInstruction(const MCInst &MI, raw_ostream &OS, 161 SmallVectorImpl<MCFixup> &Fixups, 162 const MCSubtargetInfo &STI) const override; 163 164 unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue, 165 const MCSubtargetInfo &STI) const; 166 167 template<int hasRs, int hasRt2> unsigned 168 fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue, 169 const MCSubtargetInfo &STI) const; 170 171 unsigned fixOneOperandFPComparison(const MCInst &MI, unsigned EncodedValue, 172 const MCSubtargetInfo &STI) const; 173}; 174 175} // end anonymous namespace 176 177MCCodeEmitter *llvm::createAArch64MCCodeEmitter(const MCInstrInfo &MCII, 178 const MCRegisterInfo &MRI, 179 MCContext &Ctx) { 180 return new AArch64MCCodeEmitter(MCII, Ctx); 181} 182 183/// getMachineOpValue - Return binary encoding of operand. If the machine 184/// operand requires relocation, record the relocation and return zero. 185unsigned 186AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, 187 SmallVectorImpl<MCFixup> &Fixups, 188 const MCSubtargetInfo &STI) const { 189 if (MO.isReg()) 190 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 191 192 assert(MO.isImm() && "did not expect relocated expression"); 193 return static_cast<unsigned>(MO.getImm()); 194} 195 196template<unsigned FixupKind> uint32_t 197AArch64MCCodeEmitter::getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx, 198 SmallVectorImpl<MCFixup> &Fixups, 199 const MCSubtargetInfo &STI) const { 200 const MCOperand &MO = MI.getOperand(OpIdx); 201 uint32_t ImmVal = 0; 202 203 if (MO.isImm()) 204 ImmVal = static_cast<uint32_t>(MO.getImm()); 205 else { 206 assert(MO.isExpr() && "unable to encode load/store imm operand"); 207 MCFixupKind Kind = MCFixupKind(FixupKind); 208 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 209 ++MCNumFixups; 210 } 211 212 return ImmVal; 213} 214 215/// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label 216/// target. 217uint32_t 218AArch64MCCodeEmitter::getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, 219 SmallVectorImpl<MCFixup> &Fixups, 220 const MCSubtargetInfo &STI) const { 221 const MCOperand &MO = MI.getOperand(OpIdx); 222 223 // If the destination is an immediate, we have nothing to do. 224 if (MO.isImm()) 225 return MO.getImm(); 226 assert(MO.isExpr() && "Unexpected target type!"); 227 const MCExpr *Expr = MO.getExpr(); 228 229 MCFixupKind Kind = MI.getOpcode() == AArch64::ADR 230 ? MCFixupKind(AArch64::fixup_aarch64_pcrel_adr_imm21) 231 : MCFixupKind(AArch64::fixup_aarch64_pcrel_adrp_imm21); 232 Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); 233 234 MCNumFixups += 1; 235 236 // All of the information is in the fixup. 237 return 0; 238} 239 240/// getAddSubImmOpValue - Return encoding for the 12-bit immediate value and 241/// the 2-bit shift field. The shift field is stored in bits 13-14 of the 242/// return value. 243uint32_t 244AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx, 245 SmallVectorImpl<MCFixup> &Fixups, 246 const MCSubtargetInfo &STI) const { 247 // Suboperands are [imm, shifter]. 248 const MCOperand &MO = MI.getOperand(OpIdx); 249 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); 250 assert(AArch64_AM::getShiftType(MO1.getImm()) == AArch64_AM::LSL && 251 "unexpected shift type for add/sub immediate"); 252 unsigned ShiftVal = AArch64_AM::getShiftValue(MO1.getImm()); 253 assert((ShiftVal == 0 || ShiftVal == 12) && 254 "unexpected shift value for add/sub immediate"); 255 if (MO.isImm()) 256 return MO.getImm() | (ShiftVal == 0 ? 0 : (1 << 12)); 257 assert(MO.isExpr() && "Unable to encode MCOperand!"); 258 const MCExpr *Expr = MO.getExpr(); 259 260 // Encode the 12 bits of the fixup. 261 MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_add_imm12); 262 Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc())); 263 264 ++MCNumFixups; 265 266 return 0; 267} 268 269/// getCondBranchTargetOpValue - Return the encoded value for a conditional 270/// branch target. 271uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue( 272 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, 273 const MCSubtargetInfo &STI) const { 274 const MCOperand &MO = MI.getOperand(OpIdx); 275 276 // If the destination is an immediate, we have nothing to do. 277 if (MO.isImm()) 278 return MO.getImm(); 279 assert(MO.isExpr() && "Unexpected target type!"); 280 281 MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch19); 282 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 283 284 ++MCNumFixups; 285 286 // All of the information is in the fixup. 287 return 0; 288} 289 290/// getLoadLiteralOpValue - Return the encoded value for a load-literal 291/// pc-relative address. 292uint32_t 293AArch64MCCodeEmitter::getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx, 294 SmallVectorImpl<MCFixup> &Fixups, 295 const MCSubtargetInfo &STI) const { 296 const MCOperand &MO = MI.getOperand(OpIdx); 297 298 // If the destination is an immediate, we have nothing to do. 299 if (MO.isImm()) 300 return MO.getImm(); 301 assert(MO.isExpr() && "Unexpected target type!"); 302 303 MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_ldr_pcrel_imm19); 304 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 305 306 ++MCNumFixups; 307 308 // All of the information is in the fixup. 309 return 0; 310} 311 312uint32_t 313AArch64MCCodeEmitter::getMemExtendOpValue(const MCInst &MI, unsigned OpIdx, 314 SmallVectorImpl<MCFixup> &Fixups, 315 const MCSubtargetInfo &STI) const { 316 unsigned SignExtend = MI.getOperand(OpIdx).getImm(); 317 unsigned DoShift = MI.getOperand(OpIdx + 1).getImm(); 318 return (SignExtend << 1) | DoShift; 319} 320 321uint32_t 322AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx, 323 SmallVectorImpl<MCFixup> &Fixups, 324 const MCSubtargetInfo &STI) const { 325 const MCOperand &MO = MI.getOperand(OpIdx); 326 327 if (MO.isImm()) 328 return MO.getImm(); 329 assert(MO.isExpr() && "Unexpected movz/movk immediate"); 330 331 Fixups.push_back(MCFixup::create( 332 0, MO.getExpr(), MCFixupKind(AArch64::fixup_aarch64_movw), MI.getLoc())); 333 334 ++MCNumFixups; 335 336 return 0; 337} 338 339/// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and- 340/// branch target. 341uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue( 342 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, 343 const MCSubtargetInfo &STI) const { 344 const MCOperand &MO = MI.getOperand(OpIdx); 345 346 // If the destination is an immediate, we have nothing to do. 347 if (MO.isImm()) 348 return MO.getImm(); 349 assert(MO.isExpr() && "Unexpected ADR target type!"); 350 351 MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch14); 352 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 353 354 ++MCNumFixups; 355 356 // All of the information is in the fixup. 357 return 0; 358} 359 360/// getBranchTargetOpValue - Return the encoded value for an unconditional 361/// branch target. 362uint32_t 363AArch64MCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, 364 SmallVectorImpl<MCFixup> &Fixups, 365 const MCSubtargetInfo &STI) const { 366 const MCOperand &MO = MI.getOperand(OpIdx); 367 368 // If the destination is an immediate, we have nothing to do. 369 if (MO.isImm()) 370 return MO.getImm(); 371 assert(MO.isExpr() && "Unexpected ADR target type!"); 372 373 MCFixupKind Kind = MI.getOpcode() == AArch64::BL 374 ? MCFixupKind(AArch64::fixup_aarch64_pcrel_call26) 375 : MCFixupKind(AArch64::fixup_aarch64_pcrel_branch26); 376 Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); 377 378 ++MCNumFixups; 379 380 // All of the information is in the fixup. 381 return 0; 382} 383 384/// getVecShifterOpValue - Return the encoded value for the vector shifter: 385/// 386/// 00 -> 0 387/// 01 -> 8 388/// 10 -> 16 389/// 11 -> 24 390uint32_t 391AArch64MCCodeEmitter::getVecShifterOpValue(const MCInst &MI, unsigned OpIdx, 392 SmallVectorImpl<MCFixup> &Fixups, 393 const MCSubtargetInfo &STI) const { 394 const MCOperand &MO = MI.getOperand(OpIdx); 395 assert(MO.isImm() && "Expected an immediate value for the shift amount!"); 396 397 switch (MO.getImm()) { 398 default: 399 break; 400 case 0: 401 return 0; 402 case 8: 403 return 1; 404 case 16: 405 return 2; 406 case 24: 407 return 3; 408 } 409 410 llvm_unreachable("Invalid value for vector shift amount!"); 411} 412 413/// getFixedPointScaleOpValue - Return the encoded value for the 414// FP-to-fixed-point scale factor. 415uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue( 416 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, 417 const MCSubtargetInfo &STI) const { 418 const MCOperand &MO = MI.getOperand(OpIdx); 419 assert(MO.isImm() && "Expected an immediate value for the scale amount!"); 420 return 64 - MO.getImm(); 421} 422 423uint32_t 424AArch64MCCodeEmitter::getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx, 425 SmallVectorImpl<MCFixup> &Fixups, 426 const MCSubtargetInfo &STI) const { 427 const MCOperand &MO = MI.getOperand(OpIdx); 428 assert(MO.isImm() && "Expected an immediate value for the scale amount!"); 429 return 64 - MO.getImm(); 430} 431 432uint32_t 433AArch64MCCodeEmitter::getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx, 434 SmallVectorImpl<MCFixup> &Fixups, 435 const MCSubtargetInfo &STI) const { 436 const MCOperand &MO = MI.getOperand(OpIdx); 437 assert(MO.isImm() && "Expected an immediate value for the scale amount!"); 438 return 32 - MO.getImm(); 439} 440 441uint32_t 442AArch64MCCodeEmitter::getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx, 443 SmallVectorImpl<MCFixup> &Fixups, 444 const MCSubtargetInfo &STI) const { 445 const MCOperand &MO = MI.getOperand(OpIdx); 446 assert(MO.isImm() && "Expected an immediate value for the scale amount!"); 447 return 16 - MO.getImm(); 448} 449 450uint32_t 451AArch64MCCodeEmitter::getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx, 452 SmallVectorImpl<MCFixup> &Fixups, 453 const MCSubtargetInfo &STI) const { 454 const MCOperand &MO = MI.getOperand(OpIdx); 455 assert(MO.isImm() && "Expected an immediate value for the scale amount!"); 456 return 8 - MO.getImm(); 457} 458 459uint32_t 460AArch64MCCodeEmitter::getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx, 461 SmallVectorImpl<MCFixup> &Fixups, 462 const MCSubtargetInfo &STI) const { 463 const MCOperand &MO = MI.getOperand(OpIdx); 464 assert(MO.isImm() && "Expected an immediate value for the scale amount!"); 465 return MO.getImm() - 64; 466} 467 468uint32_t 469AArch64MCCodeEmitter::getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx, 470 SmallVectorImpl<MCFixup> &Fixups, 471 const MCSubtargetInfo &STI) const { 472 const MCOperand &MO = MI.getOperand(OpIdx); 473 assert(MO.isImm() && "Expected an immediate value for the scale amount!"); 474 return MO.getImm() - 32; 475} 476 477uint32_t 478AArch64MCCodeEmitter::getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx, 479 SmallVectorImpl<MCFixup> &Fixups, 480 const MCSubtargetInfo &STI) const { 481 const MCOperand &MO = MI.getOperand(OpIdx); 482 assert(MO.isImm() && "Expected an immediate value for the scale amount!"); 483 return MO.getImm() - 16; 484} 485 486uint32_t 487AArch64MCCodeEmitter::getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx, 488 SmallVectorImpl<MCFixup> &Fixups, 489 const MCSubtargetInfo &STI) const { 490 const MCOperand &MO = MI.getOperand(OpIdx); 491 assert(MO.isImm() && "Expected an immediate value for the scale amount!"); 492 return MO.getImm() - 8; 493} 494 495/// getMoveVecShifterOpValue - Return the encoded value for the vector move 496/// shifter (MSL). 497uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue( 498 const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, 499 const MCSubtargetInfo &STI) const { 500 const MCOperand &MO = MI.getOperand(OpIdx); 501 assert(MO.isImm() && 502 "Expected an immediate value for the move shift amount!"); 503 unsigned ShiftVal = AArch64_AM::getShiftValue(MO.getImm()); 504 assert((ShiftVal == 8 || ShiftVal == 16) && "Invalid shift amount!"); 505 return ShiftVal == 8 ? 0 : 1; 506} 507 508unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue, 509 const MCSubtargetInfo &STI) const { 510 // If one of the signed fixup kinds is applied to a MOVZ instruction, the 511 // eventual result could be either a MOVZ or a MOVN. It's the MCCodeEmitter's 512 // job to ensure that any bits possibly affected by this are 0. This means we 513 // must zero out bit 30 (essentially emitting a MOVN). 514 MCOperand UImm16MO = MI.getOperand(1); 515 516 // Nothing to do if there's no fixup. 517 if (UImm16MO.isImm()) 518 return EncodedValue; 519 520 const AArch64MCExpr *A64E = cast<AArch64MCExpr>(UImm16MO.getExpr()); 521 switch (A64E->getKind()) { 522 case AArch64MCExpr::VK_DTPREL_G2: 523 case AArch64MCExpr::VK_DTPREL_G1: 524 case AArch64MCExpr::VK_DTPREL_G0: 525 case AArch64MCExpr::VK_GOTTPREL_G1: 526 case AArch64MCExpr::VK_TPREL_G2: 527 case AArch64MCExpr::VK_TPREL_G1: 528 case AArch64MCExpr::VK_TPREL_G0: 529 return EncodedValue & ~(1u << 30); 530 default: 531 // Nothing to do for an unsigned fixup. 532 return EncodedValue; 533 } 534 535 536 return EncodedValue & ~(1u << 30); 537} 538 539void AArch64MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, 540 SmallVectorImpl<MCFixup> &Fixups, 541 const MCSubtargetInfo &STI) const { 542 if (MI.getOpcode() == AArch64::TLSDESCCALL) { 543 // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the 544 // following (BLR) instruction. It doesn't emit any code itself so it 545 // doesn't go through the normal TableGenerated channels. 546 MCFixupKind Fixup = MCFixupKind(AArch64::fixup_aarch64_tlsdesc_call); 547 Fixups.push_back(MCFixup::create(0, MI.getOperand(0).getExpr(), Fixup)); 548 return; 549 } 550 551 uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI); 552 support::endian::Writer<support::little>(OS).write<uint32_t>(Binary); 553 ++MCNumEmitted; // Keep track of the # of mi's emitted. 554} 555 556unsigned 557AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI, 558 unsigned EncodedValue, 559 const MCSubtargetInfo &STI) const { 560 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31 561 // (i.e. all bits 1) but is ignored by the processor. 562 EncodedValue |= 0x1f << 10; 563 return EncodedValue; 564} 565 566template<int hasRs, int hasRt2> unsigned 567AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI, 568 unsigned EncodedValue, 569 const MCSubtargetInfo &STI) const { 570 if (!hasRs) EncodedValue |= 0x001F0000; 571 if (!hasRt2) EncodedValue |= 0x00007C00; 572 573 return EncodedValue; 574} 575 576unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison( 577 const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const { 578 // The Rm field of FCMP and friends is unused - it should be assembled 579 // as 0, but is ignored by the processor. 580 EncodedValue &= ~(0x1f << 16); 581 return EncodedValue; 582} 583 584#include "AArch64GenMCCodeEmitter.inc" 585