llvm.org GIT mirror llvm / ee04a6d
Sink ARMMCExpr and ARMAddressingModes into MC layer. First step to separate ARM MC code from target. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135636 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 9 years ago
32 changed file(s) with 929 addition(s) and 921 deletion(s). Raw diff Collapse all Expand all
+0
-595
lib/Target/ARM/ARMAddressingModes.h less more
None //===- ARMAddressingModes.h - ARM Addressing Modes --------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the ARM addressing mode implementation stuff.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
14 #define LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
15
16 #include "llvm/CodeGen/SelectionDAGNodes.h"
17 #include "llvm/Support/MathExtras.h"
18 #include
19
20 namespace llvm {
21
22 /// ARM_AM - ARM Addressing Mode Stuff
23 namespace ARM_AM {
24 enum ShiftOpc {
25 no_shift = 0,
26 asr,
27 lsl,
28 lsr,
29 ror,
30 rrx
31 };
32
33 enum AddrOpc {
34 add = '+', sub = '-'
35 };
36
37 static inline const char *getAddrOpcStr(AddrOpc Op) {
38 return Op == sub ? "-" : "";
39 }
40
41 static inline const char *getShiftOpcStr(ShiftOpc Op) {
42 switch (Op) {
43 default: assert(0 && "Unknown shift opc!");
44 case ARM_AM::asr: return "asr";
45 case ARM_AM::lsl: return "lsl";
46 case ARM_AM::lsr: return "lsr";
47 case ARM_AM::ror: return "ror";
48 case ARM_AM::rrx: return "rrx";
49 }
50 }
51
52 static inline unsigned getShiftOpcEncoding(ShiftOpc Op) {
53 switch (Op) {
54 default: assert(0 && "Unknown shift opc!");
55 case ARM_AM::asr: return 2;
56 case ARM_AM::lsl: return 0;
57 case ARM_AM::lsr: return 1;
58 case ARM_AM::ror: return 3;
59 }
60 }
61
62 static inline ShiftOpc getShiftOpcForNode(SDValue N) {
63 switch (N.getOpcode()) {
64 default: return ARM_AM::no_shift;
65 case ISD::SHL: return ARM_AM::lsl;
66 case ISD::SRL: return ARM_AM::lsr;
67 case ISD::SRA: return ARM_AM::asr;
68 case ISD::ROTR: return ARM_AM::ror;
69 //case ISD::ROTL: // Only if imm -> turn into ROTR.
70 // Can't handle RRX here, because it would require folding a flag into
71 // the addressing mode. :( This causes us to miss certain things.
72 //case ARMISD::RRX: return ARM_AM::rrx;
73 }
74 }
75
76 enum AMSubMode {
77 bad_am_submode = 0,
78 ia,
79 ib,
80 da,
81 db
82 };
83
84 static inline const char *getAMSubModeStr(AMSubMode Mode) {
85 switch (Mode) {
86 default: assert(0 && "Unknown addressing sub-mode!");
87 case ARM_AM::ia: return "ia";
88 case ARM_AM::ib: return "ib";
89 case ARM_AM::da: return "da";
90 case ARM_AM::db: return "db";
91 }
92 }
93
94 /// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
95 ///
96 static inline unsigned rotr32(unsigned Val, unsigned Amt) {
97 assert(Amt < 32 && "Invalid rotate amount");
98 return (Val >> Amt) | (Val << ((32-Amt)&31));
99 }
100
101 /// rotl32 - Rotate a 32-bit unsigned value left by a specified # bits.
102 ///
103 static inline unsigned rotl32(unsigned Val, unsigned Amt) {
104 assert(Amt < 32 && "Invalid rotate amount");
105 return (Val << Amt) | (Val >> ((32-Amt)&31));
106 }
107
108 //===--------------------------------------------------------------------===//
109 // Addressing Mode #1: shift_operand with registers
110 //===--------------------------------------------------------------------===//
111 //
112 // This 'addressing mode' is used for arithmetic instructions. It can
113 // represent things like:
114 // reg
115 // reg [asr|lsl|lsr|ror|rrx] reg
116 // reg [asr|lsl|lsr|ror|rrx] imm
117 //
118 // This is stored three operands [rega, regb, opc]. The first is the base
119 // reg, the second is the shift amount (or reg0 if not present or imm). The
120 // third operand encodes the shift opcode and the imm if a reg isn't present.
121 //
122 static inline unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm) {
123 return ShOp | (Imm << 3);
124 }
125 static inline unsigned getSORegOffset(unsigned Op) {
126 return Op >> 3;
127 }
128 static inline ShiftOpc getSORegShOp(unsigned Op) {
129 return (ShiftOpc)(Op & 7);
130 }
131
132 /// getSOImmValImm - Given an encoded imm field for the reg/imm form, return
133 /// the 8-bit imm value.
134 static inline unsigned getSOImmValImm(unsigned Imm) {
135 return Imm & 0xFF;
136 }
137 /// getSOImmValRot - Given an encoded imm field for the reg/imm form, return
138 /// the rotate amount.
139 static inline unsigned getSOImmValRot(unsigned Imm) {
140 return (Imm >> 8) * 2;
141 }
142
143 /// getSOImmValRotate - Try to handle Imm with an immediate shifter operand,
144 /// computing the rotate amount to use. If this immediate value cannot be
145 /// handled with a single shifter-op, determine a good rotate amount that will
146 /// take a maximal chunk of bits out of the immediate.
147 static inline unsigned getSOImmValRotate(unsigned Imm) {
148 // 8-bit (or less) immediates are trivially shifter_operands with a rotate
149 // of zero.
150 if ((Imm & ~255U) == 0) return 0;
151
152 // Use CTZ to compute the rotate amount.
153 unsigned TZ = CountTrailingZeros_32(Imm);
154
155 // Rotate amount must be even. Something like 0x200 must be rotated 8 bits,
156 // not 9.
157 unsigned RotAmt = TZ & ~1;
158
159 // If we can handle this spread, return it.
160 if ((rotr32(Imm, RotAmt) & ~255U) == 0)
161 return (32-RotAmt)&31; // HW rotates right, not left.
162
163 // For values like 0xF000000F, we should ignore the low 6 bits, then
164 // retry the hunt.
165 if (Imm & 63U) {
166 unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U);
167 unsigned RotAmt2 = TZ2 & ~1;
168 if ((rotr32(Imm, RotAmt2) & ~255U) == 0)
169 return (32-RotAmt2)&31; // HW rotates right, not left.
170 }
171
172 // Otherwise, we have no way to cover this span of bits with a single
173 // shifter_op immediate. Return a chunk of bits that will be useful to
174 // handle.
175 return (32-RotAmt)&31; // HW rotates right, not left.
176 }
177
178 /// getSOImmVal - Given a 32-bit immediate, if it is something that can fit
179 /// into an shifter_operand immediate operand, return the 12-bit encoding for
180 /// it. If not, return -1.
181 static inline int getSOImmVal(unsigned Arg) {
182 // 8-bit (or less) immediates are trivially shifter_operands with a rotate
183 // of zero.
184 if ((Arg & ~255U) == 0) return Arg;
185
186 unsigned RotAmt = getSOImmValRotate(Arg);
187
188 // If this cannot be handled with a single shifter_op, bail out.
189 if (rotr32(~255U, RotAmt) & Arg)
190 return -1;
191
192 // Encode this correctly.
193 return rotl32(Arg, RotAmt) | ((RotAmt>>1) << 8);
194 }
195
196 /// isSOImmTwoPartVal - Return true if the specified value can be obtained by
197 /// or'ing together two SOImmVal's.
198 static inline bool isSOImmTwoPartVal(unsigned V) {
199 // If this can be handled with a single shifter_op, bail out.
200 V = rotr32(~255U, getSOImmValRotate(V)) & V;
201 if (V == 0)
202 return false;
203
204 // If this can be handled with two shifter_op's, accept.
205 V = rotr32(~255U, getSOImmValRotate(V)) & V;
206 return V == 0;
207 }
208
209 /// getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal,
210 /// return the first chunk of it.
211 static inline unsigned getSOImmTwoPartFirst(unsigned V) {
212 return rotr32(255U, getSOImmValRotate(V)) & V;
213 }
214
215 /// getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal,
216 /// return the second chunk of it.
217 static inline unsigned getSOImmTwoPartSecond(unsigned V) {
218 // Mask out the first hunk.
219 V = rotr32(~255U, getSOImmValRotate(V)) & V;
220
221 // Take what's left.
222 assert(V == (rotr32(255U, getSOImmValRotate(V)) & V));
223 return V;
224 }
225
226 /// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed
227 /// by a left shift. Returns the shift amount to use.
228 static inline unsigned getThumbImmValShift(unsigned Imm) {
229 // 8-bit (or less) immediates are trivially immediate operand with a shift
230 // of zero.
231 if ((Imm & ~255U) == 0) return 0;
232
233 // Use CTZ to compute the shift amount.
234 return CountTrailingZeros_32(Imm);
235 }
236
237 /// isThumbImmShiftedVal - Return true if the specified value can be obtained
238 /// by left shifting a 8-bit immediate.
239 static inline bool isThumbImmShiftedVal(unsigned V) {
240 // If this can be handled with
241 V = (~255U << getThumbImmValShift(V)) & V;
242 return V == 0;
243 }
244
245 /// getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed
246 /// by a left shift. Returns the shift amount to use.
247 static inline unsigned getThumbImm16ValShift(unsigned Imm) {
248 // 16-bit (or less) immediates are trivially immediate operand with a shift
249 // of zero.
250 if ((Imm & ~65535U) == 0) return 0;
251
252 // Use CTZ to compute the shift amount.
253 return CountTrailingZeros_32(Imm);
254 }
255
256 /// isThumbImm16ShiftedVal - Return true if the specified value can be
257 /// obtained by left shifting a 16-bit immediate.
258 static inline bool isThumbImm16ShiftedVal(unsigned V) {
259 // If this can be handled with
260 V = (~65535U << getThumbImm16ValShift(V)) & V;
261 return V == 0;
262 }
263
264 /// getThumbImmNonShiftedVal - If V is a value that satisfies
265 /// isThumbImmShiftedVal, return the non-shiftd value.
266 static inline unsigned getThumbImmNonShiftedVal(unsigned V) {
267 return V >> getThumbImmValShift(V);
268 }
269
270
271 /// getT2SOImmValSplat - Return the 12-bit encoded representation
272 /// if the specified value can be obtained by splatting the low 8 bits
273 /// into every other byte or every byte of a 32-bit value. i.e.,
274 /// 00000000 00000000 00000000 abcdefgh control = 0
275 /// 00000000 abcdefgh 00000000 abcdefgh control = 1
276 /// abcdefgh 00000000 abcdefgh 00000000 control = 2
277 /// abcdefgh abcdefgh abcdefgh abcdefgh control = 3
278 /// Return -1 if none of the above apply.
279 /// See ARM Reference Manual A6.3.2.
280 static inline int getT2SOImmValSplatVal(unsigned V) {
281 unsigned u, Vs, Imm;
282 // control = 0
283 if ((V & 0xffffff00) == 0)
284 return V;
285
286 // If the value is zeroes in the first byte, just shift those off
287 Vs = ((V & 0xff) == 0) ? V >> 8 : V;
288 // Any passing value only has 8 bits of payload, splatted across the word
289 Imm = Vs & 0xff;
290 // Likewise, any passing values have the payload splatted into the 3rd byte
291 u = Imm | (Imm << 16);
292
293 // control = 1 or 2
294 if (Vs == u)
295 return (((Vs == V) ? 1 : 2) << 8) | Imm;
296
297 // control = 3
298 if (Vs == (u | (u << 8)))
299 return (3 << 8) | Imm;
300
301 return -1;
302 }
303
304 /// getT2SOImmValRotateVal - Return the 12-bit encoded representation if the
305 /// specified value is a rotated 8-bit value. Return -1 if no rotation
306 /// encoding is possible.
307 /// See ARM Reference Manual A6.3.2.
308 static inline int getT2SOImmValRotateVal(unsigned V) {
309 unsigned RotAmt = CountLeadingZeros_32(V);
310 if (RotAmt >= 24)
311 return -1;
312
313 // If 'Arg' can be handled with a single shifter_op return the value.
314 if ((rotr32(0xff000000U, RotAmt) & V) == V)
315 return (rotr32(V, 24 - RotAmt) & 0x7f) | ((RotAmt + 8) << 7);
316
317 return -1;
318 }
319
320 /// getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit
321 /// into a Thumb-2 shifter_operand immediate operand, return the 12-bit
322 /// encoding for it. If not, return -1.
323 /// See ARM Reference Manual A6.3.2.
324 static inline int getT2SOImmVal(unsigned Arg) {
325 // If 'Arg' is an 8-bit splat, then get the encoded value.
326 int Splat = getT2SOImmValSplatVal(Arg);
327 if (Splat != -1)
328 return Splat;
329
330 // If 'Arg' can be handled with a single shifter_op return the value.
331 int Rot = getT2SOImmValRotateVal(Arg);
332 if (Rot != -1)
333 return Rot;
334
335 return -1;
336 }
337
338 static inline unsigned getT2SOImmValRotate(unsigned V) {
339 if ((V & ~255U) == 0) return 0;
340 // Use CTZ to compute the rotate amount.
341 unsigned RotAmt = CountTrailingZeros_32(V);
342 return (32 - RotAmt) & 31;
343 }
344
345 static inline bool isT2SOImmTwoPartVal (unsigned Imm) {
346 unsigned V = Imm;
347 // Passing values can be any combination of splat values and shifter
348 // values. If this can be handled with a single shifter or splat, bail
349 // out. Those should be handled directly, not with a two-part val.
350 if (getT2SOImmValSplatVal(V) != -1)
351 return false;
352 V = rotr32 (~255U, getT2SOImmValRotate(V)) & V;
353 if (V == 0)
354 return false;
355
356 // If this can be handled as an immediate, accept.
357 if (getT2SOImmVal(V) != -1) return true;
358
359 // Likewise, try masking out a splat value first.
360 V = Imm;
361 if (getT2SOImmValSplatVal(V & 0xff00ff00U) != -1)
362 V &= ~0xff00ff00U;
363 else if (getT2SOImmValSplatVal(V & 0x00ff00ffU) != -1)
364 V &= ~0x00ff00ffU;
365 // If what's left can be handled as an immediate, accept.
366 if (getT2SOImmVal(V) != -1) return true;
367
368 // Otherwise, do not accept.
369 return false;
370 }
371
372 static inline unsigned getT2SOImmTwoPartFirst(unsigned Imm) {
373 assert (isT2SOImmTwoPartVal(Imm) &&
374 "Immedate cannot be encoded as two part immediate!");
375 // Try a shifter operand as one part
376 unsigned V = rotr32 (~255, getT2SOImmValRotate(Imm)) & Imm;
377 // If the rest is encodable as an immediate, then return it.
378 if (getT2SOImmVal(V) != -1) return V;
379
380 // Try masking out a splat value first.
381 if (getT2SOImmValSplatVal(Imm & 0xff00ff00U) != -1)
382 return Imm & 0xff00ff00U;
383
384 // The other splat is all that's left as an option.
385 assert (getT2SOImmValSplatVal(Imm & 0x00ff00ffU) != -1);
386 return Imm & 0x00ff00ffU;
387 }
388
389 static inline unsigned getT2SOImmTwoPartSecond(unsigned Imm) {
390 // Mask out the first hunk
391 Imm ^= getT2SOImmTwoPartFirst(Imm);
392 // Return what's left
393 assert (getT2SOImmVal(Imm) != -1 &&
394 "Unable to encode second part of T2 two part SO immediate");
395 return Imm;
396 }
397
398
399 //===--------------------------------------------------------------------===//
400 // Addressing Mode #2
401 //===--------------------------------------------------------------------===//
402 //
403 // This is used for most simple load/store instructions.
404 //
405 // addrmode2 := reg +/- reg shop imm
406 // addrmode2 := reg +/- imm12
407 //
408 // The first operand is always a Reg. The second operand is a reg if in
409 // reg/reg form, otherwise it's reg#0. The third field encodes the operation
410 // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
411 // fourth operand 16-17 encodes the index mode.
412 //
413 // If this addressing mode is a frame index (before prolog/epilog insertion
414 // and code rewriting), this operand will have the form: FI#, reg0,
415 // with no shift amount for the frame offset.
416 //
417 static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO,
418 unsigned IdxMode = 0) {
419 assert(Imm12 < (1 << 12) && "Imm too large!");
420 bool isSub = Opc == sub;
421 return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
422 }
423 static inline unsigned getAM2Offset(unsigned AM2Opc) {
424 return AM2Opc & ((1 << 12)-1);
425 }
426 static inline AddrOpc getAM2Op(unsigned AM2Opc) {
427 return ((AM2Opc >> 12) & 1) ? sub : add;
428 }
429 static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) {
430 return (ShiftOpc)((AM2Opc >> 13) & 7);
431 }
432 static inline unsigned getAM2IdxMode(unsigned AM2Opc) {
433 return (AM2Opc >> 16);
434 }
435
436
437 //===--------------------------------------------------------------------===//
438 // Addressing Mode #3
439 //===--------------------------------------------------------------------===//
440 //
441 // This is used for sign-extending loads, and load/store-pair instructions.
442 //
443 // addrmode3 := reg +/- reg
444 // addrmode3 := reg +/- imm8
445 //
446 // The first operand is always a Reg. The second operand is a reg if in
447 // reg/reg form, otherwise it's reg#0. The third field encodes the operation
448 // in bit 8, the immediate in bits 0-7. The fourth operand 9-10 encodes the
449 // index mode.
450
451 /// getAM3Opc - This function encodes the addrmode3 opc field.
452 static inline unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset,
453 unsigned IdxMode = 0) {
454 bool isSub = Opc == sub;
455 return ((int)isSub << 8) | Offset | (IdxMode << 9);
456 }
457 static inline unsigned char getAM3Offset(unsigned AM3Opc) {
458 return AM3Opc & 0xFF;
459 }
460 static inline AddrOpc getAM3Op(unsigned AM3Opc) {
461 return ((AM3Opc >> 8) & 1) ? sub : add;
462 }
463 static inline unsigned getAM3IdxMode(unsigned AM3Opc) {
464 return (AM3Opc >> 9);
465 }
466
467 //===--------------------------------------------------------------------===//
468 // Addressing Mode #4
469 //===--------------------------------------------------------------------===//
470 //
471 // This is used for load / store multiple instructions.
472 //
473 // addrmode4 := reg,
474 //
475 // The four modes are:
476 // IA - Increment after
477 // IB - Increment before
478 // DA - Decrement after
479 // DB - Decrement before
480 // For VFP instructions, only the IA and DB modes are valid.
481
482 static inline AMSubMode getAM4SubMode(unsigned Mode) {
483 return (AMSubMode)(Mode & 0x7);
484 }
485
486 static inline unsigned getAM4ModeImm(AMSubMode SubMode) {
487 return (int)SubMode;
488 }
489
490 //===--------------------------------------------------------------------===//
491 // Addressing Mode #5
492 //===--------------------------------------------------------------------===//
493 //
494 // This is used for coprocessor instructions, such as FP load/stores.
495 //
496 // addrmode5 := reg +/- imm8*4
497 //
498 // The first operand is always a Reg. The second operand encodes the
499 // operation in bit 8 and the immediate in bits 0-7.
500
501 /// getAM5Opc - This function encodes the addrmode5 opc field.
502 static inline unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset) {
503 bool isSub = Opc == sub;
504 return ((int)isSub << 8) | Offset;
505 }
506 static inline unsigned char getAM5Offset(unsigned AM5Opc) {
507 return AM5Opc & 0xFF;
508 }
509 static inline AddrOpc getAM5Op(unsigned AM5Opc) {
510 return ((AM5Opc >> 8) & 1) ? sub : add;
511 }
512
513 //===--------------------------------------------------------------------===//
514 // Addressing Mode #6
515 //===--------------------------------------------------------------------===//
516 //
517 // This is used for NEON load / store instructions.
518 //
519 // addrmode6 := reg with optional alignment
520 //
521 // This is stored in two operands [regaddr, align]. The first is the
522 // address register. The second operand is the value of the alignment
523 // specifier in bytes or zero if no explicit alignment.
524 // Valid alignments depend on the specific instruction.
525
526 //===--------------------------------------------------------------------===//
527 // NEON Modified Immediates
528 //===--------------------------------------------------------------------===//
529 //
530 // Several NEON instructions (e.g., VMOV) take a "modified immediate"
531 // vector operand, where a small immediate encoded in the instruction
532 // specifies a full NEON vector value. These modified immediates are
533 // represented here as encoded integers. The low 8 bits hold the immediate
534 // value; bit 12 holds the "Op" field of the instruction, and bits 11-8 hold
535 // the "Cmode" field of the instruction. The interfaces below treat the
536 // Op and Cmode values as a single 5-bit value.
537
538 static inline unsigned createNEONModImm(unsigned OpCmode, unsigned Val) {
539 return (OpCmode << 8) | Val;
540 }
541 static inline unsigned getNEONModImmOpCmode(unsigned ModImm) {
542 return (ModImm >> 8) & 0x1f;
543 }
544 static inline unsigned getNEONModImmVal(unsigned ModImm) {
545 return ModImm & 0xff;
546 }
547
548 /// decodeNEONModImm - Decode a NEON modified immediate value into the
549 /// element value and the element size in bits. (If the element size is
550 /// smaller than the vector, it is splatted into all the elements.)
551 static inline uint64_t decodeNEONModImm(unsigned ModImm, unsigned &EltBits) {
552 unsigned OpCmode = getNEONModImmOpCmode(ModImm);
553 unsigned Imm8 = getNEONModImmVal(ModImm);
554 uint64_t Val = 0;
555
556 if (OpCmode == 0xe) {
557 // 8-bit vector elements
558 Val = Imm8;
559 EltBits = 8;
560 } else if ((OpCmode & 0xc) == 0x8) {
561 // 16-bit vector elements
562 unsigned ByteNum = (OpCmode & 0x6) >> 1;
563 Val = Imm8 << (8 * ByteNum);
564 EltBits = 16;
565 } else if ((OpCmode & 0x8) == 0) {
566 // 32-bit vector elements, zero with one byte set
567 unsigned ByteNum = (OpCmode & 0x6) >> 1;
568 Val = Imm8 << (8 * ByteNum);
569 EltBits = 32;
570 } else if ((OpCmode & 0xe) == 0xc) {
571 // 32-bit vector elements, one byte with low bits set
572 unsigned ByteNum = 1 + (OpCmode & 0x1);
573 Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
574 EltBits = 32;
575 } else if (OpCmode == 0x1e) {
576 // 64-bit vector elements
577 for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
578 if ((ModImm >> ByteNum) & 1)
579 Val |= (uint64_t)0xff << (8 * ByteNum);
580 }
581 EltBits = 64;
582 } else {
583 assert(false && "Unsupported NEON immediate");
584 }
585 return Val;
586 }
587
588 AMSubMode getLoadStoreMultipleSubMode(int Opcode);
589
590 } // end namespace ARM_AM
591 } // end namespace llvm
592
593 #endif
594
77 //===----------------------------------------------------------------------===//
88
99 #include "ARM.h"
10 #include "ARMAddressingModes.h"
1110 #include "ARMFixupKinds.h"
11 #include "MCTargetDesc/ARMAddressingModes.h"
1212 #include "llvm/ADT/Twine.h"
1313 #include "llvm/MC/MCAssembler.h"
1414 #include "llvm/MC/MCDirectives.h"
1414 #define DEBUG_TYPE "asm-printer"
1515 #include "ARM.h"
1616 #include "ARMAsmPrinter.h"
17 #include "ARMAddressingModes.h"
1817 #include "ARMBuildAttrs.h"
1918 #include "ARMBaseRegisterInfo.h"
2019 #include "ARMConstantPoolValue.h"
2120 #include "ARMMachineFunctionInfo.h"
22 #include "ARMMCExpr.h"
2321 #include "ARMTargetMachine.h"
2422 #include "ARMTargetObjectFile.h"
2523 #include "InstPrinter/ARMInstPrinter.h"
24 #include "MCTargetDesc/ARMAddressingModes.h"
25 #include "MCTargetDesc/ARMMCExpr.h"
2626 #include "llvm/Analysis/DebugInfo.h"
2727 #include "llvm/Constants.h"
2828 #include "llvm/Module.h"
190190 }
191191 }
192192
193 /// ARMII - This namespace holds all of the target specific flags that
194 /// instruction info tracks.
195 ///
193196 namespace ARMII {
194197
195198 /// ARM Index Modes
286289 /// call operand.
287290 MO_PLT
288291 };
292
293 enum {
294 //===------------------------------------------------------------------===//
295 // Instruction Flags.
296
297 //===------------------------------------------------------------------===//
298 // This four-bit field describes the addressing mode used.
299 AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
300
301 // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
302 // and store ops only. Generic "updating" flag is used for ld/st multiple.
303 // The index mode enums are declared in ARMBaseInfo.h
304 IndexModeShift = 5,
305 IndexModeMask = 3 << IndexModeShift,
306
307 //===------------------------------------------------------------------===//
308 // Instruction encoding formats.
309 //
310 FormShift = 7,
311 FormMask = 0x3f << FormShift,
312
313 // Pseudo instructions
314 Pseudo = 0 << FormShift,
315
316 // Multiply instructions
317 MulFrm = 1 << FormShift,
318
319 // Branch instructions
320 BrFrm = 2 << FormShift,
321 BrMiscFrm = 3 << FormShift,
322
323 // Data Processing instructions
324 DPFrm = 4 << FormShift,
325 DPSoRegFrm = 5 << FormShift,
326
327 // Load and Store
328 LdFrm = 6 << FormShift,
329 StFrm = 7 << FormShift,
330 LdMiscFrm = 8 << FormShift,
331 StMiscFrm = 9 << FormShift,
332 LdStMulFrm = 10 << FormShift,
333
334 LdStExFrm = 11 << FormShift,
335
336 // Miscellaneous arithmetic instructions
337 ArithMiscFrm = 12 << FormShift,
338 SatFrm = 13 << FormShift,
339
340 // Extend instructions
341 ExtFrm = 14 << FormShift,
342
343 // VFP formats
344 VFPUnaryFrm = 15 << FormShift,
345 VFPBinaryFrm = 16 << FormShift,
346 VFPConv1Frm = 17 << FormShift,
347 VFPConv2Frm = 18 << FormShift,
348 VFPConv3Frm = 19 << FormShift,
349 VFPConv4Frm = 20 << FormShift,
350 VFPConv5Frm = 21 << FormShift,
351 VFPLdStFrm = 22 << FormShift,
352 VFPLdStMulFrm = 23 << FormShift,
353 VFPMiscFrm = 24 << FormShift,
354
355 // Thumb format
356 ThumbFrm = 25 << FormShift,
357
358 // Miscelleaneous format
359 MiscFrm = 26 << FormShift,
360
361 // NEON formats
362 NGetLnFrm = 27 << FormShift,
363 NSetLnFrm = 28 << FormShift,
364 NDupFrm = 29 << FormShift,
365 NLdStFrm = 30 << FormShift,
366 N1RegModImmFrm= 31 << FormShift,
367 N2RegFrm = 32 << FormShift,
368 NVCVTFrm = 33 << FormShift,
369 NVDupLnFrm = 34 << FormShift,
370 N2RegVShLFrm = 35 << FormShift,
371 N2RegVShRFrm = 36 << FormShift,
372 N3RegFrm = 37 << FormShift,
373 N3RegVShFrm = 38 << FormShift,
374 NVExtFrm = 39 << FormShift,
375 NVMulSLFrm = 40 << FormShift,
376 NVTBLFrm = 41 << FormShift,
377
378 //===------------------------------------------------------------------===//
379 // Misc flags.
380
381 // UnaryDP - Indicates this is a unary data processing instruction, i.e.
382 // it doesn't have a Rn operand.
383 UnaryDP = 1 << 13,
384
385 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
386 // a 16-bit Thumb instruction if certain conditions are met.
387 Xform16Bit = 1 << 14,
388
389 //===------------------------------------------------------------------===//
390 // Code domain.
391 DomainShift = 15,
392 DomainMask = 7 << DomainShift,
393 DomainGeneral = 0 << DomainShift,
394 DomainVFP = 1 << DomainShift,
395 DomainNEON = 2 << DomainShift,
396 DomainNEONA8 = 4 << DomainShift,
397
398 //===------------------------------------------------------------------===//
399 // Field shifts - such shifts are used to set field while generating
400 // machine instructions.
401 //
402 // FIXME: This list will need adjusting/fixing as the MC code emitter
403 // takes shape and the ARMCodeEmitter.cpp bits go away.
404 ShiftTypeShift = 4,
405
406 M_BitShift = 5,
407 ShiftImmShift = 5,
408 ShiftShift = 7,
409 N_BitShift = 7,
410 ImmHiShift = 8,
411 SoRotImmShift = 8,
412 RegRsShift = 8,
413 ExtRotImmShift = 10,
414 RegRdLoShift = 12,
415 RegRdShift = 12,
416 RegRdHiShift = 16,
417 RegRnShift = 16,
418 S_BitShift = 20,
419 W_BitShift = 21,
420 AM3_I_BitShift = 22,
421 D_BitShift = 22,
422 U_BitShift = 23,
423 P_BitShift = 24,
424 I_BitShift = 25,
425 CondShift = 28
426 };
427
289428 } // end namespace ARMII
290429
291430 } // end namespace llvm;
1212
1313 #include "ARMBaseInstrInfo.h"
1414 #include "ARM.h"
15 #include "ARMAddressingModes.h"
1615 #include "ARMConstantPoolValue.h"
1716 #include "ARMHazardRecognizer.h"
1817 #include "ARMMachineFunctionInfo.h"
1918 #include "ARMRegisterInfo.h"
19 #include "MCTargetDesc/ARMAddressingModes.h"
2020 #include "llvm/Constants.h"
2121 #include "llvm/Function.h"
2222 #include "llvm/GlobalValue.h"
2828 #include "llvm/CodeGen/MachineMemOperand.h"
2929 #include "llvm/CodeGen/MachineRegisterInfo.h"
3030 #include "llvm/CodeGen/PseudoSourceValue.h"
31 #include "llvm/CodeGen/SelectionDAGNodes.h"
3132 #include "llvm/MC/MCAsmInfo.h"
3233 #include "llvm/Support/BranchProbability.h"
3334 #include "llvm/Support/CommandLine.h"
2525 namespace llvm {
2626 class ARMSubtarget;
2727 class ARMBaseRegisterInfo;
28
29 /// ARMII - This namespace holds all of the target specific flags that
30 /// instruction info tracks.
31 ///
32 namespace ARMII {
33 enum {
34 //===------------------------------------------------------------------===//
35 // Instruction Flags.
36
37 //===------------------------------------------------------------------===//
38 // This four-bit field describes the addressing mode used.
39 AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
40
41 // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
42 // and store ops only. Generic "updating" flag is used for ld/st multiple.
43 // The index mode enums are declared in ARMBaseInfo.h
44 IndexModeShift = 5,
45 IndexModeMask = 3 << IndexModeShift,
46
47 //===------------------------------------------------------------------===//
48 // Instruction encoding formats.
49 //
50 FormShift = 7,
51 FormMask = 0x3f << FormShift,
52
53 // Pseudo instructions
54 Pseudo = 0 << FormShift,
55
56 // Multiply instructions
57 MulFrm = 1 << FormShift,
58
59 // Branch instructions
60 BrFrm = 2 << FormShift,
61 BrMiscFrm = 3 << FormShift,
62
63 // Data Processing instructions
64 DPFrm = 4 << FormShift,
65 DPSoRegFrm = 5 << FormShift,
66
67 // Load and Store
68 LdFrm = 6 << FormShift,
69 StFrm = 7 << FormShift,
70 LdMiscFrm = 8 << FormShift,
71 StMiscFrm = 9 << FormShift,
72 LdStMulFrm = 10 << FormShift,
73
74 LdStExFrm = 11 << FormShift,
75
76 // Miscellaneous arithmetic instructions
77 ArithMiscFrm = 12 << FormShift,
78 SatFrm = 13 << FormShift,
79
80 // Extend instructions
81 ExtFrm = 14 << FormShift,
82
83 // VFP formats
84 VFPUnaryFrm = 15 << FormShift,
85 VFPBinaryFrm = 16 << FormShift,
86 VFPConv1Frm = 17 << FormShift,
87 VFPConv2Frm = 18 << FormShift,
88 VFPConv3Frm = 19 << FormShift,
89 VFPConv4Frm = 20 << FormShift,
90 VFPConv5Frm = 21 << FormShift,
91 VFPLdStFrm = 22 << FormShift,
92 VFPLdStMulFrm = 23 << FormShift,
93 VFPMiscFrm = 24 << FormShift,
94
95 // Thumb format
96 ThumbFrm = 25 << FormShift,
97
98 // Miscelleaneous format
99 MiscFrm = 26 << FormShift,
100
101 // NEON formats
102 NGetLnFrm = 27 << FormShift,
103 NSetLnFrm = 28 << FormShift,
104 NDupFrm = 29 << FormShift,
105 NLdStFrm = 30 << FormShift,
106 N1RegModImmFrm= 31 << FormShift,
107 N2RegFrm = 32 << FormShift,
108 NVCVTFrm = 33 << FormShift,
109 NVDupLnFrm = 34 << FormShift,
110 N2RegVShLFrm = 35 << FormShift,
111 N2RegVShRFrm = 36 << FormShift,
112 N3RegFrm = 37 << FormShift,
113 N3RegVShFrm = 38 << FormShift,
114 NVExtFrm = 39 << FormShift,
115 NVMulSLFrm = 40 << FormShift,
116 NVTBLFrm = 41 << FormShift,
117
118 //===------------------------------------------------------------------===//
119 // Misc flags.
120
121 // UnaryDP - Indicates this is a unary data processing instruction, i.e.
122 // it doesn't have a Rn operand.
123 UnaryDP = 1 << 13,
124
125 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
126 // a 16-bit Thumb instruction if certain conditions are met.
127 Xform16Bit = 1 << 14,
128
129 //===------------------------------------------------------------------===//
130 // Code domain.
131 DomainShift = 15,
132 DomainMask = 7 << DomainShift,
133 DomainGeneral = 0 << DomainShift,
134 DomainVFP = 1 << DomainShift,
135 DomainNEON = 2 << DomainShift,
136 DomainNEONA8 = 4 << DomainShift,
137
138 //===------------------------------------------------------------------===//
139 // Field shifts - such shifts are used to set field while generating
140 // machine instructions.
141 //
142 // FIXME: This list will need adjusting/fixing as the MC code emitter
143 // takes shape and the ARMCodeEmitter.cpp bits go away.
144 ShiftTypeShift = 4,
145
146 M_BitShift = 5,
147 ShiftImmShift = 5,
148 ShiftShift = 7,
149 N_BitShift = 7,
150 ImmHiShift = 8,
151 SoRotImmShift = 8,
152 RegRsShift = 8,
153 ExtRotImmShift = 10,
154 RegRdLoShift = 12,
155 RegRdShift = 12,
156 RegRdHiShift = 16,
157 RegRnShift = 16,
158 S_BitShift = 20,
159 W_BitShift = 21,
160 AM3_I_BitShift = 22,
161 D_BitShift = 22,
162 U_BitShift = 23,
163 P_BitShift = 24,
164 I_BitShift = 25,
165 CondShift = 28
166 };
167 }
16828
16929 class ARMBaseInstrInfo : public ARMGenInstrInfo {
17030 const ARMSubtarget &Subtarget;
1111 //===----------------------------------------------------------------------===//
1212
1313 #include "ARM.h"
14 #include "ARMAddressingModes.h"
1514 #include "ARMBaseInstrInfo.h"
1615 #include "ARMBaseRegisterInfo.h"
1716 #include "ARMFrameLowering.h"
1817 #include "ARMInstrInfo.h"
1918 #include "ARMMachineFunctionInfo.h"
2019 #include "ARMSubtarget.h"
20 #include "MCTargetDesc/ARMAddressingModes.h"
2121 #include "llvm/Constants.h"
2222 #include "llvm/DerivedTypes.h"
2323 #include "llvm/Function.h"
1313
1414 #define DEBUG_TYPE "jit"
1515 #include "ARM.h"
16 #include "ARMAddressingModes.h"
1716 #include "ARMConstantPoolValue.h"
1817 #include "ARMInstrInfo.h"
1918 #include "ARMRelocations.h"
2019 #include "ARMSubtarget.h"
2120 #include "ARMTargetMachine.h"
21 #include "MCTargetDesc/ARMAddressingModes.h"
2222 #include "llvm/Constants.h"
2323 #include "llvm/DerivedTypes.h"
2424 #include "llvm/Function.h"
1414
1515 #define DEBUG_TYPE "arm-cp-islands"
1616 #include "ARM.h"
17 #include "ARMAddressingModes.h"
1817 #include "ARMMachineFunctionInfo.h"
1918 #include "ARMInstrInfo.h"
2019 #include "Thumb2InstrInfo.h"
20 #include "MCTargetDesc/ARMAddressingModes.h"
2121 #include "llvm/CodeGen/MachineConstantPool.h"
2222 #include "llvm/CodeGen/MachineFunctionPass.h"
2323 #include "llvm/CodeGen/MachineJumpTableInfo.h"
1515
1616 #define DEBUG_TYPE "arm-pseudo"
1717 #include "ARM.h"
18 #include "ARMAddressingModes.h"
1918 #include "ARMBaseInstrInfo.h"
2019 #include "ARMBaseRegisterInfo.h"
2120 #include "ARMMachineFunctionInfo.h"
2221 #include "ARMRegisterInfo.h"
22 #include "MCTargetDesc/ARMAddressingModes.h"
2323 #include "llvm/CodeGen/MachineFrameInfo.h"
2424 #include "llvm/CodeGen/MachineFunctionPass.h"
2525 #include "llvm/CodeGen/MachineInstrBuilder.h"
1313 //===----------------------------------------------------------------------===//
1414
1515 #include "ARM.h"
16 #include "ARMAddressingModes.h"
1716 #include "ARMBaseInstrInfo.h"
1817 #include "ARMCallingConv.h"
1918 #include "ARMRegisterInfo.h"
2019 #include "ARMTargetMachine.h"
2120 #include "ARMSubtarget.h"
2221 #include "ARMConstantPoolValue.h"
22 #include "MCTargetDesc/ARMAddressingModes.h"
2323 #include "llvm/CallingConv.h"
2424 #include "llvm/DerivedTypes.h"
2525 #include "llvm/GlobalVariable.h"
1111 //===----------------------------------------------------------------------===//
1212
1313 #include "ARMFrameLowering.h"
14 #include "ARMAddressingModes.h"
1514 #include "ARMBaseInstrInfo.h"
1615 #include "ARMBaseRegisterInfo.h"
1716 #include "ARMMachineFunctionInfo.h"
17 #include "MCTargetDesc/ARMAddressingModes.h"
1818 #include "llvm/CodeGen/MachineFrameInfo.h"
1919 #include "llvm/CodeGen/MachineFunction.h"
2020 #include "llvm/CodeGen/MachineInstrBuilder.h"
1313 #define DEBUG_TYPE "arm-isel"
1414 #include "ARM.h"
1515 #include "ARMBaseInstrInfo.h"
16 #include "ARMAddressingModes.h"
1716 #include "ARMTargetMachine.h"
17 #include "MCTargetDesc/ARMAddressingModes.h"
1818 #include "llvm/CallingConv.h"
1919 #include "llvm/Constants.h"
2020 #include "llvm/DerivedTypes.h"
372372 if (DisableShifterOp)
373373 return false;
374374
375 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
375 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode());
376376
377377 // Don't match base register only case. That is matched to a separate
378378 // lower complexity pattern with explicit register operand.
488488
489489 // Otherwise this is R +/- [possibly shifted] R.
490490 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::SUB ? ARM_AM::sub:ARM_AM::add;
491 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1));
491 ARM_AM::ShiftOpc ShOpcVal =
492 ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode());
492493 unsigned ShAmt = 0;
493494
494495 Base = N.getOperand(0);
514515 // Try matching (R shl C) + (R).
515516 if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift &&
516517 !(Subtarget->isCortexA9() || N.getOperand(0).hasOneUse())) {
517 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0));
518 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode());
518519 if (ShOpcVal != ARM_AM::no_shift) {
519520 // Check to see if the RHS of the shift is a constant, if not, we can't
520521 // fold it.
629630
630631 // Otherwise this is R +/- [possibly shifted] R.
631632 ARM_AM::AddrOpc AddSub = N.getOpcode() != ISD::SUB ? ARM_AM::add:ARM_AM::sub;
632 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1));
633 ARM_AM::ShiftOpc ShOpcVal =
634 ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode());
633635 unsigned ShAmt = 0;
634636
635637 Base = N.getOperand(0);
655657 // Try matching (R shl C) + (R).
656658 if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift &&
657659 !(Subtarget->isCortexA9() || N.getOperand(0).hasOneUse())) {
658 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0));
660 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode());
659661 if (ShOpcVal != ARM_AM::no_shift) {
660662 // Check to see if the RHS of the shift is a constant, if not, we can't
661663 // fold it.
700702 }
701703
702704 Offset = N;
703 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
705 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode());
704706 unsigned ShAmt = 0;
705707 if (ShOpcVal != ARM_AM::no_shift) {
706708 // Check to see if the RHS of the shift is a constant, if not, we can't fold
10781080 if (DisableShifterOp)
10791081 return false;
10801082
1081 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
1083 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode());
10821084
10831085 // Don't match base register only case. That is matched to a separate
10841086 // lower complexity pattern with explicit register operand.
12191221 OffReg = N.getOperand(1);
12201222
12211223 // Swap if it is ((R << c) + R).
1222 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg);
1224 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg.getOpcode());
12231225 if (ShOpcVal != ARM_AM::lsl) {
1224 ShOpcVal = ARM_AM::getShiftOpcForNode(Base);
1226 ShOpcVal = ARM_AM::getShiftOpcForNode(Base.getOpcode());
12251227 if (ShOpcVal == ARM_AM::lsl)
12261228 std::swap(Base, OffReg);
12271229 }
1313
1414 #define DEBUG_TYPE "arm-isel"
1515 #include "ARM.h"
16 #include "ARMAddressingModes.h"
1716 #include "ARMCallingConv.h"
1817 #include "ARMConstantPoolValue.h"
1918 #include "ARMISelLowering.h"
2322 #include "ARMSubtarget.h"
2423 #include "ARMTargetMachine.h"
2524 #include "ARMTargetObjectFile.h"
25 #include "MCTargetDesc/ARMAddressingModes.h"
2626 #include "llvm/CallingConv.h"
2727 #include "llvm/Constants.h"
2828 #include "llvm/Function.h"
73507350
73517351 if (Ptr->getOpcode() == ISD::ADD) {
73527352 isInc = true;
7353 ARM_AM::ShiftOpc ShOpcVal= ARM_AM::getShiftOpcForNode(Ptr->getOperand(0));
7353 ARM_AM::ShiftOpc ShOpcVal=
7354 ARM_AM::getShiftOpcForNode(Ptr->getOperand(0).getOpcode());
73547355 if (ShOpcVal != ARM_AM::no_shift) {
73557356 Base = Ptr->getOperand(1);
73567357 Offset = Ptr->getOperand(0);
1212
1313 #include "ARMInstrInfo.h"
1414 #include "ARM.h"
15 #include "ARMAddressingModes.h"
1615 #include "ARMMachineFunctionInfo.h"
16 #include "MCTargetDesc/ARMAddressingModes.h"
1717 #include "llvm/ADT/STLExtras.h"
1818 #include "llvm/CodeGen/LiveVariables.h"
1919 #include "llvm/CodeGen/MachineFrameInfo.h"
1313
1414 #define DEBUG_TYPE "arm-ldst-opt"
1515 #include "ARM.h"
16 #include "ARMAddressingModes.h"
1716 #include "ARMBaseInstrInfo.h"
1817 #include "ARMMachineFunctionInfo.h"
1918 #include "ARMRegisterInfo.h"
19 #include "MCTargetDesc/ARMAddressingModes.h"
2020 #include "llvm/DerivedTypes.h"
2121 #include "llvm/Function.h"
2222 #include "llvm/CodeGen/MachineBasicBlock.h"
2525 #include "llvm/CodeGen/MachineInstrBuilder.h"
2626 #include "llvm/CodeGen/MachineRegisterInfo.h"
2727 #include "llvm/CodeGen/RegisterScavenging.h"
28 #include "llvm/CodeGen/SelectionDAGNodes.h"
2829 #include "llvm/Target/TargetData.h"
2930 #include "llvm/Target/TargetInstrInfo.h"
3031 #include "llvm/Target/TargetMachine.h"
1212
1313 #define DEBUG_TYPE "mccodeemitter"
1414 #include "ARM.h"
15 #include "ARMAddressingModes.h"
1615 #include "ARMFixupKinds.h"
1716 #include "ARMInstrInfo.h"
18 #include "ARMMCExpr.h"
19 #include "ARMSubtarget.h"
17 #include "MCTargetDesc/ARMAddressingModes.h"
18 #include "MCTargetDesc/ARMMCExpr.h"
2019 #include "llvm/MC/MCCodeEmitter.h"
2120 #include "llvm/MC/MCExpr.h"
2221 #include "llvm/MC/MCInst.h"
2322 #include "llvm/MC/MCInstrInfo.h"
2423 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/ADT/APFloat.h"
2525 #include "llvm/ADT/Statistic.h"
2626 #include "llvm/Support/raw_ostream.h"
2727
+0
-73
lib/Target/ARM/ARMMCExpr.cpp less more
None //===-- ARMMCExpr.cpp - ARM specific MC expression classes ----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #define DEBUG_TYPE "armmcexpr"
10 #include "ARMMCExpr.h"
11 #include "llvm/MC/MCContext.h"
12 #include "llvm/MC/MCAssembler.h"
13 using namespace llvm;
14
15 const ARMMCExpr*
16 ARMMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
17 MCContext &Ctx) {
18 return new (Ctx) ARMMCExpr(Kind, Expr);
19 }
20
21 void ARMMCExpr::PrintImpl(raw_ostream &OS) const {
22 switch (Kind) {
23 default: assert(0 && "Invalid kind!");
24 case VK_ARM_HI16: OS << ":upper16:"; break;
25 case VK_ARM_LO16: OS << ":lower16:"; break;
26 }
27
28 const MCExpr *Expr = getSubExpr();
29 if (Expr->getKind() != MCExpr::SymbolRef)
30 OS << '(';
31 Expr->print(OS);
32 if (Expr->getKind() != MCExpr::SymbolRef)
33 OS << ')';
34 }
35
36 bool
37 ARMMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
38 const MCAsmLayout *Layout) const {
39 return false;
40 }
41
42 // FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps
43 // that method should be made public?
44 static void AddValueSymbols_(const MCExpr *Value, MCAssembler *Asm) {
45 switch (Value->getKind()) {
46 case MCExpr::Target:
47 assert(0 && "Can't handle nested target expr!");
48 break;
49
50 case MCExpr::Constant:
51 break;
52
53 case MCExpr::Binary: {
54 const MCBinaryExpr *BE = cast(Value);
55 AddValueSymbols_(BE->getLHS(), Asm);
56 AddValueSymbols_(BE->getRHS(), Asm);
57 break;
58 }
59
60 case MCExpr::SymbolRef:
61 Asm->getOrCreateSymbolData(cast(Value)->getSymbol());
62 break;
63
64 case MCExpr::Unary:
65 AddValueSymbols_(cast(Value)->getSubExpr(), Asm);
66 break;
67 }
68 }
69
70 void ARMMCExpr::AddValueSymbols(MCAssembler *Asm) const {
71 AddValueSymbols_(getSubExpr(), Asm);
72 }
+0
-76
lib/Target/ARM/ARMMCExpr.h less more
None //===-- ARMMCExpr.h - ARM specific MC expression classes ------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef ARMMCEXPR_H
10 #define ARMMCEXPR_H
11
12 #include "llvm/MC/MCExpr.h"
13
14 namespace llvm {
15
16 class ARMMCExpr : public MCTargetExpr {
17 public:
18 enum VariantKind {
19 VK_ARM_None,
20 VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the .s file)
21 VK_ARM_LO16 // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the .s file)
22 };
23
24 private:
25 const VariantKind Kind;
26 const MCExpr *Expr;
27
28 explicit ARMMCExpr(VariantKind _Kind, const MCExpr *_Expr)
29 : Kind(_Kind), Expr(_Expr) {}
30
31 public:
32 /// @name Construction
33 /// @{
34
35 static const ARMMCExpr *Create(VariantKind Kind, const MCExpr *Expr,
36 MCContext &Ctx);
37
38 static const ARMMCExpr *CreateUpper16(const MCExpr *Expr, MCContext &Ctx) {
39 return Create(VK_ARM_HI16, Expr, Ctx);
40 }
41
42 static const ARMMCExpr *CreateLower16(const MCExpr *Expr, MCContext &Ctx) {
43 return Create(VK_ARM_LO16, Expr, Ctx);
44 }
45
46 /// @}
47 /// @name Accessors
48 /// @{
49
50 /// getOpcode - Get the kind of this expression.
51 VariantKind getKind() const { return Kind; }
52
53 /// getSubExpr - Get the child of this expression.
54 const MCExpr *getSubExpr() const { return Expr; }
55
56 /// @}
57
58 void PrintImpl(raw_ostream &OS) const;
59 bool EvaluateAsRelocatableImpl(MCValue &Res,
60 const MCAsmLayout *Layout) const;
61 void AddValueSymbols(MCAssembler *) const;
62 const MCSection *FindAssociatedSection() const {
63 return getSubExpr()->FindAssociatedSection();
64 }
65
66 static bool classof(const MCExpr *E) {
67 return E->getKind() == MCExpr::Target;
68 }
69
70 static bool classof(const ARMMCExpr *) { return true; }
71
72 };
73 } // end namespace llvm
74
75 #endif
1313
1414 #include "ARM.h"
1515 #include "ARMAsmPrinter.h"
16 #include "ARMMCExpr.h"
16 #include "MCTargetDesc/ARMMCExpr.h"
1717 #include "llvm/Constants.h"
1818 #include "llvm/CodeGen/MachineBasicBlock.h"
1919 #include "llvm/MC/MCExpr.h"
1313 #ifndef ARMSELECTIONDAGINFO_H
1414 #define ARMSELECTIONDAGINFO_H
1515
16 #include "MCTargetDesc/ARMAddressingModes.h"
1617 #include "llvm/Target/TargetSelectionDAGInfo.h"
1718
1819 namespace llvm {
20
21 namespace ARM_AM {
22 static inline ShiftOpc getShiftOpcForNode(unsigned Opcode) {
23 switch (Opcode) {
24 default: return ARM_AM::no_shift;
25 case ISD::SHL: return ARM_AM::lsl;
26 case ISD::SRL: return ARM_AM::lsr;
27 case ISD::SRA: return ARM_AM::asr;
28 case ISD::ROTR: return ARM_AM::ror;
29 //case ISD::ROTL: // Only if imm -> turn into ROTR.
30 // Can't handle RRX here, because it would require folding a flag into
31 // the addressing mode. :( This causes us to miss certain things.
32 //case ARMISD::RRX: return ARM_AM::rrx;
33 }
34 }
35 } // end namespace ARM_AM
1936
2037 class ARMSelectionDAGInfo : public TargetSelectionDAGInfo {
2138 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
77 //===----------------------------------------------------------------------===//
88
99 #include "ARM.h"
10 #include "ARMAddressingModes.h"
11 #include "ARMMCExpr.h"
1210 #include "ARMBaseRegisterInfo.h"
1311 #include "ARMSubtarget.h"
12 #include "MCTargetDesc/ARMAddressingModes.h"
13 #include "MCTargetDesc/ARMMCExpr.h"
1414 #include "llvm/MC/MCParser/MCAsmLexer.h"
1515 #include "llvm/MC/MCParser/MCAsmParser.h"
1616 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
3333 ARMJITInfo.cpp
3434 ARMMachObjectWriter.cpp
3535 ARMMCCodeEmitter.cpp
36 ARMMCExpr.cpp
3736 ARMLoadStoreOptimizer.cpp
3837 ARMMCInstLower.cpp
3938 ARMRegisterInfo.cpp
1515 #define DEBUG_TYPE "arm-disassembler"
1616
1717 #include "ARMDisassemblerCore.h"
18 #include "ARMAddressingModes.h"
19 #include "ARMMCExpr.h"
18 #include "MCTargetDesc/ARMAddressingModes.h"
19 #include "MCTargetDesc/ARMMCExpr.h"
20 #include "llvm/ADT/APInt.h"
21 #include "llvm/ADT/APFloat.h"
2022 #include "llvm/Support/Debug.h"
2123 #include "llvm/Support/raw_ostream.h"
2224
1313 #define DEBUG_TYPE "asm-printer"
1414 #include "ARMBaseInfo.h"
1515 #include "ARMInstPrinter.h"
16 #include "ARMAddressingModes.h"
16 #include "MCTargetDesc/ARMAddressingModes.h"
1717 #include "llvm/MC/MCInst.h"
1818 #include "llvm/MC/MCAsmInfo.h"
1919 #include "llvm/MC/MCExpr.h"
0 //===- ARMAddressingModes.h - ARM Addressing Modes --------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the ARM addressing mode implementation stuff.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
14 #define LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
15
16 #include "llvm/Support/MathExtras.h"
17 #include
18
19 namespace llvm {
20
21 /// ARM_AM - ARM Addressing Mode Stuff
22 namespace ARM_AM {
23 enum ShiftOpc {
24 no_shift = 0,
25 asr,
26 lsl,
27 lsr,
28 ror,
29 rrx
30 };
31
32 enum AddrOpc {
33 add = '+', sub = '-'
34 };
35
36 static inline const char *getAddrOpcStr(AddrOpc Op) {
37 return Op == sub ? "-" : "";
38 }
39
40 static inline const char *getShiftOpcStr(ShiftOpc Op) {
41 switch (Op) {
42 default: assert(0 && "Unknown shift opc!");
43 case ARM_AM::asr: return "asr";
44 case ARM_AM::lsl: return "lsl";
45 case ARM_AM::lsr: return "lsr";
46 case ARM_AM::ror: return "ror";
47 case ARM_AM::rrx: return "rrx";
48 }
49 }
50
51 static inline unsigned getShiftOpcEncoding(ShiftOpc Op) {
52 switch (Op) {
53 default: assert(0 && "Unknown shift opc!");
54 case ARM_AM::asr: return 2;
55 case ARM_AM::lsl: return 0;
56 case ARM_AM::lsr: return 1;
57 case ARM_AM::ror: return 3;
58 }
59 }
60
61 enum AMSubMode {
62 bad_am_submode = 0,
63 ia,
64 ib,
65 da,
66 db
67 };
68
69 static inline const char *getAMSubModeStr(AMSubMode Mode) {
70 switch (Mode) {
71 default: assert(0 && "Unknown addressing sub-mode!");
72 case ARM_AM::ia: return "ia";
73 case ARM_AM::ib: return "ib";
74 case ARM_AM::da: return "da";
75 case ARM_AM::db: return "db";
76 }
77 }
78
79 /// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
80 ///
81 static inline unsigned rotr32(unsigned Val, unsigned Amt) {
82 assert(Amt < 32 && "Invalid rotate amount");
83 return (Val >> Amt) | (Val << ((32-Amt)&31));
84 }
85
86 /// rotl32 - Rotate a 32-bit unsigned value left by a specified # bits.
87 ///
88 static inline unsigned rotl32(unsigned Val, unsigned Amt) {
89 assert(Amt < 32 && "Invalid rotate amount");
90 return (Val << Amt) | (Val >> ((32-Amt)&31));
91 }
92
93 //===--------------------------------------------------------------------===//
94 // Addressing Mode #1: shift_operand with registers
95 //===--------------------------------------------------------------------===//
96 //
97 // This 'addressing mode' is used for arithmetic instructions. It can
98 // represent things like:
99 // reg
100 // reg [asr|lsl|lsr|ror|rrx] reg
101 // reg [asr|lsl|lsr|ror|rrx] imm
102 //
103 // This is stored three operands [rega, regb, opc]. The first is the base
104 // reg, the second is the shift amount (or reg0 if not present or imm). The
105 // third operand encodes the shift opcode and the imm if a reg isn't present.
106 //
107 static inline unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm) {
108 return ShOp | (Imm << 3);
109 }
110 static inline unsigned getSORegOffset(unsigned Op) {
111 return Op >> 3;
112 }
113 static inline ShiftOpc getSORegShOp(unsigned Op) {
114 return (ShiftOpc)(Op & 7);
115 }
116
117 /// getSOImmValImm - Given an encoded imm field for the reg/imm form, return
118 /// the 8-bit imm value.
119 static inline unsigned getSOImmValImm(unsigned Imm) {
120 return Imm & 0xFF;
121 }
122 /// getSOImmValRot - Given an encoded imm field for the reg/imm form, return
123 /// the rotate amount.
124 static inline unsigned getSOImmValRot(unsigned Imm) {
125 return (Imm >> 8) * 2;
126 }
127
128 /// getSOImmValRotate - Try to handle Imm with an immediate shifter operand,
129 /// computing the rotate amount to use. If this immediate value cannot be
130 /// handled with a single shifter-op, determine a good rotate amount that will
131 /// take a maximal chunk of bits out of the immediate.
132 static inline unsigned getSOImmValRotate(unsigned Imm) {
133 // 8-bit (or less) immediates are trivially shifter_operands with a rotate
134 // of zero.
135 if ((Imm & ~255U) == 0) return 0;
136
137 // Use CTZ to compute the rotate amount.
138 unsigned TZ = CountTrailingZeros_32(Imm);
139
140 // Rotate amount must be even. Something like 0x200 must be rotated 8 bits,
141 // not 9.
142 unsigned RotAmt = TZ & ~1;
143
144 // If we can handle this spread, return it.
145 if ((rotr32(Imm, RotAmt) & ~255U) == 0)
146 return (32-RotAmt)&31; // HW rotates right, not left.
147
148 // For values like 0xF000000F, we should ignore the low 6 bits, then
149 // retry the hunt.
150 if (Imm & 63U) {
151 unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U);
152 unsigned RotAmt2 = TZ2 & ~1;
153 if ((rotr32(Imm, RotAmt2) & ~255U) == 0)
154 return (32-RotAmt2)&31; // HW rotates right, not left.
155 }
156
157 // Otherwise, we have no way to cover this span of bits with a single
158 // shifter_op immediate. Return a chunk of bits that will be useful to
159 // handle.
160 return (32-RotAmt)&31; // HW rotates right, not left.
161 }
162
163 /// getSOImmVal - Given a 32-bit immediate, if it is something that can fit
164 /// into an shifter_operand immediate operand, return the 12-bit encoding for
165 /// it. If not, return -1.
166 static inline int getSOImmVal(unsigned Arg) {
167 // 8-bit (or less) immediates are trivially shifter_operands with a rotate
168 // of zero.
169 if ((Arg & ~255U) == 0) return Arg;
170
171 unsigned RotAmt = getSOImmValRotate(Arg);
172
173 // If this cannot be handled with a single shifter_op, bail out.
174 if (rotr32(~255U, RotAmt) & Arg)
175 return -1;
176
177 // Encode this correctly.
178 return rotl32(Arg, RotAmt) | ((RotAmt>>1) << 8);
179 }
180
181 /// isSOImmTwoPartVal - Return true if the specified value can be obtained by
182 /// or'ing together two SOImmVal's.
183 static inline bool isSOImmTwoPartVal(unsigned V) {
184 // If this can be handled with a single shifter_op, bail out.
185 V = rotr32(~255U, getSOImmValRotate(V)) & V;
186 if (V == 0)
187 return false;
188
189 // If this can be handled with two shifter_op's, accept.
190 V = rotr32(~255U, getSOImmValRotate(V)) & V;
191 return V == 0;
192 }
193
194 /// getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal,
195 /// return the first chunk of it.
196 static inline unsigned getSOImmTwoPartFirst(unsigned V) {
197 return rotr32(255U, getSOImmValRotate(V)) & V;
198 }
199
200 /// getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal,
201 /// return the second chunk of it.
202 static inline unsigned getSOImmTwoPartSecond(unsigned V) {
203 // Mask out the first hunk.
204 V = rotr32(~255U, getSOImmValRotate(V)) & V;
205
206 // Take what's left.
207 assert(V == (rotr32(255U, getSOImmValRotate(V)) & V));
208 return V;
209 }
210
211 /// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed
212 /// by a left shift. Returns the shift amount to use.
213 static inline unsigned getThumbImmValShift(unsigned Imm) {
214 // 8-bit (or less) immediates are trivially immediate operand with a shift
215 // of zero.
216 if ((Imm & ~255U) == 0) return 0;
217
218 // Use CTZ to compute the shift amount.
219 return CountTrailingZeros_32(Imm);
220 }
221
222 /// isThumbImmShiftedVal - Return true if the specified value can be obtained
223 /// by left shifting a 8-bit immediate.
224 static inline bool isThumbImmShiftedVal(unsigned V) {
225 // If this can be handled with
226 V = (~255U << getThumbImmValShift(V)) & V;
227 return V == 0;
228 }
229
230 /// getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed
231 /// by a left shift. Returns the shift amount to use.
232 static inline unsigned getThumbImm16ValShift(unsigned Imm) {
233 // 16-bit (or less) immediates are trivially immediate operand with a shift
234 // of zero.
235 if ((Imm & ~65535U) == 0) return 0;
236
237 // Use CTZ to compute the shift amount.
238 return CountTrailingZeros_32(Imm);
239 }
240
241 /// isThumbImm16ShiftedVal - Return true if the specified value can be
242 /// obtained by left shifting a 16-bit immediate.
243 static inline bool isThumbImm16ShiftedVal(unsigned V) {
244 // If this can be handled with
245 V = (~65535U << getThumbImm16ValShift(V)) & V;
246 return V == 0;
247 }
248
249 /// getThumbImmNonShiftedVal - If V is a value that satisfies
250 /// isThumbImmShiftedVal, return the non-shiftd value.
251 static inline unsigned getThumbImmNonShiftedVal(unsigned V) {
252 return V >> getThumbImmValShift(V);
253 }
254
255
256 /// getT2SOImmValSplat - Return the 12-bit encoded representation
257 /// if the specified value can be obtained by splatting the low 8 bits
258 /// into every other byte or every byte of a 32-bit value. i.e.,
259 /// 00000000 00000000 00000000 abcdefgh control = 0
260 /// 00000000 abcdefgh 00000000 abcdefgh control = 1
261 /// abcdefgh 00000000 abcdefgh 00000000 control = 2
262 /// abcdefgh abcdefgh abcdefgh abcdefgh control = 3
263 /// Return -1 if none of the above apply.
264 /// See ARM Reference Manual A6.3.2.
265 static inline int getT2SOImmValSplatVal(unsigned V) {
266 unsigned u, Vs, Imm;
267 // control = 0
268 if ((V & 0xffffff00) == 0)
269 return V;
270
271 // If the value is zeroes in the first byte, just shift those off
272 Vs = ((V & 0xff) == 0) ? V >> 8 : V;
273 // Any passing value only has 8 bits of payload, splatted across the word
274 Imm = Vs & 0xff;
275 // Likewise, any passing values have the payload splatted into the 3rd byte
276 u = Imm | (Imm << 16);
277
278 // control = 1 or 2
279 if (Vs == u)
280 return (((Vs == V) ? 1 : 2) << 8) | Imm;
281
282 // control = 3
283 if (Vs == (u | (u << 8)))
284 return (3 << 8) | Imm;
285
286 return -1;
287 }
288
289 /// getT2SOImmValRotateVal - Return the 12-bit encoded representation if the
290 /// specified value is a rotated 8-bit value. Return -1 if no rotation
291 /// encoding is possible.
292 /// See ARM Reference Manual A6.3.2.
293 static inline int getT2SOImmValRotateVal(unsigned V) {
294 unsigned RotAmt = CountLeadingZeros_32(V);
295 if (RotAmt >= 24)
296 return -1;
297
298 // If 'Arg' can be handled with a single shifter_op return the value.
299 if ((rotr32(0xff000000U, RotAmt) & V) == V)
300 return (rotr32(V, 24 - RotAmt) & 0x7f) | ((RotAmt + 8) << 7);
301
302 return -1;
303 }
304
305 /// getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit
306 /// into a Thumb-2 shifter_operand immediate operand, return the 12-bit
307 /// encoding for it. If not, return -1.
308 /// See ARM Reference Manual A6.3.2.
309 static inline int getT2SOImmVal(unsigned Arg) {
310 // If 'Arg' is an 8-bit splat, then get the encoded value.
311 int Splat = getT2SOImmValSplatVal(Arg);
312 if (Splat != -1)
313 return Splat;
314
315 // If 'Arg' can be handled with a single shifter_op return the value.
316 int Rot = getT2SOImmValRotateVal(Arg);
317 if (Rot != -1)
318 return Rot;
319
320 return -1;
321 }
322
323 static inline unsigned getT2SOImmValRotate(unsigned V) {
324 if ((V & ~255U) == 0) return 0;
325 // Use CTZ to compute the rotate amount.
326 unsigned RotAmt = CountTrailingZeros_32(V);
327 return (32 - RotAmt) & 31;
328 }
329
330 static inline bool isT2SOImmTwoPartVal (unsigned Imm) {
331 unsigned V = Imm;
332 // Passing values can be any combination of splat values and shifter
333 // values. If this can be handled with a single shifter or splat, bail
334 // out. Those should be handled directly, not with a two-part val.
335 if (getT2SOImmValSplatVal(V) != -1)
336 return false;
337 V = rotr32 (~255U, getT2SOImmValRotate(V)) & V;
338 if (V == 0)
339 return false;
340
341 // If this can be handled as an immediate, accept.
342 if (getT2SOImmVal(V) != -1) return true;
343
344 // Likewise, try masking out a splat value first.
345 V = Imm;
346 if (getT2SOImmValSplatVal(V & 0xff00ff00U) != -1)
347 V &= ~0xff00ff00U;
348 else if (getT2SOImmValSplatVal(V & 0x00ff00ffU) != -1)
349 V &= ~0x00ff00ffU;
350 // If what's left can be handled as an immediate, accept.
351 if (getT2SOImmVal(V) != -1) return true;
352
353 // Otherwise, do not accept.
354 return false;
355 }
356
357 static inline unsigned getT2SOImmTwoPartFirst(unsigned Imm) {
358 assert (isT2SOImmTwoPartVal(Imm) &&
359 "Immedate cannot be encoded as two part immediate!");
360 // Try a shifter operand as one part
361 unsigned V = rotr32 (~255, getT2SOImmValRotate(Imm)) & Imm;
362 // If the rest is encodable as an immediate, then return it.
363 if (getT2SOImmVal(V) != -1) return V;
364
365 // Try masking out a splat value first.
366 if (getT2SOImmValSplatVal(Imm & 0xff00ff00U) != -1)
367 return Imm & 0xff00ff00U;
368
369 // The other splat is all that's left as an option.
370 assert (getT2SOImmValSplatVal(Imm & 0x00ff00ffU) != -1);
371 return Imm & 0x00ff00ffU;
372 }
373
374 static inline unsigned getT2SOImmTwoPartSecond(unsigned Imm) {
375 // Mask out the first hunk
376 Imm ^= getT2SOImmTwoPartFirst(Imm);
377 // Return what's left
378 assert (getT2SOImmVal(Imm) != -1 &&
379 "Unable to encode second part of T2 two part SO immediate");
380 return Imm;
381 }
382
383
384 //===--------------------------------------------------------------------===//
385 // Addressing Mode #2
386 //===--------------------------------------------------------------------===//
387 //
388 // This is used for most simple load/store instructions.
389 //
390 // addrmode2 := reg +/- reg shop imm
391 // addrmode2 := reg +/- imm12
392 //
393 // The first operand is always a Reg. The second operand is a reg if in
394 // reg/reg form, otherwise it's reg#0. The third field encodes the operation
395 // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
396 // fourth operand 16-17 encodes the index mode.
397 //
398 // If this addressing mode is a frame index (before prolog/epilog insertion
399 // and code rewriting), this operand will have the form: FI#, reg0,
400 // with no shift amount for the frame offset.
401 //
402 static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO,
403 unsigned IdxMode = 0) {
404 assert(Imm12 < (1 << 12) && "Imm too large!");
405 bool isSub = Opc == sub;
406 return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
407 }
408 static inline unsigned getAM2Offset(unsigned AM2Opc) {
409 return AM2Opc & ((1 << 12)-1);
410 }
411 static inline AddrOpc getAM2Op(unsigned AM2Opc) {
412 return ((AM2Opc >> 12) & 1) ? sub : add;
413 }
414 static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) {
415 return (ShiftOpc)((AM2Opc >> 13) & 7);
416 }
417 static inline unsigned getAM2IdxMode(unsigned AM2Opc) {
418 return (AM2Opc >> 16);
419 }
420
421
422 //===--------------------------------------------------------------------===//
423 // Addressing Mode #3
424 //===--------------------------------------------------------------------===//
425 //
426 // This is used for sign-extending loads, and load/store-pair instructions.
427 //
428 // addrmode3 := reg +/- reg
429 // addrmode3 := reg +/- imm8
430 //
431 // The first operand is always a Reg. The second operand is a reg if in
432 // reg/reg form, otherwise it's reg#0. The third field encodes the operation
433 // in bit 8, the immediate in bits 0-7. The fourth operand 9-10 encodes the
434 // index mode.
435
436 /// getAM3Opc - This function encodes the addrmode3 opc field.
437 static inline unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset,
438 unsigned IdxMode = 0) {
439 bool isSub = Opc == sub;
440 return ((int)isSub << 8) | Offset | (IdxMode << 9);
441 }
442 static inline unsigned char getAM3Offset(unsigned AM3Opc) {
443 return AM3Opc & 0xFF;
444 }
445 static inline AddrOpc getAM3Op(unsigned AM3Opc) {
446 return ((AM3Opc >> 8) & 1) ? sub : add;
447 }
448 static inline unsigned getAM3IdxMode(unsigned AM3Opc) {
449 return (AM3Opc >> 9);
450 }
451
452 //===--------------------------------------------------------------------===//
453 // Addressing Mode #4
454 //===--------------------------------------------------------------------===//
455 //
456 // This is used for load / store multiple instructions.
457 //
458 // addrmode4 := reg,
459 //
460 // The four modes are:
461 // IA - Increment after
462 // IB - Increment before
463 // DA - Decrement after
464 // DB - Decrement before
465 // For VFP instructions, only the IA and DB modes are valid.
466
467 static inline AMSubMode getAM4SubMode(unsigned Mode) {
468 return (AMSubMode)(Mode & 0x7);
469 }
470
471 static inline unsigned getAM4ModeImm(AMSubMode SubMode) {
472 return (int)SubMode;
473 }
474
475 //===--------------------------------------------------------------------===//
476 // Addressing Mode #5
477 //===--------------------------------------------------------------------===//
478 //
479 // This is used for coprocessor instructions, such as FP load/stores.
480 //
481 // addrmode5 := reg +/- imm8*4
482 //
483 // The first operand is always a Reg. The second operand encodes the
484 // operation in bit 8 and the immediate in bits 0-7.
485
486 /// getAM5Opc - This function encodes the addrmode5 opc field.
487 static inline unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset) {
488 bool isSub = Opc == sub;
489 return ((int)isSub << 8) | Offset;
490 }
491 static inline unsigned char getAM5Offset(unsigned AM5Opc) {
492 return AM5Opc & 0xFF;
493 }
494 static inline AddrOpc getAM5Op(unsigned AM5Opc) {
495 return ((AM5Opc >> 8) & 1) ? sub : add;
496 }
497
498 //===--------------------------------------------------------------------===//
499 // Addressing Mode #6
500 //===--------------------------------------------------------------------===//
501 //
502 // This is used for NEON load / store instructions.
503 //
504 // addrmode6 := reg with optional alignment
505 //
506 // This is stored in two operands [regaddr, align]. The first is the
507 // address register. The second operand is the value of the alignment
508 // specifier in bytes or zero if no explicit alignment.
509 // Valid alignments depend on the specific instruction.
510
511 //===--------------------------------------------------------------------===//
512 // NEON Modified Immediates
513 //===--------------------------------------------------------------------===//
514 //
515 // Several NEON instructions (e.g., VMOV) take a "modified immediate"
516 // vector operand, where a small immediate encoded in the instruction
517 // specifies a full NEON vector value. These modified immediates are
518 // represented here as encoded integers. The low 8 bits hold the immediate
519 // value; bit 12 holds the "Op" field of the instruction, and bits 11-8 hold
520 // the "Cmode" field of the instruction. The interfaces below treat the
521 // Op and Cmode values as a single 5-bit value.
522
523 static inline unsigned createNEONModImm(unsigned OpCmode, unsigned Val) {
524 return (OpCmode << 8) | Val;
525 }
526 static inline unsigned getNEONModImmOpCmode(unsigned ModImm) {
527 return (ModImm >> 8) & 0x1f;
528 }
529 static inline unsigned getNEONModImmVal(unsigned ModImm) {
530 return ModImm & 0xff;
531 }
532
533 /// decodeNEONModImm - Decode a NEON modified immediate value into the
534 /// element value and the element size in bits. (If the element size is
535 /// smaller than the vector, it is splatted into all the elements.)
536 static inline uint64_t decodeNEONModImm(unsigned ModImm, unsigned &EltBits) {
537 unsigned OpCmode = getNEONModImmOpCmode(ModImm);
538 unsigned Imm8 = getNEONModImmVal(ModImm);
539 uint64_t Val = 0;
540
541 if (OpCmode == 0xe) {
542 // 8-bit vector elements
543 Val = Imm8;
544 EltBits = 8;
545 } else if ((OpCmode & 0xc) == 0x8) {
546 // 16-bit vector elements
547 unsigned ByteNum = (OpCmode & 0x6) >> 1;
548 Val = Imm8 << (8 * ByteNum);
549 EltBits = 16;
550 } else if ((OpCmode & 0x8) == 0) {
551 // 32-bit vector elements, zero with one byte set
552 unsigned ByteNum = (OpCmode & 0x6) >> 1;
553 Val = Imm8 << (8 * ByteNum);
554 EltBits = 32;
555 } else if ((OpCmode & 0xe) == 0xc) {
556 // 32-bit vector elements, one byte with low bits set
557 unsigned ByteNum = 1 + (OpCmode & 0x1);
558 Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
559 EltBits = 32;
560 } else if (OpCmode == 0x1e) {
561 // 64-bit vector elements
562 for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
563 if ((ModImm >> ByteNum) & 1)
564 Val |= (uint64_t)0xff << (8 * ByteNum);
565 }
566 EltBits = 64;
567 } else {
568 assert(false && "Unsupported NEON immediate");
569 }
570 return Val;
571 }
572
573 AMSubMode getLoadStoreMultipleSubMode(int Opcode);
574
575 } // end namespace ARM_AM
576 } // end namespace llvm
577
578 #endif
579
0 //===-- ARMMCExpr.cpp - ARM specific MC expression classes ----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #define DEBUG_TYPE "armmcexpr"
10 #include "ARMMCExpr.h"
11 #include "llvm/MC/MCContext.h"
12 #include "llvm/MC/MCAssembler.h"
13 using namespace llvm;
14
15 const ARMMCExpr*
16 ARMMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
17 MCContext &Ctx) {
18 return new (Ctx) ARMMCExpr(Kind, Expr);
19 }
20
21 void ARMMCExpr::PrintImpl(raw_ostream &OS) const {
22 switch (Kind) {
23 default: assert(0 && "Invalid kind!");
24 case VK_ARM_HI16: OS << ":upper16:"; break;
25 case VK_ARM_LO16: OS << ":lower16:"; break;
26 }
27
28 const MCExpr *Expr = getSubExpr();
29 if (Expr->getKind() != MCExpr::SymbolRef)
30 OS << '(';
31 Expr->print(OS);
32 if (Expr->getKind() != MCExpr::SymbolRef)
33 OS << ')';
34 }
35
36 bool
37 ARMMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
38 const MCAsmLayout *Layout) const {
39 return false;
40 }
41
42 // FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps
43 // that method should be made public?
44 static void AddValueSymbols_(const MCExpr *Value, MCAssembler *Asm) {
45 switch (Value->getKind()) {
46 case MCExpr::Target:
47 assert(0 && "Can't handle nested target expr!");
48 break;
49
50 case MCExpr::Constant:
51 break;
52
53 case MCExpr::Binary: {
54 const MCBinaryExpr *BE = cast(Value);
55 AddValueSymbols_(BE->getLHS(), Asm);
56 AddValueSymbols_(BE->getRHS(), Asm);
57 break;
58 }
59
60 case MCExpr::SymbolRef:
61 Asm->getOrCreateSymbolData(cast(Value)->getSymbol());
62 break;
63
64 case MCExpr::Unary:
65 AddValueSymbols_(cast(Value)->getSubExpr(), Asm);
66 break;
67 }
68 }
69
70 void ARMMCExpr::AddValueSymbols(MCAssembler *Asm) const {
71 AddValueSymbols_(getSubExpr(), Asm);
72 }
0 //===-- ARMMCExpr.h - ARM specific MC expression classes ------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef ARMMCEXPR_H
10 #define ARMMCEXPR_H
11
12 #include "llvm/MC/MCExpr.h"
13
14 namespace llvm {
15
16 class ARMMCExpr : public MCTargetExpr {
17 public:
18 enum VariantKind {
19 VK_ARM_None,
20 VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the .s file)
21 VK_ARM_LO16 // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the .s file)
22 };
23
24 private:
25 const VariantKind Kind;
26 const MCExpr *Expr;
27
28 explicit ARMMCExpr(VariantKind _Kind, const MCExpr *_Expr)
29 : Kind(_Kind), Expr(_Expr) {}
30
31 public:
32 /// @name Construction
33 /// @{
34
35 static const ARMMCExpr *Create(VariantKind Kind, const MCExpr *Expr,
36 MCContext &Ctx);
37
38 static const ARMMCExpr *CreateUpper16(const MCExpr *Expr, MCContext &Ctx) {
39 return Create(VK_ARM_HI16, Expr, Ctx);
40 }
41
42 static const ARMMCExpr *CreateLower16(const MCExpr *Expr, MCContext &Ctx) {
43 return Create(VK_ARM_LO16, Expr, Ctx);
44 }
45
46 /// @}
47 /// @name Accessors
48 /// @{
49
50 /// getOpcode - Get the kind of this expression.
51 VariantKind getKind() const { return Kind; }
52
53 /// getSubExpr - Get the child of this expression.
54 const MCExpr *getSubExpr() const { return Expr; }
55
56 /// @}
57
58 void PrintImpl(raw_ostream &OS) const;
59 bool EvaluateAsRelocatableImpl(MCValue &Res,
60 const MCAsmLayout *Layout) const;
61 void AddValueSymbols(MCAssembler *) const;
62 const MCSection *FindAssociatedSection() const {
63 return getSubExpr()->FindAssociatedSection();
64 }
65
66 static bool classof(const MCExpr *E) {
67 return E->getKind() == MCExpr::Target;
68 }
69
70 static bool classof(const ARMMCExpr *) { return true; }
71
72 };
73 } // end namespace llvm
74
75 #endif
0 add_llvm_library(LLVMARMDesc
11 ARMMCTargetDesc.cpp
22 ARMMCAsmInfo.cpp
3 ARMMCExpr.cpp
34 )
45
56 # Hack: we need to include 'main' target directory to grab private headers
1212 //===----------------------------------------------------------------------===//
1313
1414 #include "ARM.h"
15 #include "ARMAddressingModes.h"
1615 #include "ARMBaseInstrInfo.h"
1716 #include "ARMMachineFunctionInfo.h"
1817 #include "ARMSubtarget.h"
1918 #include "Thumb1InstrInfo.h"
2019 #include "Thumb1RegisterInfo.h"
20 #include "MCTargetDesc/ARMAddressingModes.h"
2121 #include "llvm/Constants.h"
2222 #include "llvm/DerivedTypes.h"
2323 #include "llvm/Function.h"
1313 #include "Thumb2InstrInfo.h"
1414 #include "ARM.h"
1515 #include "ARMConstantPoolValue.h"
16 #include "ARMAddressingModes.h"
1716 #include "ARMMachineFunctionInfo.h"
1817 #include "Thumb2InstrInfo.h"
18 #include "MCTargetDesc/ARMAddressingModes.h"
1919 #include "llvm/CodeGen/MachineFrameInfo.h"
2020 #include "llvm/CodeGen/MachineInstrBuilder.h"
2121 #include "llvm/CodeGen/MachineMemOperand.h"
88
99 #define DEBUG_TYPE "t2-reduce-size"
1010 #include "ARM.h"
11 #include "ARMAddressingModes.h"
1211 #include "ARMBaseRegisterInfo.h"
1312 #include "ARMBaseInstrInfo.h"
1413 #include "ARMSubtarget.h"
1514 #include "Thumb2InstrInfo.h"
15 #include "MCTargetDesc/ARMAddressingModes.h"
1616 #include "llvm/CodeGen/MachineInstr.h"
1717 #include "llvm/CodeGen/MachineInstrBuilder.h"
1818 #include "llvm/CodeGen/MachineFunctionPass.h"