Fix reading Time zone rules using Julian days (#17672)
[platform/upstream/coreclr.git] / src / jit / emitarm.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 XX                                                                           XX
8 XX                             emitArm.cpp                                   XX
9 XX                                                                           XX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12 */
13 #include "jitpch.h"
14 #ifdef _MSC_VER
15 #pragma hdrstop
16 #endif
17
18 #if defined(_TARGET_ARM_)
19
20 /*****************************************************************************/
21 /*****************************************************************************/
22
23 #include "instr.h"
24 #include "emit.h"
25 #include "codegen.h"
26
27 /*****************************************************************************/
28
29 const instruction emitJumpKindInstructions[] = {
30     INS_nop,
31
32 #define JMP_SMALL(en, rev, ins) INS_##ins,
33 #include "emitjmps.h"
34 };
35
36 const emitJumpKind emitReverseJumpKinds[] = {
37     EJ_NONE,
38
39 #define JMP_SMALL(en, rev, ins) EJ_##rev,
40 #include "emitjmps.h"
41 };
42
43 /*****************************************************************************
44  * Look up the instruction for a jump kind
45  */
46
47 /*static*/ instruction emitter::emitJumpKindToIns(emitJumpKind jumpKind)
48 {
49     assert((unsigned)jumpKind < ArrLen(emitJumpKindInstructions));
50     return emitJumpKindInstructions[jumpKind];
51 }
52
53 /*****************************************************************************
54  * Look up the jump kind for an instruction. It better be a conditional
55  * branch instruction with a jump kind!
56  */
57
58 /*static*/ emitJumpKind emitter::emitInsToJumpKind(instruction ins)
59 {
60     for (unsigned i = 0; i < ArrLen(emitJumpKindInstructions); i++)
61     {
62         if (ins == emitJumpKindInstructions[i])
63         {
64             emitJumpKind ret = (emitJumpKind)i;
65             assert(EJ_NONE < ret && ret < EJ_COUNT);
66             return ret;
67         }
68     }
69     unreached();
70 }
71
72 /*****************************************************************************
73  * Reverse the conditional jump
74  */
75
76 /*static*/ emitJumpKind emitter::emitReverseJumpKind(emitJumpKind jumpKind)
77 {
78     assert(jumpKind < EJ_COUNT);
79     return emitReverseJumpKinds[jumpKind];
80 }
81
82 /*****************************************************************************
83  *
84  *  Return the allocated size (in bytes) of the given instruction descriptor.
85  */
86
87 size_t emitter::emitSizeOfInsDsc(instrDesc* id)
88 {
89     assert(!emitIsTinyInsDsc(id));
90
91     if (emitIsScnsInsDsc(id))
92         return SMALL_IDSC_SIZE;
93
94     assert((unsigned)id->idInsFmt() < emitFmtCount);
95
96     ID_OPS idOp         = (ID_OPS)emitFmtToOps[id->idInsFmt()];
97     bool   isCallIns    = (id->idIns() == INS_bl) || (id->idIns() == INS_blx);
98     bool   maybeCallIns = (id->idIns() == INS_b) || (id->idIns() == INS_bx);
99
100     // An INS_call instruction may use a "fat" direct/indirect call descriptor
101     // except for a local call to a label (i.e. call to a finally).
102     // Only ID_OP_CALL and ID_OP_SPEC check for this, so we enforce that the
103     // INS_call instruction always uses one of these idOps.
104
105     assert(!isCallIns ||         // either not a call or
106            idOp == ID_OP_CALL || // is a direct call
107            idOp == ID_OP_SPEC || // is an indirect call
108            idOp == ID_OP_JMP);   // is a local call to finally clause
109
110     switch (idOp)
111     {
112         case ID_OP_NONE:
113             break;
114
115         case ID_OP_JMP:
116             return sizeof(instrDescJmp);
117
118         case ID_OP_LBL:
119             return sizeof(instrDescLbl);
120
121         case ID_OP_CALL:
122         case ID_OP_SPEC:
123             assert(isCallIns || maybeCallIns);
124             if (id->idIsLargeCall())
125             {
126                 /* Must be a "fat" indirect call descriptor */
127                 return sizeof(instrDescCGCA);
128             }
129             else
130             {
131                 assert(!id->idIsLargeDsp());
132                 assert(!id->idIsLargeCns());
133                 return sizeof(instrDesc);
134             }
135             break;
136
137         default:
138             NO_WAY("unexpected instruction descriptor format");
139             break;
140     }
141
142     if (id->idIsLargeCns())
143     {
144         if (id->idIsLargeDsp())
145             return sizeof(instrDescCnsDsp);
146         else
147             return sizeof(instrDescCns);
148     }
149     else
150     {
151         if (id->idIsLargeDsp())
152             return sizeof(instrDescDsp);
153         else
154             return sizeof(instrDesc);
155     }
156 }
157
158 bool offsetFitsInVectorMem(int disp)
159 {
160     unsigned imm = unsigned_abs(disp);
161     return ((imm & 0x03fc) == imm);
162 }
163
164 #ifdef DEBUG
165 /*****************************************************************************
166  *
167  *  The following called for each recorded instruction -- use for debugging.
168  */
169 void emitter::emitInsSanityCheck(instrDesc* id)
170 {
171     /* What instruction format have we got? */
172
173     switch (id->idInsFmt())
174     {
175         case IF_T1_A: // T1_A    ................
176         case IF_T2_A: // T2_A    ................ ................
177             break;
178
179         case IF_T1_B: // T1_B    ........cccc....                                           cond
180         case IF_T2_B: // T2_B    ................ ............iiii                          imm4
181             assert(emitGetInsSC(id) < 0x10);
182             break;
183
184         case IF_T1_C: // T1_C    .....iiiiinnnddd                       R1  R2              imm5
185             assert(isLowRegister(id->idReg1()));
186             assert(isLowRegister(id->idReg2()));
187             if (emitInsIsLoadOrStore(id->idIns()))
188             {
189                 emitAttr size = id->idOpSize();
190                 int      imm  = emitGetInsSC(id);
191
192                 imm = insUnscaleImm(imm, size);
193                 assert(imm < 0x20);
194             }
195             else
196             {
197                 assert(id->idSmallCns() < 0x20);
198             }
199             break;
200
201         case IF_T1_D0: // T1_D0   ........Dmmmmddd                       R1* R2*
202             assert(isGeneralRegister(id->idReg1()));
203             assert(isGeneralRegister(id->idReg2()));
204             break;
205
206         case IF_T1_D1: // T1_D1   .........mmmm...                       R1*
207             assert(isGeneralRegister(id->idReg1()));
208             break;
209
210         case IF_T1_D2: // T1_D2   .........mmmm...                               R3*
211             assert(isGeneralRegister(id->idReg3()));
212             break;
213
214         case IF_T1_E: // T1_E    ..........nnnddd                       R1  R2
215             assert(isLowRegister(id->idReg1()));
216             assert(isLowRegister(id->idReg2()));
217             assert(id->idSmallCns() < 0x20);
218             break;
219
220         case IF_T1_F: // T1_F    .........iiiiiii                       SP                  imm7
221             assert(id->idReg1() == REG_SP);
222             assert(id->idOpSize() == EA_4BYTE);
223             assert((emitGetInsSC(id) & ~0x1FC) == 0);
224             break;
225
226         case IF_T1_G: // T1_G    .......iiinnnddd                       R1  R2              imm3
227             assert(isLowRegister(id->idReg1()));
228             assert(isLowRegister(id->idReg2()));
229             assert(id->idSmallCns() < 0x8);
230             break;
231
232         case IF_T1_H: // T1_H    .......mmmnnnddd                       R1  R2  R3
233             assert(isLowRegister(id->idReg1()));
234             assert(isLowRegister(id->idReg2()));
235             assert(isLowRegister(id->idReg3()));
236             break;
237
238         case IF_T1_I: // T1_I    ......i.iiiiiddd                       R1                  imm6
239             assert(isLowRegister(id->idReg1()));
240             break;
241
242         case IF_T1_J0: // T1_J0   .....dddiiiiiiii                       R1                  imm8
243             assert(isLowRegister(id->idReg1()));
244             assert(emitGetInsSC(id) < 0x100);
245             break;
246
247         case IF_T1_J1: // T1_J1   .....dddiiiiiiii                       R1                  <regmask8>
248             assert(isLowRegister(id->idReg1()));
249             assert(emitGetInsSC(id) < 0x100);
250             break;
251
252         case IF_T1_J2: // T1_J2   .....dddiiiiiiii                       R1  SP              imm8
253             assert(isLowRegister(id->idReg1()));
254             assert(id->idReg2() == REG_SP);
255             assert(id->idOpSize() == EA_4BYTE);
256             assert((emitGetInsSC(id) & ~0x3FC) == 0);
257             break;
258
259         case IF_T1_L0: // T1_L0   ........iiiiiiii                                           imm8
260             assert(emitGetInsSC(id) < 0x100);
261             break;
262
263         case IF_T1_L1: // T1_L1   .......Rrrrrrrrr                                           <regmask8+2>
264             assert(emitGetInsSC(id) < 0x400);
265             break;
266
267         case IF_T2_C0: // T2_C0   ...........Snnnn .iiiddddiishmmmm       R1  R2  R3      S, imm5, sh
268             assert(isGeneralRegister(id->idReg1()));
269             assert(isGeneralRegister(id->idReg2()));
270             assert(isGeneralRegister(id->idReg3()));
271             assert(emitGetInsSC(id) < 0x20);
272             break;
273
274         case IF_T2_C4: // T2_C4   ...........Snnnn ....dddd....mmmm       R1  R2  R3      S
275         case IF_T2_C5: // T2_C5   ............nnnn ....dddd....mmmm       R1  R2  R3
276         case IF_T2_G1: // T2_G1   ............nnnn ttttTTTT........       R1  R2  R3
277             assert(isGeneralRegister(id->idReg1()));
278             assert(isGeneralRegister(id->idReg2()));
279             assert(isGeneralRegister(id->idReg3()));
280             break;
281
282         case IF_T2_C1: // T2_C1   ...........S.... .iiiddddiishmmmm       R1  R2          S, imm5, sh
283         case IF_T2_C2: // T2_C2   ...........S.... .iiiddddii..mmmm       R1  R2          S, imm5
284         case IF_T2_C8: // T2_C8   ............nnnn .iii....iishmmmm       R1  R2             imm5, sh
285             assert(isGeneralRegister(id->idReg1()));
286             assert(isGeneralRegister(id->idReg2()));
287             assert(emitGetInsSC(id) < 0x20);
288             break;
289
290         case IF_T2_C6: // T2_C6   ................ ....dddd..iimmmm       R1  R2                   imm2
291         case IF_T2_C7: // T2_C7   ............nnnn ..........shmmmm       R1  R2                   imm2
292             assert(isGeneralRegister(id->idReg1()));
293             assert(isGeneralRegister(id->idReg2()));
294             assert(emitGetInsSC(id) < 0x4);
295             break;
296
297         case IF_T2_C3:  // T2_C3   ...........S.... ....dddd....mmmm       R1  R2          S
298         case IF_T2_C9:  // T2_C9   ............nnnn ............mmmm       R1  R2
299         case IF_T2_C10: // T2_C10  ............mmmm ....dddd....mmmm       R1  R2
300             assert(isGeneralRegister(id->idReg1()));
301             assert(isGeneralRegister(id->idReg2()));
302             break;
303
304         case IF_T2_D0: // T2_D0   ............nnnn .iiiddddii.wwwww       R1  R2             imm5, imm5
305             assert(isGeneralRegister(id->idReg1()));
306             assert(isGeneralRegister(id->idReg2()));
307             assert(emitGetInsSC(id) < 0x400);
308             break;
309
310         case IF_T2_D1: // T2_D1   ................ .iiiddddii.wwwww       R1                 imm5, imm5
311             assert(isGeneralRegister(id->idReg1()));
312             assert(emitGetInsSC(id) < 0x400);
313             break;
314
315         case IF_T2_E0: // T2_E0   ............nnnn tttt......shmmmm       R1  R2  R3               imm2
316             assert(isGeneralRegister(id->idReg1()));
317             assert(isGeneralRegister(id->idReg2()));
318             if (id->idIsLclVar())
319             {
320                 assert(isGeneralRegister(codeGen->rsGetRsvdReg()));
321             }
322             else
323             {
324                 assert(isGeneralRegister(id->idReg3()));
325                 assert(emitGetInsSC(id) < 0x4);
326             }
327             break;
328
329         case IF_T2_E1: // T2_E1   ............nnnn tttt............       R1  R2
330             assert(isGeneralRegister(id->idReg1()));
331             assert(isGeneralRegister(id->idReg2()));
332             break;
333
334         case IF_T2_E2: // T2_E2   ................ tttt............       R1
335             assert(isGeneralRegister(id->idReg1()));
336             break;
337
338         case IF_T2_F1: // T2_F1    ............nnnn ttttdddd....mmmm       R1  R2  R3  R4
339         case IF_T2_F2: // T2_F2    ............nnnn aaaadddd....mmmm       R1  R2  R3  R4
340             assert(isGeneralRegister(id->idReg1()));
341             assert(isGeneralRegister(id->idReg2()));
342             assert(isGeneralRegister(id->idReg3()));
343             assert(isGeneralRegister(id->idReg4()));
344             break;
345
346         case IF_T2_G0: // T2_G0   .......PU.W.nnnn ttttTTTTiiiiiiii       R1  R2  R3         imm8, PUW
347             assert(isGeneralRegister(id->idReg1()));
348             assert(isGeneralRegister(id->idReg2()));
349             assert(isGeneralRegister(id->idReg3()));
350             assert(unsigned_abs(emitGetInsSC(id)) < 0x100);
351             break;
352
353         case IF_T2_H0: // T2_H0   ............nnnn tttt.PUWiiiiiiii       R1  R2             imm8, PUW
354             assert(isGeneralRegister(id->idReg1()));
355             assert(isGeneralRegister(id->idReg2()));
356             assert(unsigned_abs(emitGetInsSC(id)) < 0x100);
357             break;
358
359         case IF_T2_H1: // T2_H1   ............nnnn tttt....iiiiiiii       R1  R2             imm8
360             assert(isGeneralRegister(id->idReg1()));
361             assert(isGeneralRegister(id->idReg2()));
362             assert(emitGetInsSC(id) < 0x100);
363             break;
364
365         case IF_T2_H2: // T2_H2   ............nnnn ........iiiiiiii       R1                 imm8
366             assert(isGeneralRegister(id->idReg1()));
367             assert(emitGetInsSC(id) < 0x100);
368             break;
369
370         case IF_T2_I0: // T2_I0   ..........W.nnnn rrrrrrrrrrrrrrrr       R1              W, imm16
371             assert(isGeneralRegister(id->idReg1()));
372             assert(emitGetInsSC(id) < 0x10000);
373             break;
374
375         case IF_T2_N: // T2_N    .....i......iiii .iiiddddiiiiiiii       R1                 imm16
376             assert(isGeneralRegister(id->idReg1()));
377             break;
378
379         case IF_T2_N2: // T2_N2   .....i......iiii .iiiddddiiiiiiii       R1                 imm16
380             assert(isGeneralRegister(id->idReg1()));
381             assert((size_t)emitGetInsSC(id) < emitDataSize());
382             break;
383
384         case IF_T2_I1: // T2_I1   ................ rrrrrrrrrrrrrrrr                          imm16
385             assert(emitGetInsSC(id) < 0x10000);
386             break;
387
388         case IF_T2_K1: // T2_K1   ............nnnn ttttiiiiiiiiiiii       R1  R2             imm12
389         case IF_T2_M0: // T2_M0   .....i......nnnn .iiiddddiiiiiiii       R1  R2             imm12
390             assert(isGeneralRegister(id->idReg1()));
391             assert(isGeneralRegister(id->idReg2()));
392             assert(emitGetInsSC(id) < 0x1000);
393             break;
394
395         case IF_T2_L0: // T2_L0   .....i.....Snnnn .iiiddddiiiiiiii       R1  R2          S, imm8<<imm4
396             assert(isGeneralRegister(id->idReg1()));
397             assert(isGeneralRegister(id->idReg2()));
398             assert(isModImmConst(emitGetInsSC(id)));
399             break;
400
401         case IF_T2_K4: // T2_K4   ........U....... ttttiiiiiiiiiiii       R1  PC          U, imm12
402         case IF_T2_M1: // T2_M1   .....i.......... .iiiddddiiiiiiii       R1  PC             imm12
403             assert(isGeneralRegister(id->idReg1()));
404             assert(id->idReg2() == REG_PC);
405             assert(emitGetInsSC(id) < 0x1000);
406             break;
407
408         case IF_T2_K3: // T2_K3   ........U....... ....iiiiiiiiiiii       PC              U, imm12
409             assert(id->idReg1() == REG_PC);
410             assert(emitGetInsSC(id) < 0x1000);
411             break;
412
413         case IF_T2_K2: // T2_K2   ............nnnn ....iiiiiiiiiiii       R1                 imm12
414             assert(isGeneralRegister(id->idReg1()));
415             assert(emitGetInsSC(id) < 0x1000);
416             break;
417
418         case IF_T2_L1: // T2_L1   .....i.....S.... .iiiddddiiiiiiii       R1              S, imm8<<imm4
419         case IF_T2_L2: // T2_L2   .....i......nnnn .iii....iiiiiiii       R1                 imm8<<imm4
420             assert(isGeneralRegister(id->idReg1()));
421             assert(isModImmConst(emitGetInsSC(id)));
422             break;
423
424         case IF_T1_J3: // T1_J3   .....dddiiiiiiii                        R1  PC             imm8
425             assert(isGeneralRegister(id->idReg1()));
426             assert(id->idReg2() == REG_PC);
427             assert(emitGetInsSC(id) < 0x100);
428             break;
429
430         case IF_T1_K:  // T1_K    ....cccciiiiiiii                        Branch             imm8, cond4
431         case IF_T1_M:  // T1_M    .....iiiiiiiiiii                        Branch             imm11
432         case IF_T2_J1: // T2_J1   .....Scccciiiiii ..j.jiiiiiiiiiii       Branch             imm20, cond4
433         case IF_T2_J2: // T2_J2   .....Siiiiiiiiii ..j.jiiiiiiiiii.       Branch             imm24
434         case IF_T2_N1: // T2_N    .....i......iiii .iiiddddiiiiiiii       R1                 imm16
435         case IF_T2_J3: // T2_J3   .....Siiiiiiiiii ..j.jiiiiiiiiii.       Call               imm24
436         case IF_LARGEJMP:
437             break;
438
439         case IF_T2_VFP3:
440             if (id->idOpSize() == EA_8BYTE)
441             {
442                 assert(isDoubleReg(id->idReg1()));
443                 assert(isDoubleReg(id->idReg2()));
444                 assert(isDoubleReg(id->idReg3()));
445             }
446             else
447             {
448                 assert(id->idOpSize() == EA_4BYTE);
449                 assert(isFloatReg(id->idReg1()));
450                 assert(isFloatReg(id->idReg2()));
451                 assert(isFloatReg(id->idReg3()));
452             }
453             break;
454
455         case IF_T2_VFP2:
456             assert(isFloatReg(id->idReg1()));
457             assert(isFloatReg(id->idReg2()));
458             break;
459
460         case IF_T2_VLDST:
461             if (id->idOpSize() == EA_8BYTE)
462                 assert(isDoubleReg(id->idReg1()));
463             else
464                 assert(isFloatReg(id->idReg1()));
465             assert(isGeneralRegister(id->idReg2()));
466             assert(offsetFitsInVectorMem(emitGetInsSC(id)));
467             break;
468
469         case IF_T2_VMOVD:
470             assert(id->idOpSize() == EA_8BYTE);
471             if (id->idIns() == INS_vmov_d2i)
472             {
473                 assert(isGeneralRegister(id->idReg1()));
474                 assert(isGeneralRegister(id->idReg2()));
475                 assert(isDoubleReg(id->idReg3()));
476             }
477             else
478             {
479                 assert(id->idIns() == INS_vmov_i2d);
480                 assert(isDoubleReg(id->idReg1()));
481                 assert(isGeneralRegister(id->idReg2()));
482                 assert(isGeneralRegister(id->idReg3()));
483             }
484             break;
485
486         case IF_T2_VMOVS:
487             assert(id->idOpSize() == EA_4BYTE);
488             if (id->idIns() == INS_vmov_i2f)
489             {
490                 assert(isFloatReg(id->idReg1()));
491                 assert(isGeneralRegister(id->idReg2()));
492             }
493             else
494             {
495                 assert(id->idIns() == INS_vmov_f2i);
496                 assert(isGeneralRegister(id->idReg1()));
497                 assert(isFloatReg(id->idReg2()));
498             }
499             break;
500
501         default:
502             printf("unexpected format %s\n", emitIfName(id->idInsFmt()));
503             assert(!"Unexpected format");
504             break;
505     }
506 }
507 #endif // DEBUG
508
509 bool emitter::emitInsMayWriteToGCReg(instrDesc* id)
510 {
511     instruction ins = id->idIns();
512     insFormat   fmt = id->idInsFmt();
513
514     switch (fmt)
515     {
516
517         // These are the formats with "destination" or "target" registers:
518         case IF_T1_C:
519         case IF_T1_D0:
520         case IF_T1_E:
521         case IF_T1_G:
522         case IF_T1_H:
523         case IF_T1_J0:
524         case IF_T1_J1:
525         case IF_T1_J2:
526         case IF_T1_J3:
527         case IF_T2_C0:
528         case IF_T2_C1:
529         case IF_T2_C2:
530         case IF_T2_C3:
531         case IF_T2_C4:
532         case IF_T2_C5:
533         case IF_T2_C6:
534         case IF_T2_C10:
535         case IF_T2_D0:
536         case IF_T2_D1:
537         case IF_T2_F1:
538         case IF_T2_F2:
539         case IF_T2_L0:
540         case IF_T2_L1:
541         case IF_T2_M0:
542         case IF_T2_M1:
543         case IF_T2_N:
544         case IF_T2_N1:
545         case IF_T2_N2:
546         case IF_T2_VFP3:
547         case IF_T2_VFP2:
548         case IF_T2_VLDST:
549         case IF_T2_E0:
550         case IF_T2_E1:
551         case IF_T2_E2:
552         case IF_T2_G0:
553         case IF_T2_G1:
554         case IF_T2_H0:
555         case IF_T2_H1:
556         case IF_T2_K1:
557         case IF_T2_K4:
558             // Some formats with "destination" or "target" registers are actually used for store instructions, for the
559             // "source" value written to memory.
560             // Similarly, PUSH has a target register, indicating the start of the set of registers to push.  POP
561             // *does* write to at least one register, so we do not make that a special case.
562             // Various compare/test instructions do not write (except to the flags). Technically "teq" does not need to
563             // be
564             // be in this list because it has no forms matched above, but I'm putting it here for completeness.
565             switch (ins)
566             {
567                 case INS_str:
568                 case INS_strb:
569                 case INS_strh:
570                 case INS_strd:
571                 case INS_strex:
572                 case INS_strexb:
573                 case INS_strexd:
574                 case INS_strexh:
575                 case INS_push:
576                 case INS_cmp:
577                 case INS_cmn:
578                 case INS_tst:
579                 case INS_teq:
580                     return false;
581                 default:
582                     return true;
583             }
584         case IF_T2_VMOVS:
585             // VMOV.i2f reads from the integer register. Conversely VMOV.f2i writes to GC pointer-sized
586             // integer register that might have previously held GC pointers, so they need to be included.
587             assert(id->idGCref() == GCT_NONE);
588             return (ins == INS_vmov_f2i);
589
590         case IF_T2_VMOVD:
591             // VMOV.i2d reads from the integer registers. Conversely VMOV.d2i writes to GC pointer-sized
592             // integer registers that might have previously held GC pointers, so they need to be included.
593             assert(id->idGCref() == GCT_NONE);
594             return (ins == INS_vmov_d2i);
595
596         default:
597             return false;
598     }
599 }
600
601 bool emitter::emitInsWritesToLclVarStackLoc(instrDesc* id)
602 {
603     if (!id->idIsLclVar())
604         return false;
605
606     instruction ins = id->idIns();
607
608     // This list is related to the list of instructions used to store local vars in emitIns_S_R().
609     // We don't accept writing to float local vars.
610
611     switch (ins)
612     {
613         case INS_strb:
614         case INS_strh:
615         case INS_str:
616             return true;
617         default:
618             return false;
619     }
620 }
621
622 bool emitter::emitInsMayWriteMultipleRegs(instrDesc* id)
623 {
624     instruction ins = id->idIns();
625
626     switch (ins)
627     {
628         case INS_ldm:
629         case INS_ldmdb:
630         case INS_pop:
631         case INS_smlal:
632         case INS_smull:
633         case INS_umlal:
634         case INS_umull:
635         case INS_vmov_d2i:
636             return true;
637         default:
638             return false;
639     }
640 }
641
642 /*****************************************************************************/
643 #ifdef DEBUG
644 /*****************************************************************************
645  *
646  *  Return a string that represents the given register.
647  */
648
649 const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName)
650 {
651     assert(reg < REG_COUNT);
652
653     const char* rn = emitComp->compRegVarName(reg, varName, false);
654
655     assert(strlen(rn) >= 1);
656
657     return rn;
658 }
659
660 const char* emitter::emitFloatRegName(regNumber reg, emitAttr attr, bool varName)
661 {
662     assert(reg < REG_COUNT);
663
664     const char* rn = emitComp->compRegVarName(reg, varName, true);
665
666     assert(strlen(rn) >= 1);
667
668     return rn;
669 }
670 #endif // DEBUG
671
672 /*****************************************************************************
673  *
674  *  Returns the base encoding of the given CPU instruction.
675  */
676
677 emitter::insFormat emitter::emitInsFormat(instruction ins)
678 {
679     // clang-format off
680     const static insFormat insFormats[] =
681     {
682         #define INST1(id, nm, fp, ldst, fmt, e1                                ) fmt,
683         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            ) fmt,
684         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        ) fmt,
685         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    ) fmt,
686         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                ) fmt,
687         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            ) fmt,
688         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) fmt,
689         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) fmt,
690         #include "instrs.h"
691     };
692     // clang-format on
693
694     assert(ins < ArrLen(insFormats));
695     assert((insFormats[ins] != IF_NONE));
696
697     return insFormats[ins];
698 }
699
700 // INST_FP is 1
701 #define LD 2
702 #define ST 4
703 #define CMP 8
704
705 // clang-format off
706 /*static*/ const BYTE CodeGenInterface::instInfo[] =
707 {
708     #define INST1(id, nm, fp, ldst, fmt, e1                                ) ldst | INST_FP*fp,
709     #define INST2(id, nm, fp, ldst, fmt, e1, e2                            ) ldst | INST_FP*fp,
710     #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        ) ldst | INST_FP*fp,
711     #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    ) ldst | INST_FP*fp,
712     #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                ) ldst | INST_FP*fp,
713     #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            ) ldst | INST_FP*fp,
714     #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) ldst | INST_FP*fp,
715     #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) ldst | INST_FP*fp,
716     #include "instrs.h"
717 };
718 // clang-format on
719
720 /*****************************************************************************
721  *
722  *  Returns true if the instruction is some kind of load instruction
723  */
724
725 bool emitter::emitInsIsLoad(instruction ins)
726 {
727     // We have pseudo ins like lea which are not included in emitInsLdStTab.
728     if (ins < ArrLen(CodeGenInterface::instInfo))
729         return (CodeGenInterface::instInfo[ins] & LD) ? true : false;
730     else
731         return false;
732 }
733
734 /*****************************************************************************
735  *
736  *  Returns true if the instruction is some kind of compare or test instruction
737  */
738
739 bool emitter::emitInsIsCompare(instruction ins)
740 {
741     // We have pseudo ins like lea which are not included in emitInsLdStTab.
742     if (ins < ArrLen(CodeGenInterface::instInfo))
743         return (CodeGenInterface::instInfo[ins] & CMP) ? true : false;
744     else
745         return false;
746 }
747
748 /*****************************************************************************
749  *
750  *  Returns true if the instruction is some kind of store instruction
751  */
752
753 bool emitter::emitInsIsStore(instruction ins)
754 {
755     // We have pseudo ins like lea which are not included in emitInsLdStTab.
756     if (ins < ArrLen(CodeGenInterface::instInfo))
757         return (CodeGenInterface::instInfo[ins] & ST) ? true : false;
758     else
759         return false;
760 }
761
762 /*****************************************************************************
763  *
764  *  Returns true if the instruction is some kind of load/store instruction
765  */
766
767 bool emitter::emitInsIsLoadOrStore(instruction ins)
768 {
769     // We have pseudo ins like lea which are not included in emitInsLdStTab.
770     if (ins < ArrLen(CodeGenInterface::instInfo))
771         return (CodeGenInterface::instInfo[ins] & (LD | ST)) ? true : false;
772     else
773         return false;
774 }
775
776 #undef LD
777 #undef ST
778 #undef CMP
779
780 /*****************************************************************************
781  *
782  *  Returns the specific encoding of the given CPU instruction and format
783  */
784
785 emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt)
786 {
787     // clang-format off
788     const static code_t insCodes1[] =
789     {
790         #define INST1(id, nm, fp, ldst, fmt, e1                                ) e1,
791         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            ) e1,
792         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        ) e1,
793         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    ) e1,
794         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                ) e1,
795         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            ) e1,
796         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) e1,
797         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e1,
798         #include "instrs.h"
799     };
800     const static code_t insCodes2[] =
801     {
802         #define INST1(id, nm, fp, ldst, fmt, e1                                )
803         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            ) e2,
804         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        ) e2,
805         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    ) e2,
806         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                ) e2,
807         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            ) e2,
808         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) e2,
809         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e2,
810         #include "instrs.h"
811     };
812     const static code_t insCodes3[] =
813     {
814         #define INST1(id, nm, fp, ldst, fmt, e1                                )
815         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            )
816         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        ) e3,
817         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    ) e3,
818         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                ) e3,
819         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            ) e3,
820         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) e3,
821         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e3,
822         #include "instrs.h"
823     };
824     const static code_t insCodes4[] =
825     {
826         #define INST1(id, nm, fp, ldst, fmt, e1                                )
827         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            )
828         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        )
829         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    ) e4,
830         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                ) e4,
831         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            ) e4,
832         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) e4,
833         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e4,
834         #include "instrs.h"
835     };
836     const static code_t insCodes5[] =
837     {
838         #define INST1(id, nm, fp, ldst, fmt, e1                                )
839         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            )
840         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        )
841         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    )
842         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                ) e5,
843         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            ) e5,
844         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) e5,
845         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e5,
846         #include "instrs.h"
847     };
848     const static code_t insCodes6[] =
849     {
850         #define INST1(id, nm, fp, ldst, fmt, e1                                )
851         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            )
852         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        )
853         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    )
854         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                )
855         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            ) e6,
856         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) e6,
857         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e6,
858         #include "instrs.h"
859     };
860     const static code_t insCodes7[] =
861     {
862         #define INST1(id, nm, fp, ldst, fmt, e1                                )
863         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            )
864         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        )
865         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    )
866         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                )
867         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            )
868         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) e7,
869         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e7,
870         #include "instrs.h"
871     };
872     const static code_t insCodes8[] =
873     {
874         #define INST1(id, nm, fp, ldst, fmt, e1                                )
875         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            )
876         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        )
877         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    )
878         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                )
879         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            )
880         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    ) e8,
881         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e8,
882         #include "instrs.h"
883     };
884     const static code_t insCodes9[] =
885     {
886         #define INST1(id, nm, fp, ldst, fmt, e1                                )
887         #define INST2(id, nm, fp, ldst, fmt, e1, e2                            )
888         #define INST3(id, nm, fp, ldst, fmt, e1, e2, e3                        )
889         #define INST4(id, nm, fp, ldst, fmt, e1, e2, e3, e4                    )
890         #define INST5(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5                )
891         #define INST6(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6            )
892         #define INST8(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8    )
893         #define INST9(id, nm, fp, ldst, fmt, e1, e2, e3, e4, e5, e6, e7, e8, e9) e9,
894         #include "instrs.h"
895     };
896     const static insFormat formatEncode9[9]  = { IF_T1_D0, IF_T1_H,  IF_T1_J0, IF_T1_G,  IF_T2_L0, IF_T2_C0, IF_T1_F,  IF_T1_J2, IF_T1_J3 };
897     const static insFormat formatEncode8[8]  = { IF_T1_H,  IF_T1_C,  IF_T2_E0, IF_T2_H0, IF_T2_K1, IF_T2_K4, IF_T1_J2, IF_T1_J3 };
898     const static insFormat formatEncode6A[6] = { IF_T1_H,  IF_T1_C,  IF_T2_E0, IF_T2_H0, IF_T2_K1, IF_T2_K4};
899     const static insFormat formatEncode6B[6] = { IF_T1_H,  IF_T1_C,  IF_T2_E0, IF_T2_H0, IF_T2_K1, IF_T1_J2 };
900     const static insFormat formatEncode5A[5] = { IF_T1_E,  IF_T1_D0, IF_T1_J0, IF_T2_L1, IF_T2_C3 };
901     const static insFormat formatEncode5B[5] = { IF_T1_E,  IF_T1_D0, IF_T1_J0, IF_T2_L2, IF_T2_C8 };
902     const static insFormat formatEncode4A[4] = { IF_T1_E,  IF_T1_C,  IF_T2_C4, IF_T2_C2 };
903     const static insFormat formatEncode4B[4] = { IF_T2_K2, IF_T2_H2, IF_T2_C7, IF_T2_K3 };
904     const static insFormat formatEncode3A[3] = { IF_T1_E,  IF_T2_C0, IF_T2_L0 };
905     const static insFormat formatEncode3B[3] = { IF_T1_E,  IF_T2_C8, IF_T2_L2 };
906     const static insFormat formatEncode3C[3] = { IF_T1_E,  IF_T2_C1, IF_T2_L1 };
907     const static insFormat formatEncode3D[3] = { IF_T1_L1, IF_T2_E2, IF_T2_I1 };
908     const static insFormat formatEncode3E[3] = { IF_T2_N,  IF_T2_N1, IF_T2_N2 };
909     const static insFormat formatEncode3F[3] = { IF_T1_M,  IF_T2_J2, IF_T2_J3 };
910     const static insFormat formatEncode2A[2] = { IF_T1_K,  IF_T2_J1 };
911     const static insFormat formatEncode2B[2] = { IF_T1_D1, IF_T1_D2 };
912     const static insFormat formatEncode2C[2] = { IF_T1_D2, IF_T2_J3 };
913     const static insFormat formatEncode2D[2] = { IF_T1_J1, IF_T2_I0 };
914     const static insFormat formatEncode2E[2] = { IF_T1_E,  IF_T2_C6 };
915     const static insFormat formatEncode2F[2] = { IF_T1_E,  IF_T2_C5 };
916     const static insFormat formatEncode2G[2] = { IF_T1_J3, IF_T2_M1 };
917     // clang-format on
918
919     code_t    code   = BAD_CODE;
920     insFormat insFmt = emitInsFormat(ins);
921     bool      found  = false;
922     int       index  = 0;
923
924     switch (insFmt)
925     {
926         case IF_EN9:
927             for (index = 0; index < 9; index++)
928             {
929                 if (fmt == formatEncode9[index])
930                 {
931                     found = true;
932                     break;
933                 }
934             }
935             break;
936
937         case IF_EN8:
938             for (index = 0; index < 8; index++)
939             {
940                 if (fmt == formatEncode8[index])
941                 {
942                     found = true;
943                     break;
944                 }
945             }
946             break;
947
948         case IF_EN6A:
949             for (index = 0; index < 6; index++)
950             {
951                 if (fmt == formatEncode6A[index])
952                 {
953                     found = true;
954                     break;
955                 }
956             }
957             break;
958
959         case IF_EN6B:
960             for (index = 0; index < 6; index++)
961             {
962                 if (fmt == formatEncode6B[index])
963                 {
964                     found = true;
965                     break;
966                 }
967             }
968             break;
969
970         case IF_EN5A:
971             for (index = 0; index < 5; index++)
972             {
973                 if (fmt == formatEncode5A[index])
974                 {
975                     found = true;
976                     break;
977                 }
978             }
979             break;
980
981         case IF_EN5B:
982             for (index = 0; index < 5; index++)
983             {
984                 if (fmt == formatEncode5B[index])
985                 {
986                     found = true;
987                     break;
988                 }
989             }
990             break;
991
992         case IF_EN4A:
993             for (index = 0; index < 4; index++)
994             {
995                 if (fmt == formatEncode4A[index])
996                 {
997                     found = true;
998                     break;
999                 }
1000             }
1001             break;
1002
1003         case IF_EN4B:
1004             for (index = 0; index < 4; index++)
1005             {
1006                 if (fmt == formatEncode4B[index])
1007                 {
1008                     found = true;
1009                     break;
1010                 }
1011             }
1012             break;
1013
1014         case IF_EN3A:
1015             for (index = 0; index < 3; index++)
1016             {
1017                 if (fmt == formatEncode3A[index])
1018                 {
1019                     found = true;
1020                     break;
1021                 }
1022             }
1023             break;
1024
1025         case IF_EN3B:
1026             for (index = 0; index < 3; index++)
1027             {
1028                 if (fmt == formatEncode3B[index])
1029                 {
1030                     found = true;
1031                     break;
1032                 }
1033             }
1034             break;
1035         case IF_EN3C:
1036             for (index = 0; index < 3; index++)
1037             {
1038                 if (fmt == formatEncode3C[index])
1039                 {
1040                     found = true;
1041                     break;
1042                 }
1043             }
1044             break;
1045         case IF_EN3D:
1046             for (index = 0; index < 3; index++)
1047             {
1048                 if (fmt == formatEncode3D[index])
1049                 {
1050                     found = true;
1051                     break;
1052                 }
1053             }
1054             break;
1055         case IF_EN3E:
1056             for (index = 0; index < 3; index++)
1057             {
1058                 if (fmt == formatEncode3E[index])
1059                 {
1060                     found = true;
1061                     break;
1062                 }
1063             }
1064             break;
1065         case IF_EN3F:
1066             for (index = 0; index < 3; index++)
1067             {
1068                 if (fmt == formatEncode3F[index])
1069                 {
1070                     found = true;
1071                     break;
1072                 }
1073             }
1074             break;
1075
1076         case IF_EN2A:
1077             for (index = 0; index < 2; index++)
1078             {
1079                 if (fmt == formatEncode2A[index])
1080                 {
1081                     found = true;
1082                     break;
1083                 }
1084             }
1085             break;
1086         case IF_EN2B:
1087             for (index = 0; index < 2; index++)
1088             {
1089                 if (fmt == formatEncode2B[index])
1090                 {
1091                     found = true;
1092                     break;
1093                 }
1094             }
1095             break;
1096         case IF_EN2C:
1097             for (index = 0; index < 2; index++)
1098             {
1099                 if (fmt == formatEncode2C[index])
1100                 {
1101                     found = true;
1102                     break;
1103                 }
1104             }
1105             break;
1106         case IF_EN2D:
1107             for (index = 0; index < 2; index++)
1108             {
1109                 if (fmt == formatEncode2D[index])
1110                 {
1111                     found = true;
1112                     break;
1113                 }
1114             }
1115             break;
1116         case IF_EN2E:
1117             for (index = 0; index < 2; index++)
1118             {
1119                 if (fmt == formatEncode2E[index])
1120                 {
1121                     found = true;
1122                     break;
1123                 }
1124             }
1125             break;
1126         case IF_EN2F:
1127             for (index = 0; index < 2; index++)
1128             {
1129                 if (fmt == formatEncode2F[index])
1130                 {
1131                     found = true;
1132                     break;
1133                 }
1134             }
1135             break;
1136
1137         case IF_EN2G:
1138             for (index = 0; index < 2; index++)
1139             {
1140                 if (fmt == formatEncode2G[index])
1141                 {
1142                     found = true;
1143                     break;
1144                 }
1145             }
1146             break;
1147
1148         default:
1149             index = 0;
1150             found = true;
1151             break;
1152     }
1153
1154     assert(found);
1155
1156     switch (index)
1157     {
1158         case 0:
1159             assert(ins < ArrLen(insCodes1));
1160             code = insCodes1[ins];
1161             break;
1162         case 1:
1163             assert(ins < ArrLen(insCodes2));
1164             code = insCodes2[ins];
1165             break;
1166         case 2:
1167             assert(ins < ArrLen(insCodes3));
1168             code = insCodes3[ins];
1169             break;
1170         case 3:
1171             assert(ins < ArrLen(insCodes4));
1172             code = insCodes4[ins];
1173             break;
1174         case 4:
1175             assert(ins < ArrLen(insCodes5));
1176             code = insCodes5[ins];
1177             break;
1178         case 5:
1179             assert(ins < ArrLen(insCodes6));
1180             code = insCodes6[ins];
1181             break;
1182         case 6:
1183             assert(ins < ArrLen(insCodes7));
1184             code = insCodes7[ins];
1185             break;
1186         case 7:
1187             assert(ins < ArrLen(insCodes8));
1188             code = insCodes8[ins];
1189             break;
1190         case 8:
1191             assert(ins < ArrLen(insCodes9));
1192             code = insCodes9[ins];
1193             break;
1194     }
1195
1196     assert((code != BAD_CODE));
1197
1198     return code;
1199 }
1200
1201 /*****************************************************************************
1202  *
1203  *  Return the code size of the given instruction format. The 'insSize' return type enum
1204  *  indicates a 16 bit, 32 bit, or 48 bit instruction.
1205  */
1206
1207 emitter::insSize emitter::emitInsSize(insFormat insFmt)
1208 {
1209     if ((insFmt >= IF_T1_A) && (insFmt < IF_T2_A))
1210         return ISZ_16BIT;
1211
1212     if ((insFmt >= IF_T2_A) && (insFmt < IF_INVALID))
1213         return ISZ_32BIT;
1214
1215     if (insFmt == IF_LARGEJMP)
1216         return ISZ_48BIT;
1217
1218     assert(!"Invalid insFormat");
1219     return ISZ_48BIT;
1220 }
1221
1222 /*****************************************************************************
1223  *
1224  *  isModImmConst() returns true when immediate 'val32' can be encoded
1225  *   using the special modified immediate constant available in Thumb
1226  */
1227
1228 /*static*/ bool emitter::isModImmConst(int val32)
1229 {
1230     unsigned uval32 = (unsigned)val32;
1231     unsigned imm8   = uval32 & 0xff;
1232
1233     /* encode = 0000x */
1234     if (imm8 == uval32)
1235         return true;
1236
1237     unsigned imm32a = (imm8 << 16) | imm8;
1238     /* encode = 0001x */
1239     if (imm32a == uval32)
1240         return true;
1241
1242     unsigned imm32b = (imm32a << 8);
1243     /* encode = 0010x */
1244     if (imm32b == uval32)
1245         return true;
1246
1247     unsigned imm32c = (imm32a | imm32b);
1248     /* encode = 0011x */
1249     if (imm32c == uval32)
1250         return true;
1251
1252     unsigned mask32 = 0x00000ff;
1253
1254     unsigned encode = 31; /* 11111 */
1255     unsigned temp;
1256
1257     do
1258     {
1259         mask32 <<= 1;
1260         temp = uval32 & ~mask32;
1261         if (temp == 0)
1262             return true;
1263         encode--;
1264     } while (encode >= 8);
1265
1266     return false;
1267 }
1268
1269 /*****************************************************************************
1270  *
1271  *  encodeModImmConst() returns the special ARM 12-bit immediate encoding.
1272  *   that is used to encode the immediate.  (4-bits, 8-bits)
1273  *   If the imm can not be encoded then 0x0BADC0DE is returned.
1274  */
1275
1276 /*static*/ int emitter::encodeModImmConst(int val32)
1277 {
1278     unsigned uval32 = (unsigned)val32;
1279     unsigned imm8   = uval32 & 0xff;
1280     unsigned encode = imm8 >> 7;
1281     unsigned imm32a;
1282     unsigned imm32b;
1283     unsigned imm32c;
1284     unsigned mask32;
1285     unsigned temp;
1286
1287     /* encode = 0000x */
1288     if (imm8 == uval32)
1289     {
1290         goto DONE;
1291     }
1292
1293     imm32a = (imm8 << 16) | imm8;
1294     /* encode = 0001x */
1295     if (imm32a == uval32)
1296     {
1297         encode += 2;
1298         goto DONE;
1299     }
1300
1301     imm32b = (imm32a << 8);
1302     /* encode = 0010x */
1303     if (imm32b == uval32)
1304     {
1305         encode += 4;
1306         goto DONE;
1307     }
1308
1309     imm32c = (imm32a | imm32b);
1310     /* encode = 0011x */
1311     if (imm32c == uval32)
1312     {
1313         encode += 6;
1314         goto DONE;
1315     }
1316
1317     mask32 = 0x00000ff;
1318
1319     encode = 31; /* 11111 */
1320     do
1321     {
1322         mask32 <<= 1;
1323         temp = uval32 & ~mask32;
1324         if (temp == 0)
1325         {
1326             imm8 = (uval32 & mask32) >> (32 - encode);
1327             assert((imm8 & 0x80) != 0);
1328             goto DONE;
1329         }
1330         encode--;
1331     } while (encode >= 8);
1332
1333     assert(!"encodeModImmConst failed!");
1334     return BAD_CODE;
1335
1336 DONE:
1337     unsigned result = (encode << 7) | (imm8 & 0x7f);
1338     assert(result <= 0x0fff);
1339     assert(result >= 0);
1340     return (int)result;
1341 }
1342
1343 /*****************************************************************************
1344  *
1345  *  emitIns_valid_imm_for_alu() returns true when the immediate 'imm'
1346  *   can be encoded using the 12-bit funky Arm immediate encoding
1347  */
1348 /*static*/ bool emitter::emitIns_valid_imm_for_alu(int imm)
1349 {
1350     if (isModImmConst(imm))
1351         return true;
1352     return false;
1353 }
1354
1355 /*****************************************************************************
1356  *
1357  *  emitIns_valid_imm_for_mov() returns true when the immediate 'imm'
1358  *   can be encoded using a single mov or mvn instruction.
1359  */
1360 /*static*/ bool emitter::emitIns_valid_imm_for_mov(int imm)
1361 {
1362     if ((imm & 0x0000ffff) == imm) // 16-bit immediate
1363         return true;
1364     if (isModImmConst(imm)) // funky arm immediate
1365         return true;
1366     if (isModImmConst(~imm)) // funky arm immediate via mvn
1367         return true;
1368     return false;
1369 }
1370
1371 /*****************************************************************************
1372  *
1373  *  emitIns_valid_imm_for_small_mov() returns true when the immediate 'imm'
1374  *   can be encoded using a single 2-byte mov instruction.
1375  */
1376 /*static*/ bool emitter::emitIns_valid_imm_for_small_mov(regNumber reg, int imm, insFlags flags)
1377 {
1378     return isLowRegister(reg) && insSetsFlags(flags) && ((imm & 0x00ff) == imm);
1379 }
1380
1381 /*****************************************************************************
1382  *
1383  *  emitins_valid_imm_for_add() returns true when the immediate 'imm'
1384  *   can be encoded using a single add or sub instruction.
1385  */
1386 /*static*/ bool emitter::emitIns_valid_imm_for_add(int imm, insFlags flags)
1387 {
1388     if ((unsigned_abs(imm) <= 0x00000fff) && (flags != INS_FLAGS_SET)) // 12-bit immediate via add/sub
1389         return true;
1390     if (isModImmConst(imm)) // funky arm immediate
1391         return true;
1392     if (isModImmConst(-imm)) // funky arm immediate via sub
1393         return true;
1394     return false;
1395 }
1396
1397 /*****************************************************************************
1398  *
1399  *  emitins_valid_imm_for_cmp() returns true if this 'imm'
1400  *   can be encoded as a input operand to an cmp instruction.
1401  */
1402 /*static*/ bool emitter::emitIns_valid_imm_for_cmp(int imm, insFlags flags)
1403 {
1404     if (isModImmConst(imm)) // funky arm immediate
1405         return true;
1406     if (isModImmConst(-imm)) // funky arm immediate via sub
1407         return true;
1408     return false;
1409 }
1410
1411 /*****************************************************************************
1412  *
1413  *  emitIns_valid_imm_for_add_sp() returns true when the immediate 'imm'
1414  *   can be encoded in "add Rd,SP,i10".
1415  */
1416 /*static*/ bool emitter::emitIns_valid_imm_for_add_sp(int imm)
1417 {
1418     if ((imm & 0x03fc) == imm)
1419         return true;
1420     return false;
1421 }
1422
1423 /*****************************************************************************
1424  *
1425  *  emitIns_valid_imm_for_ldst_offset() returns true when the immediate 'imm'
1426  *   can be encoded as the offset in a ldr/str instruction.
1427  */
1428 /*static*/ bool emitter::emitIns_valid_imm_for_ldst_offset(int imm, emitAttr size)
1429 {
1430     if ((imm & 0x0fff) == imm)
1431         return true; // encodable using IF_T2_K1
1432     if (unsigned_abs(imm) <= 0x0ff)
1433         return true; // encodable using IF_T2_H0
1434     return false;
1435 }
1436
1437 /*****************************************************************************
1438  *
1439  *  emitIns_valid_imm_for_vldst_offset() returns true when the immediate 'imm'
1440  *   can be encoded as the offset in a vldr/vstr instruction, i.e. when it is
1441  *   a non-negative multiple of 4 that is less than 1024.
1442  */
1443 /*static*/ bool emitter::emitIns_valid_imm_for_vldst_offset(int imm)
1444 {
1445     if ((imm & 0x3fc) == imm)
1446         return true;
1447     return false;
1448 }
1449
1450 /*****************************************************************************
1451  *
1452  *  Add an instruction with no operands.
1453  */
1454
1455 void emitter::emitIns(instruction ins)
1456 {
1457     instrDesc* id  = emitNewInstrSmall(EA_4BYTE);
1458     insFormat  fmt = emitInsFormat(ins);
1459     insSize    isz = emitInsSize(fmt);
1460
1461     assert((fmt == IF_T1_A) || (fmt == IF_T2_A));
1462
1463     id->idIns(ins);
1464     id->idInsFmt(fmt);
1465     id->idInsSize(isz);
1466
1467     dispIns(id);
1468     appendToCurIG(id);
1469 }
1470
1471 /*****************************************************************************
1472  *
1473  *  Add an instruction with a single immediate value.
1474  */
1475
1476 void emitter::emitIns_I(instruction ins, emitAttr attr, ssize_t imm)
1477 {
1478     insFormat fmt    = IF_NONE;
1479     bool      hasLR  = false;
1480     bool      hasPC  = false;
1481     bool      useT2  = false;
1482     bool      onlyT1 = false;
1483
1484     /* Figure out the encoding format of the instruction */
1485     switch (ins)
1486     {
1487 #ifdef FEATURE_ITINSTRUCTION
1488         case INS_it:
1489         case INS_itt:
1490         case INS_ite:
1491         case INS_ittt:
1492         case INS_itte:
1493         case INS_itet:
1494         case INS_itee:
1495         case INS_itttt:
1496         case INS_ittte:
1497         case INS_ittet:
1498         case INS_ittee:
1499         case INS_itett:
1500         case INS_itete:
1501         case INS_iteet:
1502         case INS_iteee:
1503             assert((imm & 0x0F) == imm);
1504             fmt  = IF_T1_B;
1505             attr = EA_4BYTE;
1506             break;
1507 #endif // FEATURE_ITINSTRUCTION
1508
1509         case INS_push:
1510             assert((imm & 0xA000) == 0); // Cannot push PC or SP
1511
1512             if (imm & 0x4000) // Is the LR being pushed?
1513                 hasLR = true;
1514
1515             goto COMMON_PUSH_POP;
1516
1517         case INS_pop:
1518             assert((imm & 0x2000) == 0);      // Cannot pop SP
1519             assert((imm & 0xC000) != 0xC000); // Cannot pop both PC and LR
1520
1521             if (imm & 0x8000) // Is the PC being popped?
1522                 hasPC = true;
1523             if (imm & 0x4000) // Is the LR being popped?
1524             {
1525                 hasLR = true;
1526                 useT2 = true;
1527             }
1528
1529         COMMON_PUSH_POP:
1530
1531             if (((imm - 1) & imm) == 0) // Is only one or zero bits set in imm?
1532             {
1533                 if (((imm == 0) && !hasLR) || // imm has no bits set, but hasLR is set
1534                     (!hasPC && !hasLR))       // imm has one bit set, and neither of hasPC/hasLR are set
1535                 {
1536                     onlyT1 = true; // if only one bit is set we must use the T1 encoding
1537                 }
1538             }
1539
1540             imm &= ~0xE000; // ensure that PC, LR and SP bits are removed from imm
1541
1542             if (((imm & 0x00ff) == imm) && !useT2)
1543             {
1544                 fmt = IF_T1_L1;
1545             }
1546             else if (!onlyT1)
1547             {
1548                 fmt = IF_T2_I1;
1549             }
1550             else
1551             {
1552                 // We have to use the Thumb-2 push single register encoding
1553                 regNumber reg = genRegNumFromMask(imm);
1554                 emitIns_R(ins, attr, reg);
1555                 return;
1556             }
1557
1558             //
1559             // Encode the PC and LR bits as the lowest two bits
1560             //
1561             imm <<= 2;
1562             if (hasPC)
1563                 imm |= 2;
1564             if (hasLR)
1565                 imm |= 1;
1566
1567             assert(imm != 0);
1568
1569             break;
1570
1571 #if 0
1572     // TODO-ARM-Cleanup: Enable or delete.
1573     case INS_bkpt:   // Windows uses a different encoding
1574         if ((imm & 0x0000ffff) == imm)
1575         {
1576             fmt = IF_T1_L0;
1577         }
1578         else
1579         {
1580             assert(!"Instruction cannot be encoded");
1581         }
1582         break;
1583 #endif
1584
1585         case INS_dmb:
1586         case INS_ism:
1587             if ((imm & 0x000f) == imm)
1588             {
1589                 fmt  = IF_T2_B;
1590                 attr = EA_4BYTE;
1591             }
1592             else
1593             {
1594                 assert(!"Instruction cannot be encoded");
1595             }
1596             break;
1597
1598         default:
1599             unreached();
1600     }
1601     assert((fmt == IF_T1_B) || (fmt == IF_T1_L0) || (fmt == IF_T1_L1) || (fmt == IF_T2_I1) || (fmt == IF_T2_B));
1602
1603     instrDesc* id  = emitNewInstrSC(attr, imm);
1604     insSize    isz = emitInsSize(fmt);
1605
1606     id->idIns(ins);
1607     id->idInsFmt(fmt);
1608     id->idInsSize(isz);
1609
1610     dispIns(id);
1611     appendToCurIG(id);
1612 }
1613
1614 /*****************************************************************************
1615  *
1616  *  Add an instruction referencing a single register.
1617  */
1618
1619 void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg)
1620 {
1621     emitAttr  size = EA_SIZE(attr);
1622     insFormat fmt  = IF_NONE;
1623
1624     /* Figure out the encoding format of the instruction */
1625     switch (ins)
1626     {
1627         case INS_pop:
1628         case INS_push:
1629             if (isLowRegister(reg))
1630             {
1631                 int regmask = 1 << ((int)reg);
1632                 emitIns_I(ins, attr, regmask);
1633                 return;
1634             }
1635             assert(size == EA_PTRSIZE);
1636             fmt = IF_T2_E2;
1637             break;
1638
1639         case INS_vmrs:
1640             assert(size == EA_PTRSIZE);
1641             fmt = IF_T2_E2;
1642             break;
1643
1644         case INS_bx:
1645             assert(size == EA_PTRSIZE);
1646             fmt = IF_T1_D1;
1647             break;
1648         case INS_rsb:
1649         case INS_mvn:
1650             emitIns_R_R_I(ins, attr, reg, reg, 0);
1651             return;
1652
1653         default:
1654             unreached();
1655     }
1656     assert((fmt == IF_T1_D1) || (fmt == IF_T2_E2));
1657
1658     instrDesc* id  = emitNewInstrSmall(attr);
1659     insSize    isz = emitInsSize(fmt);
1660
1661     id->idIns(ins);
1662     id->idInsFmt(fmt);
1663     id->idInsSize(isz);
1664     id->idReg1(reg);
1665
1666     dispIns(id);
1667     appendToCurIG(id);
1668 }
1669
1670 /*****************************************************************************
1671  *
1672  *  Add an instruction referencing a register and a constant.
1673  */
1674
1675 void emitter::emitIns_R_I(
1676     instruction ins, emitAttr attr, regNumber reg, ssize_t imm, insFlags flags /* = INS_FLAGS_DONT_CARE */)
1677
1678 {
1679     insFormat fmt = IF_NONE;
1680     insFlags  sf  = INS_FLAGS_DONT_CARE;
1681
1682     /* Figure out the encoding format of the instruction */
1683     switch (ins)
1684     {
1685         case INS_add:
1686         case INS_sub:
1687             if ((reg == REG_SP) && insDoesNotSetFlags(flags) && ((imm & 0x01fc) == imm))
1688             {
1689                 fmt = IF_T1_F;
1690                 sf  = INS_FLAGS_NOT_SET;
1691             }
1692             else if (isLowRegister(reg) && insSetsFlags(flags) && (unsigned_abs(imm) <= 0x00ff))
1693             {
1694                 if (imm < 0)
1695                 {
1696                     assert((ins == INS_add) || (ins == INS_sub));
1697                     if (ins == INS_add)
1698                         ins = INS_sub;
1699                     else // ins == INS_sub
1700                         ins = INS_add;
1701                     imm     = -imm;
1702                 }
1703                 fmt = IF_T1_J0;
1704                 sf  = INS_FLAGS_SET;
1705             }
1706             else
1707             {
1708                 // otherwise we have to use a Thumb-2 encoding
1709                 emitIns_R_R_I(ins, attr, reg, reg, imm, flags);
1710                 return;
1711             }
1712             break;
1713
1714         case INS_adc:
1715             emitIns_R_R_I(ins, attr, reg, reg, imm, flags);
1716             return;
1717
1718         case INS_vpush:
1719         case INS_vpop:
1720             assert(imm > 0);
1721             if (attr == EA_8BYTE)
1722             {
1723                 assert(isDoubleReg(reg));
1724                 assert(imm <= 16);
1725                 imm *= 2;
1726             }
1727             else
1728             {
1729                 assert(attr == EA_4BYTE);
1730                 assert(isFloatReg(reg));
1731                 assert(imm <= 16);
1732             }
1733             assert(((reg - REG_F0) + imm) <= 32);
1734             imm *= 4;
1735
1736             if (ins == INS_vpush)
1737                 imm = -imm;
1738
1739             sf  = INS_FLAGS_NOT_SET;
1740             fmt = IF_T2_VLDST;
1741             break;
1742
1743         case INS_stm:
1744         {
1745             sf = INS_FLAGS_NOT_SET;
1746
1747             bool hasLR  = false;
1748             bool hasPC  = false;
1749             bool useT2  = false;
1750             bool onlyT1 = false;
1751
1752             assert((imm & 0x2000) == 0);      // Cannot pop SP
1753             assert((imm & 0xC000) != 0xC000); // Cannot pop both PC and LR
1754             assert((imm & 0xFFFF0000) == 0);  // Can only contain lower 16 bits
1755
1756             if (imm & 0x8000) // Is the PC being popped?
1757                 hasPC = true;
1758
1759             if (imm & 0x4000) // Is the LR being pushed?
1760             {
1761                 hasLR = true;
1762                 useT2 = true;
1763             }
1764
1765             if (!isLowRegister(reg))
1766                 useT2 = true;
1767
1768             if (((imm - 1) & imm) == 0) // Is only one or zero bits set in imm?
1769             {
1770                 if (((imm == 0) && !hasLR) || // imm has no bits set, but hasLR is set
1771                     (!hasPC && !hasLR))       // imm has one bit set, and neither of hasPC/hasLR are set
1772                 {
1773                     onlyT1 = true; // if only one bit is set we must use the T1 encoding
1774                 }
1775             }
1776
1777             imm &= ~0xE000; // ensure that PC, LR and SP bits are removed from imm
1778
1779             if (((imm & 0x00ff) == imm) && !useT2)
1780             {
1781                 fmt = IF_T1_J1;
1782             }
1783             else if (!onlyT1)
1784             {
1785                 fmt = IF_T2_I0;
1786             }
1787             else
1788             {
1789                 assert(!"Instruction cannot be encoded");
1790                 // We have to use the Thumb-2 str single register encoding
1791                 // reg = genRegNumFromMask(imm);
1792                 // emitIns_R(ins, attr, reg);
1793                 return;
1794             }
1795
1796             //
1797             // Encode the PC and LR bits as the lowest two bits
1798             //
1799             if (fmt == IF_T2_I0)
1800             {
1801                 imm <<= 2;
1802                 if (hasPC)
1803                     imm |= 2;
1804                 if (hasLR)
1805                     imm |= 1;
1806             }
1807             assert(imm != 0);
1808         }
1809         break;
1810
1811         case INS_and:
1812         case INS_bic:
1813         case INS_eor:
1814         case INS_orr:
1815         case INS_orn:
1816         case INS_rsb:
1817         case INS_sbc:
1818
1819         case INS_ror:
1820         case INS_asr:
1821         case INS_lsl:
1822         case INS_lsr:
1823             // use the Reg, Reg, Imm encoding
1824             emitIns_R_R_I(ins, attr, reg, reg, imm, flags);
1825             return;
1826
1827         case INS_mov:
1828             assert(!EA_IS_CNS_RELOC(attr));
1829
1830             if (isLowRegister(reg) && insSetsFlags(flags) && ((imm & 0x00ff) == imm))
1831             {
1832                 fmt = IF_T1_J0;
1833                 sf  = INS_FLAGS_SET;
1834             }
1835             else if (isModImmConst(imm))
1836             {
1837                 fmt = IF_T2_L1;
1838                 sf  = insMustSetFlags(flags);
1839             }
1840             else if (isModImmConst(~imm)) // See if we can use move negated instruction instead
1841             {
1842                 ins = INS_mvn;
1843                 imm = ~imm;
1844                 fmt = IF_T2_L1;
1845                 sf  = insMustSetFlags(flags);
1846             }
1847             else if (insDoesNotSetFlags(flags) && ((imm & 0x0000ffff) == imm))
1848             {
1849                 // mov => movw instruction
1850                 ins = INS_movw;
1851                 fmt = IF_T2_N;
1852                 sf  = INS_FLAGS_NOT_SET;
1853             }
1854             else
1855             {
1856                 assert(!"Instruction cannot be encoded");
1857             }
1858             break;
1859
1860         case INS_movw:
1861         case INS_movt:
1862             assert(insDoesNotSetFlags(flags));
1863             sf = INS_FLAGS_NOT_SET;
1864             if ((imm & 0x0000ffff) == imm || EA_IS_RELOC(attr))
1865             {
1866                 fmt = IF_T2_N;
1867             }
1868             else
1869             {
1870                 assert(!"Instruction cannot be encoded");
1871             }
1872             break;
1873
1874         case INS_mvn:
1875             if (isModImmConst(imm))
1876             {
1877                 fmt = IF_T2_L1;
1878                 sf  = insMustSetFlags(flags);
1879             }
1880             else
1881             {
1882                 assert(!"Instruction cannot be encoded");
1883             }
1884             break;
1885
1886         case INS_cmp:
1887             assert(!EA_IS_CNS_RELOC(attr));
1888             assert(insSetsFlags(flags));
1889             sf = INS_FLAGS_SET;
1890             if (isLowRegister(reg) && ((imm & 0x0ff) == imm))
1891             {
1892                 fmt = IF_T1_J0;
1893             }
1894             else if (isModImmConst(imm))
1895             {
1896                 fmt = IF_T2_L2;
1897             }
1898             else if (isModImmConst(-imm))
1899             {
1900                 ins = INS_cmn;
1901                 fmt = IF_T2_L2;
1902                 imm = -imm;
1903             }
1904             else
1905             {
1906 #ifndef LEGACY_BACKEND
1907                 assert(!"emitIns_R_I: immediate doesn't fit into the instruction");
1908 #else  // LEGACY_BACKEND
1909                 // Load val into a register
1910                 regNumber valReg = codeGen->regSet.rsGrabReg(RBM_ALLINT & ~genRegMask(reg));
1911                 codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, valReg, (ssize_t)imm);
1912                 emitIns_R_R(ins, attr, reg, valReg, flags);
1913 #endif // LEGACY_BACKEND
1914                 return;
1915             }
1916             break;
1917
1918         case INS_cmn:
1919         case INS_tst:
1920         case INS_teq:
1921             assert(insSetsFlags(flags));
1922             sf = INS_FLAGS_SET;
1923             if (isModImmConst(imm))
1924             {
1925                 fmt = IF_T2_L2;
1926             }
1927             else
1928             {
1929                 assert(!"Instruction cannot be encoded");
1930             }
1931             break;
1932
1933 #ifdef FEATURE_PLI_INSTRUCTION
1934         case INS_pli:
1935             assert(insDoesNotSetFlags(flags));
1936             if ((reg == REG_SP) && (unsigned_abs(imm) <= 0x0fff))
1937             {
1938                 fmt = IF_T2_K3;
1939                 sf  = INS_FLAGS_NOT_SET;
1940             }
1941             __fallthrough;
1942 #endif // FEATURE_PLI_INSTRUCTION
1943
1944         case INS_pld:
1945         case INS_pldw:
1946             assert(insDoesNotSetFlags(flags));
1947             sf = INS_FLAGS_NOT_SET;
1948             if ((imm >= 0) && (imm <= 0x0fff))
1949             {
1950                 fmt = IF_T2_K2;
1951             }
1952             else if ((imm < 0) && (-imm <= 0x00ff))
1953             {
1954                 imm = -imm;
1955                 fmt = IF_T2_H2;
1956             }
1957             else
1958             {
1959                 assert(!"Instruction cannot be encoded");
1960             }
1961             break;
1962
1963         default:
1964             unreached();
1965     }
1966     assert((fmt == IF_T1_F) || (fmt == IF_T1_J0) || (fmt == IF_T1_J1) || (fmt == IF_T2_H2) || (fmt == IF_T2_I0) ||
1967            (fmt == IF_T2_K2) || (fmt == IF_T2_K3) || (fmt == IF_T2_L1) || (fmt == IF_T2_L2) || (fmt == IF_T2_M1) ||
1968            (fmt == IF_T2_N) || (fmt == IF_T2_VLDST));
1969
1970     assert(sf != INS_FLAGS_DONT_CARE);
1971
1972     instrDesc* id  = emitNewInstrSC(attr, imm);
1973     insSize    isz = emitInsSize(fmt);
1974
1975     id->idIns(ins);
1976     id->idInsFmt(fmt);
1977     id->idInsSize(isz);
1978     id->idInsFlags(sf);
1979     id->idReg1(reg);
1980
1981     dispIns(id);
1982     appendToCurIG(id);
1983 }
1984
1985 /*****************************************************************************
1986  *
1987  *  Add an instruction referencing two registers
1988  */
1989
1990 void emitter::emitIns_R_R(
1991     instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, insFlags flags /* = INS_FLAGS_DONT_CARE */)
1992
1993 {
1994     emitAttr  size = EA_SIZE(attr);
1995     insFormat fmt  = IF_NONE;
1996     insFlags  sf   = INS_FLAGS_DONT_CARE;
1997
1998     /* Figure out the encoding format of the instruction */
1999     switch (ins)
2000     {
2001         case INS_add:
2002             if (insDoesNotSetFlags(flags))
2003             {
2004                 fmt = IF_T1_D0;
2005                 sf  = INS_FLAGS_NOT_SET;
2006                 break;
2007             }
2008             __fallthrough;
2009
2010         case INS_sub:
2011             // Use the Thumb-1 reg,reg,reg encoding
2012             emitIns_R_R_R(ins, attr, reg1, reg1, reg2, flags);
2013             return;
2014
2015         case INS_mov:
2016             if (insDoesNotSetFlags(flags))
2017             {
2018                 assert(reg1 != reg2);
2019                 fmt = IF_T1_D0;
2020                 sf  = INS_FLAGS_NOT_SET;
2021             }
2022             else // insSetsFlags(flags)
2023             {
2024                 sf = INS_FLAGS_SET;
2025                 if (isLowRegister(reg1) && isLowRegister(reg2))
2026                 {
2027                     fmt = IF_T1_E;
2028                 }
2029                 else
2030                 {
2031                     fmt = IF_T2_C3;
2032                 }
2033             }
2034             break;
2035
2036         case INS_cmp:
2037             assert(insSetsFlags(flags));
2038             sf = INS_FLAGS_SET;
2039             if (isLowRegister(reg1) && isLowRegister(reg2))
2040             {
2041                 fmt = IF_T1_E; // both are low registers
2042             }
2043             else
2044             {
2045                 fmt = IF_T1_D0; // one or both are high registers
2046             }
2047             break;
2048
2049         case INS_vmov_f2i:
2050             assert(isGeneralRegister(reg1));
2051             assert(isFloatReg(reg2));
2052             fmt = IF_T2_VMOVS;
2053             sf  = INS_FLAGS_NOT_SET;
2054             break;
2055
2056         case INS_vmov_i2f:
2057             assert(isFloatReg(reg1));
2058             assert(isGeneralRegister(reg2));
2059             fmt = IF_T2_VMOVS;
2060             sf  = INS_FLAGS_NOT_SET;
2061             break;
2062
2063         case INS_vcvt_d2i:
2064         case INS_vcvt_d2u:
2065         case INS_vcvt_d2f:
2066             assert(isFloatReg(reg1));
2067             assert(isDoubleReg(reg2));
2068             goto VCVT_COMMON;
2069
2070         case INS_vcvt_f2d:
2071         case INS_vcvt_u2d:
2072         case INS_vcvt_i2d:
2073             assert(isDoubleReg(reg1));
2074             assert(isFloatReg(reg2));
2075             goto VCVT_COMMON;
2076
2077         case INS_vcvt_u2f:
2078         case INS_vcvt_i2f:
2079         case INS_vcvt_f2i:
2080         case INS_vcvt_f2u:
2081             assert(size == EA_4BYTE);
2082             assert(isFloatReg(reg1));
2083             assert(isFloatReg(reg2));
2084             goto VCVT_COMMON;
2085
2086         case INS_vmov:
2087             assert(reg1 != reg2);
2088             __fallthrough;
2089
2090         case INS_vabs:
2091         case INS_vsqrt:
2092         case INS_vcmp:
2093         case INS_vneg:
2094             if (size == EA_8BYTE)
2095             {
2096                 assert(isDoubleReg(reg1));
2097                 assert(isDoubleReg(reg2));
2098             }
2099             else
2100             {
2101                 assert(isFloatReg(reg1));
2102                 assert(isFloatReg(reg2));
2103             }
2104             __fallthrough;
2105
2106         VCVT_COMMON:
2107             fmt = IF_T2_VFP2;
2108             sf  = INS_FLAGS_NOT_SET;
2109             break;
2110
2111         case INS_vadd:
2112         case INS_vmul:
2113         case INS_vsub:
2114         case INS_vdiv:
2115             emitIns_R_R_R(ins, attr, reg1, reg1, reg2);
2116             return;
2117
2118         case INS_vldr:
2119         case INS_vstr:
2120         case INS_ldr:
2121         case INS_ldrb:
2122         case INS_ldrsb:
2123         case INS_ldrh:
2124         case INS_ldrsh:
2125
2126         case INS_str:
2127         case INS_strb:
2128         case INS_strh:
2129             emitIns_R_R_I(ins, attr, reg1, reg2, 0);
2130             return;
2131
2132         case INS_adc:
2133         case INS_and:
2134         case INS_bic:
2135         case INS_eor:
2136         case INS_orr:
2137         case INS_sbc:
2138             if (insSetsFlags(flags) && isLowRegister(reg1) && isLowRegister(reg2))
2139             {
2140                 fmt = IF_T1_E;
2141                 sf  = INS_FLAGS_SET;
2142                 break;
2143             }
2144             __fallthrough;
2145
2146         case INS_orn:
2147             // assert below fired for bug 281892 where the two operands of an OR were
2148             // the same static field load which got cse'd.
2149             // there's no reason why this assert would be true in general
2150             // assert(reg1 != reg2);
2151             // Use the Thumb-2 three register encoding
2152             emitIns_R_R_R_I(ins, attr, reg1, reg1, reg2, 0, flags);
2153             return;
2154
2155         case INS_asr:
2156         case INS_lsl:
2157         case INS_lsr:
2158         case INS_ror:
2159             // assert below fired for bug 296394 where the two operands of an
2160             // arithmetic right shift were the same local variable
2161             // there's no reason why this assert would be true in general
2162             // assert(reg1 != reg2);
2163             if (insSetsFlags(flags) && isLowRegister(reg1) && isLowRegister(reg2))
2164             {
2165                 fmt = IF_T1_E;
2166                 sf  = INS_FLAGS_SET;
2167             }
2168             else
2169             {
2170                 // Use the Thumb-2 three register encoding
2171                 emitIns_R_R_R(ins, attr, reg1, reg1, reg2, flags);
2172                 return;
2173             }
2174             break;
2175
2176         case INS_mul:
2177             // We will prefer the T2 encoding, unless (flags == INS_FLAGS_SET)
2178             // The thumb-1 instruction executes much slower as it must always set the flags
2179             //
2180             if (insMustSetFlags(flags) && isLowRegister(reg1) && isLowRegister(reg2))
2181             {
2182                 fmt = IF_T1_E;
2183                 sf  = INS_FLAGS_SET;
2184             }
2185             else
2186             {
2187                 // Use the Thumb-2 three register encoding
2188                 emitIns_R_R_R(ins, attr, reg1, reg2, reg1, flags);
2189                 return;
2190             }
2191             break;
2192
2193         case INS_mvn:
2194         case INS_cmn:
2195         case INS_tst:
2196             if (insSetsFlags(flags) && isLowRegister(reg1) && isLowRegister(reg2))
2197             {
2198                 fmt = IF_T1_E;
2199                 sf  = INS_FLAGS_SET;
2200             }
2201             else
2202             {
2203                 // Use the Thumb-2 register with shift encoding
2204                 emitIns_R_R_I(ins, attr, reg1, reg2, 0, flags);
2205                 return;
2206             }
2207             break;
2208
2209         case INS_sxtb:
2210         case INS_uxtb:
2211             assert(size == EA_1BYTE);
2212             goto EXTEND_COMMON;
2213
2214         case INS_sxth:
2215         case INS_uxth:
2216             assert(size == EA_2BYTE);
2217         EXTEND_COMMON:
2218             assert(insDoesNotSetFlags(flags));
2219             if (isLowRegister(reg1) && isLowRegister(reg2))
2220             {
2221                 fmt = IF_T1_E;
2222                 sf  = INS_FLAGS_NOT_SET;
2223             }
2224             else
2225             {
2226                 // Use the Thumb-2 reg,reg with rotation encoding
2227                 emitIns_R_R_I(ins, attr, reg1, reg2, 0, INS_FLAGS_NOT_SET);
2228                 return;
2229             }
2230             break;
2231
2232         case INS_tbb:
2233             assert(size == EA_1BYTE);
2234             assert(insDoesNotSetFlags(flags));
2235             fmt = IF_T2_C9;
2236             sf  = INS_FLAGS_NOT_SET;
2237             break;
2238
2239         case INS_tbh:
2240             assert(size == EA_2BYTE);
2241             assert(insDoesNotSetFlags(flags));
2242             fmt = IF_T2_C9;
2243             sf  = INS_FLAGS_NOT_SET;
2244             break;
2245
2246         case INS_clz:
2247             assert(insDoesNotSetFlags(flags));
2248             fmt = IF_T2_C10;
2249             sf  = INS_FLAGS_NOT_SET;
2250             break;
2251
2252         case INS_ldrexb:
2253         case INS_strexb:
2254             assert(size == EA_1BYTE);
2255             assert(insDoesNotSetFlags(flags));
2256             fmt = IF_T2_E1;
2257             sf  = INS_FLAGS_NOT_SET;
2258             break;
2259
2260         case INS_ldrexh:
2261         case INS_strexh:
2262             assert(size == EA_2BYTE);
2263             assert(insDoesNotSetFlags(flags));
2264             fmt = IF_T2_E1;
2265             sf  = INS_FLAGS_NOT_SET;
2266             break;
2267         default:
2268 #ifdef DEBUG
2269             printf("did not expect instruction %s\n", codeGen->genInsName(ins));
2270 #endif
2271             unreached();
2272     }
2273
2274     assert((fmt == IF_T1_D0) || (fmt == IF_T1_E) || (fmt == IF_T2_C3) || (fmt == IF_T2_C9) || (fmt == IF_T2_C10) ||
2275            (fmt == IF_T2_VFP2) || (fmt == IF_T2_VMOVD) || (fmt == IF_T2_VMOVS) || (fmt == IF_T2_E1));
2276
2277     assert(sf != INS_FLAGS_DONT_CARE);
2278
2279     instrDesc* id  = emitNewInstrSmall(attr);
2280     insSize    isz = emitInsSize(fmt);
2281
2282     id->idIns(ins);
2283     id->idInsFmt(fmt);
2284     id->idInsSize(isz);
2285     id->idInsFlags(sf);
2286     id->idReg1(reg1);
2287     id->idReg2(reg2);
2288
2289     dispIns(id);
2290     appendToCurIG(id);
2291 }
2292
2293 /*****************************************************************************
2294  *
2295  *  Add an instruction referencing a register and two constants.
2296  */
2297
2298 void emitter::emitIns_R_I_I(
2299     instruction ins, emitAttr attr, regNumber reg, int imm1, int imm2, insFlags flags /* = INS_FLAGS_DONT_CARE */)
2300
2301 {
2302     insFormat fmt = IF_NONE;
2303     insFlags  sf  = INS_FLAGS_DONT_CARE;
2304     int       imm = 0; // combined immediates
2305
2306     /* Figure out the encoding format of the instruction */
2307     switch (ins)
2308     {
2309         case INS_bfc:
2310         {
2311             int lsb = imm1;
2312             int msb = lsb + imm2 - 1;
2313
2314             assert((lsb >= 0) && (lsb <= 31)); // required for encoding of INS_bfc
2315             assert((msb >= 0) && (msb <= 31)); // required for encoding of INS_bfc
2316             assert(msb >= lsb);                // required for encoding of INS_bfc
2317
2318             imm = (lsb << 5) | msb;
2319
2320             assert(insDoesNotSetFlags(flags));
2321             fmt = IF_T2_D1;
2322             sf  = INS_FLAGS_NOT_SET;
2323         }
2324         break;
2325
2326         default:
2327             unreached();
2328     }
2329     assert(fmt == IF_T2_D1);
2330     assert(sf != INS_FLAGS_DONT_CARE);
2331
2332     instrDesc* id  = emitNewInstrSC(attr, imm);
2333     insSize    isz = emitInsSize(fmt);
2334
2335     id->idIns(ins);
2336     id->idInsFmt(fmt);
2337     id->idInsSize(isz);
2338     id->idInsFlags(sf);
2339     id->idReg1(reg);
2340
2341     dispIns(id);
2342     appendToCurIG(id);
2343 }
2344
2345 /*****************************************************************************
2346  *
2347  *  Add an instruction referencing two registers and a constant.
2348  */
2349
2350 void emitter::emitIns_R_R_I(instruction ins,
2351                             emitAttr    attr,
2352                             regNumber   reg1,
2353                             regNumber   reg2,
2354                             int         imm,
2355                             insFlags    flags /* = INS_FLAGS_DONT_CARE */,
2356                             insOpts     opt /* = INS_OPTS_NONE */)
2357 {
2358     emitAttr  size = EA_SIZE(attr);
2359     insFormat fmt  = IF_NONE;
2360     insFlags  sf   = INS_FLAGS_DONT_CARE;
2361
2362     if (ins == INS_lea)
2363     {
2364         ins = INS_add;
2365     }
2366
2367     /* Figure out the encoding format of the instruction */
2368     switch (ins)
2369     {
2370         case INS_add:
2371             assert(insOptsNone(opt));
2372
2373             // Can we possibly encode the immediate 'imm' using a Thumb-1 encoding?
2374             if ((reg2 == REG_SP) && insDoesNotSetFlags(flags) && ((imm & 0x03fc) == imm))
2375             {
2376                 if ((reg1 == REG_SP) && ((imm & 0x01fc) == imm))
2377                 {
2378                     // Use Thumb-1 encoding
2379                     emitIns_R_I(ins, attr, reg1, imm, flags);
2380                     return;
2381                 }
2382                 else if (isLowRegister(reg1))
2383                 {
2384                     fmt = IF_T1_J2;
2385                     sf  = INS_FLAGS_NOT_SET;
2386                     break;
2387                 }
2388             }
2389             __fallthrough;
2390
2391         case INS_sub:
2392             assert(insOptsNone(opt));
2393
2394             // Is it just a mov?
2395             if ((imm == 0) && insDoesNotSetFlags(flags))
2396             {
2397                 // Is the mov even necessary?
2398                 // Fix 383915 ARM ILGEN
2399                 if (reg1 != reg2)
2400                 {
2401                     emitIns_R_R(INS_mov, attr, reg1, reg2, flags);
2402                 }
2403                 return;
2404             }
2405             // Can we encode the immediate 'imm' using a Thumb-1 encoding?
2406             else if (isLowRegister(reg1) && isLowRegister(reg2) && insSetsFlags(flags) && (unsigned_abs(imm) <= 0x0007))
2407             {
2408                 if (imm < 0)
2409                 {
2410                     assert((ins == INS_add) || (ins == INS_sub));
2411                     if (ins == INS_add)
2412                         ins = INS_sub;
2413                     else
2414                         ins = INS_add;
2415                     imm     = -imm;
2416                 }
2417                 fmt = IF_T1_G;
2418                 sf  = INS_FLAGS_SET;
2419             }
2420             else if ((reg1 == reg2) && isLowRegister(reg1) && insSetsFlags(flags) && (unsigned_abs(imm) <= 0x00ff))
2421             {
2422                 if (imm < 0)
2423                 {
2424                     assert((ins == INS_add) || (ins == INS_sub));
2425                     if (ins == INS_add)
2426                         ins = INS_sub;
2427                     else
2428                         ins = INS_add;
2429                     imm     = -imm;
2430                 }
2431                 // Use Thumb-1 encoding
2432                 emitIns_R_I(ins, attr, reg1, imm, flags);
2433                 return;
2434             }
2435             else if (isModImmConst(imm))
2436             {
2437                 fmt = IF_T2_L0;
2438                 sf  = insMustSetFlags(flags);
2439             }
2440             else if (isModImmConst(-imm))
2441             {
2442                 assert((ins == INS_add) || (ins == INS_sub));
2443                 ins = (ins == INS_add) ? INS_sub : INS_add;
2444                 imm = -imm;
2445                 fmt = IF_T2_L0;
2446                 sf  = insMustSetFlags(flags);
2447             }
2448             else if (insDoesNotSetFlags(flags) && (unsigned_abs(imm) <= 0x0fff))
2449             {
2450                 if (imm < 0)
2451                 {
2452                     assert((ins == INS_add) || (ins == INS_sub));
2453                     ins = (ins == INS_add) ? INS_sub : INS_add;
2454                     imm = -imm;
2455                 }
2456                 // add/sub => addw/subw instruction
2457                 // Note that even when using the w prefix the immediate is still only 12 bits?
2458                 ins = (ins == INS_add) ? INS_addw : INS_subw;
2459                 fmt = IF_T2_M0;
2460                 sf  = INS_FLAGS_NOT_SET;
2461             }
2462             else if (insDoesNotSetFlags(flags) && (reg1 != REG_SP) && (reg1 != REG_PC))
2463             {
2464                 // movw,movt reg1, imm
2465                 codeGen->instGen_Set_Reg_To_Imm(attr, reg1, (ins == INS_sub ? -1 : 1) * imm);
2466
2467                 // ins reg1, reg2
2468                 emitIns_R_R(INS_add, attr, reg1, reg2);
2469
2470                 return;
2471             }
2472             else
2473             {
2474                 assert(!"Instruction cannot be encoded");
2475             }
2476             break;
2477
2478         case INS_and:
2479         case INS_bic:
2480         case INS_orr:
2481         case INS_orn:
2482             assert(insOptsNone(opt));
2483             if (isModImmConst(imm))
2484             {
2485                 fmt = IF_T2_L0;
2486                 sf  = insMustSetFlags(flags);
2487             }
2488             else if (isModImmConst(~imm))
2489             {
2490                 fmt = IF_T2_L0;
2491                 sf  = insMustSetFlags(flags);
2492                 imm = ~imm;
2493
2494                 if (ins == INS_and)
2495                     ins = INS_bic;
2496                 else if (ins == INS_bic)
2497                     ins = INS_and;
2498                 else if (ins == INS_orr)
2499                     ins = INS_orn;
2500                 else if (ins == INS_orn)
2501                     ins = INS_orr;
2502                 else
2503                     assert(!"Instruction cannot be encoded");
2504             }
2505             else
2506             {
2507                 assert(!"Instruction cannot be encoded");
2508             }
2509             break;
2510
2511         case INS_rsb:
2512             assert(insOptsNone(opt));
2513             if (imm == 0 && isLowRegister(reg1) && isLowRegister(reg2) && insSetsFlags(flags))
2514             {
2515                 fmt = IF_T1_E;
2516                 sf  = INS_FLAGS_SET;
2517                 break;
2518             }
2519             __fallthrough;
2520
2521         case INS_adc:
2522         case INS_eor:
2523         case INS_sbc:
2524             assert(insOptsNone(opt));
2525             if (isModImmConst(imm))
2526             {
2527                 fmt = IF_T2_L0;
2528                 sf  = insMustSetFlags(flags);
2529             }
2530             else
2531             {
2532                 assert(!"Instruction cannot be encoded");
2533             }
2534             break;
2535
2536         case INS_adr:
2537             assert(insOptsNone(opt));
2538             assert(insDoesNotSetFlags(flags));
2539             assert(reg2 == REG_PC);
2540             sf = INS_FLAGS_NOT_SET;
2541
2542             if (isLowRegister(reg1) && ((imm & 0x00ff) == imm))
2543             {
2544                 fmt = IF_T1_J3;
2545             }
2546             else if ((imm & 0x0fff) == imm)
2547             {
2548                 fmt = IF_T2_M1;
2549             }
2550             else
2551             {
2552                 assert(!"Instruction cannot be encoded");
2553             }
2554             break;
2555
2556         case INS_mvn:
2557             assert((imm >= 0) && (imm <= 31)); // required for encoding
2558             assert(!insOptAnyInc(opt));
2559             if (imm == 0)
2560             {
2561                 assert(insOptsNone(opt));
2562                 if (isLowRegister(reg1) && isLowRegister(reg2) && insSetsFlags(flags))
2563                 {
2564                     // Use the Thumb-1 reg,reg encoding
2565                     emitIns_R_R(ins, attr, reg1, reg2, flags);
2566                     return;
2567                 }
2568             }
2569             else // imm > 0  &&  imm <= 31
2570             {
2571                 assert(insOptAnyShift(opt));
2572             }
2573             fmt = IF_T2_C1;
2574             sf  = insMustSetFlags(flags);
2575             break;
2576
2577         case INS_cmp:
2578         case INS_cmn:
2579         case INS_teq:
2580         case INS_tst:
2581             assert(insSetsFlags(flags));
2582             assert((imm >= 0) && (imm <= 31)); // required for encoding
2583             assert(!insOptAnyInc(opt));
2584             if (imm == 0)
2585             {
2586                 assert(insOptsNone(opt));
2587                 if (ins == INS_cmp)
2588                 {
2589                     // Use the Thumb-1 reg,reg encoding
2590                     emitIns_R_R(ins, attr, reg1, reg2, flags);
2591                     return;
2592                 }
2593                 if (((ins == INS_cmn) || (ins == INS_tst)) && isLowRegister(reg1) && isLowRegister(reg2))
2594                 {
2595                     // Use the Thumb-1 reg,reg encoding
2596                     emitIns_R_R(ins, attr, reg1, reg2, flags);
2597                     return;
2598                 }
2599             }
2600             else // imm > 0  &&  imm <= 31)
2601             {
2602                 assert(insOptAnyShift(opt));
2603                 if (insOptsRRX(opt))
2604                     assert(imm == 1);
2605             }
2606
2607             fmt = IF_T2_C8;
2608             sf  = INS_FLAGS_SET;
2609             break;
2610
2611         case INS_ror:
2612         case INS_asr:
2613         case INS_lsl:
2614         case INS_lsr:
2615             assert(insOptsNone(opt));
2616
2617             // On ARM, the immediate shift count of LSL and ROR must be between 1 and 31. For LSR and ASR, it is between
2618             // 1 and 32, though we don't ever use 32. Although x86 allows an immediate shift count of 8-bits in
2619             // instruction encoding, the CPU looks at only the lower 5 bits. As per ECMA, specifying a shift count to
2620             // the IL SHR, SHL, or SHL.UN instruction that is greater than or equal to the width of the type will yield
2621             // an undefined value. We choose that undefined value in this case to match x86 behavior, by only using the
2622             // lower 5 bits of the constant shift count.
2623             imm &= 0x1f;
2624
2625             if (imm == 0)
2626             {
2627                 // Additional Fix 383915 ARM ILGEN
2628                 if ((reg1 != reg2) || insMustSetFlags(flags))
2629                 {
2630                     // Use MOV/MOVS instriction
2631                     emitIns_R_R(INS_mov, attr, reg1, reg2, flags);
2632                 }
2633                 return;
2634             }
2635
2636             if (insSetsFlags(flags) && (ins != INS_ror) && isLowRegister(reg1) && isLowRegister(reg2))
2637             {
2638                 fmt = IF_T1_C;
2639                 sf  = INS_FLAGS_SET;
2640             }
2641             else
2642             {
2643                 fmt = IF_T2_C2;
2644                 sf  = insMustSetFlags(flags);
2645             }
2646             break;
2647
2648         case INS_sxtb:
2649         case INS_uxtb:
2650             assert(size == EA_1BYTE);
2651             goto EXTEND_COMMON;
2652
2653         case INS_sxth:
2654         case INS_uxth:
2655             assert(size == EA_2BYTE);
2656         EXTEND_COMMON:
2657             assert(insOptsNone(opt));
2658             assert(insDoesNotSetFlags(flags));
2659             assert((imm & 0x018) == imm); // required for encoding
2660
2661             if ((imm == 0) && isLowRegister(reg1) && isLowRegister(reg2))
2662             {
2663                 // Use Thumb-1 encoding
2664                 emitIns_R_R(ins, attr, reg1, reg2, INS_FLAGS_NOT_SET);
2665                 return;
2666             }
2667
2668             fmt = IF_T2_C6;
2669             sf  = INS_FLAGS_NOT_SET;
2670             break;
2671
2672         case INS_pld:
2673         case INS_pldw:
2674 #ifdef FEATURE_PLI_INSTRUCTION
2675         case INS_pli:
2676 #endif // FEATURE_PLI_INSTRUCTION
2677             assert(insOptsNone(opt));
2678             assert(insDoesNotSetFlags(flags));
2679             assert((imm & 0x003) == imm); // required for encoding
2680
2681             fmt = IF_T2_C7;
2682             sf  = INS_FLAGS_NOT_SET;
2683             break;
2684
2685         case INS_ldrb:
2686         case INS_strb:
2687             assert(size == EA_1BYTE);
2688             assert(insDoesNotSetFlags(flags));
2689
2690             if (isLowRegister(reg1) && isLowRegister(reg2) && insOptsNone(opt) && ((imm & 0x001f) == imm))
2691             {
2692                 fmt = IF_T1_C;
2693                 sf  = INS_FLAGS_NOT_SET;
2694                 break;
2695             }
2696             goto COMMON_THUMB2_LDST;
2697
2698         case INS_ldrsb:
2699             assert(size == EA_1BYTE);
2700             goto COMMON_THUMB2_LDST;
2701
2702         case INS_ldrh:
2703         case INS_strh:
2704             assert(size == EA_2BYTE);
2705             assert(insDoesNotSetFlags(flags));
2706
2707             if (isLowRegister(reg1) && isLowRegister(reg2) && insOptsNone(opt) && ((imm & 0x003e) == imm))
2708             {
2709                 fmt = IF_T1_C;
2710                 sf  = INS_FLAGS_NOT_SET;
2711                 break;
2712             }
2713             goto COMMON_THUMB2_LDST;
2714
2715         case INS_ldrsh:
2716             assert(size == EA_2BYTE);
2717             goto COMMON_THUMB2_LDST;
2718
2719         case INS_vldr:
2720         case INS_vstr:
2721         case INS_vldm:
2722         case INS_vstm:
2723             assert(fmt == IF_NONE);
2724             assert(insDoesNotSetFlags(flags));
2725             assert(offsetFitsInVectorMem(imm)); // required for encoding
2726             if (insOptAnyInc(opt))
2727             {
2728                 if (insOptsPostInc(opt))
2729                 {
2730                     assert(imm > 0);
2731                 }
2732                 else // insOptsPreDec(opt)
2733                 {
2734                     assert(imm < 0);
2735                 }
2736             }
2737             else
2738             {
2739                 assert(insOptsNone(opt));
2740             }
2741
2742             sf  = INS_FLAGS_NOT_SET;
2743             fmt = IF_T2_VLDST;
2744             break;
2745
2746         case INS_ldr:
2747         case INS_str:
2748             assert(size == EA_4BYTE);
2749             assert(insDoesNotSetFlags(flags));
2750
2751             // Can we possibly encode the immediate 'imm' using a Thumb-1 encoding?
2752             if (isLowRegister(reg1) && insOptsNone(opt) && ((imm & 0x03fc) == imm))
2753             {
2754                 if (reg2 == REG_SP)
2755                 {
2756                     fmt = IF_T1_J2;
2757                     sf  = INS_FLAGS_NOT_SET;
2758                     break;
2759                 }
2760                 else if (reg2 == REG_PC)
2761                 {
2762                     if (ins == INS_ldr)
2763                     {
2764                         fmt = IF_T1_J3;
2765                         sf  = INS_FLAGS_NOT_SET;
2766                         break;
2767                     }
2768                 }
2769                 else if (isLowRegister(reg2))
2770                 {
2771                     // Only the smaller range 'imm' can be encoded
2772                     if ((imm & 0x07c) == imm)
2773                     {
2774                         fmt = IF_T1_C;
2775                         sf  = INS_FLAGS_NOT_SET;
2776                         break;
2777                     }
2778                 }
2779             }
2780             //
2781             // If we did not find a thumb-1 encoding above
2782             //
2783             __fallthrough;
2784
2785         COMMON_THUMB2_LDST:
2786             assert(fmt == IF_NONE);
2787             assert(insDoesNotSetFlags(flags));
2788             sf = INS_FLAGS_NOT_SET;
2789
2790             if (insOptAnyInc(opt))
2791             {
2792                 if (insOptsPostInc(opt))
2793                     assert(imm > 0);
2794                 else // insOptsPreDec(opt)
2795                     assert(imm < 0);
2796
2797                 if (unsigned_abs(imm) <= 0x00ff)
2798                 {
2799                     fmt = IF_T2_H0;
2800                 }
2801                 else
2802                 {
2803                     assert(!"Instruction cannot be encoded");
2804                 }
2805             }
2806             else
2807             {
2808                 assert(insOptsNone(opt));
2809                 if ((reg2 == REG_PC) && (unsigned_abs(imm) <= 0x0fff))
2810                 {
2811                     fmt = IF_T2_K4;
2812                 }
2813                 else if ((imm & 0x0fff) == imm)
2814                 {
2815                     fmt = IF_T2_K1;
2816                 }
2817                 else if (unsigned_abs(imm) <= 0x0ff)
2818                 {
2819                     fmt = IF_T2_H0;
2820                 }
2821                 else
2822                 {
2823                     // Load imm into a register
2824                     regNumber rsvdReg = codeGen->rsGetRsvdReg();
2825                     codeGen->instGen_Set_Reg_To_Imm(EA_4BYTE, rsvdReg, (ssize_t)imm);
2826                     emitIns_R_R_R(ins, attr, reg1, reg2, rsvdReg);
2827                     return;
2828                 }
2829             }
2830             break;
2831
2832         case INS_ldrex:
2833         case INS_strex:
2834             assert(insOptsNone(opt));
2835             assert(insDoesNotSetFlags(flags));
2836             sf = INS_FLAGS_NOT_SET;
2837
2838             if ((imm & 0x03fc) == imm)
2839             {
2840                 fmt = IF_T2_H0;
2841             }
2842             else
2843             {
2844                 assert(!"Instruction cannot be encoded");
2845             }
2846             break;
2847
2848         default:
2849             assert(!"Unexpected instruction");
2850     }
2851     assert((fmt == IF_T1_C) || (fmt == IF_T1_E) || (fmt == IF_T1_G) || (fmt == IF_T1_J2) || (fmt == IF_T1_J3) ||
2852            (fmt == IF_T2_C1) || (fmt == IF_T2_C2) || (fmt == IF_T2_C6) || (fmt == IF_T2_C7) || (fmt == IF_T2_C8) ||
2853            (fmt == IF_T2_H0) || (fmt == IF_T2_H1) || (fmt == IF_T2_K1) || (fmt == IF_T2_K4) || (fmt == IF_T2_L0) ||
2854            (fmt == IF_T2_M0) || (fmt == IF_T2_VLDST) || (fmt == IF_T2_M1));
2855     assert(sf != INS_FLAGS_DONT_CARE);
2856
2857     instrDesc* id  = emitNewInstrSC(attr, imm);
2858     insSize    isz = emitInsSize(fmt);
2859
2860     id->idIns(ins);
2861     id->idInsFmt(fmt);
2862     id->idInsSize(isz);
2863     id->idInsFlags(sf);
2864     id->idInsOpt(opt);
2865     id->idReg1(reg1);
2866     id->idReg2(reg2);
2867
2868     dispIns(id);
2869     appendToCurIG(id);
2870 }
2871
2872 /*****************************************************************************
2873  *
2874  *  Add an instruction referencing three registers.
2875  */
2876
2877 void emitter::emitIns_R_R_R(instruction ins,
2878                             emitAttr    attr,
2879                             regNumber   reg1,
2880                             regNumber   reg2,
2881                             regNumber   reg3,
2882                             insFlags    flags /* = INS_FLAGS_DONT_CARE */)
2883 {
2884     emitAttr  size = EA_SIZE(attr);
2885     insFormat fmt  = IF_NONE;
2886     insFlags  sf   = INS_FLAGS_DONT_CARE;
2887
2888     /* Figure out the encoding format of the instruction */
2889     switch (ins)
2890     {
2891         case INS_add:
2892             // Encodings do not support SP in the reg3 slot
2893             if (reg3 == REG_SP)
2894             {
2895                 // Swap reg2 and reg3
2896                 reg3 = reg2;
2897                 reg2 = REG_SP;
2898             }
2899             __fallthrough;
2900
2901         case INS_sub:
2902             assert(reg3 != REG_SP);
2903
2904             if (isLowRegister(reg1) && isLowRegister(reg2) && isLowRegister(reg3) && insSetsFlags(flags))
2905             {
2906                 fmt = IF_T1_H;
2907                 sf  = INS_FLAGS_SET;
2908                 break;
2909             }
2910
2911             if ((ins == INS_add) && insDoesNotSetFlags(flags))
2912             {
2913                 if (reg1 == reg2)
2914                 {
2915                     // Use the Thumb-1 regdest,reg encoding
2916                     emitIns_R_R(ins, attr, reg1, reg3, flags);
2917                     return;
2918                 }
2919                 if (reg1 == reg3)
2920                 {
2921                     // Use the Thumb-1 regdest,reg encoding
2922                     emitIns_R_R(ins, attr, reg1, reg2, flags);
2923                     return;
2924                 }
2925             }
2926
2927             // Use the Thumb-2 reg,reg,reg with shift encoding
2928             emitIns_R_R_R_I(ins, attr, reg1, reg2, reg3, 0, flags);
2929             return;
2930
2931         case INS_adc:
2932         case INS_and:
2933         case INS_bic:
2934         case INS_eor:
2935         case INS_orr:
2936         case INS_sbc:
2937             if (reg1 == reg2)
2938             {
2939                 // Try to encode as a Thumb-1 instruction
2940                 emitIns_R_R(ins, attr, reg1, reg3, flags);
2941                 return;
2942             }
2943             __fallthrough;
2944
2945         case INS_orn:
2946             // Use the Thumb-2 three register encoding, with imm=0
2947             emitIns_R_R_R_I(ins, attr, reg1, reg2, reg3, 0, flags);
2948             return;
2949
2950         case INS_asr:
2951         case INS_lsl:
2952         case INS_lsr:
2953             if (reg1 == reg2 && insSetsFlags(flags) && isLowRegister(reg1) && isLowRegister(reg3))
2954             {
2955                 // Use the Thumb-1 regdest,reg encoding
2956                 emitIns_R_R(ins, attr, reg1, reg3, flags);
2957                 return;
2958             }
2959             __fallthrough;
2960
2961         case INS_ror:
2962             fmt = IF_T2_C4;
2963             sf  = insMustSetFlags(flags);
2964             break;
2965
2966         case INS_mul:
2967             if (insMustSetFlags(flags))
2968             {
2969                 if ((reg1 == reg2) && isLowRegister(reg1))
2970                 {
2971                     // Use the Thumb-1 regdest,reg encoding
2972                     emitIns_R_R(ins, attr, reg1, reg3, flags);
2973                     return;
2974                 }
2975                 if ((reg1 == reg3) && isLowRegister(reg1))
2976                 {
2977                     // Use the Thumb-1 regdest,reg encoding
2978                     emitIns_R_R(ins, attr, reg1, reg2, flags);
2979                     return;
2980                 }
2981                 else
2982                 {
2983                     assert(!"Instruction cannot be encoded");
2984                 }
2985             }
2986             __fallthrough;
2987
2988 #if !defined(USE_HELPERS_FOR_INT_DIV)
2989         case INS_sdiv:
2990         case INS_udiv:
2991 #endif // !USE_HELPERS_FOR_INT_DIV
2992
2993             assert(insDoesNotSetFlags(flags));
2994             fmt = IF_T2_C5;
2995             sf  = INS_FLAGS_NOT_SET;
2996             break;
2997
2998         case INS_ldrb:
2999         case INS_strb:
3000         case INS_ldrsb:
3001             assert(size == EA_1BYTE);
3002             goto COMMON_THUMB1_LDST;
3003
3004         case INS_ldrsh:
3005         case INS_ldrh:
3006         case INS_strh:
3007             assert(size == EA_2BYTE);
3008             goto COMMON_THUMB1_LDST;
3009
3010         case INS_ldr:
3011         case INS_str:
3012             assert(size == EA_4BYTE);
3013
3014         COMMON_THUMB1_LDST:
3015             assert(insDoesNotSetFlags(flags));
3016
3017             if (isLowRegister(reg1) && isLowRegister(reg2) && isLowRegister(reg3))
3018             {
3019                 fmt = IF_T1_H;
3020                 sf  = INS_FLAGS_NOT_SET;
3021             }
3022             else
3023             {
3024                 // Use the Thumb-2 reg,reg,reg with shift encoding
3025                 emitIns_R_R_R_I(ins, attr, reg1, reg2, reg3, 0, flags);
3026                 return;
3027             }
3028             break;
3029
3030         case INS_vadd:
3031         case INS_vmul:
3032         case INS_vsub:
3033         case INS_vdiv:
3034             if (size == EA_8BYTE)
3035             {
3036                 assert(isDoubleReg(reg1));
3037                 assert(isDoubleReg(reg2));
3038                 assert(isDoubleReg(reg3));
3039             }
3040             else
3041             {
3042                 assert(isFloatReg(reg1));
3043                 assert(isFloatReg(reg2));
3044                 assert(isFloatReg(reg3));
3045             }
3046             fmt = IF_T2_VFP3;
3047             sf  = INS_FLAGS_NOT_SET;
3048             break;
3049
3050         case INS_vmov_i2d:
3051             assert(isDoubleReg(reg1));
3052             assert(isGeneralRegister(reg2));
3053             assert(isGeneralRegister(reg3));
3054             fmt = IF_T2_VMOVD;
3055             sf  = INS_FLAGS_NOT_SET;
3056             break;
3057
3058         case INS_vmov_d2i:
3059             assert(isGeneralRegister(reg1));
3060             assert(isGeneralRegister(reg2));
3061             assert(isDoubleReg(reg3));
3062             fmt = IF_T2_VMOVD;
3063             sf  = INS_FLAGS_NOT_SET;
3064             break;
3065
3066         case INS_ldrexd:
3067         case INS_strexd:
3068             assert(insDoesNotSetFlags(flags));
3069             fmt = IF_T2_G1;
3070             sf  = INS_FLAGS_NOT_SET;
3071             break;
3072
3073         default:
3074             unreached();
3075     }
3076     assert((fmt == IF_T1_H) || (fmt == IF_T2_C4) || (fmt == IF_T2_C5) || (fmt == IF_T2_VFP3) || (fmt == IF_T2_VMOVD) ||
3077            (fmt == IF_T2_G1));
3078     assert(sf != INS_FLAGS_DONT_CARE);
3079
3080     instrDesc* id  = emitNewInstr(attr);
3081     insSize    isz = emitInsSize(fmt);
3082
3083     id->idIns(ins);
3084     id->idInsFmt(fmt);
3085     id->idInsSize(isz);
3086     id->idInsFlags(sf);
3087     id->idReg1(reg1);
3088     id->idReg2(reg2);
3089     id->idReg3(reg3);
3090
3091     dispIns(id);
3092     appendToCurIG(id);
3093 }
3094
3095 /*****************************************************************************
3096  *
3097  *  Add an instruction referencing two registers and two constants.
3098  */
3099
3100 void emitter::emitIns_R_R_I_I(instruction ins,
3101                               emitAttr    attr,
3102                               regNumber   reg1,
3103                               regNumber   reg2,
3104                               int         imm1,
3105                               int         imm2,
3106                               insFlags    flags /* = INS_FLAGS_DONT_CARE */)
3107 {
3108     insFormat fmt = IF_NONE;
3109     insFlags  sf  = INS_FLAGS_DONT_CARE;
3110
3111     int lsb   = imm1;
3112     int width = imm2;
3113     int msb   = lsb + width - 1;
3114     int imm   = 0; /* combined immediate */
3115
3116     assert((lsb >= 0) && (lsb <= 31));    // required for encodings
3117     assert((width > 0) && (width <= 32)); // required for encodings
3118     assert((msb >= 0) && (msb <= 31));    // required for encodings
3119     assert(msb >= lsb);                   // required for encodings
3120
3121     /* Figure out the encoding format of the instruction */
3122     switch (ins)
3123     {
3124         case INS_bfi:
3125             assert(insDoesNotSetFlags(flags));
3126             imm = (lsb << 5) | msb;
3127
3128             fmt = IF_T2_D0;
3129             sf  = INS_FLAGS_NOT_SET;
3130             break;
3131
3132         case INS_sbfx:
3133         case INS_ubfx:
3134             assert(insDoesNotSetFlags(flags));
3135             imm = (lsb << 5) | (width - 1);
3136
3137             fmt = IF_T2_D0;
3138             sf  = INS_FLAGS_NOT_SET;
3139             break;
3140
3141         default:
3142             unreached();
3143     }
3144     assert((fmt == IF_T2_D0));
3145     assert(sf != INS_FLAGS_DONT_CARE);
3146
3147     instrDesc* id  = emitNewInstrSC(attr, imm);
3148     insSize    isz = emitInsSize(fmt);
3149
3150     id->idIns(ins);
3151     id->idInsFmt(fmt);
3152     id->idInsSize(isz);
3153     id->idInsFlags(sf);
3154     id->idReg1(reg1);
3155     id->idReg2(reg2);
3156
3157     dispIns(id);
3158     appendToCurIG(id);
3159 }
3160
3161 /*****************************************************************************
3162  *
3163  *  Add an instruction referencing three registers and a constant.
3164  */
3165
3166 void emitter::emitIns_R_R_R_I(instruction ins,
3167                               emitAttr    attr,
3168                               regNumber   reg1,
3169                               regNumber   reg2,
3170                               regNumber   reg3,
3171                               int         imm,
3172                               insFlags    flags /* = INS_FLAGS_DONT_CARE */,
3173                               insOpts     opt /* = INS_OPTS_NONE */)
3174 {
3175     emitAttr  size = EA_SIZE(attr);
3176     insFormat fmt  = IF_NONE;
3177     insFlags  sf   = INS_FLAGS_DONT_CARE;
3178
3179     /* Figure out the encoding format of the instruction */
3180     switch (ins)
3181     {
3182
3183         case INS_add:
3184         case INS_sub:
3185             if (imm == 0)
3186             {
3187                 if (isLowRegister(reg1) && isLowRegister(reg2) && isLowRegister(reg3) && insSetsFlags(flags))
3188                 {
3189                     // Use the Thumb-1 reg,reg,reg encoding
3190                     emitIns_R_R_R(ins, attr, reg1, reg2, reg3, flags);
3191                     return;
3192                 }
3193                 if ((ins == INS_add) && insDoesNotSetFlags(flags))
3194                 {
3195                     if (reg1 == reg2)
3196                     {
3197                         // Use the Thumb-1 regdest,reg encoding
3198                         emitIns_R_R(ins, attr, reg1, reg3, flags);
3199                         return;
3200                     }
3201                     if (reg1 == reg3)
3202                     {
3203                         // Use the Thumb-1 regdest,reg encoding
3204                         emitIns_R_R(ins, attr, reg1, reg2, flags);
3205                         return;
3206                     }
3207                 }
3208             }
3209             __fallthrough;
3210
3211         case INS_adc:
3212         case INS_and:
3213         case INS_bic:
3214         case INS_eor:
3215         case INS_orn:
3216         case INS_orr:
3217         case INS_sbc:
3218             assert((imm >= 0) && (imm <= 31)); // required for encoding
3219             assert(!insOptAnyInc(opt));
3220             if (imm == 0)
3221             {
3222                 if (opt == INS_OPTS_LSL) // left shift of zero
3223                     opt = INS_OPTS_NONE; //           is a nop
3224
3225                 assert(insOptsNone(opt));
3226                 if (isLowRegister(reg1) && isLowRegister(reg2) && isLowRegister(reg3) && insSetsFlags(flags))
3227                 {
3228                     if (reg1 == reg2)
3229                     {
3230                         // Use the Thumb-1 regdest,reg encoding
3231                         emitIns_R_R(ins, attr, reg1, reg3, flags);
3232                         return;
3233                     }
3234                     if ((reg1 == reg3) && (ins != INS_bic) && (ins != INS_orn) && (ins != INS_sbc))
3235                     {
3236                         // Use the Thumb-1 regdest,reg encoding
3237                         emitIns_R_R(ins, attr, reg1, reg2, flags);
3238                         return;
3239                     }
3240                 }
3241             }
3242             else // imm > 0  &&  imm <= 31)
3243             {
3244                 assert(insOptAnyShift(opt));
3245                 if (insOptsRRX(opt))
3246                     assert(imm == 1);
3247             }
3248             fmt = IF_T2_C0;
3249             sf  = insMustSetFlags(flags);
3250             break;
3251
3252         case INS_ldrb:
3253         case INS_ldrsb:
3254         case INS_strb:
3255             assert(size == EA_1BYTE);
3256             goto COMMON_THUMB2_LDST;
3257
3258         case INS_ldrh:
3259         case INS_ldrsh:
3260         case INS_strh:
3261             assert(size == EA_2BYTE);
3262             goto COMMON_THUMB2_LDST;
3263
3264         case INS_ldr:
3265         case INS_str:
3266             assert(size == EA_4BYTE);
3267
3268         COMMON_THUMB2_LDST:
3269             assert(insDoesNotSetFlags(flags));
3270             assert((imm & 0x0003) == imm); // required for encoding
3271
3272             if ((imm == 0) && insOptsNone(opt) && isLowRegister(reg1) && isLowRegister(reg2) && isLowRegister(reg3))
3273             {
3274                 // Use the Thumb-1 reg,reg,reg encoding
3275                 emitIns_R_R_R(ins, attr, reg1, reg2, reg3, flags);
3276                 return;
3277             }
3278             assert(insOptsNone(opt) || insOptsLSL(opt));
3279             fmt = IF_T2_E0;
3280             sf  = INS_FLAGS_NOT_SET;
3281             break;
3282
3283         case INS_ldrd:
3284         case INS_strd:
3285             assert(insDoesNotSetFlags(flags));
3286             assert((imm & 0x03) == 0);
3287             sf = INS_FLAGS_NOT_SET;
3288
3289             if (insOptAnyInc(opt))
3290             {
3291                 if (insOptsPostInc(opt))
3292                     assert(imm > 0);
3293                 else // insOptsPreDec(opt)
3294                     assert(imm < 0);
3295             }
3296             else
3297             {
3298                 assert(insOptsNone(opt));
3299             }
3300
3301             if (unsigned_abs(imm) <= 0x03fc)
3302             {
3303                 imm >>= 2;
3304                 fmt = IF_T2_G0;
3305             }
3306             else
3307             {
3308                 assert(!"Instruction cannot be encoded");
3309             }
3310             break;
3311
3312         default:
3313             unreached();
3314     }
3315     assert((fmt == IF_T2_C0) || (fmt == IF_T2_E0) || (fmt == IF_T2_G0));
3316     assert(sf != INS_FLAGS_DONT_CARE);
3317
3318     // 3-reg ops can't use the small instrdesc
3319     instrDescCns* id = emitAllocInstrCns(attr);
3320     id->idSetIsLargeCns();
3321     id->idcCnsVal = imm;
3322
3323     id->idIns(ins);
3324     id->idInsFmt(fmt);
3325     id->idInsSize(emitInsSize(fmt));
3326
3327     id->idInsFlags(sf);
3328     id->idInsOpt(opt);
3329     id->idReg1(reg1);
3330     id->idReg2(reg2);
3331     id->idReg3(reg3);
3332
3333     dispIns(id);
3334     appendToCurIG(id);
3335 }
3336
3337 /*****************************************************************************
3338  *
3339  *  Add an instruction referencing four registers.
3340  */
3341
3342 void emitter::emitIns_R_R_R_R(
3343     instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber reg3, regNumber reg4)
3344 {
3345     insFormat fmt = IF_NONE;
3346     insFlags  sf  = INS_FLAGS_NOT_SET;
3347
3348     /* Figure out the encoding format of the instruction */
3349     switch (ins)
3350     {
3351
3352         case INS_smull:
3353         case INS_umull:
3354         case INS_smlal:
3355         case INS_umlal:
3356             assert(reg1 != reg2); // Illegal encoding
3357             fmt = IF_T2_F1;
3358             break;
3359         case INS_mla:
3360         case INS_mls:
3361             fmt = IF_T2_F2;
3362             break;
3363         default:
3364             unreached();
3365     }
3366     assert((fmt == IF_T2_F1) || (fmt == IF_T2_F2));
3367
3368     instrDesc* id  = emitNewInstr(attr);
3369     insSize    isz = emitInsSize(fmt);
3370
3371     id->idIns(ins);
3372     id->idInsFmt(fmt);
3373     id->idInsSize(isz);
3374     id->idInsFlags(sf);
3375     id->idReg1(reg1);
3376     id->idReg2(reg2);
3377     id->idReg3(reg3);
3378     id->idReg4(reg4);
3379
3380     dispIns(id);
3381     appendToCurIG(id);
3382 }
3383
3384 /*****************************************************************************
3385  *
3386  *  Add an instruction with a static data member operand. If 'size' is 0, the
3387  *  instruction operates on the address of the static member instead of its
3388  *  value (e.g. "push offset clsvar", rather than "push dword ptr [clsvar]").
3389  */
3390
3391 void emitter::emitIns_C(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fldHnd, int offs)
3392 {
3393     NYI("emitIns_C");
3394 }
3395
3396 /*****************************************************************************
3397  *
3398  *  Add an instruction referencing stack-based local variable.
3399  */
3400
3401 void emitter::emitIns_S(instruction ins, emitAttr attr, int varx, int offs)
3402 {
3403     NYI("emitIns_S");
3404 }
3405
3406 /*****************************************************************************
3407  *
3408  *  Add an instruction referencing a register and a stack-based local variable.
3409  */
3410 void emitter::emitIns_R_S(instruction ins, emitAttr attr, regNumber reg1, int varx, int offs)
3411 {
3412     if (ins == INS_mov)
3413     {
3414         assert(!"Please use ins_Load() to select the correct instruction");
3415     }
3416
3417     switch (ins)
3418     {
3419         case INS_add:
3420         case INS_ldr:
3421         case INS_ldrh:
3422         case INS_ldrb:
3423         case INS_ldrsh:
3424         case INS_ldrsb:
3425         case INS_vldr:
3426         case INS_vmov:
3427         case INS_movw:
3428         case INS_movt:
3429             break;
3430
3431         case INS_lea:
3432             ins = INS_add;
3433             break;
3434
3435         default:
3436             NYI("emitIns_R_S");
3437             return;
3438     }
3439
3440     insFormat fmt = IF_NONE;
3441     insFlags  sf  = INS_FLAGS_NOT_SET;
3442     regNumber reg2;
3443
3444     /* Figure out the variable's frame position */
3445     int      base;
3446     int      disp;
3447     unsigned undisp;
3448
3449     base = emitComp->lvaFrameAddress(varx, emitComp->funCurrentFunc()->funKind != FUNC_ROOT, &reg2, offs);
3450
3451     disp   = base + offs;
3452     undisp = unsigned_abs(disp);
3453
3454     if (CodeGen::instIsFP(ins))
3455     {
3456         // all fp mem ops take 8 bit immediate, multiplied by 4, plus sign
3457         //
3458         // Note if undisp is not a multiple of four we will fail later on
3459         //   when we try to encode this instruction
3460         // Its better to fail later with a better error message than
3461         //   to fail here when the RBM_OPT_RSVD is not available
3462         //
3463         if (undisp <= 0x03fb)
3464         {
3465             fmt = IF_T2_VLDST;
3466         }
3467         else
3468         {
3469             regNumber rsvdReg = codeGen->rsGetRsvdReg();
3470             emitIns_genStackOffset(rsvdReg, varx, offs);
3471             emitIns_R_R(INS_add, EA_4BYTE, rsvdReg, reg2);
3472             emitIns_R_R_I(ins, attr, reg1, rsvdReg, 0);
3473             return;
3474         }
3475     }
3476     else if (emitInsIsLoadOrStore(ins))
3477     {
3478         if (isLowRegister(reg1) && (reg2 == REG_SP) && (ins == INS_ldr) && ((disp & 0x03fc) == disp && disp <= 0x03f8))
3479         {
3480             fmt = IF_T1_J2;
3481         }
3482         else if (disp >= 0 && disp <= 0x0ffb)
3483         {
3484             fmt = IF_T2_K1;
3485         }
3486         else if (undisp <= 0x0fb)
3487         {
3488             fmt = IF_T2_H0;
3489         }
3490         else
3491         {
3492             // Load disp into a register
3493             regNumber rsvdReg = codeGen->rsGetRsvdReg();
3494             emitIns_genStackOffset(rsvdReg, varx, offs);
3495             fmt = IF_T2_E0;
3496         }
3497     }
3498     else if (ins == INS_add)
3499     {
3500         if (isLowRegister(reg1) && (reg2 == REG_SP) && ((disp & 0x03fc) == disp && disp <= 0x03f8))
3501         {
3502             fmt = IF_T1_J2;
3503         }
3504         else if (undisp <= 0x0ffb)
3505         {
3506             if (disp < 0)
3507             {
3508                 ins  = INS_sub;
3509                 disp = -disp;
3510             }
3511             // add/sub => addw/subw instruction
3512             // Note that even when using the w prefix the immediate is still only 12 bits?
3513             ins = (ins == INS_add) ? INS_addw : INS_subw;
3514             fmt = IF_T2_M0;
3515         }
3516         else
3517         {
3518             // Load disp into a register
3519             regNumber rsvdReg = codeGen->rsGetRsvdReg();
3520             emitIns_genStackOffset(rsvdReg, varx, offs);
3521             emitIns_R_R_R(ins, attr, reg1, reg2, rsvdReg);
3522             return;
3523         }
3524     }
3525     else if (ins == INS_movw || ins == INS_movt)
3526     {
3527         fmt = IF_T2_N;
3528     }
3529
3530     assert((fmt == IF_T1_J2) || (fmt == IF_T2_E0) || (fmt == IF_T2_H0) || (fmt == IF_T2_K1) || (fmt == IF_T2_L0) ||
3531            (fmt == IF_T2_N) || (fmt == IF_T2_VLDST) || (fmt == IF_T2_M0));
3532     assert(sf != INS_FLAGS_DONT_CARE);
3533
3534     instrDesc* id  = emitNewInstrCns(attr, disp);
3535     insSize    isz = emitInsSize(fmt);
3536
3537     id->idIns(ins);
3538     id->idInsFmt(fmt);
3539     id->idInsSize(isz);
3540     id->idInsFlags(sf);
3541     id->idInsOpt(INS_OPTS_NONE);
3542     id->idReg1(reg1);
3543     id->idReg2(reg2);
3544     id->idAddr()->iiaLclVar.initLclVarAddr(varx, offs);
3545     id->idSetIsLclVar();
3546     if (reg2 == REG_FP)
3547         id->idSetIsLclFPBase();
3548
3549 #ifdef DEBUG
3550     id->idDebugOnlyInfo()->idVarRefOffs = emitVarRefOffs;
3551 #endif
3552
3553     dispIns(id);
3554     appendToCurIG(id);
3555 }
3556
3557 // generate the offset of &varx + offs into a register
3558 void emitter::emitIns_genStackOffset(regNumber r, int varx, int offs)
3559 {
3560     regNumber regBase;
3561     int       base;
3562     int       disp;
3563
3564     base = emitComp->lvaFrameAddress(varx, emitComp->funCurrentFunc()->funKind != FUNC_ROOT, &regBase, offs);
3565     disp = base + offs;
3566
3567     emitIns_R_S(INS_movw, EA_4BYTE, r, varx, offs);
3568
3569     if ((disp & 0xffff) != disp)
3570     {
3571         emitIns_R_S(INS_movt, EA_4BYTE, r, varx, offs);
3572     }
3573 }
3574
3575 /*****************************************************************************
3576  *
3577  *  Add an instruction referencing a stack-based local variable and a register
3578  */
3579 void emitter::emitIns_S_R(instruction ins, emitAttr attr, regNumber reg1, int varx, int offs)
3580 {
3581     if (ins == INS_mov)
3582     {
3583         assert(!"Please use ins_Store() to select the correct instruction");
3584     }
3585
3586     switch (ins)
3587     {
3588         case INS_str:
3589         case INS_strh:
3590         case INS_strb:
3591         case INS_vstr:
3592             break;
3593
3594         default:
3595             NYI("emitIns_R_S");
3596             return;
3597     }
3598
3599     insFormat fmt = IF_NONE;
3600     insFlags  sf  = INS_FLAGS_NOT_SET;
3601     regNumber reg2;
3602
3603     /* Figure out the variable's frame position */
3604     int      base;
3605     int      disp;
3606     unsigned undisp;
3607
3608     base = emitComp->lvaFrameAddress(varx, emitComp->funCurrentFunc()->funKind != FUNC_ROOT, &reg2, offs);
3609
3610     disp   = base + offs;
3611     undisp = unsigned_abs(disp);
3612
3613     if (CodeGen::instIsFP(ins))
3614     {
3615         // all fp mem ops take 8 bit immediate, multiplied by 4, plus sign
3616         //
3617         // Note if undisp is not a multiple of four we will fail later on
3618         //   when we try to encode this instruction
3619         // Its better to fail later with a better error message than
3620         //   to fail here when the RBM_OPT_RSVD is not available
3621         //
3622         if (undisp <= 0x03fb)
3623         {
3624             fmt = IF_T2_VLDST;
3625         }
3626         else
3627         {
3628             regNumber rsvdReg = codeGen->rsGetRsvdReg();
3629             emitIns_genStackOffset(rsvdReg, varx, offs);
3630             emitIns_R_R(INS_add, EA_4BYTE, rsvdReg, reg2);
3631             emitIns_R_R_I(ins, attr, reg1, rsvdReg, 0);
3632             return;
3633         }
3634     }
3635     else if (isLowRegister(reg1) && (reg2 == REG_SP) && (ins == INS_str) && ((disp & 0x03fc) == disp && disp <= 0x03f8))
3636     {
3637         fmt = IF_T1_J2;
3638     }
3639     else if (disp >= 0 && disp <= 0x0ffb)
3640     {
3641         fmt = IF_T2_K1;
3642     }
3643     else if (undisp <= 0x0fb)
3644     {
3645         fmt = IF_T2_H0;
3646     }
3647     else
3648     {
3649         // Load disp into a register
3650         regNumber rsvdReg = codeGen->rsGetRsvdReg();
3651         emitIns_genStackOffset(rsvdReg, varx, offs);
3652         fmt = IF_T2_E0;
3653     }
3654     assert((fmt == IF_T1_J2) || (fmt == IF_T2_E0) || (fmt == IF_T2_H0) || (fmt == IF_T2_VLDST) || (fmt == IF_T2_K1));
3655     assert(sf != INS_FLAGS_DONT_CARE);
3656
3657     instrDesc* id  = emitNewInstrCns(attr, disp);
3658     insSize    isz = emitInsSize(fmt);
3659
3660     id->idIns(ins);
3661     id->idInsFmt(fmt);
3662     id->idInsSize(isz);
3663     id->idInsFlags(sf);
3664     id->idInsOpt(INS_OPTS_NONE);
3665     id->idReg1(reg1);
3666     id->idReg2(reg2);
3667     id->idAddr()->iiaLclVar.initLclVarAddr(varx, offs);
3668     id->idSetIsLclVar();
3669     if (reg2 == REG_FP)
3670         id->idSetIsLclFPBase();
3671 #ifdef DEBUG
3672     id->idDebugOnlyInfo()->idVarRefOffs = emitVarRefOffs;
3673 #endif
3674
3675     dispIns(id);
3676     appendToCurIG(id);
3677 }
3678
3679 /*****************************************************************************
3680  *
3681  *  Add an instruction referencing stack-based local variable and an immediate
3682  */
3683 void emitter::emitIns_S_I(instruction ins, emitAttr attr, int varx, int offs, int val)
3684 {
3685     NYI("emitIns_S_I");
3686 }
3687
3688 /*****************************************************************************
3689  *
3690  *  Add an instruction with a register + static member operands.
3691  */
3692 void emitter::emitIns_R_C(instruction ins, emitAttr attr, regNumber reg, CORINFO_FIELD_HANDLE fldHnd, int offs)
3693 {
3694     if (ins == INS_mov)
3695     {
3696         assert(!"Please use ins_Load() to select the correct instruction");
3697     }
3698     assert(emitInsIsLoad(ins) || (ins == INS_lea));
3699     if (ins == INS_lea)
3700     {
3701         ins = INS_add;
3702     }
3703
3704     int     doff = Compiler::eeGetJitDataOffs(fldHnd);
3705     ssize_t addr = NULL;
3706
3707     if (doff >= 0)
3708     {
3709         NYI_ARM("JitDataOffset static fields");
3710     }
3711     else if (fldHnd == FLD_GLOBAL_FS)
3712     {
3713         NYI_ARM("Thread-Local-Storage static fields");
3714     }
3715     else if (fldHnd == FLD_GLOBAL_DS)
3716     {
3717         addr = (ssize_t)offs;
3718         offs = 0;
3719     }
3720     else
3721     {
3722         assert(!jitStaticFldIsGlobAddr(fldHnd));
3723         addr = (ssize_t)emitComp->info.compCompHnd->getFieldAddress(fldHnd, NULL);
3724         if (addr == NULL)
3725             NO_WAY("could not obtain address of static field");
3726     }
3727
3728     // We can use reg to load the constant address,
3729     //  as long as it is not a floating point register
3730     regNumber regTmp = reg;
3731
3732     if (isFloatReg(regTmp))
3733     {
3734 #ifndef LEGACY_BACKEND
3735         assert(!"emitIns_R_C() cannot be called with floating point target");
3736 #else  // LEGACY_BACKEND
3737         regTmp = codeGen->regSet.rsPickFreeReg(RBM_ALLINT & ~genRegMask(reg));
3738 #endif // LEGACY_BACKEND
3739     }
3740
3741     // Load address of CLS_VAR into a register
3742     codeGen->instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regTmp, addr);
3743
3744     if ((ins != INS_add) || (offs != 0) || (reg != regTmp))
3745     {
3746         emitIns_R_R_I(ins, attr, reg, regTmp, offs);
3747     }
3748 }
3749
3750 /*****************************************************************************
3751  *
3752  *  Add an instruction with a static member + register operands.
3753  */
3754
3755 void emitter::emitIns_C_R(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fldHnd, regNumber reg, int offs)
3756 {
3757 #ifndef LEGACY_BACKEND
3758     assert(!"emitIns_C_R not supported for RyuJIT backend");
3759 #else  // LEGACY_BACKEND
3760     if (ins == INS_mov)
3761     {
3762         assert(!"Please use ins_Store() to select the correct instruction");
3763     }
3764     assert(emitInsIsStore(ins));
3765
3766     int     doff = Compiler::eeGetJitDataOffs(fldHnd);
3767     ssize_t addr = NULL;
3768
3769     if (doff >= 0)
3770     {
3771         NYI_ARM("JitDataOffset static fields");
3772     }
3773     else if (fldHnd == FLD_GLOBAL_FS)
3774     {
3775         NYI_ARM("Thread-Local-Storage static fields");
3776     }
3777     else if (fldHnd == FLD_GLOBAL_DS)
3778     {
3779         addr = (ssize_t)offs;
3780         offs = 0;
3781     }
3782     else
3783     {
3784         assert(!jitStaticFldIsGlobAddr(fldHnd));
3785         addr = (ssize_t)emitComp->info.compCompHnd->getFieldAddress(fldHnd, NULL);
3786         if (addr == NULL)
3787             NO_WAY("could not obtain address of static field");
3788     }
3789
3790     regNumber regTmp = codeGen->regSet.rsPickFreeReg(RBM_ALLINT & ~genRegMask(reg));
3791
3792     // Load address of CLS_VAR into a register
3793     codeGen->instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regTmp, addr);
3794
3795     emitIns_R_R_I(ins, attr, reg, regTmp, offs);
3796 #endif // LEGACY_BACKEND
3797 }
3798
3799 /*****************************************************************************
3800  *
3801  *  Add an instruction with a static member + constant.
3802  */
3803
3804 void emitter::emitIns_C_I(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fldHnd, int offs, ssize_t val)
3805 {
3806     NYI("emitIns_C_I");
3807 }
3808
3809 /*****************************************************************************
3810  *
3811  *  The following adds instructions referencing address modes.
3812  */
3813
3814 void emitter::emitIns_I_AR(instruction ins, emitAttr attr, int val, regNumber reg, int offs)
3815 {
3816     NYI("emitIns_I_AR");
3817 }
3818
3819 void emitter::emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, int offs)
3820 {
3821     if (ins == INS_mov)
3822     {
3823         assert(!"Please use ins_Load() to select the correct instruction");
3824     }
3825
3826     if (ins == INS_lea)
3827     {
3828         if (emitter::emitIns_valid_imm_for_add(offs, INS_FLAGS_DONT_CARE))
3829         {
3830             emitIns_R_R_I(INS_add, attr, ireg, reg, offs);
3831         }
3832         else
3833         {
3834 #ifndef LEGACY_BACKEND
3835             assert(!"emitIns_R_AR: immediate doesn't fit in the instruction");
3836 #else  // LEGACY_BACKEND
3837             // Load val into a register
3838             regNumber immReg = codeGen->regSet.rsGrabReg(RBM_ALLINT & ~genRegMask(ireg) & ~genRegMask(reg));
3839             codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, immReg, (ssize_t)offs);
3840             emitIns_R_R_R(INS_add, attr, ireg, reg, immReg);
3841 #endif // LEGACY_BACKEND
3842         }
3843         return;
3844     }
3845     else if (emitInsIsLoad(ins))
3846     {
3847         emitIns_R_R_I(ins, attr, ireg, reg, offs);
3848         return;
3849     }
3850     else if ((ins == INS_mov) || (ins == INS_ldr))
3851     {
3852         if (EA_SIZE(attr) == EA_4BYTE)
3853         {
3854             emitIns_R_R_I(INS_ldr, attr, ireg, reg, offs);
3855             return;
3856         }
3857     }
3858     else if (ins == INS_vldr)
3859     {
3860         emitIns_R_R_I(ins, attr, ireg, reg, offs);
3861     }
3862     NYI("emitIns_R_AR");
3863 }
3864
3865 void emitter::emitIns_R_AI(instruction ins, emitAttr attr, regNumber ireg, ssize_t disp)
3866 {
3867     if (emitInsIsLoad(ins))
3868     {
3869         // We can use ireg to load the constant address,
3870         //  as long as it is not a floating point register
3871         regNumber regTmp = ireg;
3872
3873         if (isFloatReg(regTmp))
3874         {
3875 #ifndef LEGACY_BACKEND
3876             assert(!"emitIns_R_AI with floating point reg");
3877 #else  // LEGACY_BACKEND
3878             regTmp = codeGen->regSet.rsPickFreeReg(RBM_ALLINT & ~genRegMask(ireg));
3879 #endif // LEGACY_BACKEND
3880         }
3881
3882         codeGen->instGen_Set_Reg_To_Imm(EA_IS_RELOC(attr) ? EA_HANDLE_CNS_RELOC : EA_PTRSIZE, regTmp, disp);
3883         emitIns_R_R_I(ins, EA_TYPE(attr), ireg, regTmp, 0);
3884         return;
3885     }
3886     NYI("emitIns_R_AI");
3887 }
3888
3889 void emitter::emitIns_AR_R(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, int offs)
3890 {
3891     if (ins == INS_mov)
3892     {
3893         assert(!"Please use ins_Store() to select the correct instruction");
3894     }
3895     emitIns_R_R_I(ins, attr, ireg, reg, offs);
3896 }
3897
3898 void emitter::emitIns_R_ARR(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, regNumber rg2, int disp)
3899 {
3900     if (ins == INS_mov)
3901     {
3902         assert(!"Please use ins_Load() to select the correct instruction");
3903     }
3904
3905     if (ins == INS_lea)
3906     {
3907         emitIns_R_R_R(INS_add, attr, ireg, reg, rg2);
3908         if (disp != 0)
3909         {
3910             emitIns_R_R_I(INS_add, attr, ireg, ireg, disp);
3911         }
3912         return;
3913     }
3914     else if (emitInsIsLoad(ins))
3915     {
3916         if (disp == 0)
3917         {
3918             emitIns_R_R_R_I(ins, attr, ireg, reg, rg2, 0, INS_FLAGS_DONT_CARE, INS_OPTS_NONE);
3919             return;
3920         }
3921     }
3922     assert(!"emitIns_R_ARR: Unexpected instruction");
3923 }
3924
3925 void emitter::emitIns_ARR_R(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, regNumber rg2, int disp)
3926 {
3927     if (ins == INS_mov)
3928     {
3929         assert(!"Please use ins_Store() to select the correct instruction");
3930     }
3931     if (emitInsIsStore(ins))
3932     {
3933         if (disp == 0)
3934         {
3935             emitIns_R_R_R(ins, attr, ireg, reg, rg2);
3936         }
3937         else
3938         {
3939             emitIns_R_R_R(INS_add, attr, ireg, reg, rg2);
3940             emitIns_R_R_I(ins, attr, ireg, ireg, disp);
3941         }
3942         return;
3943     }
3944     assert(!"emitIns_ARR_R: Unexpected instruction");
3945 }
3946
3947 void emitter::emitIns_R_ARX(
3948     instruction ins, emitAttr attr, regNumber ireg, regNumber reg, regNumber rg2, unsigned mul, int disp)
3949 {
3950     if (ins == INS_mov)
3951     {
3952         assert(!"Please use ins_Load() to select the correct instruction");
3953     }
3954
3955     unsigned shift = genLog2((unsigned)mul);
3956
3957     if ((ins == INS_lea) || emitInsIsLoad(ins))
3958     {
3959         if (ins == INS_lea)
3960         {
3961             ins = INS_add;
3962         }
3963         if (disp == 0)
3964         {
3965             emitIns_R_R_R_I(ins, attr, ireg, reg, rg2, (int)shift, INS_FLAGS_DONT_CARE, INS_OPTS_LSL);
3966             return;
3967         }
3968         else
3969         {
3970             bool useForm2     = false;
3971             bool mustUseForm1 = ((disp % mul) != 0) || (reg == ireg);
3972             if (!mustUseForm1)
3973             {
3974                 // If all of the below things are true we can generate a Thumb-1 add instruction
3975                 //  followed by a Thumb-2 add instruction
3976                 // We also useForm1 when reg is a low register since the second instruction
3977                 //  can then always be generated using a Thumb-1 add
3978                 //
3979                 if ((reg >= REG_R8) && (ireg < REG_R8) && (rg2 < REG_R8) && ((disp >> shift) <= 7))
3980                 {
3981                     useForm2 = true;
3982                 }
3983             }
3984
3985             if (useForm2)
3986             {
3987                 // Form2:
3988                 //     Thumb-1   instruction    add     Rd, Rx, disp>>shift
3989                 //     Thumb-2   instructions   ldr     Rd, Rb, Rd LSL shift
3990                 //
3991                 emitIns_R_R_I(INS_add, EA_4BYTE, ireg, rg2, disp >> shift);
3992                 emitIns_R_R_R_I(ins, attr, ireg, reg, ireg, shift, INS_FLAGS_NOT_SET, INS_OPTS_LSL);
3993             }
3994             else
3995             {
3996                 // Form1:
3997                 //     Thumb-2   instruction    add     Rd, Rb, Rx LSL shift
3998                 //     Thumb-1/2 instructions   ldr     Rd, Rd, disp
3999                 //
4000                 emitIns_R_R_R_I(INS_add, attr, ireg, reg, rg2, shift, INS_FLAGS_NOT_SET, INS_OPTS_LSL);
4001                 emitIns_R_R_I(ins, attr, ireg, ireg, disp);
4002             }
4003             return;
4004         }
4005     }
4006
4007     assert(!"emitIns_R_ARX: Unexpected instruction");
4008 }
4009
4010 /*****************************************************************************
4011  *
4012  *  Record that a jump instruction uses the short encoding
4013  *
4014  */
4015 void emitter::emitSetShortJump(instrDescJmp* id)
4016 {
4017     if (id->idjKeepLong)
4018         return;
4019
4020     if (emitIsCondJump(id))
4021     {
4022         id->idInsFmt(IF_T1_K);
4023     }
4024     else if (emitIsCmpJump(id))
4025     {
4026         // These are always only ever short!
4027         assert(id->idjShort);
4028         return;
4029     }
4030     else if (emitIsUncondJump(id))
4031     {
4032         id->idInsFmt(IF_T1_M);
4033     }
4034     else if (emitIsLoadLabel(id))
4035     {
4036         return; // Keep long - we don't know the alignment of the target
4037     }
4038     else
4039     {
4040         assert(!"Unknown instruction in emitSetShortJump()");
4041     }
4042
4043     id->idjShort = true;
4044
4045 #if DEBUG_EMIT
4046     if (id->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
4047     {
4048         printf("[8] Converting jump %u to short\n", id->idDebugOnlyInfo()->idNum);
4049     }
4050 #endif // DEBUG_EMIT
4051
4052     insSize isz = emitInsSize(id->idInsFmt());
4053     id->idInsSize(isz);
4054 }
4055
4056 /*****************************************************************************
4057  *
4058  *  Record that a jump instruction uses the medium encoding
4059  *
4060  */
4061 void emitter::emitSetMediumJump(instrDescJmp* id)
4062 {
4063     if (id->idjKeepLong)
4064         return;
4065
4066 #if DEBUG_EMIT
4067     if (id->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
4068     {
4069         printf("[9] Converting jump %u to medium\n", id->idDebugOnlyInfo()->idNum);
4070     }
4071 #endif // DEBUG_EMIT
4072
4073     assert(emitIsCondJump(id));
4074     id->idInsFmt(IF_T2_J1);
4075     id->idjShort = false;
4076
4077     insSize isz = emitInsSize(id->idInsFmt());
4078     id->idInsSize(isz);
4079 }
4080
4081 /*****************************************************************************
4082  *
4083  *  Add a jmp instruction.
4084  *  When dst is NULL, instrCount specifies number of instructions
4085  *       to jump: positive is forward, negative is backward.
4086  *  Unconditional branches have two sizes: short and long.
4087  *  Conditional branches have three sizes: short, medium, and long. A long
4088  *     branch is a pseudo-instruction that represents two instructions:
4089  *     a short conditional branch to branch around a large unconditional
4090  *     branch. Thus, we can handle branch offsets of imm24 instead of just imm20.
4091  */
4092
4093 void emitter::emitIns_J(instruction ins, BasicBlock* dst, int instrCount /* = 0 */)
4094 {
4095     insFormat fmt = IF_NONE;
4096
4097     if (dst != NULL)
4098     {
4099         assert(dst->bbFlags & BBF_JMP_TARGET);
4100     }
4101     else
4102     {
4103         assert(instrCount != 0);
4104     }
4105
4106     /* Figure out the encoding format of the instruction */
4107     switch (ins)
4108     {
4109         case INS_b:
4110             fmt = IF_T2_J2; /* Assume the jump will be long */
4111             break;
4112
4113         case INS_beq:
4114         case INS_bne:
4115         case INS_bhs:
4116         case INS_blo:
4117         case INS_bmi:
4118         case INS_bpl:
4119         case INS_bvs:
4120         case INS_bvc:
4121         case INS_bhi:
4122         case INS_bls:
4123         case INS_bge:
4124         case INS_blt:
4125         case INS_bgt:
4126         case INS_ble:
4127             fmt = IF_LARGEJMP; /* Assume the jump will be long */
4128             break;
4129
4130         default:
4131             unreached();
4132     }
4133     assert((fmt == IF_LARGEJMP) || (fmt == IF_T2_J2));
4134
4135     instrDescJmp* id  = emitNewInstrJmp();
4136     insSize       isz = emitInsSize(fmt);
4137
4138     id->idIns(ins);
4139     id->idInsFmt(fmt);
4140     id->idInsSize(isz);
4141
4142 #ifdef DEBUG
4143     // Mark the finally call
4144     if (ins == INS_b && emitComp->compCurBB->bbJumpKind == BBJ_CALLFINALLY)
4145     {
4146         id->idDebugOnlyInfo()->idFinallyCall = true;
4147     }
4148 #endif // DEBUG
4149
4150     /* Assume the jump will be long */
4151
4152     id->idjShort = 0;
4153     if (dst != NULL)
4154     {
4155         id->idAddr()->iiaBBlabel = dst;
4156         id->idjKeepLong          = emitComp->fgInDifferentRegions(emitComp->compCurBB, dst);
4157
4158 #ifdef DEBUG
4159         if (emitComp->opts.compLongAddress) // Force long branches
4160             id->idjKeepLong = 1;
4161 #endif // DEBUG
4162     }
4163     else
4164     {
4165         id->idAddr()->iiaSetInstrCount(instrCount);
4166         id->idjKeepLong = false;
4167         /* This jump must be short */
4168         emitSetShortJump(id);
4169         id->idSetIsBound();
4170     }
4171
4172     /* Record the jump's IG and offset within it */
4173
4174     id->idjIG   = emitCurIG;
4175     id->idjOffs = emitCurIGsize;
4176
4177     /* Append this jump to this IG's jump list */
4178
4179     id->idjNext      = emitCurIGjmpList;
4180     emitCurIGjmpList = id;
4181
4182 #if EMITTER_STATS
4183     emitTotalIGjmps++;
4184 #endif
4185
4186     /* Figure out the max. size of the jump/call instruction */
4187
4188     if (!id->idjKeepLong)
4189     {
4190         insGroup* tgt = NULL;
4191
4192         /* Can we guess at the jump distance? */
4193
4194         if (dst != NULL)
4195         {
4196             tgt = (insGroup*)emitCodeGetCookie(dst);
4197         }
4198
4199         if (tgt)
4200         {
4201             UNATIVE_OFFSET srcOffs;
4202             int            jmpDist;
4203
4204             assert(JMP_SIZE_SMALL == JCC_SIZE_SMALL);
4205
4206             /* This is a backward jump - figure out the distance */
4207
4208             srcOffs = emitCurCodeOffset + emitCurIGsize;
4209
4210             /* Compute the distance estimate */
4211
4212             jmpDist = srcOffs - tgt->igOffs;
4213             assert(jmpDist >= 0);
4214             jmpDist += 4; // Adjustment for ARM PC
4215
4216             switch (fmt)
4217             {
4218                 case IF_T2_J2:
4219                     if (JMP_DIST_SMALL_MAX_NEG <= -jmpDist)
4220                     {
4221                         /* This jump surely will be short */
4222                         emitSetShortJump(id);
4223                     }
4224                     break;
4225
4226                 case IF_LARGEJMP:
4227                     if (JCC_DIST_SMALL_MAX_NEG <= -jmpDist)
4228                     {
4229                         /* This jump surely will be short */
4230                         emitSetShortJump(id);
4231                     }
4232                     else if (JCC_DIST_MEDIUM_MAX_NEG <= -jmpDist)
4233                     {
4234                         /* This jump surely will be medium */
4235                         emitSetMediumJump(id);
4236                     }
4237                     break;
4238
4239                 default:
4240                     unreached();
4241                     break;
4242             }
4243         }
4244     }
4245
4246     dispIns(id);
4247     appendToCurIG(id);
4248 }
4249
4250 /*****************************************************************************
4251  *
4252  *  Add a label instruction.
4253  */
4254
4255 void emitter::emitIns_R_L(instruction ins, emitAttr attr, BasicBlock* dst, regNumber reg)
4256 {
4257     assert(dst->bbFlags & BBF_JMP_TARGET);
4258
4259     insFormat     fmt = IF_NONE;
4260     instrDescJmp* id;
4261
4262     /* Figure out the encoding format of the instruction */
4263     switch (ins)
4264     {
4265         case INS_adr:
4266             id  = emitNewInstrLbl();
4267             fmt = IF_T2_M1;
4268             break;
4269         case INS_movt:
4270         case INS_movw:
4271             id  = emitNewInstrJmp();
4272             fmt = IF_T2_N1;
4273             break;
4274         default:
4275             unreached();
4276     }
4277     assert((fmt == IF_T2_M1) || (fmt == IF_T2_N1));
4278
4279     insSize isz = emitInsSize(fmt);
4280
4281     id->idIns(ins);
4282     id->idReg1(reg);
4283     id->idInsFmt(fmt);
4284     id->idInsSize(isz);
4285
4286 #ifdef DEBUG
4287     // Mark the catch return
4288     if (emitComp->compCurBB->bbJumpKind == BBJ_EHCATCHRET)
4289     {
4290         id->idDebugOnlyInfo()->idCatchRet = true;
4291     }
4292 #endif // DEBUG
4293
4294     id->idAddr()->iiaBBlabel = dst;
4295     id->idjShort             = false;
4296
4297     if (ins == INS_adr)
4298     {
4299         id->idReg2(REG_PC);
4300         id->idjKeepLong = emitComp->fgInDifferentRegions(emitComp->compCurBB, dst);
4301     }
4302     else
4303     {
4304         id->idjKeepLong = true;
4305     }
4306
4307     /* Record the jump's IG and offset within it */
4308
4309     id->idjIG   = emitCurIG;
4310     id->idjOffs = emitCurIGsize;
4311
4312     /* Append this jump to this IG's jump list */
4313
4314     id->idjNext      = emitCurIGjmpList;
4315     emitCurIGjmpList = id;
4316
4317     // Set the relocation flags - these give hint to zap to perform
4318     // relocation of the specified 32bit address.
4319     id->idSetRelocFlags(attr);
4320
4321 #if EMITTER_STATS
4322     emitTotalIGjmps++;
4323 #endif
4324
4325     dispIns(id);
4326     appendToCurIG(id);
4327 }
4328
4329 /*****************************************************************************
4330  *
4331  *  Add a data label instruction.
4332  */
4333
4334 void emitter::emitIns_R_D(instruction ins, emitAttr attr, unsigned offs, regNumber reg)
4335 {
4336     noway_assert((ins == INS_movw) || (ins == INS_movt));
4337
4338     insFormat  fmt = IF_T2_N2;
4339     instrDesc* id  = emitNewInstrSC(attr, offs);
4340     insSize    isz = emitInsSize(fmt);
4341
4342     id->idIns(ins);
4343     id->idReg1(reg);
4344     id->idInsFmt(fmt);
4345     id->idInsSize(isz);
4346
4347     if (emitComp->opts.compReloc)
4348     {
4349         // Set the relocation flags - these give hint to zap to perform
4350         // relocation of the specified 32bit address.
4351         id->idSetRelocFlags(attr);
4352     }
4353
4354     dispIns(id);
4355     appendToCurIG(id);
4356 }
4357
4358 void emitter::emitIns_J_R(instruction ins, emitAttr attr, BasicBlock* dst, regNumber reg)
4359 {
4360     assert(dst->bbFlags & BBF_JMP_TARGET);
4361
4362     insFormat fmt = IF_NONE;
4363     switch (ins)
4364     {
4365         case INS_cbz:
4366         case INS_cbnz:
4367             fmt = IF_T1_I;
4368             break;
4369         default:
4370             unreached();
4371     }
4372     assert(fmt == IF_T1_I);
4373
4374     assert(isLowRegister(reg));
4375
4376     instrDescJmp* id = emitNewInstrJmp();
4377     id->idIns(ins);
4378     id->idInsFmt(IF_T1_I);
4379     id->idInsSize(emitInsSize(IF_T1_I));
4380     id->idReg1(reg);
4381
4382     /* This jump better be short or-else! */
4383     id->idjShort             = true;
4384     id->idAddr()->iiaBBlabel = dst;
4385     id->idjKeepLong          = false;
4386
4387     /* Record the jump's IG and offset within it */
4388
4389     id->idjIG   = emitCurIG;
4390     id->idjOffs = emitCurIGsize;
4391
4392     /* Append this jump to this IG's jump list */
4393
4394     id->idjNext      = emitCurIGjmpList;
4395     emitCurIGjmpList = id;
4396
4397 #if EMITTER_STATS
4398     emitTotalIGjmps++;
4399 #endif
4400
4401     dispIns(id);
4402     appendToCurIG(id);
4403 }
4404
4405 /*****************************************************************************
4406  *
4407  *  Add a call instruction (direct or indirect).
4408  *      argSize<0 means that the caller will pop the arguments
4409  *
4410  * The other arguments are interpreted depending on callType as shown:
4411  * Unless otherwise specified, ireg,xreg,xmul,disp should have default values.
4412  *
4413  * EC_FUNC_TOKEN       : addr is the method address
4414  * EC_FUNC_ADDR        : addr is the absolute address of the function
4415  *                       if addr is NULL, it is a recursive call
4416  *
4417  * If callType is one of these emitCallTypes, addr has to be NULL.
4418  * EC_INDIR_R          : "call ireg".
4419  *
4420  * For ARM xreg, xmul and disp are never used and should always be 0/REG_NA.
4421  *
4422  *  Please consult the "debugger team notification" comment in genFnProlog().
4423  */
4424
4425 void emitter::emitIns_Call(EmitCallType          callType,
4426                            CORINFO_METHOD_HANDLE methHnd,                   // used for pretty printing
4427                            INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) // used to report call sites to the EE
4428                            void*            addr,
4429                            ssize_t          argSize,
4430                            emitAttr         retSize,
4431                            VARSET_VALARG_TP ptrVars,
4432                            regMaskTP        gcrefRegs,
4433                            regMaskTP        byrefRegs,
4434                            IL_OFFSETX       ilOffset /* = BAD_IL_OFFSET */,
4435                            regNumber        ireg /* = REG_NA */,
4436                            regNumber        xreg /* = REG_NA */,
4437                            unsigned         xmul /* = 0     */,
4438                            int              disp /* = 0     */,
4439                            bool             isJump /* = false */,
4440                            bool             isNoGC /* = false */,
4441                            bool             isProfLeaveCB /* = false */)
4442 {
4443     /* Sanity check the arguments depending on callType */
4444
4445     assert(callType < EC_COUNT);
4446     assert((callType != EC_FUNC_TOKEN && callType != EC_FUNC_ADDR) ||
4447            (ireg == REG_NA && xreg == REG_NA && xmul == 0 && disp == 0));
4448     assert(callType < EC_INDIR_R || addr == NULL);
4449     assert(callType != EC_INDIR_R || (ireg < REG_COUNT && xreg == REG_NA && xmul == 0 && disp == 0));
4450
4451     // ARM never uses these
4452     assert(xreg == REG_NA && xmul == 0 && disp == 0);
4453
4454     // Our stack level should be always greater than the bytes of arguments we push. Just
4455     // a sanity test.
4456     assert((unsigned)abs(argSize) <= codeGen->genStackLevel);
4457
4458     int        argCnt;
4459     instrDesc* id;
4460
4461     /* This is the saved set of registers after a normal call */
4462     regMaskTP savedSet = RBM_CALLEE_SAVED;
4463
4464     /* some special helper calls have a different saved set registers */
4465
4466     if (isNoGC)
4467     {
4468         assert(emitNoGChelper(Compiler::eeGetHelperNum(methHnd)));
4469
4470         // Get the set of registers that this call kills and remove it from the saved set.
4471         savedSet = RBM_ALLINT & ~emitComp->compNoGCHelperCallKillSet(Compiler::eeGetHelperNum(methHnd));
4472
4473         // In case of Leave profiler callback, we need to preserve liveness of REG_PROFILER_RET_SCRATCH
4474         if (isProfLeaveCB)
4475         {
4476             savedSet |= RBM_PROFILER_RET_SCRATCH;
4477         }
4478
4479 #ifdef DEBUG
4480         if (emitComp->verbose)
4481         {
4482             printf("NOGC Call: savedSet=");
4483             printRegMaskInt(savedSet);
4484             emitDispRegSet(savedSet);
4485             printf("\n");
4486         }
4487 #endif
4488     }
4489     else
4490     {
4491         assert(!emitNoGChelper(Compiler::eeGetHelperNum(methHnd)));
4492     }
4493
4494     /* Trim out any callee-trashed registers from the live set */
4495
4496     gcrefRegs &= savedSet;
4497     byrefRegs &= savedSet;
4498
4499 #ifdef DEBUG
4500     if (EMIT_GC_VERBOSE)
4501     {
4502         printf("Call: GCvars=%s ", VarSetOps::ToString(emitComp, ptrVars));
4503         dumpConvertedVarSet(emitComp, ptrVars);
4504         printf(", gcrefRegs=");
4505         printRegMaskInt(gcrefRegs);
4506         emitDispRegSet(gcrefRegs);
4507         printf(", byrefRegs=");
4508         printRegMaskInt(byrefRegs);
4509         emitDispRegSet(byrefRegs);
4510         printf("\n");
4511     }
4512 #endif
4513
4514     assert(argSize % (int)REGSIZE_BYTES == 0);
4515     argCnt = argSize / (int)REGSIZE_BYTES;
4516
4517     /* Managed RetVal: emit sequence point for the call */
4518     if (emitComp->opts.compDbgInfo && ilOffset != BAD_IL_OFFSET)
4519     {
4520         codeGen->genIPmappingAdd(ilOffset, false);
4521     }
4522
4523     /*
4524         We need to allocate the appropriate instruction descriptor based
4525         on whether this is a direct/indirect call, and whether we need to
4526         record an updated set of live GC variables.
4527
4528         The stats for a ton of classes is as follows:
4529
4530             Direct call w/o  GC vars        220,216
4531             Indir. call w/o  GC vars        144,781
4532
4533             Direct call with GC vars          9,440
4534             Indir. call with GC vars          5,768
4535      */
4536
4537     if (callType >= EC_INDIR_R)
4538     {
4539         /* Indirect call, virtual calls */
4540
4541         assert(callType == EC_INDIR_R);
4542
4543         id = emitNewInstrCallInd(argCnt, disp, ptrVars, gcrefRegs, byrefRegs, retSize);
4544     }
4545     else
4546     {
4547         /* Helper/static/nonvirtual/function calls (direct or through handle),
4548            and calls to an absolute addr. */
4549
4550         assert(callType == EC_FUNC_TOKEN || callType == EC_FUNC_ADDR);
4551
4552         id = emitNewInstrCallDir(argCnt, ptrVars, gcrefRegs, byrefRegs, retSize);
4553     }
4554
4555     /* Update the emitter's live GC ref sets */
4556
4557     VarSetOps::Assign(emitComp, emitThisGCrefVars, ptrVars);
4558     emitThisGCrefRegs = gcrefRegs;
4559     emitThisByrefRegs = byrefRegs;
4560
4561     /* Set the instruction - special case jumping a function */
4562     instruction ins;
4563     insFormat   fmt = IF_NONE;
4564
4565     id->idSetIsNoGC(isNoGC);
4566
4567     /* Record the address: method, indirection, or funcptr */
4568
4569     if (callType > EC_FUNC_ADDR)
4570     {
4571         /* This is an indirect call (either a virtual call or func ptr call) */
4572
4573         switch (callType)
4574         {
4575             case EC_INDIR_R: // the address is in a register
4576
4577                 id->idSetIsCallRegPtr();
4578
4579                 if (isJump)
4580                 {
4581                     ins = INS_bx; // INS_bx  Reg
4582                 }
4583                 else
4584                 {
4585                     ins = INS_blx; // INS_blx Reg
4586                 }
4587                 fmt = IF_T1_D2;
4588
4589                 id->idIns(ins);
4590                 id->idInsFmt(fmt);
4591                 id->idInsSize(emitInsSize(fmt));
4592                 id->idReg3(ireg);
4593                 assert(xreg == REG_NA);
4594                 break;
4595
4596             default:
4597                 NO_WAY("unexpected instruction");
4598                 break;
4599         }
4600     }
4601     else
4602     {
4603         /* This is a simple direct call: "call helper/method/addr" */
4604
4605         assert(callType == EC_FUNC_TOKEN || callType == EC_FUNC_ADDR);
4606
4607         // if addr is nullptr then this call is treated as a recursive call.
4608         assert(addr == nullptr || codeGen->arm_Valid_Imm_For_BL((ssize_t)addr));
4609
4610         if (isJump)
4611         {
4612             ins = INS_b; // INS_b imm24
4613         }
4614         else
4615         {
4616             ins = INS_bl; // INS_bl imm24
4617         }
4618
4619         fmt = IF_T2_J3;
4620
4621         id->idIns(ins);
4622         id->idInsFmt(fmt);
4623         id->idInsSize(emitInsSize(fmt));
4624
4625         id->idAddr()->iiaAddr = (BYTE*)addr;
4626
4627         if (callType == EC_FUNC_ADDR)
4628         {
4629             id->idSetIsCallAddr();
4630         }
4631
4632         if (emitComp->opts.compReloc)
4633         {
4634             // Since this is an indirect call through a pointer and we don't
4635             // currently pass in emitAttr into this function we have decided
4636             // to always mark the displacement as being relocatable.
4637
4638             id->idSetIsDspReloc();
4639         }
4640     }
4641
4642 #ifdef DEBUG
4643     if (EMIT_GC_VERBOSE)
4644     {
4645         if (id->idIsLargeCall())
4646         {
4647             printf("[%02u] Rec call GC vars = %s\n", id->idDebugOnlyInfo()->idNum,
4648                    VarSetOps::ToString(emitComp, ((instrDescCGCA*)id)->idcGCvars));
4649         }
4650     }
4651
4652     id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token
4653     id->idDebugOnlyInfo()->idCallSig   = sigInfo;
4654 #endif // DEBUG
4655
4656 #ifdef LATE_DISASM
4657     if (addr != nullptr)
4658     {
4659         codeGen->getDisAssembler().disSetMethod((size_t)addr, methHnd);
4660     }
4661 #endif // LATE_DISASM
4662
4663     dispIns(id);
4664     appendToCurIG(id);
4665 }
4666
4667 /*****************************************************************************
4668  *
4669  *  Returns an encoding for the specified register (any-reg) to be used in
4670  *   a Thumb-1 encoding in the M4 position
4671  */
4672
4673 inline unsigned insEncodeRegT1_M4(regNumber reg)
4674 {
4675     assert(reg < REG_STK);
4676
4677     return reg << 3;
4678 }
4679
4680 /*****************************************************************************
4681  *
4682  *  Returns an encoding for the specified register (any-reg) to be used in
4683  *   a Thumb-1 encoding in the D4 position
4684  */
4685
4686 inline unsigned insEncodeRegT1_D4(regNumber reg)
4687 {
4688     assert(reg < REG_STK);
4689
4690     return (reg & 0x7) | ((reg & 0x8) << 4);
4691 }
4692
4693 /*****************************************************************************
4694  *
4695  *  Returns an encoding for the specified register (low-only) to be used in
4696  *   a Thumb-1 encoding in the M3 position
4697  */
4698
4699 inline unsigned insEncodeRegT1_M3(regNumber reg)
4700 {
4701     assert(reg < REG_R8);
4702
4703     return reg << 6;
4704 }
4705
4706 /*****************************************************************************
4707  *
4708  *  Returns an encoding for the specified register (low-only) to be used in
4709  *   a Thumb-1 encoding in the N3 position
4710  */
4711
4712 inline unsigned insEncodeRegT1_N3(regNumber reg)
4713 {
4714     assert(reg < REG_R8);
4715
4716     return reg << 3;
4717 }
4718
4719 /*****************************************************************************
4720  *
4721  *  Returns an encoding for the specified register (low-only) to be used in
4722  *   a Thumb-1 encoding in the D3 position
4723  */
4724
4725 inline unsigned insEncodeRegT1_D3(regNumber reg)
4726 {
4727     assert(reg < REG_R8);
4728
4729     return reg;
4730 }
4731 /*****************************************************************************
4732  *
4733  *  Returns an encoding for the specified register (low-only) to be used in
4734  *   a Thumb-1 encoding in the DI position
4735  */
4736
4737 inline unsigned insEncodeRegT1_DI(regNumber reg)
4738 {
4739     assert(reg < REG_R8);
4740
4741     return reg << 8;
4742 }
4743
4744 /*****************************************************************************
4745  *
4746  *  Returns an encoding for the specified register to be used in
4747  *   a Thumb-2 encoding in the N position
4748  */
4749
4750 inline unsigned insEncodeRegT2_N(regNumber reg)
4751 {
4752     assert(reg < REG_STK);
4753
4754     return reg << 16;
4755 }
4756
4757 inline unsigned floatRegIndex(regNumber reg, int size)
4758 {
4759     // theoretically this could support quad floats as well but for now...
4760     assert(size == EA_8BYTE || size == EA_4BYTE);
4761
4762     if (size == EA_8BYTE)
4763         assert(emitter::isDoubleReg(reg));
4764     else
4765         assert(emitter::isFloatReg(reg));
4766
4767     unsigned result = reg - REG_F0;
4768
4769     // the assumption here is that the register F8 also refers to D4
4770     if (size == EA_8BYTE)
4771     {
4772         result >>= 1;
4773     }
4774
4775     return result;
4776 }
4777
4778 // variant: SOME arm VFP instructions use the convention that
4779 // for doubles, the split bit holds the msb of the register index
4780 // for singles it holds the lsb
4781 // excerpt : d = if dp_operation then UInt(D:Vd)
4782 // if single  UInt(Vd:D);
4783
4784 inline unsigned floatRegEncoding(unsigned index, int size, bool variant = false)
4785 {
4786     if (!variant || size == EA_8BYTE)
4787         return index;
4788     else
4789     {
4790         return ((index & 1) << 4) | (index >> 1);
4791     }
4792 }
4793
4794 // thumb2 VFP M register encoding
4795 inline unsigned insEncodeRegT2_VectorM(regNumber reg, int size, bool variant)
4796 {
4797     unsigned enc = floatRegIndex(reg, size);
4798     enc          = floatRegEncoding(enc, size, variant);
4799     return ((enc & 0xf) << 0) | ((enc & 0x10) << 1);
4800 }
4801
4802 // thumb2 VFP N register encoding
4803 inline unsigned insEncodeRegT2_VectorN(regNumber reg, int size, bool variant)
4804 {
4805     unsigned enc = floatRegIndex(reg, size);
4806     enc          = floatRegEncoding(enc, size, variant);
4807     return ((enc & 0xf) << 16) | ((enc & 0x10) << 3);
4808 }
4809
4810 // thumb2 VFP D register encoding
4811 inline unsigned insEncodeRegT2_VectorD(regNumber reg, int size, bool variant)
4812 {
4813     unsigned enc = floatRegIndex(reg, size);
4814     enc          = floatRegEncoding(enc, size, variant);
4815     return ((enc & 0xf) << 12) | ((enc & 0x10) << 18);
4816 }
4817
4818 /*****************************************************************************
4819  *
4820  *  Returns an encoding for the specified register to be used in
4821  *   a Thumb-2 encoding in the T position
4822  */
4823
4824 inline unsigned insEncodeRegT2_T(regNumber reg)
4825 {
4826     assert(reg < REG_STK);
4827
4828     return reg << 12;
4829 }
4830
4831 /*****************************************************************************
4832  *
4833  *  Returns an encoding for the specified register to be used in
4834  *   a Thumb-2 encoding in the D position
4835  */
4836
4837 inline unsigned insEncodeRegT2_D(regNumber reg)
4838 {
4839     assert(reg < REG_STK);
4840
4841     return reg << 8;
4842 }
4843
4844 /*****************************************************************************
4845  *
4846  *  Returns an encoding for the specified register to be used in
4847  *   a Thumb-2 encoding in the M position
4848  */
4849
4850 inline unsigned insEncodeRegT2_M(regNumber reg)
4851 {
4852     assert(reg < REG_STK);
4853
4854     return reg;
4855 }
4856
4857 /*****************************************************************************
4858  *
4859  *  Returns the encoding for the Set Flags bit to be used in a Thumb-2 encoding
4860  */
4861
4862 unsigned emitter::insEncodeSetFlags(insFlags sf)
4863 {
4864     if (sf == INS_FLAGS_SET)
4865         return (1 << 20);
4866     else
4867         return 0;
4868 }
4869
4870 /*****************************************************************************
4871  *
4872  *  Returns the encoding for the Shift Type bits to be used in a Thumb-2 encoding
4873  */
4874
4875 unsigned emitter::insEncodeShiftOpts(insOpts opt)
4876 {
4877     if (opt == INS_OPTS_NONE)
4878         return 0;
4879     else if (opt == INS_OPTS_LSL)
4880         return 0x00;
4881     else if (opt == INS_OPTS_LSR)
4882         return 0x10;
4883     else if (opt == INS_OPTS_ASR)
4884         return 0x20;
4885     else if (opt == INS_OPTS_ROR)
4886         return 0x30;
4887     else if (opt == INS_OPTS_RRX)
4888         return 0x30;
4889
4890     assert(!"Invalid insOpts");
4891     return 0;
4892 }
4893
4894 /*****************************************************************************
4895  *
4896  *  Returns the encoding for the PUW bits to be used in a T2_G0 Thumb-2 encoding
4897  */
4898
4899 unsigned emitter::insEncodePUW_G0(insOpts opt, int imm)
4900 {
4901     unsigned result = 0;
4902
4903     if (opt != INS_OPTS_LDST_POST_INC)
4904         result |= (1 << 24); // The P bit
4905
4906     if (imm >= 0)
4907         result |= (1 << 23); // The U bit
4908
4909     if (opt != INS_OPTS_NONE)
4910         result |= (1 << 21); // The W bits
4911     return result;
4912 }
4913
4914 /*****************************************************************************
4915  *
4916  *  Returns the encoding for the PUW bits to be used in a T2_H0 Thumb-2 encoding
4917  */
4918
4919 unsigned emitter::insEncodePUW_H0(insOpts opt, int imm)
4920 {
4921     unsigned result = 0;
4922
4923     if (opt != INS_OPTS_LDST_POST_INC)
4924         result |= (1 << 10); // The P bit
4925
4926     if (imm >= 0)
4927         result |= (1 << 9); // The U bit
4928
4929     if (opt != INS_OPTS_NONE)
4930         result |= (1 << 8); // The W bits
4931
4932     return result;
4933 }
4934
4935 /*****************************************************************************
4936  *
4937  *  Returns the encoding for the Shift Count bits to be used in a Thumb-2 encoding
4938  */
4939
4940 inline unsigned insEncodeShiftCount(int imm)
4941 {
4942     unsigned result;
4943
4944     assert((imm & 0x001F) == imm);
4945     result = (imm & 0x03) << 6;
4946     result |= (imm & 0x1C) << 10;
4947
4948     return result;
4949 }
4950
4951 /*****************************************************************************
4952  *
4953  *  Returns the encoding for the immediate use by BFI/BFC Thumb-2 encodings
4954  */
4955
4956 inline unsigned insEncodeBitFieldImm(int imm)
4957 {
4958     unsigned result;
4959
4960     assert((imm & 0x03FF) == imm);
4961     result = (imm & 0x001f);
4962     result |= (imm & 0x0060) << 1;
4963     result |= (imm & 0x0380) << 5;
4964
4965     return result;
4966 }
4967
4968 /*****************************************************************************
4969  *
4970  *  Unscales the immediate based on the operand size in 'size'
4971  */
4972 /*static*/ int emitter::insUnscaleImm(int imm, emitAttr size)
4973 {
4974     switch (size)
4975     {
4976         case EA_8BYTE:
4977         case EA_4BYTE:
4978             assert((imm & 0x0003) == 0);
4979             imm >>= 2;
4980             break;
4981
4982         case EA_2BYTE:
4983             assert((imm & 0x0001) == 0);
4984             imm >>= 1;
4985             break;
4986
4987         case EA_1BYTE:
4988             // Do nothing
4989             break;
4990
4991         default:
4992             assert(!"Invalid value in size");
4993             break;
4994     }
4995     return imm;
4996 }
4997
4998 /*****************************************************************************
4999  *
5000  *  Emit a Thumb-1 instruction (a 16-bit integer as code)
5001  */
5002
5003 /*static*/ unsigned emitter::emitOutput_Thumb1Instr(BYTE* dst, code_t code)
5004 {
5005     unsigned short word1 = code & 0xffff;
5006     assert(word1 == code);
5007
5008 #ifdef DEBUG
5009     unsigned short top5bits = (word1 & 0xf800) >> 11;
5010     assert(top5bits < 29);
5011 #endif
5012
5013     MISALIGNED_WR_I2(dst, word1);
5014
5015     return sizeof(short);
5016 }
5017 /*****************************************************************************
5018  *
5019  *  Emit a Thumb-2 instruction (two 16-bit integers as code)
5020  */
5021
5022 /*static*/ unsigned emitter::emitOutput_Thumb2Instr(BYTE* dst, code_t code)
5023 {
5024     unsigned short word1 = (code >> 16) & 0xffff;
5025     unsigned short word2 = (code)&0xffff;
5026     assert((code_t)((word1 << 16) | word2) == code);
5027
5028 #ifdef DEBUG
5029     unsigned short top5bits = (word1 & 0xf800) >> 11;
5030     assert(top5bits >= 29);
5031 #endif
5032
5033     MISALIGNED_WR_I2(dst, word1);
5034     dst += 2;
5035     MISALIGNED_WR_I2(dst, word2);
5036
5037     return sizeof(short) * 2;
5038 }
5039
5040 /*****************************************************************************
5041  *
5042  *  Output a local jump instruction.
5043  *  Note that this may be invoked to overwrite an existing jump instruction at 'dst'
5044  *  to handle forward branch patching.
5045  */
5046
5047 BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i)
5048 {
5049     unsigned srcOffs;
5050     unsigned dstOffs;
5051     ssize_t  distVal;
5052
5053     instrDescJmp* id  = (instrDescJmp*)i;
5054     instruction   ins = id->idIns();
5055     code_t        code;
5056
5057     bool loadLabel = false;
5058     bool isJump    = false;
5059     bool relAddr   = true; // does the instruction use relative-addressing?
5060
5061     size_t sdistneg;
5062
5063     switch (ins)
5064     {
5065         default:
5066             sdistneg = JCC_DIST_SMALL_MAX_NEG;
5067             isJump   = true;
5068             break;
5069
5070         case INS_cbz:
5071         case INS_cbnz:
5072             // One size fits all!
5073             sdistneg = 0;
5074             isJump   = true;
5075             break;
5076
5077         case INS_adr:
5078             sdistneg  = LBL_DIST_SMALL_MAX_NEG;
5079             loadLabel = true;
5080             break;
5081
5082         case INS_movw:
5083         case INS_movt:
5084             sdistneg  = LBL_DIST_SMALL_MAX_NEG;
5085             relAddr   = false;
5086             loadLabel = true;
5087             break;
5088     }
5089
5090     /* Figure out the distance to the target */
5091
5092     srcOffs = emitCurCodeOffs(dst);
5093     if (id->idAddr()->iiaHasInstrCount())
5094     {
5095         assert(ig != NULL);
5096         int      instrCount = id->idAddr()->iiaGetInstrCount();
5097         unsigned insNum     = emitFindInsNum(ig, id);
5098         if (instrCount < 0)
5099         {
5100             // Backward branches using instruction count must be within the same instruction group.
5101             assert(insNum + 1 >= (unsigned)(-instrCount));
5102         }
5103         dstOffs = ig->igOffs + emitFindOffset(ig, (insNum + 1 + instrCount));
5104     }
5105     else
5106     {
5107         dstOffs = id->idAddr()->iiaIGlabel->igOffs;
5108     }
5109
5110     if (relAddr)
5111     {
5112         if (ins == INS_adr)
5113         {
5114             // for adr, the distance is calculated from 4-byte aligned srcOffs.
5115             distVal = (ssize_t)((emitOffsetToPtr(dstOffs) - (BYTE*)(((size_t)emitOffsetToPtr(srcOffs)) & ~3)) + 1);
5116         }
5117         else
5118         {
5119             distVal = (ssize_t)(emitOffsetToPtr(dstOffs) - emitOffsetToPtr(srcOffs));
5120         }
5121     }
5122     else
5123     {
5124         assert(ins == INS_movw || ins == INS_movt);
5125         distVal = (ssize_t)emitOffsetToPtr(dstOffs) + 1; // Or in thumb bit
5126     }
5127
5128     if (dstOffs <= srcOffs)
5129     {
5130 /* This is a backward jump - distance is known at this point */
5131
5132 #if DEBUG_EMIT
5133         if (id->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
5134         {
5135             size_t blkOffs = id->idjIG->igOffs;
5136
5137             if (INTERESTING_JUMP_NUM == 0)
5138                 printf("[3] Jump %u:\n", id->idDebugOnlyInfo()->idNum);
5139             printf("[3] Jump  block is at %08X - %02X = %08X\n", blkOffs, emitOffsAdj, blkOffs - emitOffsAdj);
5140             printf("[3] Jump        is at %08X - %02X = %08X\n", srcOffs, emitOffsAdj, srcOffs - emitOffsAdj);
5141             printf("[3] Label block is at %08X - %02X = %08X\n", dstOffs, emitOffsAdj, dstOffs - emitOffsAdj);
5142         }
5143 #endif
5144
5145         // This format only supports forward branches
5146         noway_assert(id->idInsFmt() != IF_T1_I);
5147
5148         /* Can we use a short jump? */
5149
5150         if (isJump && ((unsigned)(distVal - 4) >= (unsigned)sdistneg))
5151         {
5152             emitSetShortJump(id);
5153         }
5154     }
5155     else
5156     {
5157         /* This is a  forward jump - distance will be an upper limit */
5158
5159         emitFwdJumps = true;
5160
5161         /* The target offset will be closer by at least 'emitOffsAdj', but only if this
5162            jump doesn't cross the hot-cold boundary. */
5163
5164         if (!emitJumpCrossHotColdBoundary(srcOffs, dstOffs))
5165         {
5166             dstOffs -= emitOffsAdj;
5167             distVal -= emitOffsAdj;
5168         }
5169
5170         /* Record the location of the jump for later patching */
5171
5172         id->idjOffs = dstOffs;
5173
5174         /* Are we overflowing the id->idjOffs bitfield? */
5175         if (id->idjOffs != dstOffs)
5176             IMPL_LIMITATION("Method is too large");
5177
5178 #if DEBUG_EMIT
5179         if (id->idDebugOnlyInfo()->idNum == (unsigned)INTERESTING_JUMP_NUM || INTERESTING_JUMP_NUM == 0)
5180         {
5181             size_t blkOffs = id->idjIG->igOffs;
5182
5183             if (INTERESTING_JUMP_NUM == 0)
5184                 printf("[4] Jump %u:\n", id->idDebugOnlyInfo()->idNum);
5185             printf("[4] Jump  block is at %08X\n", blkOffs);
5186             printf("[4] Jump        is at %08X\n", srcOffs);
5187             printf("[4] Label block is at %08X - %02X = %08X\n", dstOffs + emitOffsAdj, emitOffsAdj, dstOffs);
5188         }
5189 #endif
5190     }
5191
5192     /* Adjust the offset to emit relative to the end of the instruction */
5193
5194     if (relAddr)
5195         distVal -= 4;
5196
5197 #ifdef DEBUG
5198     if (0 && emitComp->verbose)
5199     {
5200         size_t sz          = 4; // Thumb-2 pretends all instructions are 4-bytes long for computing jump offsets?
5201         int    distValSize = id->idjShort ? 4 : 8;
5202         printf("; %s jump [%08X/%03u] from %0*X to %0*X: dist = %08XH\n", (dstOffs <= srcOffs) ? "Fwd" : "Bwd",
5203                dspPtr(id), id->idDebugOnlyInfo()->idNum, distValSize, srcOffs + sz, distValSize, dstOffs, distVal);
5204     }
5205 #endif
5206
5207     insFormat fmt = id->idInsFmt();
5208
5209     if (isJump)
5210     {
5211         /* What size jump should we use? */
5212
5213         if (id->idjShort)
5214         {
5215             /* Short jump */
5216
5217             assert(!id->idjKeepLong);
5218             assert(emitJumpCrossHotColdBoundary(srcOffs, dstOffs) == false);
5219
5220             assert(JMP_SIZE_SMALL == JCC_SIZE_SMALL);
5221             assert(JMP_SIZE_SMALL == 2);
5222
5223             /* For forward jumps, record the address of the distance value */
5224             id->idjTemp.idjAddr = (distVal > 0) ? dst : NULL;
5225
5226             dst = emitOutputShortBranch(dst, ins, fmt, distVal, id);
5227         }
5228         else
5229         {
5230             /* Long  jump */
5231
5232             /* For forward jumps, record the address of the distance value */
5233             id->idjTemp.idjAddr = (dstOffs > srcOffs) ? dst : NULL;
5234
5235             if (fmt == IF_LARGEJMP)
5236             {
5237                 // This is a pseudo-instruction format representing a large conditional branch, to allow
5238                 // us to get a greater branch target range than we can get by using a straightforward conditional
5239                 // branch. It is encoded as a short conditional branch that branches around a long unconditional
5240                 // branch.
5241                 //
5242                 // Conceptually, we have:
5243                 //
5244                 //      b<cond> L_target
5245                 //
5246                 // The code we emit is:
5247                 //
5248                 //      b<!cond> L_not  // 2 bytes. Note that we reverse the condition.
5249                 //      b L_target      // 4 bytes
5250                 //   L_not:
5251                 //
5252                 // Note that we don't actually insert any blocks: we simply encode "b <!cond> L_not" as a branch with
5253                 // the correct offset. Note also that this works for both integer and floating-point conditions, because
5254                 // the condition inversion takes ordered/unordered into account, preserving NaN behavior. For example,
5255                 // "GT" (greater than) is inverted to "LE" (less than, equal, or unordered).
5256                 //
5257                 // History: previously, we generated:
5258                 //      it<cond>
5259                 //      b L_target
5260                 // but the "it" instruction was deprecated, so we can't use it.
5261
5262                 dst = emitOutputShortBranch(dst,
5263                                             emitJumpKindToIns(emitReverseJumpKind(
5264                                                 emitInsToJumpKind(ins))), // reverse the conditional instruction
5265                                             IF_T1_K,
5266                                             6 - 4, /* 6 bytes from start of this large conditional pseudo-instruction to
5267                                                       L_not. Jumps are encoded as offset from instr address + 4. */
5268                                             NULL /* only used for cbz/cbnz */);
5269
5270                 // Now, pretend we've got a normal unconditional branch, and fall through to the code to emit that.
5271                 ins = INS_b;
5272                 fmt = IF_T2_J2;
5273
5274                 // The distVal was computed based on the beginning of the pseudo-instruction, which is
5275                 // the IT. So subtract the size of the IT from the offset, so it is relative to the
5276                 // unconditional branch.
5277                 distVal -= 2;
5278             }
5279
5280             code = emitInsCode(ins, fmt);
5281
5282             if (fmt == IF_T2_J1)
5283             {
5284                 // Can't use this form for jumps between the hot and cold regions
5285                 assert(!id->idjKeepLong);
5286                 assert(emitJumpCrossHotColdBoundary(srcOffs, dstOffs) == false);
5287
5288                 assert((distVal & 1) == 0);
5289                 assert(distVal >= -1048576);
5290                 assert(distVal <= 1048574);
5291
5292                 if (distVal < 0)
5293                     code |= 1 << 26;
5294                 code |= ((distVal >> 1) & 0x0007ff);
5295                 code |= (((distVal >> 1) & 0x01f800) << 5);
5296                 code |= (((distVal >> 1) & 0x020000) >> 4);
5297                 code |= (((distVal >> 1) & 0x040000) >> 7);
5298             }
5299             else if (fmt == IF_T2_J2)
5300             {
5301                 assert((distVal & 1) == 0);
5302                 if (emitComp->opts.compReloc && emitJumpCrossHotColdBoundary(srcOffs, dstOffs))
5303                 {
5304                     // dst isn't an actual final target location, just some intermediate
5305                     // location.  Thus we cannot make any guarantees about distVal (not
5306                     // even the direction/sign).  Instead we don't encode any offset and
5307                     // rely on the relocation to do all the work
5308                 }
5309                 else
5310                 {
5311                     assert(distVal >= CALL_DIST_MAX_NEG);
5312                     assert(distVal <= CALL_DIST_MAX_POS);
5313
5314                     if (distVal < 0)
5315                         code |= 1 << 26;
5316                     code |= ((distVal >> 1) & 0x0007ff);
5317                     code |= (((distVal >> 1) & 0x1ff800) << 5);
5318
5319                     bool S  = (distVal < 0);
5320                     bool I1 = ((distVal & 0x00800000) == 0);
5321                     bool I2 = ((distVal & 0x00400000) == 0);
5322
5323                     if (S ^ I1)
5324                         code |= (1 << 13); // J1 bit
5325                     if (S ^ I2)
5326                         code |= (1 << 11); // J2 bit
5327                 }
5328             }
5329             else
5330             {
5331                 assert(!"Unknown fmt");
5332             }
5333
5334             unsigned instrSize = emitOutput_Thumb2Instr(dst, code);
5335
5336             if (emitComp->opts.compReloc)
5337             {
5338                 if (emitJumpCrossHotColdBoundary(srcOffs, dstOffs))
5339                 {
5340                     assert(id->idjKeepLong);
5341                     if (emitComp->info.compMatchedVM)
5342                     {
5343                         void* target = emitOffsetToPtr(dstOffs);
5344                         emitRecordRelocation((void*)dst, target, IMAGE_REL_BASED_THUMB_BRANCH24);
5345                     }
5346                 }
5347             }
5348
5349             dst += instrSize;
5350         }
5351     }
5352     else if (loadLabel)
5353     {
5354         /* For forward jumps, record the address of the distance value */
5355         id->idjTemp.idjAddr = (distVal > 0) ? dst : NULL;
5356
5357         code = emitInsCode(ins, fmt);
5358
5359         if (fmt == IF_T1_J3)
5360         {
5361             assert((dstOffs & 3) == 0); // The target label must be 4-byte aligned
5362             assert(distVal >= 0);
5363             assert(distVal <= 1022);
5364             code |= ((distVal >> 2) & 0xff);
5365
5366             dst += emitOutput_Thumb1Instr(dst, code);
5367         }
5368         else if (fmt == IF_T2_M1)
5369         {
5370             assert(distVal >= -4095);
5371             assert(distVal <= +4095);
5372             if (distVal < 0)
5373             {
5374                 code |= 0x00A0 << 16;
5375                 distVal = -distVal;
5376             }
5377             assert((distVal & 0x0fff) == distVal);
5378             code |= (distVal & 0x00ff);
5379             code |= ((distVal & 0x0700) << 4);
5380
5381             code |= ((distVal & 0x0800) << 15);
5382             code |= id->idReg1() << 8;
5383
5384             dst += emitOutput_Thumb2Instr(dst, code);
5385         }
5386         else if (fmt == IF_T2_N1)
5387         {
5388             code |= insEncodeRegT2_D(id->idReg1());
5389             unsigned imm = distVal;
5390             if (ins == INS_movw)
5391             {
5392                 imm &= 0xffff;
5393             }
5394             else
5395             {
5396                 imm = (imm >> 16) & 0xffff;
5397             }
5398             ((instrDescJmp*)id)->idjTemp.idjAddr = (dstOffs > srcOffs) ? dst : NULL;
5399
5400             assert((imm & 0x0000ffff) == imm);
5401             code |= (imm & 0x00ff);
5402             code |= ((imm & 0x0700) << 4);
5403             code |= ((imm & 0x0800) << 15);
5404             code |= ((imm & 0xf000) << 4);
5405             dst += emitOutput_Thumb2Instr(dst, code);
5406
5407             if (id->idIsCnsReloc() || id->idIsDspReloc())
5408             {
5409                 assert(ins == INS_movt || ins == INS_movw);
5410                 if ((ins == INS_movt) && emitComp->info.compMatchedVM)
5411                     emitHandlePCRelativeMov32((void*)(dst - 8), (void*)distVal);
5412             }
5413         }
5414         else
5415         {
5416             assert(!"Unknown fmt");
5417         }
5418     }
5419
5420     return dst;
5421 }
5422
5423 /*****************************************************************************
5424  *
5425  *  Output a short branch instruction.
5426  */
5427
5428 BYTE* emitter::emitOutputShortBranch(BYTE* dst, instruction ins, insFormat fmt, ssize_t distVal, instrDescJmp* id)
5429 {
5430     code_t code;
5431
5432     code = emitInsCode(ins, fmt);
5433
5434     if (fmt == IF_T1_K)
5435     {
5436         assert((distVal & 1) == 0);
5437         assert(distVal >= -256);
5438         assert(distVal <= 254);
5439
5440         if (distVal < 0)
5441             code |= 1 << 7;
5442         code |= ((distVal >> 1) & 0x7f);
5443     }
5444     else if (fmt == IF_T1_M)
5445     {
5446         assert((distVal & 1) == 0);
5447         assert(distVal >= -2048);
5448         assert(distVal <= 2046);
5449
5450         if (distVal < 0)
5451             code |= 1 << 10;
5452         code |= ((distVal >> 1) & 0x3ff);
5453     }
5454     else if (fmt == IF_T1_I)
5455     {
5456         assert(id != NULL);
5457         assert(ins == INS_cbz || INS_cbnz);
5458         assert((distVal & 1) == 0);
5459         assert(distVal >= 0);
5460         assert(distVal <= 126);
5461
5462         code |= ((distVal << 3) & 0x0200);
5463         code |= ((distVal << 2) & 0x00F8);
5464         code |= (id->idReg1() & 0x0007);
5465     }
5466     else
5467     {
5468         assert(!"Unknown fmt");
5469     }
5470
5471     dst += emitOutput_Thumb1Instr(dst, code);
5472
5473     return dst;
5474 }
5475
5476 #ifdef FEATURE_ITINSTRUCTION
5477
5478 /*****************************************************************************
5479  * The "IT" instruction is deprecated (with a very few exceptions). Don't generate it!
5480  * Don't delete this code, though, in case we ever want to bring it back.
5481  *****************************************************************************/
5482
5483 /*****************************************************************************
5484  *
5485  *  Output an IT instruction.
5486  */
5487
5488 BYTE* emitter::emitOutputIT(BYTE* dst, instruction ins, insFormat fmt, code_t condcode)
5489 {
5490     code_t imm0;
5491     code_t code, mask, bit;
5492
5493     code = emitInsCode(ins, fmt);
5494     code |= (condcode << 4);        // encode firstcond
5495     imm0 = condcode & 1;            // this is firstcond[0]
5496     mask = code & 0x0f;             // initialize mask encoded in opcode
5497     bit  = 0x08;                    // where in mask we are encoding
5498     while ((mask & (bit - 1)) != 0) // are the remaining bits all zeros?
5499     {                               //  then we are done
5500         // otherwise determine the setting of bit
5501         if ((imm0 == 1) ^ ((bit & mask) != 0))
5502         {
5503             code |= bit; // set the current bit
5504         }
5505         else
5506         {
5507             code &= ~bit; // clear the current bit
5508         }
5509         bit >>= 1;
5510     }
5511     dst += emitOutput_Thumb1Instr(dst, code);
5512
5513     return dst;
5514 }
5515
5516 #endif // FEATURE_ITINSTRUCTION
5517
5518 /*****************************************************************************
5519  *
5520  *  Output a 32-bit nop instruction.
5521  */
5522
5523 BYTE* emitter::emitOutputNOP(BYTE* dst, instruction ins, insFormat fmt)
5524 {
5525     code_t code = emitInsCode(ins, fmt);
5526
5527     dst += emitOutput_Thumb2Instr(dst, code);
5528
5529     return dst;
5530 }
5531
5532 /*****************************************************************************
5533 *
5534  *  Append the machine code corresponding to the given instruction descriptor
5535  *  to the code block at '*dp'; the base of the code block is 'bp', and 'ig'
5536  *  is the instruction group that contains the instruction. Updates '*dp' to
5537  *  point past the generated code, and returns the size of the instruction
5538  *  descriptor in bytes.
5539  */
5540
5541 size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
5542 {
5543     BYTE*         dst           = *dp;
5544     BYTE*         odst          = dst;
5545     code_t        code          = 0;
5546     size_t        sz            = 0;
5547     instruction   ins           = id->idIns();
5548     insFormat     fmt           = id->idInsFmt();
5549     emitAttr      size          = id->idOpSize();
5550     unsigned char callInstrSize = 0;
5551     ssize_t       condcode;
5552
5553 #ifdef DEBUG
5554     bool dspOffs = emitComp->opts.dspGCtbls || !emitComp->opts.disDiffable;
5555 #endif // DEBUG
5556
5557     assert(REG_NA == (int)REG_NA);
5558
5559     VARSET_TP GCvars(VarSetOps::UninitVal());
5560
5561     /* What instruction format have we got? */
5562
5563     switch (fmt)
5564     {
5565         int       imm;
5566         int       imm0;
5567         int       mask;
5568         int       bit;
5569         BYTE*     addr;
5570         regMaskTP gcrefRegs;
5571         regMaskTP byrefRegs;
5572
5573         case IF_T1_A: // T1_A    ................
5574             sz   = SMALL_IDSC_SIZE;
5575             code = emitInsCode(ins, fmt);
5576             dst += emitOutput_Thumb1Instr(dst, code);
5577             break;
5578
5579 #ifdef FEATURE_ITINSTRUCTION
5580         case IF_T1_B: // T1_B    ........cccc....                                           cond
5581             assert(id->idGCref() == GCT_NONE);
5582             condcode = emitGetInsSC(id);
5583             dst      = emitOutputIT(dst, ins, fmt, condcode);
5584             sz       = SMALL_IDSC_SIZE;
5585             break;
5586 #endif // FEATURE_ITINSTRUCTION
5587
5588         case IF_T1_C: // T1_C    .....iiiiinnnddd                       R1  R2              imm5
5589             sz   = SMALL_IDSC_SIZE;
5590             imm  = emitGetInsSC(id);
5591             code = emitInsCode(ins, fmt);
5592             code |= insEncodeRegT1_D3(id->idReg1());
5593             code |= insEncodeRegT1_N3(id->idReg2());
5594             if (emitInsIsLoadOrStore(ins))
5595             {
5596                 imm = insUnscaleImm(imm, size);
5597             }
5598             assert((imm & 0x001f) == imm);
5599             code |= (imm << 6);
5600             dst += emitOutput_Thumb1Instr(dst, code);
5601             break;
5602
5603         case IF_T1_D0: // T1_D0   ........Dmmmmddd                       R1* R2*
5604             sz   = SMALL_IDSC_SIZE;
5605             code = emitInsCode(ins, fmt);
5606             code |= insEncodeRegT1_D4(id->idReg1());
5607             code |= insEncodeRegT1_M4(id->idReg2());
5608             dst += emitOutput_Thumb1Instr(dst, code);
5609             break;
5610
5611         case IF_T1_E: // T1_E    ..........nnnddd                       R1  R2
5612             sz   = SMALL_IDSC_SIZE;
5613             code = emitInsCode(ins, fmt);
5614             code |= insEncodeRegT1_D3(id->idReg1());
5615             code |= insEncodeRegT1_N3(id->idReg2());
5616             dst += emitOutput_Thumb1Instr(dst, code);
5617             break;
5618
5619         case IF_T1_F: // T1_F    .........iiiiiii                       SP                  imm7
5620             sz   = emitGetInstrDescSize(id);
5621             imm  = emitGetInsSC(id);
5622             code = emitInsCode(ins, fmt);
5623             imm  = insUnscaleImm(imm, size);
5624             assert((imm & 0x007F) == imm);
5625             code |= imm;
5626             dst += emitOutput_Thumb1Instr(dst, code);
5627             break;
5628
5629         case IF_T1_G: // T1_G    .......iiinnnddd                       R1  R2              imm3
5630             sz   = SMALL_IDSC_SIZE;
5631             imm  = emitGetInsSC(id);
5632             code = emitInsCode(ins, fmt);
5633             code |= insEncodeRegT1_D3(id->idReg1());
5634             code |= insEncodeRegT1_N3(id->idReg2());
5635             assert((imm & 0x0007) == imm);
5636             code |= (imm << 6);
5637             dst += emitOutput_Thumb1Instr(dst, code);
5638             break;
5639
5640         case IF_T1_H: // T1_H    .......mmmnnnddd                       R1  R2  R3
5641             sz   = emitGetInstrDescSize(id);
5642             code = emitInsCode(ins, fmt);
5643             code |= insEncodeRegT1_D3(id->idReg1());
5644             code |= insEncodeRegT1_N3(id->idReg2());
5645             code |= insEncodeRegT1_M3(id->idReg3());
5646             dst += emitOutput_Thumb1Instr(dst, code);
5647             break;
5648
5649         case IF_T1_I: // T1_I    ......i.iiiiiddd                       R1                  imm6
5650             assert(id->idIsBound());
5651
5652             dst = emitOutputLJ(ig, dst, id);
5653             sz  = sizeof(instrDescJmp);
5654             break;
5655
5656         case IF_T1_J0: // T1_J0   .....dddiiiiiiii                       R1                  imm8
5657         case IF_T1_J1: // T1_J1   .....dddiiiiiiii                       R1                  <regmask8>
5658         case IF_T1_J2: // T1_J2   .....dddiiiiiiii                       R1  SP              imm8
5659             sz   = emitGetInstrDescSize(id);
5660             imm  = emitGetInsSC(id);
5661             code = emitInsCode(ins, fmt);
5662             code |= insEncodeRegT1_DI(id->idReg1());
5663             if (fmt == IF_T1_J2)
5664             {
5665                 imm = insUnscaleImm(imm, size);
5666             }
5667             assert((imm & 0x00ff) == imm);
5668             code |= imm;
5669             dst += emitOutput_Thumb1Instr(dst, code);
5670             break;
5671
5672         case IF_T1_L0: // T1_L0   ........iiiiiiii                                           imm8
5673         case IF_T1_L1: // T1_L1   .......Rrrrrrrrr                                           <regmask8>
5674             sz   = emitGetInstrDescSize(id);
5675             imm  = emitGetInsSC(id);
5676             code = emitInsCode(ins, fmt);
5677             if (fmt == IF_T1_L1)
5678             {
5679                 assert((imm & 0x3) != 0x3);
5680                 if (imm & 0x3)
5681                     code |= 0x0100; //  R bit
5682                 imm >>= 2;
5683             }
5684             assert((imm & 0x00ff) == imm);
5685             code |= imm;
5686             dst += emitOutput_Thumb1Instr(dst, code);
5687             break;
5688
5689         case IF_T2_A: // T2_A    ................ ................
5690             sz   = SMALL_IDSC_SIZE;
5691             code = emitInsCode(ins, fmt);
5692             dst += emitOutput_Thumb2Instr(dst, code);
5693             break;
5694
5695         case IF_T2_B: // T2_B    ................ ............iiii                          imm4
5696             sz   = SMALL_IDSC_SIZE;
5697             imm  = emitGetInsSC(id);
5698             code = emitInsCode(ins, fmt);
5699             assert((imm & 0x000F) == imm);
5700             code |= imm;
5701             dst += emitOutput_Thumb2Instr(dst, code);
5702             break;
5703
5704         case IF_T2_C0: // T2_C0   ...........Snnnn .iiiddddiishmmmm       R1  R2  R3      S, imm5, sh
5705         case IF_T2_C4: // T2_C4   ...........Snnnn ....dddd....mmmm       R1  R2  R3      S
5706         case IF_T2_C5: // T2_C5   ............nnnn ....dddd....mmmm       R1  R2  R3
5707             sz   = emitGetInstrDescSize(id);
5708             code = emitInsCode(ins, fmt);
5709             code |= insEncodeRegT2_D(id->idReg1());
5710             code |= insEncodeRegT2_N(id->idReg2());
5711             code |= insEncodeRegT2_M(id->idReg3());
5712             if (fmt != IF_T2_C5)
5713                 code |= insEncodeSetFlags(id->idInsFlags());
5714             if (fmt == IF_T2_C0)
5715             {
5716                 imm = emitGetInsSC(id);
5717                 code |= insEncodeShiftCount(imm);
5718                 code |= insEncodeShiftOpts(id->idInsOpt());
5719             }
5720             dst += emitOutput_Thumb2Instr(dst, code);
5721             break;
5722
5723         case IF_T2_C1: // T2_C1   ...........S.... .iiiddddiishmmmm       R1  R2          S, imm5, sh
5724         case IF_T2_C2: // T2_C2   ...........S.... .iiiddddii..mmmm       R1  R2          S, imm5
5725         case IF_T2_C6: // T2_C6   ................ ....dddd..iimmmm       R1  R2                   imm2
5726             sz   = SMALL_IDSC_SIZE;
5727             imm  = emitGetInsSC(id);
5728             code = emitInsCode(ins, fmt);
5729             code |= insEncodeRegT2_D(id->idReg1());
5730             code |= insEncodeRegT2_M(id->idReg2());
5731             if (fmt == IF_T2_C6)
5732             {
5733                 assert((imm & 0x0018) == imm);
5734                 code |= (imm << 1);
5735             }
5736             else
5737             {
5738                 code |= insEncodeSetFlags(id->idInsFlags());
5739                 code |= insEncodeShiftCount(imm);
5740                 if (fmt == IF_T2_C1)
5741                     code |= insEncodeShiftOpts(id->idInsOpt());
5742             }
5743             dst += emitOutput_Thumb2Instr(dst, code);
5744             break;
5745
5746         case IF_T2_C3: // T2_C3   ...........S.... ....dddd....mmmm       R1  R2          S
5747             sz   = SMALL_IDSC_SIZE;
5748             code = emitInsCode(ins, fmt);
5749             code |= insEncodeRegT2_D(id->idReg1());
5750             code |= insEncodeRegT2_M(id->idReg2());
5751             code |= insEncodeSetFlags(id->idInsFlags());
5752             dst += emitOutput_Thumb2Instr(dst, code);
5753             break;
5754
5755         case IF_T2_C7: // T2_C7   ............nnnn ..........shmmmm       R1  R2                   imm2
5756         case IF_T2_C8: // T2_C8   ............nnnn .iii....iishmmmm       R1  R2             imm5, sh
5757             sz   = SMALL_IDSC_SIZE;
5758             imm  = emitGetInsSC(id);
5759             code = emitInsCode(ins, fmt);
5760             code |= insEncodeRegT2_N(id->idReg1());
5761             code |= insEncodeRegT2_M(id->idReg2());
5762             if (fmt == IF_T2_C7)
5763             {
5764                 assert((imm & 0x0003) == imm);
5765                 code |= (imm << 4);
5766             }
5767             else if (fmt == IF_T2_C8)
5768             {
5769                 code |= insEncodeShiftCount(imm);
5770                 code |= insEncodeShiftOpts(id->idInsOpt());
5771             }
5772             dst += emitOutput_Thumb2Instr(dst, code);
5773             break;
5774
5775         case IF_T2_C9: // T2_C9   ............nnnn ............mmmm       R1  R2
5776             sz   = SMALL_IDSC_SIZE;
5777             code = emitInsCode(ins, fmt);
5778             code |= insEncodeRegT2_N(id->idReg1());
5779             code |= insEncodeRegT2_M(id->idReg2());
5780             dst += emitOutput_Thumb2Instr(dst, code);
5781             break;
5782
5783         case IF_T2_C10: // T2_C10  ............mmmm ....dddd....mmmm       R1  R2
5784             sz   = SMALL_IDSC_SIZE;
5785             code = emitInsCode(ins, fmt);
5786             code |= insEncodeRegT2_D(id->idReg1());
5787             code |= insEncodeRegT2_M(id->idReg2());
5788             code |= insEncodeRegT2_N(id->idReg2());
5789             dst += emitOutput_Thumb2Instr(dst, code);
5790             break;
5791
5792         case IF_T2_D0: // T2_D0   ............nnnn .iiiddddii.wwwww       R1  R2             imm5, imm5
5793         case IF_T2_D1: // T2_D1   ................ .iiiddddii.wwwww       R1                 imm5, imm5
5794             sz   = SMALL_IDSC_SIZE;
5795             imm  = emitGetInsSC(id);
5796             code = emitInsCode(ins, fmt);
5797             code |= insEncodeRegT2_D(id->idReg1());
5798             if (fmt == IF_T2_D0)
5799                 code |= insEncodeRegT2_N(id->idReg2());
5800             code |= insEncodeBitFieldImm(imm);
5801             dst += emitOutput_Thumb2Instr(dst, code);
5802             break;
5803
5804         case IF_T2_E0: // T2_E0   ............nnnn tttt......shmmmm       R1  R2  R3               imm2
5805         case IF_T2_E1: // T2_E1   ............nnnn tttt............       R1  R2
5806         case IF_T2_E2: // T2_E2   ................ tttt............       R1
5807             code = emitInsCode(ins, fmt);
5808             code |= insEncodeRegT2_T(id->idReg1());
5809             if (fmt == IF_T2_E0)
5810             {
5811                 sz = emitGetInstrDescSize(id);
5812                 code |= insEncodeRegT2_N(id->idReg2());
5813                 if (id->idIsLclVar())
5814                 {
5815                     code |= insEncodeRegT2_M(codeGen->rsGetRsvdReg());
5816                     imm = 0;
5817                 }
5818                 else
5819                 {
5820                     code |= insEncodeRegT2_M(id->idReg3());
5821                     imm = emitGetInsSC(id);
5822                     assert((imm & 0x0003) == imm);
5823                     code |= (imm << 4);
5824                 }
5825             }
5826             else
5827             {
5828                 sz = SMALL_IDSC_SIZE;
5829                 if (fmt != IF_T2_E2)
5830                 {
5831                     code |= insEncodeRegT2_N(id->idReg2());
5832                 }
5833             }
5834             dst += emitOutput_Thumb2Instr(dst, code);
5835             break;
5836
5837         case IF_T2_F1: // T2_F1    ............nnnn ttttdddd....mmmm       R1  R2  R3  R4
5838             sz = emitGetInstrDescSize(id);
5839             ;
5840             code = emitInsCode(ins, fmt);
5841             code |= insEncodeRegT2_T(id->idReg1());
5842             code |= insEncodeRegT2_D(id->idReg2());
5843             code |= insEncodeRegT2_N(id->idReg3());
5844             code |= insEncodeRegT2_M(id->idReg4());
5845             dst += emitOutput_Thumb2Instr(dst, code);
5846             break;
5847
5848         case IF_T2_F2: // T2_F2    ............nnnn aaaadddd....mmmm       R1  R2  R3  R4
5849             sz   = emitGetInstrDescSize(id);
5850             code = emitInsCode(ins, fmt);
5851             code |= insEncodeRegT2_D(id->idReg1());
5852             code |= insEncodeRegT2_N(id->idReg2());
5853             code |= insEncodeRegT2_M(id->idReg3());
5854             code |= insEncodeRegT2_T(id->idReg4());
5855             dst += emitOutput_Thumb2Instr(dst, code);
5856             break;
5857
5858         case IF_T2_G0: // T2_G0   .......PU.W.nnnn ttttTTTTiiiiiiii       R1  R2  R3         imm8, PUW
5859         case IF_T2_G1: // T2_G1   ............nnnn ttttTTTT........       R1  R2  R3
5860             code = emitInsCode(ins, fmt);
5861             code |= insEncodeRegT2_T(id->idReg1());
5862             code |= insEncodeRegT2_D(id->idReg2());
5863             code |= insEncodeRegT2_N(id->idReg3());
5864             if (fmt == IF_T2_G0)
5865             {
5866                 sz  = emitGetInstrDescSizeSC(id);
5867                 imm = emitGetInsSC(id);
5868                 assert(unsigned_abs(imm) <= 0x00ff);
5869                 code |= abs(imm);
5870                 code |= insEncodePUW_G0(id->idInsOpt(), imm);
5871             }
5872             else
5873             {
5874                 sz = emitGetInstrDescSize(id);
5875             }
5876             dst += emitOutput_Thumb2Instr(dst, code);
5877             break;
5878
5879         case IF_T2_H0: // T2_H0   ............nnnn tttt.PUWiiiiiiii       R1  R2             imm8, PUW
5880         case IF_T2_H1: // T2_H1   ............nnnn tttt....iiiiiiii       R1  R2             imm8
5881         case IF_T2_H2: // T2_H2   ............nnnn ........iiiiiiii       R1                 imm8
5882             sz   = emitGetInstrDescSizeSC(id);
5883             imm  = emitGetInsSC(id);
5884             code = emitInsCode(ins, fmt);
5885             code |= insEncodeRegT2_T(id->idReg1());
5886
5887             if (fmt != IF_T2_H2)
5888                 code |= insEncodeRegT2_N(id->idReg2());
5889
5890             if (fmt == IF_T2_H0)
5891             {
5892                 assert(unsigned_abs(imm) <= 0x00ff);
5893                 code |= insEncodePUW_H0(id->idInsOpt(), imm);
5894                 code |= unsigned_abs(imm);
5895             }
5896             else
5897             {
5898                 assert((imm & 0x00ff) == imm);
5899                 code |= imm;
5900             }
5901             dst += emitOutput_Thumb2Instr(dst, code);
5902             break;
5903
5904         case IF_T2_I0: // T2_I0   ..........W.nnnn rrrrrrrrrrrrrrrr       R1              W, imm16
5905         case IF_T2_I1: // T2_I1   ................ rrrrrrrrrrrrrrrr                          imm16
5906             sz   = emitGetInstrDescSizeSC(id);
5907             code = emitInsCode(ins, fmt);
5908             if (fmt == IF_T2_I0)
5909             {
5910                 code |= insEncodeRegT2_N(id->idReg1());
5911                 code |= (1 << 21); //  W bit
5912             }
5913             imm = emitGetInsSC(id);
5914             assert((imm & 0x3) != 0x3);
5915             if (imm & 0x2)
5916                 code |= 0x8000; //  PC bit
5917             if (imm & 0x1)
5918                 code |= 0x4000; //  LR bit
5919             imm >>= 2;
5920             assert(imm <= 0x1fff); //  13 bits
5921             code |= imm;
5922             dst += emitOutput_Thumb2Instr(dst, code);
5923             break;
5924
5925         case IF_T2_K1: // T2_K1   ............nnnn ttttiiiiiiiiiiii       R1  R2             imm12
5926         case IF_T2_K4: // T2_K4   ........U....... ttttiiiiiiiiiiii       R1  PC          U, imm12
5927         case IF_T2_K3: // T2_K3   ........U....... ....iiiiiiiiiiii       PC              U, imm12
5928             sz   = emitGetInstrDescSize(id);
5929             imm  = emitGetInsSC(id);
5930             code = emitInsCode(ins, fmt);
5931             if (fmt != IF_T2_K3)
5932             {
5933                 code |= insEncodeRegT2_T(id->idReg1());
5934             }
5935             if (fmt == IF_T2_K1)
5936             {
5937                 code |= insEncodeRegT2_N(id->idReg2());
5938                 assert(imm <= 0xfff); //  12 bits
5939                 code |= imm;
5940             }
5941             else
5942             {
5943                 assert(unsigned_abs(imm) <= 0xfff); //  12 bits (signed)
5944                 code |= abs(imm);
5945                 if (imm >= 0)
5946                     code |= (1 << 23); //  U bit
5947             }
5948             dst += emitOutput_Thumb2Instr(dst, code);
5949             break;
5950
5951         case IF_T2_K2: // T2_K2   ............nnnn ....iiiiiiiiiiii       R1                 imm12
5952             sz   = emitGetInstrDescSizeSC(id);
5953             imm  = emitGetInsSC(id);
5954             code = emitInsCode(ins, fmt);
5955             code |= insEncodeRegT2_N(id->idReg1());
5956             assert(imm <= 0xfff); //  12 bits
5957             code |= imm;
5958             dst += emitOutput_Thumb2Instr(dst, code);
5959             break;
5960
5961         case IF_T2_L0: // T2_L0   .....i.....Snnnn .iiiddddiiiiiiii       R1  R2          S, imm8<<imm4
5962         case IF_T2_L1: // T2_L1   .....i.....S.... .iiiddddiiiiiiii       R1              S, imm8<<imm4
5963         case IF_T2_L2: // T2_L2   .....i......nnnn .iii....iiiiiiii       R1                 imm8<<imm4
5964             sz   = emitGetInstrDescSize(id);
5965             imm  = emitGetInsSC(id);
5966             code = emitInsCode(ins, fmt);
5967
5968             if (fmt == IF_T2_L2)
5969                 code |= insEncodeRegT2_N(id->idReg1());
5970             else
5971             {
5972                 code |= insEncodeSetFlags(id->idInsFlags());
5973                 code |= insEncodeRegT2_D(id->idReg1());
5974                 if (fmt == IF_T2_L0)
5975                     code |= insEncodeRegT2_N(id->idReg2());
5976             }
5977             assert(isModImmConst(imm)); // Funky ARM imm encoding
5978             imm = encodeModImmConst(imm);
5979             assert(imm <= 0xfff); //  12 bits
5980             code |= (imm & 0x00ff);
5981             code |= (imm & 0x0700) << 4;
5982             code |= (imm & 0x0800) << 15;
5983             dst += emitOutput_Thumb2Instr(dst, code);
5984             break;
5985
5986         case IF_T2_M0: // T2_M0   .....i......nnnn .iiiddddiiiiiiii       R1  R2             imm12
5987             sz   = emitGetInstrDescSizeSC(id);
5988             imm  = emitGetInsSC(id);
5989             code = emitInsCode(ins, fmt);
5990             code |= insEncodeRegT2_D(id->idReg1());
5991             if (fmt == IF_T2_M0)
5992                 code |= insEncodeRegT2_N(id->idReg2());
5993             imm = emitGetInsSC(id);
5994             assert(imm <= 0xfff); //  12 bits
5995             code |= (imm & 0x00ff);
5996             code |= (imm & 0x0700) << 4;
5997             code |= (imm & 0x0800) << 15;
5998             dst += emitOutput_Thumb2Instr(dst, code);
5999             break;
6000
6001         case IF_T2_N:  // T2_N    .....i......iiii .iiiddddiiiiiiii       R1                 imm16
6002         case IF_T2_N2: // T2_N2   .....i......iiii .iiiddddiiiiiiii       R1                 imm16
6003             sz   = emitGetInstrDescSizeSC(id);
6004             code = emitInsCode(ins, fmt);
6005             code |= insEncodeRegT2_D(id->idReg1());
6006             imm = emitGetInsSC(id);
6007             if (fmt == IF_T2_N2)
6008             {
6009                 assert(!id->idIsLclVar());
6010                 assert((ins == INS_movw) || (ins == INS_movt));
6011                 imm += (size_t)emitConsBlock;
6012                 if (!id->idIsCnsReloc() && !id->idIsDspReloc())
6013                 {
6014                     goto SPLIT_IMM;
6015                 }
6016             }
6017             else if (id->idIsLclVar())
6018             {
6019             SPLIT_IMM:
6020                 if (ins == INS_movw)
6021                 {
6022                     imm &= 0xffff;
6023                 }
6024                 else
6025                 {
6026                     imm = (imm >> 16) & 0xffff;
6027                 }
6028             }
6029
6030             if (id->idIsCnsReloc() || id->idIsDspReloc())
6031             {
6032                 assert((ins == INS_movt) || (ins == INS_movw));
6033                 dst += emitOutput_Thumb2Instr(dst, code);
6034                 if ((ins == INS_movt) && emitComp->info.compMatchedVM)
6035                     emitHandlePCRelativeMov32((void*)(dst - 8), (void*)imm);
6036             }
6037             else
6038             {
6039                 assert((imm & 0x0000ffff) == imm);
6040                 code |= (imm & 0x00ff);
6041                 code |= ((imm & 0x0700) << 4);
6042                 code |= ((imm & 0x0800) << 15);
6043                 code |= ((imm & 0xf000) << 4);
6044                 dst += emitOutput_Thumb2Instr(dst, code);
6045             }
6046             break;
6047
6048         case IF_T2_VFP3:
6049             // these are the binary operators
6050             // d = n - m
6051             sz   = emitGetInstrDescSize(id);
6052             code = emitInsCode(ins, fmt);
6053             code |= insEncodeRegT2_VectorN(id->idReg2(), size, true);
6054             code |= insEncodeRegT2_VectorM(id->idReg3(), size, true);
6055             code |= insEncodeRegT2_VectorD(id->idReg1(), size, true);
6056             if (size == EA_8BYTE)
6057                 code |= 1 << 8;
6058             dst += emitOutput_Thumb2Instr(dst, code);
6059             break;
6060
6061         case IF_T2_VFP2:
6062         {
6063             emitAttr srcSize;
6064             emitAttr dstSize;
6065             size_t   szCode = 0;
6066
6067             switch (ins)
6068             {
6069                 case INS_vcvt_i2d:
6070                 case INS_vcvt_u2d:
6071                 case INS_vcvt_f2d:
6072                     srcSize = EA_4BYTE;
6073                     dstSize = EA_8BYTE;
6074                     break;
6075
6076                 case INS_vcvt_d2i:
6077                 case INS_vcvt_d2u:
6078                 case INS_vcvt_d2f:
6079                     srcSize = EA_8BYTE;
6080                     dstSize = EA_4BYTE;
6081                     break;
6082
6083                 case INS_vmov:
6084                 case INS_vabs:
6085                 case INS_vsqrt:
6086                 case INS_vcmp:
6087                 case INS_vneg:
6088                     if (id->idOpSize() == EA_8BYTE)
6089                         szCode |= (1 << 8);
6090                     __fallthrough;
6091
6092                 default:
6093                     srcSize = dstSize = id->idOpSize();
6094                     break;
6095             }
6096
6097             sz   = emitGetInstrDescSize(id);
6098             code = emitInsCode(ins, fmt);
6099             code |= szCode;
6100             code |= insEncodeRegT2_VectorD(id->idReg1(), dstSize, true);
6101             code |= insEncodeRegT2_VectorM(id->idReg2(), srcSize, true);
6102
6103             dst += emitOutput_Thumb2Instr(dst, code);
6104             break;
6105         }
6106
6107         case IF_T2_VLDST:
6108             sz   = emitGetInstrDescSizeSC(id);
6109             code = emitInsCode(ins, fmt);
6110             code |= insEncodeRegT2_N(id->idReg2());
6111             code |= insEncodeRegT2_VectorD(id->idReg1(), size, true);
6112
6113             imm = emitGetInsSC(id);
6114             if (imm < 0)
6115                 imm = -imm; // bit 23 at 0 means negate
6116             else
6117                 code |= 1 << 23; // set the positive bit
6118
6119             // offset is +/- 1020
6120             assert(!(imm % 4));
6121             assert(imm >> 10 == 0);
6122             code |= imm >> 2;
6123             // bit 8 is set for doubles
6124             if (id->idOpSize() == EA_8BYTE)
6125                 code |= (1 << 8);
6126             dst += emitOutput_Thumb2Instr(dst, code);
6127             break;
6128
6129         case IF_T2_VMOVD:
6130             // 3op assemble a double from two int regs (or back)
6131             sz   = emitGetInstrDescSize(id);
6132             code = emitInsCode(ins, fmt);
6133             if (ins == INS_vmov_i2d)
6134             {
6135                 code |= insEncodeRegT2_VectorM(id->idReg1(), size, true);
6136                 code |= id->idReg2() << 12;
6137                 code |= id->idReg3() << 16;
6138             }
6139             else
6140             {
6141                 assert(ins == INS_vmov_d2i);
6142                 code |= id->idReg1() << 12;
6143                 code |= id->idReg2() << 16;
6144                 code |= insEncodeRegT2_VectorM(id->idReg3(), size, true);
6145             }
6146             dst += emitOutput_Thumb2Instr(dst, code);
6147             break;
6148
6149         case IF_T2_VMOVS:
6150             // 2op assemble a float from one int reg (or back)
6151             sz   = emitGetInstrDescSize(id);
6152             code = emitInsCode(ins, fmt);
6153             if (ins == INS_vmov_f2i)
6154             {
6155                 code |= insEncodeRegT2_VectorN(id->idReg2(), EA_4BYTE, true);
6156                 code |= id->idReg1() << 12;
6157             }
6158             else
6159             {
6160                 assert(ins == INS_vmov_i2f);
6161                 code |= insEncodeRegT2_VectorN(id->idReg1(), EA_4BYTE, true);
6162                 code |= id->idReg2() << 12;
6163             }
6164
6165             dst += emitOutput_Thumb2Instr(dst, code);
6166             break;
6167
6168         case IF_T1_J3: // T1_J3   .....dddiiiiiiii                        R1  PC             imm8
6169         case IF_T2_M1: // T2_M1   .....i.......... .iiiddddiiiiiiii       R1  PC             imm12
6170             assert(id->idGCref() == GCT_NONE);
6171             assert(id->idIsBound());
6172
6173             dst = emitOutputLJ(ig, dst, id);
6174             sz  = sizeof(instrDescLbl);
6175             break;
6176
6177         case IF_T1_K:  // T1_K    ....cccciiiiiiii                       Branch              imm8, cond4
6178         case IF_T1_M:  // T1_M    .....iiiiiiiiiii                       Branch              imm11
6179         case IF_T2_J1: // T2_J1   .....Scccciiiiii ..j.jiiiiiiiiiii      Branch              imm20, cond4
6180         case IF_T2_J2: // T2_J2   .....Siiiiiiiiii ..j.jiiiiiiiiii.      Branch              imm24
6181         case IF_T2_N1: // T2_N    .....i......iiii .iiiddddiiiiiiii       R1                 imm16
6182         case IF_LARGEJMP:
6183             assert(id->idGCref() == GCT_NONE);
6184             assert(id->idIsBound());
6185
6186             dst = emitOutputLJ(ig, dst, id);
6187             sz  = sizeof(instrDescJmp);
6188             break;
6189
6190         case IF_T1_D1: // T1_D1   .........mmmm...                       R1*
6191
6192             code = emitInsCode(ins, fmt);
6193             code |= insEncodeRegT1_M4(id->idReg1());
6194             dst += emitOutput_Thumb1Instr(dst, code);
6195             sz = SMALL_IDSC_SIZE;
6196             break;
6197
6198         case IF_T1_D2: // T1_D2   .........mmmm...                                R3*
6199
6200             /* Is this a "fat" call descriptor? */
6201
6202             if (id->idIsLargeCall())
6203             {
6204                 instrDescCGCA* idCall = (instrDescCGCA*)id;
6205                 gcrefRegs             = idCall->idcGcrefRegs;
6206                 byrefRegs             = idCall->idcByrefRegs;
6207                 VarSetOps::Assign(emitComp, GCvars, idCall->idcGCvars);
6208                 sz = sizeof(instrDescCGCA);
6209             }
6210             else
6211             {
6212                 assert(!id->idIsLargeDsp());
6213                 assert(!id->idIsLargeCns());
6214
6215                 gcrefRegs = emitDecodeCallGCregs(id);
6216                 byrefRegs = 0;
6217                 VarSetOps::AssignNoCopy(emitComp, GCvars, VarSetOps::MakeEmpty(emitComp));
6218                 sz = sizeof(instrDesc);
6219             }
6220
6221             code = emitInsCode(ins, fmt);
6222             code |= insEncodeRegT1_M4(id->idReg3());
6223             callInstrSize = SafeCvtAssert<unsigned char>(emitOutput_Thumb1Instr(dst, code));
6224             dst += callInstrSize;
6225             goto DONE_CALL;
6226
6227         case IF_T2_J3: // T2_J3   .....Siiiiiiiiii ..j.jiiiiiiiiii.      Call                imm24
6228
6229             /* Is this a "fat" call descriptor? */
6230
6231             if (id->idIsLargeCall())
6232             {
6233                 instrDescCGCA* idCall = (instrDescCGCA*)id;
6234                 gcrefRegs             = idCall->idcGcrefRegs;
6235                 byrefRegs             = idCall->idcByrefRegs;
6236                 VarSetOps::Assign(emitComp, GCvars, idCall->idcGCvars);
6237                 sz = sizeof(instrDescCGCA);
6238             }
6239             else
6240             {
6241                 assert(!id->idIsLargeDsp());
6242                 assert(!id->idIsLargeCns());
6243
6244                 gcrefRegs = emitDecodeCallGCregs(id);
6245                 byrefRegs = 0;
6246                 VarSetOps::AssignNoCopy(emitComp, GCvars, VarSetOps::MakeEmpty(emitComp));
6247                 sz = sizeof(instrDesc);
6248             }
6249
6250             if (id->idAddr()->iiaAddr == NULL) /* a recursive call */
6251             {
6252                 addr = emitCodeBlock;
6253             }
6254             else
6255             {
6256                 addr = id->idAddr()->iiaAddr;
6257             }
6258             code = emitInsCode(ins, fmt);
6259
6260             if (id->idIsDspReloc())
6261             {
6262                 callInstrSize = SafeCvtAssert<unsigned char>(emitOutput_Thumb2Instr(dst, code));
6263                 dst += callInstrSize;
6264                 if (emitComp->info.compMatchedVM)
6265                     emitRecordRelocation((void*)(dst - 4), addr, IMAGE_REL_BASED_THUMB_BRANCH24);
6266             }
6267             else
6268             {
6269                 addr = (BYTE*)((size_t)addr & ~1); // Clear the lowest bit from target address
6270
6271                 /* Calculate PC relative displacement */
6272                 int  disp = addr - (dst + 4);
6273                 bool S    = (disp < 0);
6274                 bool I1   = ((disp & 0x00800000) == 0);
6275                 bool I2   = ((disp & 0x00400000) == 0);
6276
6277                 if (S)
6278                     code |= (1 << 26); // S bit
6279                 if (S ^ I1)
6280                     code |= (1 << 13); // J1 bit
6281                 if (S ^ I2)
6282                     code |= (1 << 11); // J2 bit
6283
6284                 int immLo = (disp & 0x00000ffe) >> 1;
6285                 int immHi = (disp & 0x003ff000) >> 12;
6286
6287                 code |= (immHi << 16);
6288                 code |= immLo;
6289
6290                 disp = abs(disp);
6291                 assert((disp & 0x00fffffe) == disp);
6292
6293                 callInstrSize = SafeCvtAssert<unsigned char>(emitOutput_Thumb2Instr(dst, code));
6294                 dst += callInstrSize;
6295             }
6296
6297         DONE_CALL:
6298
6299             /* We update the GC info before the call as the variables cannot be
6300                used by the call. Killing variables before the call helps with
6301                boundary conditions if the call is CORINFO_HELP_THROW - see bug 50029.
6302                If we ever track aliased variables (which could be used by the
6303                call), we would have to keep them alive past the call. */
6304
6305             emitUpdateLiveGCvars(GCvars, *dp);
6306
6307             // If the method returns a GC ref, mark R0 appropriately.
6308             if (id->idGCref() == GCT_GCREF)
6309                 gcrefRegs |= RBM_R0;
6310             else if (id->idGCref() == GCT_BYREF)
6311                 byrefRegs |= RBM_R0;
6312
6313             // If the GC register set has changed, report the new set.
6314             if (gcrefRegs != emitThisGCrefRegs)
6315                 emitUpdateLiveGCregs(GCT_GCREF, gcrefRegs, dst);
6316
6317             if (byrefRegs != emitThisByrefRegs)
6318                 emitUpdateLiveGCregs(GCT_BYREF, byrefRegs, dst);
6319
6320             // Some helper calls may be marked as not requiring GC info to be recorded.
6321             if ((!id->idIsNoGC()))
6322             {
6323                 // On ARM, as on AMD64, we don't change the stack pointer to push/pop args.
6324                 // So we're not really doing a "stack pop" here (note that "args" is 0), but we use this mechanism
6325                 // to record the call for GC info purposes.  (It might be best to use an alternate call,
6326                 // and protect "emitStackPop" under the EMIT_TRACK_STACK_DEPTH preprocessor variable.)
6327                 emitStackPop(dst, /*isCall*/ true, callInstrSize, /*args*/ 0);
6328
6329                 /* Do we need to record a call location for GC purposes? */
6330
6331                 if (!emitFullGCinfo)
6332                 {
6333                     emitRecordGCcall(dst, callInstrSize);
6334                 }
6335             }
6336
6337             break;
6338
6339         /********************************************************************/
6340         /*                            oops                                  */
6341         /********************************************************************/
6342
6343         default:
6344
6345 #ifdef DEBUG
6346             printf("unexpected format %s\n", emitIfName(id->idInsFmt()));
6347             assert(!"don't know how to encode this instruction");
6348 #endif
6349             break;
6350     }
6351
6352     // Determine if any registers now hold GC refs, or whether a register that was overwritten held a GC ref.
6353     // We assume here that "id->idGCref()" is not GC_NONE only if the instruction described by "id" writes a
6354     // GC ref to register "id->idReg1()".  (It may, apparently, also not be GC_NONE in other cases, such as
6355     // for stores, but we ignore those cases here.)
6356     if (emitInsMayWriteToGCReg(id)) // True if "id->idIns()" writes to a register than can hold GC ref.
6357     {
6358         // If we ever generate instructions that write to multiple registers (LDM, or POP),
6359         // then we'd need to more work here to ensure that changes in the status of GC refs are
6360         // tracked properly.
6361         if (emitInsMayWriteMultipleRegs(id))
6362         {
6363             // We explicitly list the multiple-destination-target instruction that we expect to
6364             // be emitted outside of the prolog and epilog here.
6365             switch (ins)
6366             {
6367                 case INS_smull:
6368                 case INS_umull:
6369                 case INS_smlal:
6370                 case INS_umlal:
6371                 case INS_vmov_d2i:
6372                     // For each of these, idReg1() and idReg2() are the destination registers.
6373                     emitGCregDeadUpd(id->idReg1(), dst);
6374                     emitGCregDeadUpd(id->idReg2(), dst);
6375                     break;
6376                 default:
6377                     assert(false); // We need to recognize this multi-target instruction...
6378             }
6379         }
6380         else
6381         {
6382             if (id->idGCref() != GCT_NONE)
6383             {
6384                 emitGCregLiveUpd(id->idGCref(), id->idReg1(), dst);
6385             }
6386             else
6387             {
6388                 // I also assume that "idReg1" is the destination register of all instructions that write to registers.
6389                 emitGCregDeadUpd(id->idReg1(), dst);
6390             }
6391         }
6392     }
6393
6394     // Now we determine if the instruction has written to a (local variable) stack location, and either written a GC
6395     // ref or overwritten one.
6396     if (emitInsWritesToLclVarStackLoc(id))
6397     {
6398         int       varNum = id->idAddr()->iiaLclVar.lvaVarNum();
6399         unsigned  ofs    = AlignDown(id->idAddr()->iiaLclVar.lvaOffset(), TARGET_POINTER_SIZE);
6400         regNumber regBase;
6401         int       adr = emitComp->lvaFrameAddress(varNum, true, &regBase, ofs);
6402         if (id->idGCref() != GCT_NONE)
6403         {
6404             emitGCvarLiveUpd(adr + ofs, varNum, id->idGCref(), dst);
6405         }
6406         else
6407         {
6408             // If the type of the local is a gc ref type, update the liveness.
6409             var_types vt;
6410             if (varNum >= 0)
6411             {
6412                 // "Regular" (non-spill-temp) local.
6413                 vt = var_types(emitComp->lvaTable[varNum].lvType);
6414             }
6415             else
6416             {
6417                 TempDsc* tmpDsc = emitComp->tmpFindNum(varNum);
6418                 vt              = tmpDsc->tdTempType();
6419             }
6420             if (vt == TYP_REF || vt == TYP_BYREF)
6421                 emitGCvarDeadUpd(adr + ofs, dst);
6422         }
6423     }
6424
6425 #ifdef DEBUG
6426     /* Make sure we set the instruction descriptor size correctly */
6427
6428     size_t expected = emitSizeOfInsDsc(id);
6429     assert(sz == expected);
6430
6431     if (emitComp->opts.disAsm || emitComp->opts.dspEmit || emitComp->verbose)
6432     {
6433         emitDispIns(id, false, dspOffs, true, emitCurCodeOffs(odst), *dp, (dst - *dp), ig);
6434     }
6435
6436     if (emitComp->compDebugBreak)
6437     {
6438         // set JitEmitPrintRefRegs=1 will print out emitThisGCrefRegs and emitThisByrefRegs
6439         // at the beginning of this method.
6440         if (JitConfig.JitEmitPrintRefRegs() != 0)
6441         {
6442             printf("Before emitOutputInstr for id->idDebugOnlyInfo()->idNum=0x%02x\n", id->idDebugOnlyInfo()->idNum);
6443             printf("  emitThisGCrefRegs(0x%p)=", dspPtr(&emitThisGCrefRegs));
6444             printRegMaskInt(emitThisGCrefRegs);
6445             emitDispRegSet(emitThisGCrefRegs);
6446             printf("\n");
6447             printf("  emitThisByrefRegs(0x%p)=", dspPtr(&emitThisByrefRegs));
6448             printRegMaskInt(emitThisByrefRegs);
6449             emitDispRegSet(emitThisByrefRegs);
6450             printf("\n");
6451         }
6452
6453         // For example, set JitBreakEmitOutputInstr=a6 will break when this method is called for
6454         // emitting instruction a6, (i.e. IN00a6 in jitdump).
6455         if ((unsigned)JitConfig.JitBreakEmitOutputInstr() == id->idDebugOnlyInfo()->idNum)
6456         {
6457             assert(!"JitBreakEmitOutputInstr reached");
6458         }
6459     }
6460 #endif
6461
6462     /* All instructions are expected to generate code */
6463
6464     assert(*dp != dst);
6465
6466     *dp = dst;
6467
6468     return sz;
6469 }
6470
6471 /*****************************************************************************/
6472 /*****************************************************************************/
6473
6474 #ifdef DEBUG
6475
6476 static bool insAlwaysSetFlags(instruction ins)
6477 {
6478     bool result = false;
6479     switch (ins)
6480     {
6481         case INS_cmp:
6482         case INS_cmn:
6483         case INS_teq:
6484         case INS_tst:
6485             result = true;
6486             break;
6487
6488         default:
6489             break;
6490     }
6491     return result;
6492 }
6493
6494 /*****************************************************************************
6495  *
6496  *  Display the instruction name, optionally the instruction
6497  *   can add the "s" suffix if it must set the flags.
6498  */
6499 void emitter::emitDispInst(instruction ins, insFlags flags)
6500 {
6501     const char* insstr = codeGen->genInsName(ins);
6502     int         len    = strlen(insstr);
6503
6504     /* Display the instruction name */
6505
6506     printf("%s", insstr);
6507     if (insSetsFlags(flags) && !insAlwaysSetFlags(ins))
6508     {
6509         printf("s");
6510         len++;
6511     }
6512
6513     //
6514     // Add at least one space after the instruction name
6515     // and add spaces until we have reach the normal size of 8
6516     do
6517     {
6518         printf(" ");
6519         len++;
6520     } while (len < 8);
6521 }
6522
6523 /*****************************************************************************
6524  *
6525  *  Display an reloc value
6526  *  If we are formatting for an assembly listing don't print the hex value
6527  *  since it will prevent us from doing assembly diffs
6528  */
6529 void emitter::emitDispReloc(int value, bool addComma)
6530 {
6531     if (emitComp->opts.disAsm)
6532     {
6533         printf("(reloc)");
6534     }
6535     else
6536     {
6537         printf("(reloc 0x%x)", dspPtr(value));
6538     }
6539
6540     if (addComma)
6541         printf(", ");
6542 }
6543
6544 #define STRICT_ARM_ASM 0
6545
6546 /*****************************************************************************
6547  *
6548  *  Display an immediate value
6549  */
6550 void emitter::emitDispImm(int imm, bool addComma, bool alwaysHex /* =false */)
6551 {
6552     if (!alwaysHex && (imm > -1000) && (imm < 1000))
6553         printf("%d", imm);
6554     else if ((imm > 0) ||
6555              (imm == -imm) || // -0x80000000 == 0x80000000. So we don't want to add an extra "-" at the beginning.
6556              (emitComp->opts.disDiffable && (imm == 0xD1FFAB1E))) // Don't display this as negative
6557         printf("0x%02x", imm);
6558     else // val <= -1000
6559         printf("-0x%02x", -imm);
6560
6561     if (addComma)
6562         printf(", ");
6563 }
6564
6565 /*****************************************************************************
6566  *
6567  *  Display an arm condition for the IT instructions
6568  */
6569 void emitter::emitDispCond(int cond)
6570 {
6571     const static char* armCond[16] = {"eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc",
6572                                       "hi", "ls", "ge", "lt", "gt", "le", "AL", "NV"}; // The last two are invalid
6573     assert(0 <= cond && (unsigned)cond < ArrLen(armCond));
6574     printf(armCond[cond]);
6575 }
6576
6577 /*****************************************************************************
6578  *
6579  *  Display a register range in a range format
6580  */
6581 void emitter::emitDispRegRange(regNumber reg, int len, emitAttr attr)
6582 {
6583     printf("{");
6584     emitDispReg(reg, attr, false);
6585     if (len > 1)
6586     {
6587         printf("-");
6588         emitDispReg((regNumber)(reg + len - 1), attr, false);
6589     }
6590     printf("}");
6591 }
6592
6593 /*****************************************************************************
6594  *
6595  *  Display an register mask in a list format
6596  */
6597 void emitter::emitDispRegmask(int imm, bool encodedPC_LR)
6598 {
6599     bool printedOne = false;
6600     bool hasPC;
6601     bool hasLR;
6602
6603     if (encodedPC_LR)
6604     {
6605         hasPC = (imm & 2) != 0;
6606         hasLR = (imm & 1) != 0;
6607         imm >>= 2;
6608     }
6609     else
6610     {
6611         hasPC = (imm & RBM_PC) != 0;
6612         hasLR = (imm & RBM_LR) != 0;
6613         imm &= ~(RBM_PC | RBM_LR);
6614     }
6615
6616     regNumber reg = REG_R0;
6617     unsigned  bit = 1;
6618
6619     printf("{");
6620     while (imm != 0)
6621     {
6622         if (bit & imm)
6623         {
6624             if (printedOne)
6625                 printf(",");
6626             printf("%s", emitRegName(reg));
6627             printedOne = true;
6628             imm -= bit;
6629         }
6630
6631         reg = regNumber(reg + 1);
6632         bit <<= 1;
6633     }
6634
6635     if (hasLR)
6636     {
6637         if (printedOne)
6638             printf(",");
6639         printf("%s", emitRegName(REG_LR));
6640         printedOne = true;
6641     }
6642
6643     if (hasPC)
6644     {
6645         if (printedOne)
6646             printf(",");
6647         printf("%s", emitRegName(REG_PC));
6648         printedOne = true;
6649     }
6650     printf("}");
6651 }
6652
6653 /*****************************************************************************
6654  *
6655  *  Returns the encoding for the Shift Type bits to be used in a Thumb-2 encoding
6656  */
6657
6658 void emitter::emitDispShiftOpts(insOpts opt)
6659 {
6660     if (opt == INS_OPTS_LSL)
6661         printf(" LSL ");
6662     else if (opt == INS_OPTS_LSR)
6663         printf(" LSR ");
6664     else if (opt == INS_OPTS_ASR)
6665         printf(" ASR ");
6666     else if (opt == INS_OPTS_ROR)
6667         printf(" ROR ");
6668     else if (opt == INS_OPTS_RRX)
6669         printf(" RRX ");
6670 }
6671
6672 /*****************************************************************************
6673  *
6674  *  Display a register
6675  */
6676 void emitter::emitDispReg(regNumber reg, emitAttr attr, bool addComma)
6677 {
6678     if (isFloatReg(reg))
6679     {
6680         const char* size = attr == EA_8BYTE ? "d" : "s";
6681         printf("%s%s", size, emitFloatRegName(reg, attr) + 1);
6682     }
6683     else
6684     {
6685         printf("%s", emitRegName(reg, attr));
6686     }
6687
6688     if (addComma)
6689         printf(", ");
6690 }
6691
6692 void emitter::emitDispFloatReg(regNumber reg, emitAttr attr, bool addComma)
6693 {
6694 }
6695
6696 /*****************************************************************************
6697  *
6698  *  Display an addressing operand [reg]
6699  */
6700 void emitter::emitDispAddrR(regNumber reg, emitAttr attr)
6701 {
6702     printf("[");
6703     emitDispReg(reg, attr, false);
6704     printf("]");
6705     emitDispGC(attr);
6706 }
6707
6708 /*****************************************************************************
6709  *
6710  *  Display an addressing operand [reg + imm]
6711  */
6712 void emitter::emitDispAddrRI(regNumber reg, int imm, emitAttr attr)
6713 {
6714     bool regIsSPorFP = (reg == REG_SP) || (reg == REG_FP);
6715
6716     printf("[");
6717     emitDispReg(reg, attr, false);
6718     if (imm != 0)
6719     {
6720         if (imm >= 0)
6721         {
6722 #if STRICT_ARM_ASM
6723             printf(", ");
6724 #else
6725             printf("+");
6726 #endif
6727         }
6728         emitDispImm(imm, false, regIsSPorFP);
6729     }
6730     printf("]");
6731     emitDispGC(attr);
6732 }
6733
6734 /*****************************************************************************
6735  *
6736  *  Display an addressing operand [reg + reg]
6737  */
6738 void emitter::emitDispAddrRR(regNumber reg1, regNumber reg2, emitAttr attr)
6739 {
6740     printf("[");
6741     emitDispReg(reg1, attr, false);
6742 #if STRICT_ARM_ASM
6743     printf(", ");
6744 #else
6745     printf("+");
6746 #endif
6747     emitDispReg(reg2, attr, false);
6748     printf("]");
6749     emitDispGC(attr);
6750 }
6751
6752 /*****************************************************************************
6753  *
6754  *  Display an addressing operand [reg + reg * imm]
6755  */
6756 void emitter::emitDispAddrRRI(regNumber reg1, regNumber reg2, int imm, emitAttr attr)
6757 {
6758     printf("[");
6759     emitDispReg(reg1, attr, false);
6760 #if STRICT_ARM_ASM
6761     printf(", ");
6762     emitDispReg(reg2, attr, false);
6763     if (imm > 0)
6764     {
6765         printf(" LSL ");
6766         emitDispImm(1 << imm, false);
6767     }
6768 #else
6769     printf("+");
6770     if (imm > 0)
6771     {
6772         emitDispImm(1 << imm, false);
6773         printf("*");
6774     }
6775     emitDispReg(reg2, attr, false);
6776 #endif
6777     printf("]");
6778     emitDispGC(attr);
6779 }
6780
6781 /*****************************************************************************
6782  *
6783  *  Display an addressing operand [reg + imm]
6784  */
6785 void emitter::emitDispAddrPUW(regNumber reg, int imm, insOpts opt, emitAttr attr)
6786 {
6787     bool regIsSPorFP = (reg == REG_SP) || (reg == REG_FP);
6788
6789     printf("[");
6790     emitDispReg(reg, attr, false);
6791     if (insOptAnyInc(opt))
6792         printf("!");
6793
6794     if (imm != 0)
6795     {
6796         if (imm >= 0)
6797         {
6798 #if STRICT_ARM_ASM
6799             printf(", ");
6800 #else
6801             printf("+");
6802 #endif
6803         }
6804         emitDispImm(imm, false, regIsSPorFP);
6805     }
6806     printf("]");
6807
6808     emitDispGC(attr);
6809 }
6810
6811 /*****************************************************************************
6812  *
6813  *  Display the gc-ness of the operand
6814  */
6815 void emitter::emitDispGC(emitAttr attr)
6816 {
6817 #if 0
6818     // TODO-ARM-Cleanup: Fix or delete.
6819     if (attr == EA_GCREF)
6820         printf(" @gc");
6821     else if (attr == EA_BYREF)
6822         printf(" @byref");
6823 #endif
6824 }
6825
6826 /*****************************************************************************
6827  *
6828  *  Display (optionally) the instruction encoding in hex
6829  */
6830
6831 void emitter::emitDispInsHex(BYTE* code, size_t sz)
6832 {
6833     // We do not display the instruction hex if we want diff-able disassembly
6834     if (!emitComp->opts.disDiffable)
6835     {
6836         if (sz == 2)
6837         {
6838             printf("  %04X     ", (*((unsigned short*)code)));
6839         }
6840         else if (sz == 4)
6841         {
6842             printf("  %04X %04X", (*((unsigned short*)(code + 0))), (*((unsigned short*)(code + 2))));
6843         }
6844     }
6845 }
6846
6847 /****************************************************************************
6848  *
6849  *  Display the given instruction.
6850  */
6851
6852 void emitter::emitDispInsHelp(
6853     instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* code, size_t sz, insGroup* ig)
6854 {
6855     if (EMITVERBOSE)
6856     {
6857         unsigned idNum = id->idDebugOnlyInfo()->idNum; // Do not remove this!  It is needed for VisualStudio
6858                                                        // conditional breakpoints
6859
6860         printf("IN%04x: ", idNum);
6861     }
6862
6863     if (code == NULL)
6864         sz = 0;
6865
6866     if (!emitComp->opts.dspEmit && !isNew && !asmfm && sz)
6867         doffs = true;
6868
6869     /* Display the instruction offset */
6870
6871     emitDispInsOffs(offset, doffs);
6872
6873     /* Display the instruction hex code */
6874
6875     emitDispInsHex(code, sz);
6876
6877     printf("      ");
6878
6879     /* Get the instruction and format */
6880
6881     instruction ins = id->idIns();
6882     insFormat   fmt = id->idInsFmt();
6883
6884     emitDispInst(ins, id->idInsFlags());
6885
6886     /* If this instruction has just been added, check its size */
6887
6888     assert(isNew == false || (int)emitSizeOfInsDsc(id) == emitCurIGfreeNext - (BYTE*)id);
6889
6890     /* Figure out the operand size */
6891     emitAttr attr;
6892     if (id->idGCref() == GCT_GCREF)
6893         attr = EA_GCREF;
6894     else if (id->idGCref() == GCT_BYREF)
6895         attr = EA_BYREF;
6896     else
6897         attr = id->idOpSize();
6898
6899     switch (fmt)
6900     {
6901         int         imm;
6902         int         offs;
6903         const char* methodName;
6904
6905         case IF_T1_A: // None
6906         case IF_T2_A:
6907             break;
6908
6909         case IF_T1_L0: // Imm
6910         case IF_T2_B:
6911             emitDispImm(emitGetInsSC(id), false);
6912             break;
6913
6914         case IF_T1_B: // <cond>
6915             emitDispCond(emitGetInsSC(id));
6916             break;
6917
6918         case IF_T1_L1: // <regmask8>
6919         case IF_T2_I1: // <regmask16>
6920             emitDispRegmask(emitGetInsSC(id), true);
6921             break;
6922
6923         case IF_T2_E2: // Reg
6924             if (id->idIns() == INS_vmrs)
6925             {
6926                 if (id->idReg1() != REG_R15)
6927                 {
6928                     emitDispReg(id->idReg1(), attr, true);
6929                     printf("FPSCR");
6930                 }
6931                 else
6932                 {
6933                     printf("APSR, FPSCR");
6934                 }
6935             }
6936             else
6937             {
6938                 emitDispReg(id->idReg1(), attr, false);
6939             }
6940             break;
6941
6942         case IF_T1_D1:
6943             emitDispReg(id->idReg1(), attr, false);
6944             break;
6945
6946         case IF_T1_D2:
6947             emitDispReg(id->idReg3(), attr, false);
6948             {
6949                 CORINFO_METHOD_HANDLE handle = (CORINFO_METHOD_HANDLE)id->idDebugOnlyInfo()->idMemCookie;
6950                 if (handle != 0)
6951                 {
6952                     methodName = emitComp->eeGetMethodFullName(handle);
6953                     printf("\t\t// %s", methodName);
6954                 }
6955             }
6956             break;
6957
6958         case IF_T1_F: // SP, Imm
6959             emitDispReg(REG_SP, attr, true);
6960             emitDispImm(emitGetInsSC(id), false);
6961             break;
6962
6963         case IF_T1_J0: // Reg, Imm
6964         case IF_T2_L1:
6965         case IF_T2_L2:
6966         case IF_T2_N:
6967             emitDispReg(id->idReg1(), attr, true);
6968             imm = emitGetInsSC(id);
6969             if (fmt == IF_T2_N)
6970             {
6971                 if (emitComp->opts.disDiffable)
6972                     imm = 0xD1FF;
6973                 if (id->idIsCnsReloc() || id->idIsDspReloc())
6974                 {
6975                     if (emitComp->opts.disDiffable)
6976                         imm = 0xD1FFAB1E;
6977                     printf("%s RELOC ", (id->idIns() == INS_movw) ? "LOW" : "HIGH");
6978                 }
6979             }
6980             emitDispImm(imm, false, (fmt == IF_T2_N));
6981             break;
6982
6983         case IF_T2_N2:
6984             emitDispReg(id->idReg1(), attr, true);
6985             imm = emitGetInsSC(id);
6986             {
6987                 dataSection*  jdsc = 0;
6988                 NATIVE_OFFSET offs = 0;
6989
6990                 /* Find the appropriate entry in the data section list */
6991
6992                 for (jdsc = emitConsDsc.dsdList; jdsc; jdsc = jdsc->dsNext)
6993                 {
6994                     UNATIVE_OFFSET size = jdsc->dsSize;
6995
6996                     /* Is this a label table? */
6997
6998                     if (jdsc->dsType == dataSection::blockAbsoluteAddr)
6999                     {
7000                         if (offs == imm)
7001                             break;
7002                     }
7003
7004                     offs += size;
7005                 }
7006
7007                 assert(jdsc != NULL);
7008
7009                 if (id->idIsDspReloc())
7010                 {
7011                     printf("reloc ");
7012                 }
7013                 printf("%s ADDRESS J_M%03u_DS%02u", (id->idIns() == INS_movw) ? "LOW" : "HIGH",
7014                        Compiler::s_compMethodsCount, imm);
7015
7016                 // After the MOVT, dump the table
7017                 if (id->idIns() == INS_movt)
7018                 {
7019                     unsigned     cnt = jdsc->dsSize / TARGET_POINTER_SIZE;
7020                     BasicBlock** bbp = (BasicBlock**)jdsc->dsCont;
7021
7022                     bool isBound = (emitCodeGetCookie(*bbp) != NULL);
7023
7024                     if (isBound)
7025                     {
7026                         printf("\n\n    J_M%03u_DS%02u LABEL   DWORD", Compiler::s_compMethodsCount, imm);
7027
7028                         /* Display the label table (it's stored as "BasicBlock*" values) */
7029
7030                         do
7031                         {
7032                             insGroup* lab;
7033
7034                             /* Convert the BasicBlock* value to an IG address */
7035
7036                             lab = (insGroup*)emitCodeGetCookie(*bbp++);
7037                             assert(lab);
7038
7039                             printf("\n            DD      G_M%03u_IG%02u", Compiler::s_compMethodsCount, lab->igNum);
7040                         } while (--cnt);
7041                     }
7042                 }
7043             }
7044             break;
7045
7046         case IF_T2_H2: // [Reg+imm]
7047         case IF_T2_K2:
7048             emitDispAddrRI(id->idReg1(), emitGetInsSC(id), attr);
7049             break;
7050
7051         case IF_T2_K3: // [PC+imm]
7052             emitDispAddrRI(REG_PC, emitGetInsSC(id), attr);
7053             break;
7054
7055         case IF_T1_J1: // reg, <regmask8>
7056         case IF_T2_I0: // reg, <regmask16>
7057             emitDispReg(id->idReg1(), attr, false);
7058             printf("!, ");
7059             emitDispRegmask(emitGetInsSC(id), false);
7060             break;
7061
7062         case IF_T1_D0: // Reg, Reg
7063         case IF_T1_E:
7064         case IF_T2_C3:
7065         case IF_T2_C9:
7066         case IF_T2_C10:
7067             emitDispReg(id->idReg1(), attr, true);
7068             emitDispReg(id->idReg2(), attr, false);
7069             if (fmt == IF_T1_E && id->idIns() == INS_rsb)
7070             {
7071                 printf(", 0");
7072             }
7073             break;
7074
7075         case IF_T2_E1: // Reg, [Reg]
7076             emitDispReg(id->idReg1(), attr, true);
7077             emitDispAddrR(id->idReg2(), attr);
7078             break;
7079
7080         case IF_T2_D1: // Reg, Imm, Imm
7081             emitDispReg(id->idReg1(), attr, true);
7082             imm = emitGetInsSC(id);
7083             {
7084                 int lsb  = (imm >> 5) & 0x1f;
7085                 int msb  = imm & 0x1f;
7086                 int imm1 = lsb;
7087                 int imm2 = msb + 1 - lsb;
7088                 emitDispImm(imm1, true);
7089                 emitDispImm(imm2, false);
7090             }
7091             break;
7092
7093         case IF_T1_C: // Reg, Reg, Imm
7094         case IF_T1_G:
7095         case IF_T2_C2:
7096         case IF_T2_H1:
7097         case IF_T2_K1:
7098         case IF_T2_L0:
7099         case IF_T2_M0:
7100             emitDispReg(id->idReg1(), attr, true);
7101             imm = emitGetInsSC(id);
7102             if (emitInsIsLoadOrStore(ins))
7103             {
7104                 emitDispAddrRI(id->idReg2(), imm, attr);
7105             }
7106             else
7107             {
7108                 emitDispReg(id->idReg2(), attr, true);
7109                 emitDispImm(imm, false);
7110             }
7111             break;
7112
7113         case IF_T1_J2:
7114             emitDispReg(id->idReg1(), attr, true);
7115             imm = emitGetInsSC(id);
7116             if (emitInsIsLoadOrStore(ins))
7117             {
7118                 emitDispAddrRI(REG_SP, imm, attr);
7119             }
7120             else
7121             {
7122                 emitDispReg(REG_SP, attr, true);
7123                 emitDispImm(imm, false);
7124             }
7125             break;
7126
7127         case IF_T2_K4:
7128             emitDispReg(id->idReg1(), attr, true);
7129             emitDispAddrRI(REG_PC, emitGetInsSC(id), attr);
7130             break;
7131
7132         case IF_T2_C1:
7133         case IF_T2_C8:
7134             emitDispReg(id->idReg1(), attr, true);
7135             emitDispReg(id->idReg2(), attr, false);
7136             imm = emitGetInsSC(id);
7137             if (id->idInsOpt() == INS_OPTS_RRX)
7138             {
7139                 emitDispShiftOpts(id->idInsOpt());
7140                 assert(imm == 1);
7141             }
7142             else if (imm > 0)
7143             {
7144                 emitDispShiftOpts(id->idInsOpt());
7145                 emitDispImm(imm, false);
7146             }
7147             break;
7148
7149         case IF_T2_C6:
7150             imm = emitGetInsSC(id);
7151             emitDispReg(id->idReg1(), attr, true);
7152             emitDispReg(id->idReg2(), attr, (imm != 0));
7153             if (imm != 0)
7154             {
7155                 emitDispImm(imm, false);
7156             }
7157             break;
7158
7159         case IF_T2_C7:
7160             emitDispAddrRRI(id->idReg1(), id->idReg2(), emitGetInsSC(id), attr);
7161             break;
7162
7163         case IF_T2_H0:
7164             emitDispReg(id->idReg1(), attr, true);
7165             emitDispAddrPUW(id->idReg2(), emitGetInsSC(id), id->idInsOpt(), attr);
7166             break;
7167
7168         case IF_T1_H: // Reg, Reg, Reg
7169             emitDispReg(id->idReg1(), attr, true);
7170             if (emitInsIsLoadOrStore(ins))
7171             {
7172                 emitDispAddrRR(id->idReg2(), id->idReg3(), attr);
7173             }
7174             else
7175             {
7176                 emitDispReg(id->idReg2(), attr, true);
7177                 emitDispReg(id->idReg3(), attr, false);
7178             }
7179             break;
7180
7181         case IF_T2_C4:
7182         case IF_T2_C5:
7183             emitDispReg(id->idReg1(), attr, true);
7184             emitDispReg(id->idReg2(), attr, true);
7185             emitDispReg(id->idReg3(), attr, false);
7186             break;
7187
7188         case IF_T2_VFP3:
7189             emitDispReg(id->idReg1(), attr, true);
7190             emitDispReg(id->idReg2(), attr, true);
7191             emitDispReg(id->idReg3(), attr, false);
7192             break;
7193
7194         case IF_T2_VFP2:
7195             switch (id->idIns())
7196             {
7197                 case INS_vcvt_d2i:
7198                 case INS_vcvt_d2u:
7199                 case INS_vcvt_d2f:
7200                     emitDispReg(id->idReg1(), EA_4BYTE, true);
7201                     emitDispReg(id->idReg2(), EA_8BYTE, false);
7202                     break;
7203
7204                 case INS_vcvt_i2d:
7205                 case INS_vcvt_u2d:
7206                 case INS_vcvt_f2d:
7207                     emitDispReg(id->idReg1(), EA_8BYTE, true);
7208                     emitDispReg(id->idReg2(), EA_4BYTE, false);
7209                     break;
7210
7211                 // we just use the type on the instruction
7212                 // unless it is an asymmetrical one like the converts
7213                 default:
7214                     emitDispReg(id->idReg1(), attr, true);
7215                     emitDispReg(id->idReg2(), attr, false);
7216                     break;
7217             }
7218             break;
7219
7220         case IF_T2_VLDST:
7221             imm = emitGetInsSC(id);
7222             switch (id->idIns())
7223             {
7224                 case INS_vldr:
7225                 case INS_vstr:
7226                     emitDispReg(id->idReg1(), attr, true);
7227                     emitDispAddrPUW(id->idReg2(), imm, id->idInsOpt(), attr);
7228                     break;
7229
7230                 case INS_vldm:
7231                 case INS_vstm:
7232                     emitDispReg(id->idReg2(), attr, false);
7233                     if (insOptAnyInc(id->idInsOpt()))
7234                         printf("!");
7235                     printf(", ");
7236                     emitDispRegRange(id->idReg1(), abs(imm) >> 2, attr);
7237                     break;
7238
7239                 case INS_vpush:
7240                 case INS_vpop:
7241                     emitDispRegRange(id->idReg1(), abs(imm) >> 2, attr);
7242                     break;
7243
7244                 default:
7245                     unreached();
7246             }
7247             break;
7248
7249         case IF_T2_VMOVD:
7250             switch (id->idIns())
7251             {
7252                 case INS_vmov_i2d:
7253                     emitDispReg(id->idReg1(), attr, true); // EA_8BYTE
7254                     emitDispReg(id->idReg2(), EA_4BYTE, true);
7255                     emitDispReg(id->idReg3(), EA_4BYTE, false);
7256                     break;
7257                 case INS_vmov_d2i:
7258                     emitDispReg(id->idReg1(), EA_4BYTE, true);
7259                     emitDispReg(id->idReg2(), EA_4BYTE, true);
7260                     emitDispReg(id->idReg3(), attr, false); // EA_8BYTE
7261                     break;
7262                 default:
7263                     unreached();
7264             }
7265             break;
7266
7267         case IF_T2_VMOVS:
7268             emitDispReg(id->idReg1(), attr, true);
7269             emitDispReg(id->idReg2(), attr, false);
7270             break;
7271
7272         case IF_T2_G1:
7273             emitDispReg(id->idReg1(), attr, true);
7274             emitDispAddrRR(id->idReg2(), id->idReg3(), attr);
7275             break;
7276
7277         case IF_T2_D0: // Reg, Reg, Imm, Imm
7278             emitDispReg(id->idReg1(), attr, true);
7279             emitDispReg(id->idReg2(), attr, true);
7280             imm = emitGetInsSC(id);
7281             if (ins == INS_bfi)
7282             {
7283                 int lsb  = (imm >> 5) & 0x1f;
7284                 int msb  = imm & 0x1f;
7285                 int imm1 = lsb;
7286                 int imm2 = msb + 1 - lsb;
7287                 emitDispImm(imm1, true);
7288                 emitDispImm(imm2, false);
7289             }
7290             else
7291             {
7292                 int lsb     = (imm >> 5) & 0x1f;
7293                 int widthm1 = imm & 0x1f;
7294                 int imm1    = lsb;
7295                 int imm2    = widthm1 + 1;
7296                 emitDispImm(imm1, true);
7297                 emitDispImm(imm2, false);
7298             }
7299             break;
7300
7301         case IF_T2_C0: // Reg, Reg, Reg, Imm
7302             emitDispReg(id->idReg1(), attr, true);
7303             emitDispReg(id->idReg2(), attr, true);
7304             emitDispReg(id->idReg3(), attr, false);
7305             imm = emitGetInsSC(id);
7306             if (id->idInsOpt() == INS_OPTS_RRX)
7307             {
7308                 emitDispShiftOpts(id->idInsOpt());
7309                 assert(imm == 1);
7310             }
7311             else if (imm > 0)
7312             {
7313                 emitDispShiftOpts(id->idInsOpt());
7314                 emitDispImm(imm, false);
7315             }
7316             break;
7317
7318         case IF_T2_E0:
7319             emitDispReg(id->idReg1(), attr, true);
7320             if (id->idIsLclVar())
7321             {
7322                 emitDispAddrRRI(id->idReg2(), codeGen->rsGetRsvdReg(), 0, attr);
7323             }
7324             else
7325             {
7326                 emitDispAddrRRI(id->idReg2(), id->idReg3(), emitGetInsSC(id), attr);
7327             }
7328             break;
7329
7330         case IF_T2_G0:
7331             emitDispReg(id->idReg1(), attr, true);
7332             emitDispReg(id->idReg2(), attr, true);
7333             emitDispAddrPUW(id->idReg3(), emitGetInsSC(id), id->idInsOpt(), attr);
7334             break;
7335
7336         case IF_T2_F1: // Reg, Reg, Reg, Reg
7337         case IF_T2_F2:
7338             emitDispReg(id->idReg1(), attr, true);
7339             emitDispReg(id->idReg2(), attr, true);
7340             emitDispReg(id->idReg3(), attr, true);
7341             emitDispReg(id->idReg4(), attr, false);
7342             break;
7343
7344         case IF_T1_J3:
7345         case IF_T2_M1: // Load Label
7346             emitDispReg(id->idReg1(), attr, true);
7347             if (id->idIsBound())
7348                 printf("G_M%03u_IG%02u", Compiler::s_compMethodsCount, id->idAddr()->iiaIGlabel->igNum);
7349             else
7350                 printf("L_M%03u_BB%02u", Compiler::s_compMethodsCount, id->idAddr()->iiaBBlabel->bbNum);
7351             break;
7352
7353         case IF_T1_I: // Special Compare-and-branch
7354             emitDispReg(id->idReg1(), attr, true);
7355             __fallthrough;
7356
7357         case IF_T1_K: // Special Branch, conditional
7358         case IF_T1_M:
7359             assert(((instrDescJmp*)id)->idjShort);
7360             printf("SHORT ");
7361             __fallthrough;
7362
7363         case IF_T2_N1:
7364             if (fmt == IF_T2_N1)
7365             {
7366                 emitDispReg(id->idReg1(), attr, true);
7367                 printf("%s ADDRESS ", (id->idIns() == INS_movw) ? "LOW" : "HIGH");
7368             }
7369             __fallthrough;
7370
7371         case IF_T2_J1:
7372         case IF_T2_J2:
7373         case IF_LARGEJMP:
7374         {
7375             if (id->idAddr()->iiaHasInstrCount())
7376             {
7377                 int instrCount = id->idAddr()->iiaGetInstrCount();
7378
7379                 if (ig == NULL)
7380                 {
7381                     printf("pc%s%d instructions", (instrCount >= 0) ? "+" : "", instrCount);
7382                 }
7383                 else
7384                 {
7385                     unsigned       insNum  = emitFindInsNum(ig, id);
7386                     UNATIVE_OFFSET srcOffs = ig->igOffs + emitFindOffset(ig, insNum + 1);
7387                     UNATIVE_OFFSET dstOffs = ig->igOffs + emitFindOffset(ig, insNum + 1 + instrCount);
7388                     ssize_t        relOffs = (ssize_t)(emitOffsetToPtr(dstOffs) - emitOffsetToPtr(srcOffs));
7389                     printf("pc%s%d (%d instructions)", (relOffs >= 0) ? "+" : "", relOffs, instrCount);
7390                 }
7391             }
7392             else if (id->idIsBound())
7393                 printf("G_M%03u_IG%02u", Compiler::s_compMethodsCount, id->idAddr()->iiaIGlabel->igNum);
7394             else
7395                 printf("L_M%03u_BB%02u", Compiler::s_compMethodsCount, id->idAddr()->iiaBBlabel->bbNum);
7396         }
7397         break;
7398
7399         case IF_T2_J3:
7400             if (id->idIsCallAddr())
7401             {
7402                 offs       = (ssize_t)id->idAddr()->iiaAddr;
7403                 methodName = "";
7404             }
7405             else
7406             {
7407                 offs       = 0;
7408                 methodName = emitComp->eeGetMethodFullName((CORINFO_METHOD_HANDLE)id->idDebugOnlyInfo()->idMemCookie);
7409             }
7410
7411             if (offs)
7412             {
7413                 if (id->idIsDspReloc())
7414                     printf("reloc ");
7415                 printf("%08X", offs);
7416             }
7417             else
7418             {
7419                 printf("%s", methodName);
7420             }
7421
7422             break;
7423
7424         default:
7425             printf("unexpected format %s", emitIfName(id->idInsFmt()));
7426             assert(!"unexpectedFormat");
7427             break;
7428     }
7429
7430     if (id->idDebugOnlyInfo()->idVarRefOffs)
7431     {
7432         printf("\t// ");
7433         emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(),
7434                          id->idDebugOnlyInfo()->idVarRefOffs, asmfm);
7435     }
7436
7437     printf("\n");
7438 }
7439
7440 void emitter::emitDispIns(
7441     instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* code, size_t sz, insGroup* ig)
7442 {
7443     insFormat fmt = id->idInsFmt();
7444
7445     /* Special-case IF_LARGEJMP */
7446
7447     if ((fmt == IF_LARGEJMP) && id->idIsBound())
7448     {
7449         // This is a pseudo-instruction format representing a large conditional branch. See the comment
7450         // in emitter::emitOutputLJ() for the full description.
7451         //
7452         // For this pseudo-instruction, we will actually generate:
7453         //
7454         //      b<!cond> L_not  // 2 bytes. Note that we reverse the condition.
7455         //      b L_target      // 4 bytes
7456         //   L_not:
7457         //
7458         // These instructions don't exist in the actual instruction stream, so we need to fake them
7459         // up to display them.
7460         //
7461         // Note: don't touch the actual instrDesc. If we accidentally messed it up, it would create a very
7462         // difficult to find bug.
7463
7464         instrDescJmp  idJmp;
7465         instrDescJmp* pidJmp = &idJmp;
7466
7467         memset(&idJmp, 0, sizeof(idJmp));
7468
7469         pidJmp->idIns(emitJumpKindToIns(emitReverseJumpKind(emitInsToJumpKind(id->idIns())))); // reverse the
7470                                                                                                // conditional
7471                                                                                                // instruction
7472         pidJmp->idInsFmt(IF_T1_K);
7473         pidJmp->idInsSize(emitInsSize(IF_T1_K));
7474         pidJmp->idjShort = 1;
7475         pidJmp->idAddr()->iiaSetInstrCount(1);
7476         pidJmp->idDebugOnlyInfo(id->idDebugOnlyInfo()); // share the idDebugOnlyInfo() field
7477
7478         size_t bcondSizeOrZero = (code == NULL) ? 0 : 2; // branch is 2 bytes
7479         emitDispInsHelp(pidJmp, false, doffs, asmfm, offset, code, bcondSizeOrZero,
7480                         NULL /* force display of pc-relative branch */);
7481
7482         code += bcondSizeOrZero;
7483         offset += 2;
7484
7485         // Next, display the unconditional branch
7486
7487         // Reset the local instrDesc
7488         memset(&idJmp, 0, sizeof(idJmp));
7489
7490         pidJmp->idIns(INS_b);
7491         pidJmp->idInsFmt(IF_T2_J2);
7492         pidJmp->idInsSize(emitInsSize(IF_T2_J2));
7493         pidJmp->idjShort = 0;
7494         if (id->idIsBound())
7495         {
7496             pidJmp->idSetIsBound();
7497             pidJmp->idAddr()->iiaIGlabel = id->idAddr()->iiaIGlabel;
7498         }
7499         else
7500         {
7501             pidJmp->idAddr()->iiaBBlabel = id->idAddr()->iiaBBlabel;
7502         }
7503         pidJmp->idDebugOnlyInfo(id->idDebugOnlyInfo()); // share the idDebugOnlyInfo() field
7504
7505         size_t brSizeOrZero = (code == NULL) ? 0 : 4; // unconditional branch is 4 bytes
7506         emitDispInsHelp(pidJmp, isNew, doffs, asmfm, offset, code, brSizeOrZero, ig);
7507     }
7508     else
7509     {
7510         emitDispInsHelp(id, isNew, doffs, asmfm, offset, code, sz, ig);
7511     }
7512 }
7513
7514 /*****************************************************************************
7515  *
7516  *  Display a stack frame reference.
7517  */
7518
7519 void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm)
7520 {
7521     printf("[");
7522
7523     if (varx < 0)
7524         printf("TEMP_%02u", -varx);
7525     else
7526         emitComp->gtDispLclVar(+varx, false);
7527
7528     if (disp < 0)
7529         printf("-0x%02x", -disp);
7530     else if (disp > 0)
7531         printf("+0x%02x", +disp);
7532
7533     printf("]");
7534
7535     if (varx >= 0 && emitComp->opts.varNames)
7536     {
7537         LclVarDsc*  varDsc;
7538         const char* varName;
7539
7540         assert((unsigned)varx < emitComp->lvaCount);
7541         varDsc  = emitComp->lvaTable + varx;
7542         varName = emitComp->compLocalVarName(varx, offs);
7543
7544         if (varName)
7545         {
7546             printf("'%s", varName);
7547
7548             if (disp < 0)
7549                 printf("-%d", -disp);
7550             else if (disp > 0)
7551                 printf("+%d", +disp);
7552
7553             printf("'");
7554         }
7555     }
7556 }
7557
7558 #endif // DEBUG
7559
7560 #ifndef LEGACY_BACKEND
7561
7562 void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTreeIndir* indir)
7563 {
7564     // Handle unaligned floating point loads/stores
7565     if ((indir->gtFlags & GTF_IND_UNALIGNED))
7566     {
7567         if (indir->OperGet() == GT_STOREIND)
7568         {
7569             var_types type = indir->AsStoreInd()->Data()->TypeGet();
7570             if (type == TYP_FLOAT)
7571             {
7572                 regNumber tmpReg = indir->GetSingleTempReg();
7573                 emitIns_R_R(INS_vmov_f2i, EA_4BYTE, tmpReg, dataReg);
7574                 emitInsLoadStoreOp(INS_str, EA_4BYTE, tmpReg, indir, 0);
7575                 return;
7576             }
7577             else if (type == TYP_DOUBLE)
7578             {
7579                 regNumber tmpReg1 = indir->ExtractTempReg();
7580                 regNumber tmpReg2 = indir->GetSingleTempReg();
7581                 emitIns_R_R_R(INS_vmov_d2i, EA_8BYTE, tmpReg1, tmpReg2, dataReg);
7582                 emitInsLoadStoreOp(INS_str, EA_4BYTE, tmpReg1, indir, 0);
7583                 emitInsLoadStoreOp(INS_str, EA_4BYTE, tmpReg2, indir, 4);
7584                 return;
7585             }
7586         }
7587         else if (indir->OperGet() == GT_IND)
7588         {
7589             var_types type = indir->TypeGet();
7590             if (type == TYP_FLOAT)
7591             {
7592                 regNumber tmpReg = indir->GetSingleTempReg();
7593                 emitInsLoadStoreOp(INS_ldr, EA_4BYTE, tmpReg, indir, 0);
7594                 emitIns_R_R(INS_vmov_i2f, EA_4BYTE, dataReg, tmpReg);
7595                 return;
7596             }
7597             else if (type == TYP_DOUBLE)
7598             {
7599                 regNumber tmpReg1 = indir->ExtractTempReg();
7600                 regNumber tmpReg2 = indir->GetSingleTempReg();
7601                 emitInsLoadStoreOp(INS_ldr, EA_4BYTE, tmpReg1, indir, 0);
7602                 emitInsLoadStoreOp(INS_ldr, EA_4BYTE, tmpReg2, indir, 4);
7603                 emitIns_R_R_R(INS_vmov_i2d, EA_8BYTE, dataReg, tmpReg1, tmpReg2);
7604                 return;
7605             }
7606         }
7607     }
7608
7609     // Proceed with ordinary loads/stores
7610     emitInsLoadStoreOp(ins, attr, dataReg, indir, 0);
7611 }
7612
7613 void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTreeIndir* indir, int offset)
7614 {
7615     GenTree* addr = indir->Addr();
7616
7617     if (addr->isContained())
7618     {
7619         assert(addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_LEA);
7620
7621         DWORD lsl = 0;
7622
7623         if (addr->OperGet() == GT_LEA)
7624         {
7625             offset += addr->AsAddrMode()->Offset();
7626             if (addr->AsAddrMode()->gtScale > 0)
7627             {
7628                 assert(isPow2(addr->AsAddrMode()->gtScale));
7629                 BitScanForward(&lsl, addr->AsAddrMode()->gtScale);
7630             }
7631         }
7632
7633         GenTree* memBase = indir->Base();
7634
7635         if (indir->HasIndex())
7636         {
7637             assert(addr->OperGet() == GT_LEA);
7638
7639             GenTree* index = indir->Index();
7640
7641             if (offset != 0)
7642             {
7643                 regNumber tmpReg = indir->GetSingleTempReg();
7644
7645                 // If the LEA produces a GCREF or BYREF, we need to be careful to mark any temp register
7646                 // computed with the base register as a BYREF.
7647                 GenTreeAddrMode* lea                    = addr->AsAddrMode();
7648                 emitAttr         leaAttr                = emitTypeSize(lea);
7649                 emitAttr         leaBasePartialAddrAttr = EA_IS_GCREF_OR_BYREF(leaAttr) ? EA_BYREF : EA_PTRSIZE;
7650
7651                 if (emitIns_valid_imm_for_add(offset, INS_FLAGS_DONT_CARE))
7652                 {
7653                     if (lsl > 0)
7654                     {
7655                         // Generate code to set tmpReg = base + index*scale
7656                         emitIns_R_R_R_I(INS_add, leaBasePartialAddrAttr, tmpReg, memBase->gtRegNum, index->gtRegNum,
7657                                         lsl, INS_FLAGS_DONT_CARE, INS_OPTS_LSL);
7658                     }
7659                     else // no scale
7660                     {
7661                         // Generate code to set tmpReg = base + index
7662                         emitIns_R_R_R(INS_add, leaBasePartialAddrAttr, tmpReg, memBase->gtRegNum, index->gtRegNum);
7663                     }
7664
7665                     noway_assert(emitInsIsLoad(ins) || (tmpReg != dataReg));
7666
7667                     // Then load/store dataReg from/to [tmpReg + offset]
7668                     emitIns_R_R_I(ins, attr, dataReg, tmpReg, offset);
7669                 }
7670                 else // large offset
7671                 {
7672                     // First load/store tmpReg with the large offset constant
7673                     codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset);
7674                     // Then add the base register
7675                     //      rd = rd + base
7676                     emitIns_R_R_R(INS_add, leaBasePartialAddrAttr, tmpReg, tmpReg, memBase->gtRegNum);
7677
7678                     noway_assert(emitInsIsLoad(ins) || (tmpReg != dataReg));
7679                     noway_assert(tmpReg != index->gtRegNum);
7680
7681                     // Then load/store dataReg from/to [tmpReg + index*scale]
7682                     emitIns_R_R_R_I(ins, attr, dataReg, tmpReg, index->gtRegNum, lsl, INS_FLAGS_DONT_CARE,
7683                                     INS_OPTS_LSL);
7684                 }
7685             }
7686             else // (offset == 0)
7687             {
7688                 if (lsl > 0)
7689                 {
7690                     // Then load/store dataReg from/to [memBase + index*scale]
7691                     emitIns_R_R_R_I(ins, attr, dataReg, memBase->gtRegNum, index->gtRegNum, lsl, INS_FLAGS_DONT_CARE,
7692                                     INS_OPTS_LSL);
7693                 }
7694                 else // no scale
7695                 {
7696                     // Then load/store dataReg from/to [memBase + index]
7697                     emitIns_R_R_R(ins, attr, dataReg, memBase->gtRegNum, index->gtRegNum);
7698                 }
7699             }
7700         }
7701         else // no Index
7702         {
7703             if (emitIns_valid_imm_for_ldst_offset(offset, attr))
7704             {
7705                 // Then load/store dataReg from/to [memBase + offset]
7706                 emitIns_R_R_I(ins, attr, dataReg, memBase->gtRegNum, offset);
7707             }
7708             else
7709             {
7710                 // We require a tmpReg to hold the offset
7711                 regNumber tmpReg = indir->GetSingleTempReg();
7712
7713                 // First load/store tmpReg with the large offset constant
7714                 codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset);
7715
7716                 // Then load/store dataReg from/to [memBase + tmpReg]
7717                 emitIns_R_R_R(ins, attr, dataReg, memBase->gtRegNum, tmpReg);
7718             }
7719         }
7720     }
7721     else
7722     {
7723         if (offset != 0)
7724         {
7725             assert(emitIns_valid_imm_for_add(offset, INS_FLAGS_DONT_CARE));
7726             emitIns_R_R_I(ins, attr, dataReg, addr->gtRegNum, offset);
7727         }
7728         else
7729         {
7730             emitIns_R_R(ins, attr, dataReg, addr->gtRegNum);
7731         }
7732     }
7733 }
7734
7735 // The callee must call genConsumeReg() for any non-contained srcs
7736 // and genProduceReg() for any non-contained dsts.
7737
7738 regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src)
7739 {
7740     regNumber result = REG_NA;
7741
7742     // dst can only be a reg
7743     assert(!dst->isContained());
7744
7745     // src can be immed or reg
7746     assert(!src->isContained() || src->isContainedIntOrIImmed());
7747
7748     // find immed (if any) - it cannot be a dst
7749     GenTreeIntConCommon* intConst = nullptr;
7750     if (src->isContainedIntOrIImmed())
7751     {
7752         intConst = src->AsIntConCommon();
7753     }
7754
7755     if (intConst)
7756     {
7757         emitIns_R_I(ins, attr, dst->gtRegNum, intConst->IconValue());
7758         return dst->gtRegNum;
7759     }
7760     else
7761     {
7762         emitIns_R_R(ins, attr, dst->gtRegNum, src->gtRegNum);
7763         return dst->gtRegNum;
7764     }
7765 }
7766
7767 regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src1, GenTree* src2)
7768 {
7769     // dst can only be a reg
7770     assert(!dst->isContained());
7771
7772     // find immed (if any) - it cannot be a dst
7773     // Only one src can be an int.
7774     GenTreeIntConCommon* intConst  = nullptr;
7775     GenTree*             nonIntReg = nullptr;
7776
7777     if (varTypeIsFloating(dst))
7778     {
7779         // src1 can only be a reg
7780         assert(!src1->isContained());
7781         // src2 can only be a reg
7782         assert(!src2->isContained());
7783     }
7784     else // not floating point
7785     {
7786         // src2 can be immed or reg
7787         assert(!src2->isContained() || src2->isContainedIntOrIImmed());
7788
7789         // Check src2 first as we can always allow it to be a contained immediate
7790         if (src2->isContainedIntOrIImmed())
7791         {
7792             intConst  = src2->AsIntConCommon();
7793             nonIntReg = src1;
7794         }
7795         // Only for commutative operations do we check src1 and allow it to be a contained immediate
7796         else if (dst->OperIsCommutative())
7797         {
7798             // src1 can be immed or reg
7799             assert(!src1->isContained() || src1->isContainedIntOrIImmed());
7800
7801             // Check src1 and allow it to be a contained immediate
7802             if (src1->isContainedIntOrIImmed())
7803             {
7804                 assert(!src2->isContainedIntOrIImmed());
7805                 intConst  = src1->AsIntConCommon();
7806                 nonIntReg = src2;
7807             }
7808         }
7809         else
7810         {
7811             // src1 can only be a reg
7812             assert(!src1->isContained());
7813         }
7814     }
7815
7816     insFlags flags         = INS_FLAGS_DONT_CARE;
7817     bool     isMulOverflow = false;
7818     if (dst->gtOverflowEx())
7819     {
7820         if ((ins == INS_add) || (ins == INS_adc) || (ins == INS_sub) || (ins == INS_sbc))
7821         {
7822             flags = INS_FLAGS_SET;
7823         }
7824         else if (ins == INS_mul)
7825         {
7826             isMulOverflow = true;
7827             assert(intConst == nullptr); // overflow format doesn't support an int constant operand
7828         }
7829         else
7830         {
7831             assert(!"Invalid ins for overflow check");
7832         }
7833     }
7834
7835     if (dst->gtSetFlags())
7836     {
7837         assert((ins == INS_add) || (ins == INS_adc) || (ins == INS_sub) || (ins == INS_sbc) || (ins == INS_and) ||
7838                (ins == INS_orr) || (ins == INS_eor) || (ins == INS_orn));
7839         flags = INS_FLAGS_SET;
7840     }
7841
7842     if (intConst != nullptr)
7843     {
7844         emitIns_R_R_I(ins, attr, dst->gtRegNum, nonIntReg->gtRegNum, intConst->IconValue(), flags);
7845     }
7846     else
7847     {
7848         if (isMulOverflow)
7849         {
7850             regNumber extraReg = dst->GetSingleTempReg();
7851             assert(extraReg != dst->gtRegNum);
7852
7853             if ((dst->gtFlags & GTF_UNSIGNED) != 0)
7854             {
7855                 // Compute 8 byte result from 4 byte by 4 byte multiplication.
7856                 emitIns_R_R_R_R(INS_umull, EA_4BYTE, dst->gtRegNum, extraReg, src1->gtRegNum, src2->gtRegNum);
7857
7858                 // Overflow exists if the result's high word is non-zero.
7859                 emitIns_R_I(INS_cmp, attr, extraReg, 0);
7860             }
7861             else
7862             {
7863                 // Compute 8 byte result from 4 byte by 4 byte multiplication.
7864                 emitIns_R_R_R_R(INS_smull, EA_4BYTE, dst->gtRegNum, extraReg, src1->gtRegNum, src2->gtRegNum);
7865
7866                 // Overflow exists if the result's high word is not merely a sign bit.
7867                 emitIns_R_R_I(INS_cmp, attr, extraReg, dst->gtRegNum, 31, INS_FLAGS_DONT_CARE, INS_OPTS_ASR);
7868             }
7869         }
7870         else
7871         {
7872             // We can just do the arithmetic, setting the flags if needed.
7873             emitIns_R_R_R(ins, attr, dst->gtRegNum, src1->gtRegNum, src2->gtRegNum, flags);
7874         }
7875     }
7876
7877     if (dst->gtOverflowEx())
7878     {
7879         assert(!varTypeIsFloating(dst));
7880
7881         emitJumpKind jumpKind;
7882
7883         if (dst->OperGet() == GT_MUL)
7884         {
7885             jumpKind = EJ_ne;
7886         }
7887         else
7888         {
7889             bool isUnsignedOverflow = ((dst->gtFlags & GTF_UNSIGNED) != 0);
7890             jumpKind                = isUnsignedOverflow ? EJ_lo : EJ_vs;
7891             if (jumpKind == EJ_lo)
7892             {
7893                 if ((dst->OperGet() != GT_SUB) &&
7894 #ifdef LEGACY_BACKEND
7895                     (dst->OperGet() != GT_ASG_SUB) &&
7896 #endif
7897                     (dst->OperGet() != GT_SUB_HI))
7898                 {
7899                     jumpKind = EJ_hs;
7900                 }
7901             }
7902         }
7903
7904         // Jump to the block which will throw the exception.
7905         codeGen->genJumpToThrowHlpBlk(jumpKind, SCK_OVERFLOW);
7906     }
7907
7908     return dst->gtRegNum;
7909 }
7910
7911 #endif // !LEGACY_BACKEND
7912 #endif // defined(_TARGET_ARM_)