1 //===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM code to machine code -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the ARMMCCodeEmitter class.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "mccodeemitter"
16 #include "ARMAddressingModes.h"
17 #include "ARMFixupKinds.h"
18 #include "ARMInstrInfo.h"
19 #include "llvm/MC/MCCodeEmitter.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/ADT/Statistic.h"
23 #include "llvm/Support/raw_ostream.h"
26 STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
27 STATISTIC(MCNumCPRelocations, "Number of constant pool relocations created.");
30 class ARMMCCodeEmitter : public MCCodeEmitter {
31 ARMMCCodeEmitter(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
32 void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
33 const TargetMachine &TM;
34 const TargetInstrInfo &TII;
38 ARMMCCodeEmitter(TargetMachine &tm, MCContext &ctx)
39 : TM(tm), TII(*TM.getInstrInfo()), Ctx(ctx) {
42 ~ARMMCCodeEmitter() {}
44 unsigned getNumFixupKinds() const { return ARM::NumTargetFixupKinds; }
46 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
47 const static MCFixupKindInfo Infos[] = {
48 // name off bits flags
49 { "fixup_arm_ldst_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
50 { "fixup_arm_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
51 { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
52 { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
53 { "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
54 { "fixup_arm_movt_hi16", 0, 16, 0 },
55 { "fixup_arm_movw_lo16", 0, 16, 0 },
58 if (Kind < FirstTargetFixupKind)
59 return MCCodeEmitter::getFixupKindInfo(Kind);
61 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
63 return Infos[Kind - FirstTargetFixupKind];
65 unsigned getMachineSoImmOpValue(unsigned SoImm) const;
67 // getBinaryCodeForInstr - TableGen'erated function for getting the
68 // binary encoding for an instruction.
69 unsigned getBinaryCodeForInstr(const MCInst &MI,
70 SmallVectorImpl<MCFixup> &Fixups) const;
72 /// getMachineOpValue - Return binary encoding of operand. If the machine
73 /// operand requires relocation, record the relocation and return zero.
74 unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
75 SmallVectorImpl<MCFixup> &Fixups) const;
77 /// getMovtImmOpValue - Return the encoding for the movw/movt pair
78 uint32_t getMovtImmOpValue(const MCInst &MI, unsigned OpIdx,
79 SmallVectorImpl<MCFixup> &Fixups) const;
81 bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
82 unsigned &Reg, unsigned &Imm,
83 SmallVectorImpl<MCFixup> &Fixups) const;
85 /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate
87 uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
88 SmallVectorImpl<MCFixup> &Fixups) const;
90 /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
92 uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
93 SmallVectorImpl<MCFixup> &Fixups) const;
95 /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
97 uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
98 SmallVectorImpl<MCFixup> &Fixups) const;
100 /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
102 uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
103 SmallVectorImpl<MCFixup> &Fixups) const;
105 /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
107 uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
108 SmallVectorImpl<MCFixup> &Fixups) const;
111 /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
112 /// operand as needed by load/store instructions.
113 uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
114 SmallVectorImpl<MCFixup> &Fixups) const;
116 /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
117 uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
118 SmallVectorImpl<MCFixup> &Fixups) const {
119 ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
121 default: assert(0 && "Unknown addressing sub-mode!");
122 case ARM_AM::da: return 0;
123 case ARM_AM::ia: return 1;
124 case ARM_AM::db: return 2;
125 case ARM_AM::ib: return 3;
128 /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
130 unsigned getShiftOp(ARM_AM::ShiftOpc ShOpc) const {
132 default: llvm_unreachable("Unknown shift opc!");
133 case ARM_AM::no_shift:
134 case ARM_AM::lsl: return 0;
135 case ARM_AM::lsr: return 1;
136 case ARM_AM::asr: return 2;
138 case ARM_AM::rrx: return 3;
143 /// getAddrMode2OpValue - Return encoding for addrmode2 operands.
144 uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
145 SmallVectorImpl<MCFixup> &Fixups) const;
147 /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
148 uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
149 SmallVectorImpl<MCFixup> &Fixups) const;
151 /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
152 uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
153 SmallVectorImpl<MCFixup> &Fixups) const;
155 /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
156 uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
157 SmallVectorImpl<MCFixup> &Fixups) const;
159 /// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
160 uint32_t getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
161 SmallVectorImpl<MCFixup> &Fixups) const;
163 /// getAddrModeS2OpValue - Return encoding for t_addrmode_s2 operands.
164 uint32_t getAddrModeS2OpValue(const MCInst &MI, unsigned OpIdx,
165 SmallVectorImpl<MCFixup> &Fixups) const;
167 /// getAddrModeS1OpValue - Return encoding for t_addrmode_s1 operands.
168 uint32_t getAddrModeS1OpValue(const MCInst &MI, unsigned OpIdx,
169 SmallVectorImpl<MCFixup> &Fixups) const;
171 /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
172 uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
173 SmallVectorImpl<MCFixup> &Fixups) const;
175 /// getCCOutOpValue - Return encoding of the 's' bit.
176 unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
177 SmallVectorImpl<MCFixup> &Fixups) const {
178 // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
180 return MI.getOperand(Op).getReg() == ARM::CPSR;
183 /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
184 unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
185 SmallVectorImpl<MCFixup> &Fixups) const {
186 unsigned SoImm = MI.getOperand(Op).getImm();
187 int SoImmVal = ARM_AM::getSOImmVal(SoImm);
188 assert(SoImmVal != -1 && "Not a valid so_imm value!");
190 // Encode rotate_imm.
191 unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
192 << ARMII::SoRotImmShift;
195 Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
199 /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
200 unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
201 SmallVectorImpl<MCFixup> &Fixups) const {
202 unsigned SoImm = MI.getOperand(Op).getImm();
203 unsigned Encoded = ARM_AM::getT2SOImmVal(SoImm);
204 assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
208 unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
209 SmallVectorImpl<MCFixup> &Fixups) const;
210 unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
211 SmallVectorImpl<MCFixup> &Fixups) const;
212 unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
213 SmallVectorImpl<MCFixup> &Fixups) const;
214 unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
215 SmallVectorImpl<MCFixup> &Fixups) const;
217 /// getSORegOpValue - Return an encoded so_reg shifted register value.
218 unsigned getSORegOpValue(const MCInst &MI, unsigned Op,
219 SmallVectorImpl<MCFixup> &Fixups) const;
220 unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
221 SmallVectorImpl<MCFixup> &Fixups) const;
223 unsigned getRotImmOpValue(const MCInst &MI, unsigned Op,
224 SmallVectorImpl<MCFixup> &Fixups) const {
225 switch (MI.getOperand(Op).getImm()) {
226 default: assert (0 && "Not a valid rot_imm value!");
234 unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op,
235 SmallVectorImpl<MCFixup> &Fixups) const {
236 return MI.getOperand(Op).getImm() - 1;
239 unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
240 SmallVectorImpl<MCFixup> &Fixups) const {
241 return 64 - MI.getOperand(Op).getImm();
244 unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
245 SmallVectorImpl<MCFixup> &Fixups) const;
247 unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
248 SmallVectorImpl<MCFixup> &Fixups) const;
249 unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
250 SmallVectorImpl<MCFixup> &Fixups) const;
251 unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
252 SmallVectorImpl<MCFixup> &Fixups) const;
253 unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
254 SmallVectorImpl<MCFixup> &Fixups) const;
256 unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
257 unsigned EncodedValue) const;
258 unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
259 unsigned EncodedValue) const;
260 unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
261 unsigned EncodedValue) const;
263 unsigned VFPThumb2PostEncoder(const MCInst &MI,
264 unsigned EncodedValue) const;
266 void EmitByte(unsigned char C, raw_ostream &OS) const {
270 void EmitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) const {
271 // Output the constant in little endian byte order.
272 for (unsigned i = 0; i != Size; ++i) {
273 EmitByte(Val & 255, OS);
278 void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
279 SmallVectorImpl<MCFixup> &Fixups) const;
282 } // end anonymous namespace
284 MCCodeEmitter *llvm::createARMMCCodeEmitter(const Target &, TargetMachine &TM,
286 return new ARMMCCodeEmitter(TM, Ctx);
289 /// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
290 /// instructions, and rewrite them to their Thumb2 form if we are currently in
292 unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
293 unsigned EncodedValue) const {
294 const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
295 if (Subtarget.isThumb2()) {
296 // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
297 // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
299 unsigned Bit24 = EncodedValue & 0x01000000;
300 unsigned Bit28 = Bit24 << 4;
301 EncodedValue &= 0xEFFFFFFF;
302 EncodedValue |= Bit28;
303 EncodedValue |= 0x0F000000;
309 /// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
310 /// instructions, and rewrite them to their Thumb2 form if we are currently in
312 unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
313 unsigned EncodedValue) const {
314 const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
315 if (Subtarget.isThumb2()) {
316 EncodedValue &= 0xF0FFFFFF;
317 EncodedValue |= 0x09000000;
323 /// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
324 /// instructions, and rewrite them to their Thumb2 form if we are currently in
326 unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
327 unsigned EncodedValue) const {
328 const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
329 if (Subtarget.isThumb2()) {
330 EncodedValue &= 0x00FFFFFF;
331 EncodedValue |= 0xEE000000;
337 /// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
338 /// them to their Thumb2 form if we are currently in Thumb2 mode.
339 unsigned ARMMCCodeEmitter::
340 VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const {
341 if (TM.getSubtarget<ARMSubtarget>().isThumb2()) {
342 EncodedValue &= 0x0FFFFFFF;
343 EncodedValue |= 0xE0000000;
348 /// getMachineOpValue - Return binary encoding of operand. If the machine
349 /// operand requires relocation, record the relocation and return zero.
350 unsigned ARMMCCodeEmitter::
351 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
352 SmallVectorImpl<MCFixup> &Fixups) const {
354 unsigned Reg = MO.getReg();
355 unsigned RegNo = getARMRegisterNumbering(Reg);
357 // Q registers are encoded as 2x their register number.
361 case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3:
362 case ARM::Q4: case ARM::Q5: case ARM::Q6: case ARM::Q7:
363 case ARM::Q8: case ARM::Q9: case ARM::Q10: case ARM::Q11:
364 case ARM::Q12: case ARM::Q13: case ARM::Q14: case ARM::Q15:
367 } else if (MO.isImm()) {
368 return static_cast<unsigned>(MO.getImm());
369 } else if (MO.isFPImm()) {
370 return static_cast<unsigned>(APFloat(MO.getFPImm())
371 .bitcastToAPInt().getHiBits(32).getLimitedValue());
374 llvm_unreachable("Unable to encode MCOperand!");
378 /// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
379 bool ARMMCCodeEmitter::
380 EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg,
381 unsigned &Imm, SmallVectorImpl<MCFixup> &Fixups) const {
382 const MCOperand &MO = MI.getOperand(OpIdx);
383 const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
385 Reg = getARMRegisterNumbering(MO.getReg());
387 int32_t SImm = MO1.getImm();
390 // Special value for #-0
391 if (SImm == INT32_MIN)
394 // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
404 /// getThumbBLTargetOpValue - Return encoding info for immediate
406 uint32_t ARMMCCodeEmitter::
407 getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
408 SmallVectorImpl<MCFixup> &Fixups) const {
409 const MCOperand &MO = MI.getOperand(OpIdx);
411 // If the destination is an immediate, we have nothing to do.
412 if (MO.isImm()) return MO.getImm();
413 assert (MO.isExpr() && "Unexpected branch target type!");
414 const MCExpr *Expr = MO.getExpr();
415 MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_thumb_bl);
416 Fixups.push_back(MCFixup::Create(0, Expr, Kind));
418 // All of the information is in the fixup.
422 /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
424 uint32_t ARMMCCodeEmitter::
425 getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
426 SmallVectorImpl<MCFixup> &Fixups) const {
427 const MCOperand &MO = MI.getOperand(OpIdx);
429 // If the destination is an immediate, we have nothing to do.
430 if (MO.isImm()) return MO.getImm();
431 assert (MO.isExpr() && "Unexpected branch target type!");
432 const MCExpr *Expr = MO.getExpr();
433 MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_branch);
434 Fixups.push_back(MCFixup::Create(0, Expr, Kind));
436 // All of the information is in the fixup.
440 /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
441 /// ADR label target.
442 uint32_t ARMMCCodeEmitter::
443 getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
444 SmallVectorImpl<MCFixup> &Fixups) const {
445 const MCOperand &MO = MI.getOperand(OpIdx);
446 assert (MO.isExpr() && "Unexpected adr target type!");
447 const MCExpr *Expr = MO.getExpr();
448 MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_adr_pcrel_12);
449 Fixups.push_back(MCFixup::Create(0, Expr, Kind));
450 // All of the information is in the fixup.
454 /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
455 uint32_t ARMMCCodeEmitter::
456 getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
457 SmallVectorImpl<MCFixup> &Fixups) const {
459 // {12} = (U)nsigned (add == '1', sub == '0')
463 // If The first operand isn't a register, we have a label reference.
464 const MCOperand &MO = MI.getOperand(OpIdx);
466 Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC.
468 isAdd = false ; // 'U' bit is set as part of the fixup.
470 assert(MO.isExpr() && "Unexpected machine operand type!");
471 const MCExpr *Expr = MO.getExpr();
472 MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
473 Fixups.push_back(MCFixup::Create(0, Expr, Kind));
475 ++MCNumCPRelocations;
477 isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm12, Fixups);
479 uint32_t Binary = Imm12 & 0xfff;
480 // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
483 Binary |= (Reg << 13);
487 /// getT2AddrModeImm8s4OpValue - Return encoding info for
488 /// 'reg +/- imm8<<2' operand.
489 uint32_t ARMMCCodeEmitter::
490 getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
491 SmallVectorImpl<MCFixup> &Fixups) const {
493 // {12} = (U)nsigned (add == '1', sub == '0')
497 // If The first operand isn't a register, we have a label reference.
498 const MCOperand &MO = MI.getOperand(OpIdx);
500 Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC.
502 isAdd = false ; // 'U' bit is set as part of the fixup.
504 assert(MO.isExpr() && "Unexpected machine operand type!");
505 const MCExpr *Expr = MO.getExpr();
506 MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
507 Fixups.push_back(MCFixup::Create(0, Expr, Kind));
509 ++MCNumCPRelocations;
511 isAdd = EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
513 uint32_t Binary = (Imm8 >> 2) & 0xff;
514 // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
517 Binary |= (Reg << 9);
521 uint32_t ARMMCCodeEmitter::
522 getMovtImmOpValue(const MCInst &MI, unsigned OpIdx,
523 SmallVectorImpl<MCFixup> &Fixups) const {
524 // {20-16} = imm{15-12}
525 // {11-0} = imm{11-0}
526 const MCOperand &MO = MI.getOperand(OpIdx);
528 return static_cast<unsigned>(MO.getImm());
529 } else if (const MCSymbolRefExpr *Expr =
530 dyn_cast<MCSymbolRefExpr>(MO.getExpr())) {
532 switch (Expr->getKind()) {
533 default: assert(0 && "Unsupported ARMFixup");
534 case MCSymbolRefExpr::VK_ARM_HI16:
535 Kind = MCFixupKind(ARM::fixup_arm_movt_hi16);
537 case MCSymbolRefExpr::VK_ARM_LO16:
538 Kind = MCFixupKind(ARM::fixup_arm_movw_lo16);
541 Fixups.push_back(MCFixup::Create(0, Expr, Kind));
544 llvm_unreachable("Unsupported MCExpr type in MCOperand!");
548 uint32_t ARMMCCodeEmitter::
549 getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
550 SmallVectorImpl<MCFixup> &Fixups) const {
551 const MCOperand &MO = MI.getOperand(OpIdx);
552 const MCOperand &MO1 = MI.getOperand(OpIdx+1);
553 const MCOperand &MO2 = MI.getOperand(OpIdx+2);
554 unsigned Rn = getARMRegisterNumbering(MO.getReg());
555 unsigned Rm = getARMRegisterNumbering(MO1.getReg());
556 unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
557 bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
558 ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
559 unsigned SBits = getShiftOp(ShOp);
568 uint32_t Binary = Rm;
570 Binary |= SBits << 5;
571 Binary |= ShImm << 7;
577 uint32_t ARMMCCodeEmitter::
578 getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
579 SmallVectorImpl<MCFixup> &Fixups) const {
581 // {13} 1 == imm12, 0 == Rm
584 const MCOperand &MO = MI.getOperand(OpIdx);
585 unsigned Rn = getARMRegisterNumbering(MO.getReg());
586 uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups);
591 uint32_t ARMMCCodeEmitter::
592 getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
593 SmallVectorImpl<MCFixup> &Fixups) const {
594 // {13} 1 == imm12, 0 == Rm
597 const MCOperand &MO = MI.getOperand(OpIdx);
598 const MCOperand &MO1 = MI.getOperand(OpIdx+1);
599 unsigned Imm = MO1.getImm();
600 bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
601 bool isReg = MO.getReg() != 0;
602 uint32_t Binary = ARM_AM::getAM2Offset(Imm);
603 // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
605 ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(Imm);
606 Binary <<= 7; // Shift amount is bits [11:7]
607 Binary |= getShiftOp(ShOp) << 5; // Shift type is bits [6:5]
608 Binary |= getARMRegisterNumbering(MO.getReg()); // Rm is bits [3:0]
610 return Binary | (isAdd << 12) | (isReg << 13);
613 uint32_t ARMMCCodeEmitter::
614 getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
615 SmallVectorImpl<MCFixup> &Fixups) const {
616 // {9} 1 == imm8, 0 == Rm
620 const MCOperand &MO = MI.getOperand(OpIdx);
621 const MCOperand &MO1 = MI.getOperand(OpIdx+1);
622 unsigned Imm = MO1.getImm();
623 bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
624 bool isImm = MO.getReg() == 0;
625 uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
626 // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
628 Imm8 = getARMRegisterNumbering(MO.getReg());
629 return Imm8 | (isAdd << 8) | (isImm << 9);
632 uint32_t ARMMCCodeEmitter::
633 getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
634 SmallVectorImpl<MCFixup> &Fixups) const {
635 // {13} 1 == imm8, 0 == Rm
640 const MCOperand &MO = MI.getOperand(OpIdx);
641 const MCOperand &MO1 = MI.getOperand(OpIdx+1);
642 const MCOperand &MO2 = MI.getOperand(OpIdx+2);
643 unsigned Rn = getARMRegisterNumbering(MO.getReg());
644 unsigned Imm = MO2.getImm();
645 bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
646 bool isImm = MO1.getReg() == 0;
647 uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
648 // if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
650 Imm8 = getARMRegisterNumbering(MO1.getReg());
651 return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
654 /// getAddrModeSOpValue - Encode the t_addrmode_s# operands.
655 static unsigned getAddrModeSOpValue(const MCInst &MI, unsigned OpIdx,
664 const MCOperand &MO = MI.getOperand(OpIdx);
665 const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
666 const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
667 unsigned Rn = getARMRegisterNumbering(MO.getReg());
668 unsigned Imm5 = (MO1.getImm() / Scale) & 0x1f;
670 if (MO2.getReg() != 0)
672 Imm5 = getARMRegisterNumbering(MO2.getReg());
674 return (Imm5 << 3) | Rn;
677 /// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
678 uint32_t ARMMCCodeEmitter::
679 getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
680 SmallVectorImpl<MCFixup> &) const {
681 return getAddrModeSOpValue(MI, OpIdx, 4);
684 /// getAddrModeS2OpValue - Return encoding for t_addrmode_s2 operands.
685 uint32_t ARMMCCodeEmitter::
686 getAddrModeS2OpValue(const MCInst &MI, unsigned OpIdx,
687 SmallVectorImpl<MCFixup> &) const {
688 return getAddrModeSOpValue(MI, OpIdx, 2);
691 /// getAddrModeS1OpValue - Return encoding for t_addrmode_s1 operands.
692 uint32_t ARMMCCodeEmitter::
693 getAddrModeS1OpValue(const MCInst &MI, unsigned OpIdx,
694 SmallVectorImpl<MCFixup> &) const {
695 return getAddrModeSOpValue(MI, OpIdx, 1);
698 /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand.
699 uint32_t ARMMCCodeEmitter::
700 getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
701 SmallVectorImpl<MCFixup> &Fixups) const {
703 // {8} = (U)nsigned (add == '1', sub == '0')
707 // If The first operand isn't a register, we have a label reference.
708 const MCOperand &MO = MI.getOperand(OpIdx);
710 Reg = getARMRegisterNumbering(ARM::PC); // Rn is PC.
712 isAdd = false; // 'U' bit is handled as part of the fixup.
714 assert(MO.isExpr() && "Unexpected machine operand type!");
715 const MCExpr *Expr = MO.getExpr();
716 MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
717 Fixups.push_back(MCFixup::Create(0, Expr, Kind));
719 ++MCNumCPRelocations;
721 EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups);
722 isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
725 uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
726 // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
729 Binary |= (Reg << 9);
733 unsigned ARMMCCodeEmitter::
734 getSORegOpValue(const MCInst &MI, unsigned OpIdx,
735 SmallVectorImpl<MCFixup> &Fixups) const {
736 // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
737 // shifted. The second is either Rs, the amount to shift by, or reg0 in which
738 // case the imm contains the amount to shift by.
741 // {4} = 1 if reg shift, 0 if imm shift
749 const MCOperand &MO = MI.getOperand(OpIdx);
750 const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
751 const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
752 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
755 unsigned Binary = getARMRegisterNumbering(MO.getReg());
757 // Encode the shift opcode.
759 unsigned Rs = MO1.getReg();
761 // Set shift operand (bit[7:4]).
766 // RRX - 0110 and bit[11:8] clear.
768 default: llvm_unreachable("Unknown shift opc!");
769 case ARM_AM::lsl: SBits = 0x1; break;
770 case ARM_AM::lsr: SBits = 0x3; break;
771 case ARM_AM::asr: SBits = 0x5; break;
772 case ARM_AM::ror: SBits = 0x7; break;
773 case ARM_AM::rrx: SBits = 0x6; break;
776 // Set shift operand (bit[6:4]).
782 default: llvm_unreachable("Unknown shift opc!");
783 case ARM_AM::lsl: SBits = 0x0; break;
784 case ARM_AM::lsr: SBits = 0x2; break;
785 case ARM_AM::asr: SBits = 0x4; break;
786 case ARM_AM::ror: SBits = 0x6; break;
790 Binary |= SBits << 4;
791 if (SOpc == ARM_AM::rrx)
794 // Encode the shift operation Rs or shift_imm (except rrx).
796 // Encode Rs bit[11:8].
797 assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
798 return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
801 // Encode shift_imm bit[11:7].
802 return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
805 unsigned ARMMCCodeEmitter::
806 getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
807 SmallVectorImpl<MCFixup> &Fixups) const {
808 const MCOperand &MO1 = MI.getOperand(OpNum);
809 const MCOperand &MO2 = MI.getOperand(OpNum+1);
810 const MCOperand &MO3 = MI.getOperand(OpNum+2);
812 // Encoded as [Rn, Rm, imm].
813 // FIXME: Needs fixup support.
814 unsigned Value = getARMRegisterNumbering(MO1.getReg());
816 Value |= getARMRegisterNumbering(MO2.getReg());
818 Value |= MO3.getImm();
823 unsigned ARMMCCodeEmitter::
824 getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
825 SmallVectorImpl<MCFixup> &Fixups) const {
826 const MCOperand &MO1 = MI.getOperand(OpNum);
827 const MCOperand &MO2 = MI.getOperand(OpNum+1);
829 // FIXME: Needs fixup support.
830 unsigned Value = getARMRegisterNumbering(MO1.getReg());
832 // Even though the immediate is 8 bits long, we need 9 bits in order
833 // to represent the (inverse of the) sign bit.
835 int32_t tmp = (int32_t)MO2.getImm();
839 Value |= 256; // Set the ADD bit
844 unsigned ARMMCCodeEmitter::
845 getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
846 SmallVectorImpl<MCFixup> &Fixups) const {
847 const MCOperand &MO1 = MI.getOperand(OpNum);
849 // FIXME: Needs fixup support.
851 int32_t tmp = (int32_t)MO1.getImm();
855 Value |= 256; // Set the ADD bit
860 unsigned ARMMCCodeEmitter::
861 getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
862 SmallVectorImpl<MCFixup> &Fixups) const {
863 const MCOperand &MO1 = MI.getOperand(OpNum);
865 // FIXME: Needs fixup support.
867 int32_t tmp = (int32_t)MO1.getImm();
871 Value |= 4096; // Set the ADD bit
876 unsigned ARMMCCodeEmitter::
877 getT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
878 SmallVectorImpl<MCFixup> &Fixups) const {
879 // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
880 // shifted. The second is the amount to shift by.
887 const MCOperand &MO = MI.getOperand(OpIdx);
888 const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
889 ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO1.getImm());
892 unsigned Binary = getARMRegisterNumbering(MO.getReg());
894 // Encode the shift opcode.
896 // Set shift operand (bit[6:4]).
902 default: llvm_unreachable("Unknown shift opc!");
903 case ARM_AM::lsl: SBits = 0x0; break;
904 case ARM_AM::lsr: SBits = 0x2; break;
905 case ARM_AM::asr: SBits = 0x4; break;
906 case ARM_AM::ror: SBits = 0x6; break;
909 Binary |= SBits << 4;
910 if (SOpc == ARM_AM::rrx)
913 // Encode shift_imm bit[11:7].
914 return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
917 unsigned ARMMCCodeEmitter::
918 getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
919 SmallVectorImpl<MCFixup> &Fixups) const {
920 // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
922 const MCOperand &MO = MI.getOperand(Op);
923 uint32_t v = ~MO.getImm();
924 uint32_t lsb = CountTrailingZeros_32(v);
925 uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1;
926 assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!");
927 return lsb | (msb << 5);
930 unsigned ARMMCCodeEmitter::
931 getRegisterListOpValue(const MCInst &MI, unsigned Op,
932 SmallVectorImpl<MCFixup> &Fixups) const {
935 // {7-0} = Number of registers
938 // {15-0} = Bitfield of GPRs.
939 unsigned Reg = MI.getOperand(Op).getReg();
940 bool SPRRegs = ARM::SPRRegClass.contains(Reg);
941 bool DPRRegs = ARM::DPRRegClass.contains(Reg);
945 if (SPRRegs || DPRRegs) {
947 unsigned RegNo = getARMRegisterNumbering(Reg);
948 unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
949 Binary |= (RegNo & 0x1f) << 8;
953 Binary |= NumRegs * 2;
955 for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
956 unsigned RegNo = getARMRegisterNumbering(MI.getOperand(I).getReg());
957 Binary |= 1 << RegNo;
964 /// getAddrMode6AddressOpValue - Encode an addrmode6 register number along
965 /// with the alignment operand.
966 unsigned ARMMCCodeEmitter::
967 getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
968 SmallVectorImpl<MCFixup> &Fixups) const {
969 const MCOperand &Reg = MI.getOperand(Op);
970 const MCOperand &Imm = MI.getOperand(Op + 1);
972 unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
975 switch (Imm.getImm()) {
979 case 8: Align = 0x01; break;
980 case 16: Align = 0x02; break;
981 case 32: Align = 0x03; break;
984 return RegNo | (Align << 4);
987 /// getAddrMode6DupAddressOpValue - Encode an addrmode6 register number and
988 /// alignment operand for use in VLD-dup instructions. This is the same as
989 /// getAddrMode6AddressOpValue except for the alignment encoding, which is
990 /// different for VLD4-dup.
991 unsigned ARMMCCodeEmitter::
992 getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
993 SmallVectorImpl<MCFixup> &Fixups) const {
994 const MCOperand &Reg = MI.getOperand(Op);
995 const MCOperand &Imm = MI.getOperand(Op + 1);
997 unsigned RegNo = getARMRegisterNumbering(Reg.getReg());
1000 switch (Imm.getImm()) {
1004 case 8: Align = 0x01; break;
1005 case 16: Align = 0x03; break;
1008 return RegNo | (Align << 4);
1011 unsigned ARMMCCodeEmitter::
1012 getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
1013 SmallVectorImpl<MCFixup> &Fixups) const {
1014 const MCOperand &MO = MI.getOperand(Op);
1015 if (MO.getReg() == 0) return 0x0D;
1019 void ARMMCCodeEmitter::
1020 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
1021 SmallVectorImpl<MCFixup> &Fixups) const {
1022 const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
1023 // Pseudo instructions don't get encoded.
1024 const TargetInstrDesc &Desc = TII.get(MI.getOpcode());
1025 uint64_t TSFlags = Desc.TSFlags;
1026 if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
1029 // Basic size info comes from the TSFlags field.
1030 switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
1031 default: llvm_unreachable("Unexpected instruction size!");
1032 case ARMII::Size2Bytes: Size = 2; break;
1033 case ARMII::Size4Bytes: Size = 4; break;
1035 uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
1036 // Thumb 32-bit wide instructions need to be have the high order halfword
1038 if (Subtarget.isThumb() && Size == 4) {
1039 EmitConstant(Binary >> 16, 2, OS);
1040 EmitConstant(Binary & 0xffff, 2, OS);
1042 EmitConstant(Binary, Size, OS);
1043 ++MCNumEmitted; // Keep track of the # of mi's emitted.
1046 #include "ARMGenMCCodeEmitter.inc"