DFG ARMv7 backend should optimize Float32 arrays
[WebKit-https.git] / Source / JavaScriptCore / assembler / ARMv7Assembler.h
1 /*
2  * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2010 University of Szeged
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #ifndef ARMAssembler_h
28 #define ARMAssembler_h
29
30 #if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
31
32 #include "AssemblerBuffer.h"
33 #include <wtf/Assertions.h>
34 #include <wtf/Vector.h>
35 #include <stdint.h>
36
37 namespace JSC {
38
39 namespace ARMRegisters {
40     typedef enum {
41         r0,
42         r1,
43         r2,
44         r3,
45         r4,
46         r5,
47         r6,
48         r7, wr = r7,   // thumb work register
49         r8,
50         r9, sb = r9,   // static base
51         r10, sl = r10, // stack limit
52         r11, fp = r11, // frame pointer
53         r12, ip = r12,
54         r13, sp = r13,
55         r14, lr = r14,
56         r15, pc = r15,
57     } RegisterID;
58
59     typedef enum {
60         s0,
61         s1,
62         s2,
63         s3,
64         s4,
65         s5,
66         s6,
67         s7,
68         s8,
69         s9,
70         s10,
71         s11,
72         s12,
73         s13,
74         s14,
75         s15,
76         s16,
77         s17,
78         s18,
79         s19,
80         s20,
81         s21,
82         s22,
83         s23,
84         s24,
85         s25,
86         s26,
87         s27,
88         s28,
89         s29,
90         s30,
91         s31,
92     } FPSingleRegisterID;
93
94     typedef enum {
95         d0,
96         d1,
97         d2,
98         d3,
99         d4,
100         d5,
101         d6,
102         d7,
103         d8,
104         d9,
105         d10,
106         d11,
107         d12,
108         d13,
109         d14,
110         d15,
111         d16,
112         d17,
113         d18,
114         d19,
115         d20,
116         d21,
117         d22,
118         d23,
119         d24,
120         d25,
121         d26,
122         d27,
123         d28,
124         d29,
125         d30,
126         d31,
127     } FPDoubleRegisterID;
128
129     typedef enum {
130         q0,
131         q1,
132         q2,
133         q3,
134         q4,
135         q5,
136         q6,
137         q7,
138         q8,
139         q9,
140         q10,
141         q11,
142         q12,
143         q13,
144         q14,
145         q15,
146         q16,
147         q17,
148         q18,
149         q19,
150         q20,
151         q21,
152         q22,
153         q23,
154         q24,
155         q25,
156         q26,
157         q27,
158         q28,
159         q29,
160         q30,
161         q31,
162     } FPQuadRegisterID;
163
164     inline FPSingleRegisterID asSingle(FPDoubleRegisterID reg)
165     {
166         ASSERT(reg < d16);
167         return (FPSingleRegisterID)(reg << 1);
168     }
169
170     inline FPDoubleRegisterID asDouble(FPSingleRegisterID reg)
171     {
172         ASSERT(!(reg & 1));
173         return (FPDoubleRegisterID)(reg >> 1);
174     }
175 }
176
177 class ARMv7Assembler;
178 class ARMThumbImmediate {
179     friend class ARMv7Assembler;
180
181     typedef uint8_t ThumbImmediateType;
182     static const ThumbImmediateType TypeInvalid = 0;
183     static const ThumbImmediateType TypeEncoded = 1;
184     static const ThumbImmediateType TypeUInt16 = 2;
185
186     typedef union {
187         int16_t asInt;
188         struct {
189             unsigned imm8 : 8;
190             unsigned imm3 : 3;
191             unsigned i    : 1;
192             unsigned imm4 : 4;
193         };
194         // If this is an encoded immediate, then it may describe a shift, or a pattern.
195         struct {
196             unsigned shiftValue7 : 7;
197             unsigned shiftAmount : 5;
198         };
199         struct {
200             unsigned immediate   : 8;
201             unsigned pattern     : 4;
202         };
203     } ThumbImmediateValue;
204
205     // byte0 contains least significant bit; not using an array to make client code endian agnostic.
206     typedef union {
207         int32_t asInt;
208         struct {
209             uint8_t byte0;
210             uint8_t byte1;
211             uint8_t byte2;
212             uint8_t byte3;
213         };
214     } PatternBytes;
215
216     ALWAYS_INLINE static void countLeadingZerosPartial(uint32_t& value, int32_t& zeros, const int N)
217     {
218         if (value & ~((1 << N) - 1)) /* check for any of the top N bits (of 2N bits) are set */
219             value >>= N;             /* if any were set, lose the bottom N */
220         else                         /* if none of the top N bits are set, */
221             zeros += N;              /* then we have identified N leading zeros */
222     }
223
224     static int32_t countLeadingZeros(uint32_t value)
225     {
226         if (!value)
227             return 32;
228
229         int32_t zeros = 0;
230         countLeadingZerosPartial(value, zeros, 16);
231         countLeadingZerosPartial(value, zeros, 8);
232         countLeadingZerosPartial(value, zeros, 4);
233         countLeadingZerosPartial(value, zeros, 2);
234         countLeadingZerosPartial(value, zeros, 1);
235         return zeros;
236     }
237
238     ARMThumbImmediate()
239         : m_type(TypeInvalid)
240     {
241         m_value.asInt = 0;
242     }
243         
244     ARMThumbImmediate(ThumbImmediateType type, ThumbImmediateValue value)
245         : m_type(type)
246         , m_value(value)
247     {
248     }
249
250     ARMThumbImmediate(ThumbImmediateType type, uint16_t value)
251         : m_type(TypeUInt16)
252     {
253         // Make sure this constructor is only reached with type TypeUInt16;
254         // this extra parameter makes the code a little clearer by making it
255         // explicit at call sites which type is being constructed
256         ASSERT_UNUSED(type, type == TypeUInt16);
257
258         m_value.asInt = value;
259     }
260
261 public:
262     static ARMThumbImmediate makeEncodedImm(uint32_t value)
263     {
264         ThumbImmediateValue encoding;
265         encoding.asInt = 0;
266
267         // okay, these are easy.
268         if (value < 256) {
269             encoding.immediate = value;
270             encoding.pattern = 0;
271             return ARMThumbImmediate(TypeEncoded, encoding);
272         }
273
274         int32_t leadingZeros = countLeadingZeros(value);
275         // if there were 24 or more leading zeros, then we'd have hit the (value < 256) case.
276         ASSERT(leadingZeros < 24);
277
278         // Given a number with bit fields Z:B:C, where count(Z)+count(B)+count(C) == 32,
279         // Z are the bits known zero, B is the 8-bit immediate, C are the bits to check for
280         // zero.  count(B) == 8, so the count of bits to be checked is 24 - count(Z).
281         int32_t rightShiftAmount = 24 - leadingZeros;
282         if (value == ((value >> rightShiftAmount) << rightShiftAmount)) {
283             // Shift the value down to the low byte position.  The assign to 
284             // shiftValue7 drops the implicit top bit.
285             encoding.shiftValue7 = value >> rightShiftAmount;
286             // The endoded shift amount is the magnitude of a right rotate.
287             encoding.shiftAmount = 8 + leadingZeros;
288             return ARMThumbImmediate(TypeEncoded, encoding);
289         }
290         
291         PatternBytes bytes;
292         bytes.asInt = value;
293
294         if ((bytes.byte0 == bytes.byte1) && (bytes.byte0 == bytes.byte2) && (bytes.byte0 == bytes.byte3)) {
295             encoding.immediate = bytes.byte0;
296             encoding.pattern = 3;
297             return ARMThumbImmediate(TypeEncoded, encoding);
298         }
299
300         if ((bytes.byte0 == bytes.byte2) && !(bytes.byte1 | bytes.byte3)) {
301             encoding.immediate = bytes.byte0;
302             encoding.pattern = 1;
303             return ARMThumbImmediate(TypeEncoded, encoding);
304         }
305
306         if ((bytes.byte1 == bytes.byte3) && !(bytes.byte0 | bytes.byte2)) {
307             encoding.immediate = bytes.byte1;
308             encoding.pattern = 2;
309             return ARMThumbImmediate(TypeEncoded, encoding);
310         }
311
312         return ARMThumbImmediate();
313     }
314
315     static ARMThumbImmediate makeUInt12(int32_t value)
316     {
317         return (!(value & 0xfffff000))
318             ? ARMThumbImmediate(TypeUInt16, (uint16_t)value)
319             : ARMThumbImmediate();
320     }
321
322     static ARMThumbImmediate makeUInt12OrEncodedImm(int32_t value)
323     {
324         // If this is not a 12-bit unsigned it, try making an encoded immediate.
325         return (!(value & 0xfffff000))
326             ? ARMThumbImmediate(TypeUInt16, (uint16_t)value)
327             : makeEncodedImm(value);
328     }
329
330     // The 'make' methods, above, return a !isValid() value if the argument
331     // cannot be represented as the requested type.  This methods  is called
332     // 'get' since the argument can always be represented.
333     static ARMThumbImmediate makeUInt16(uint16_t value)
334     {
335         return ARMThumbImmediate(TypeUInt16, value);
336     }
337     
338     bool isValid()
339     {
340         return m_type != TypeInvalid;
341     }
342
343     uint16_t asUInt16() const { return m_value.asInt; }
344
345     // These methods rely on the format of encoded byte values.
346     bool isUInt3() { return !(m_value.asInt & 0xfff8); }
347     bool isUInt4() { return !(m_value.asInt & 0xfff0); }
348     bool isUInt5() { return !(m_value.asInt & 0xffe0); }
349     bool isUInt6() { return !(m_value.asInt & 0xffc0); }
350     bool isUInt7() { return !(m_value.asInt & 0xff80); }
351     bool isUInt8() { return !(m_value.asInt & 0xff00); }
352     bool isUInt9() { return (m_type == TypeUInt16) && !(m_value.asInt & 0xfe00); }
353     bool isUInt10() { return (m_type == TypeUInt16) && !(m_value.asInt & 0xfc00); }
354     bool isUInt12() { return (m_type == TypeUInt16) && !(m_value.asInt & 0xf000); }
355     bool isUInt16() { return m_type == TypeUInt16; }
356     uint8_t getUInt3() { ASSERT(isUInt3()); return m_value.asInt; }
357     uint8_t getUInt4() { ASSERT(isUInt4()); return m_value.asInt; }
358     uint8_t getUInt5() { ASSERT(isUInt5()); return m_value.asInt; }
359     uint8_t getUInt6() { ASSERT(isUInt6()); return m_value.asInt; }
360     uint8_t getUInt7() { ASSERT(isUInt7()); return m_value.asInt; }
361     uint8_t getUInt8() { ASSERT(isUInt8()); return m_value.asInt; }
362     uint16_t getUInt9() { ASSERT(isUInt9()); return m_value.asInt; }
363     uint16_t getUInt10() { ASSERT(isUInt10()); return m_value.asInt; }
364     uint16_t getUInt12() { ASSERT(isUInt12()); return m_value.asInt; }
365     uint16_t getUInt16() { ASSERT(isUInt16()); return m_value.asInt; }
366
367     bool isEncodedImm() { return m_type == TypeEncoded; }
368
369 private:
370     ThumbImmediateType m_type;
371     ThumbImmediateValue m_value;
372 };
373
374 typedef enum {
375     SRType_LSL,
376     SRType_LSR,
377     SRType_ASR,
378     SRType_ROR,
379
380     SRType_RRX = SRType_ROR
381 } ARMShiftType;
382
383 class ShiftTypeAndAmount {
384     friend class ARMv7Assembler;
385
386 public:
387     ShiftTypeAndAmount()
388     {
389         m_u.type = (ARMShiftType)0;
390         m_u.amount = 0;
391     }
392     
393     ShiftTypeAndAmount(ARMShiftType type, unsigned amount)
394     {
395         m_u.type = type;
396         m_u.amount = amount & 31;
397     }
398     
399     unsigned lo4() { return m_u.lo4; }
400     unsigned hi4() { return m_u.hi4; }
401     
402 private:
403     union {
404         struct {
405             unsigned lo4 : 4;
406             unsigned hi4 : 4;
407         };
408         struct {
409             unsigned type   : 2;
410             unsigned amount : 6;
411         };
412     } m_u;
413 };
414
415 class ARMv7Assembler {
416 public:
417     typedef ARMRegisters::RegisterID RegisterID;
418     typedef ARMRegisters::FPSingleRegisterID FPSingleRegisterID;
419     typedef ARMRegisters::FPDoubleRegisterID FPDoubleRegisterID;
420     typedef ARMRegisters::FPQuadRegisterID FPQuadRegisterID;
421
422     // (HS, LO, HI, LS) -> (AE, B, A, BE)
423     // (VS, VC) -> (O, NO)
424     typedef enum {
425         ConditionEQ,
426         ConditionNE,
427         ConditionHS, ConditionCS = ConditionHS,
428         ConditionLO, ConditionCC = ConditionLO,
429         ConditionMI,
430         ConditionPL,
431         ConditionVS,
432         ConditionVC,
433         ConditionHI,
434         ConditionLS,
435         ConditionGE,
436         ConditionLT,
437         ConditionGT,
438         ConditionLE,
439         ConditionAL,
440         ConditionInvalid
441     } Condition;
442
443 #define JUMP_ENUM_WITH_SIZE(index, value) (((value) << 3) | (index))
444 #define JUMP_ENUM_SIZE(jump) ((jump) >> 3) 
445     enum JumpType { JumpFixed = JUMP_ENUM_WITH_SIZE(0, 0), 
446                     JumpNoCondition = JUMP_ENUM_WITH_SIZE(1, 5 * sizeof(uint16_t)),
447                     JumpCondition = JUMP_ENUM_WITH_SIZE(2, 6 * sizeof(uint16_t)),
448                     JumpNoConditionFixedSize = JUMP_ENUM_WITH_SIZE(3, 5 * sizeof(uint16_t)),
449                     JumpConditionFixedSize = JUMP_ENUM_WITH_SIZE(4, 6 * sizeof(uint16_t))
450     };
451     enum JumpLinkType { 
452         LinkInvalid = JUMP_ENUM_WITH_SIZE(0, 0),
453         LinkJumpT1 = JUMP_ENUM_WITH_SIZE(1, sizeof(uint16_t)),
454         LinkJumpT2 = JUMP_ENUM_WITH_SIZE(2, sizeof(uint16_t)),
455         LinkJumpT3 = JUMP_ENUM_WITH_SIZE(3, 2 * sizeof(uint16_t)),
456         LinkJumpT4 = JUMP_ENUM_WITH_SIZE(4, 2 * sizeof(uint16_t)),
457         LinkConditionalJumpT4 = JUMP_ENUM_WITH_SIZE(5, 3 * sizeof(uint16_t)),
458         LinkBX = JUMP_ENUM_WITH_SIZE(6, 5 * sizeof(uint16_t)),
459         LinkConditionalBX = JUMP_ENUM_WITH_SIZE(7, 6 * sizeof(uint16_t))
460     };
461
462     class LinkRecord {
463     public:
464         LinkRecord(intptr_t from, intptr_t to, JumpType type, Condition condition)
465             : m_from(from)
466             , m_to(to)
467             , m_type(type)
468             , m_linkType(LinkInvalid)
469             , m_condition(condition)
470         {
471         }
472         intptr_t from() const { return m_from; }
473         void setFrom(intptr_t from) { m_from = from; }
474         intptr_t to() const { return m_to; }
475         JumpType type() const { return m_type; }
476         JumpLinkType linkType() const { return m_linkType; }
477         void setLinkType(JumpLinkType linkType) { ASSERT(m_linkType == LinkInvalid); m_linkType = linkType; }
478         Condition condition() const { return m_condition; }
479     private:
480         intptr_t m_from : 31;
481         intptr_t m_to : 31;
482         JumpType m_type : 8;
483         JumpLinkType m_linkType : 8;
484         Condition m_condition : 16;
485     };
486
487 private:
488
489     // ARMv7, Appx-A.6.3
490     bool BadReg(RegisterID reg)
491     {
492         return (reg == ARMRegisters::sp) || (reg == ARMRegisters::pc);
493     }
494
495     uint32_t singleRegisterMask(FPSingleRegisterID rdNum, int highBitsShift, int lowBitShift)
496     {
497         uint32_t rdMask = (rdNum >> 1) << highBitsShift;
498         if (rdNum & 1)
499             rdMask |= 1 << lowBitShift;
500         return rdMask;
501     }
502
503     uint32_t doubleRegisterMask(FPDoubleRegisterID rdNum, int highBitShift, int lowBitsShift)
504     {
505         uint32_t rdMask = (rdNum & 0xf) << lowBitsShift;
506         if (rdNum & 16)
507             rdMask |= 1 << highBitShift;
508         return rdMask;
509     }
510
511     typedef enum {
512         OP_ADD_reg_T1       = 0x1800,
513         OP_SUB_reg_T1       = 0x1A00,
514         OP_ADD_imm_T1       = 0x1C00,
515         OP_SUB_imm_T1       = 0x1E00,
516         OP_MOV_imm_T1       = 0x2000,
517         OP_CMP_imm_T1       = 0x2800,
518         OP_ADD_imm_T2       = 0x3000,
519         OP_SUB_imm_T2       = 0x3800,
520         OP_AND_reg_T1       = 0x4000,
521         OP_EOR_reg_T1       = 0x4040,
522         OP_TST_reg_T1       = 0x4200,
523         OP_RSB_imm_T1       = 0x4240,
524         OP_CMP_reg_T1       = 0x4280,
525         OP_ORR_reg_T1       = 0x4300,
526         OP_MVN_reg_T1       = 0x43C0,
527         OP_ADD_reg_T2       = 0x4400,
528         OP_MOV_reg_T1       = 0x4600,
529         OP_BLX              = 0x4700,
530         OP_BX               = 0x4700,
531         OP_STR_reg_T1       = 0x5000,
532         OP_STRH_reg_T1      = 0x5200,
533         OP_STRB_reg_T1      = 0x5400,
534         OP_LDRSB_reg_T1     = 0x5600,
535         OP_LDR_reg_T1       = 0x5800,
536         OP_LDRH_reg_T1      = 0x5A00,
537         OP_LDRB_reg_T1      = 0x5C00,
538         OP_LDRSH_reg_T1     = 0x5E00,
539         OP_STR_imm_T1       = 0x6000,
540         OP_LDR_imm_T1       = 0x6800,
541         OP_STRB_imm_T1      = 0x7000,
542         OP_LDRB_imm_T1      = 0x7800,
543         OP_STRH_imm_T1      = 0x8000,
544         OP_LDRH_imm_T1      = 0x8800,
545         OP_STR_imm_T2       = 0x9000,
546         OP_LDR_imm_T2       = 0x9800,
547         OP_ADD_SP_imm_T1    = 0xA800,
548         OP_ADD_SP_imm_T2    = 0xB000,
549         OP_SUB_SP_imm_T1    = 0xB080,
550         OP_BKPT             = 0xBE00,
551         OP_IT               = 0xBF00,
552         OP_NOP_T1           = 0xBF00,
553     } OpcodeID;
554
555     typedef enum {
556         OP_B_T1         = 0xD000,
557         OP_B_T2         = 0xE000,
558         OP_AND_reg_T2   = 0xEA00,
559         OP_TST_reg_T2   = 0xEA10,
560         OP_ORR_reg_T2   = 0xEA40,
561         OP_ORR_S_reg_T2 = 0xEA50,
562         OP_ASR_imm_T1   = 0xEA4F,
563         OP_LSL_imm_T1   = 0xEA4F,
564         OP_LSR_imm_T1   = 0xEA4F,
565         OP_ROR_imm_T1   = 0xEA4F,
566         OP_MVN_reg_T2   = 0xEA6F,
567         OP_EOR_reg_T2   = 0xEA80,
568         OP_ADD_reg_T3   = 0xEB00,
569         OP_ADD_S_reg_T3 = 0xEB10,
570         OP_SUB_reg_T2   = 0xEBA0,
571         OP_SUB_S_reg_T2 = 0xEBB0,
572         OP_CMP_reg_T2   = 0xEBB0,
573         OP_VMOV_CtoD    = 0xEC00,
574         OP_VMOV_DtoC    = 0xEC10,
575         OP_FSTS         = 0xED00,
576         OP_VSTR         = 0xED00,
577         OP_FLDS         = 0xED10,
578         OP_VLDR         = 0xED10,
579         OP_VMOV_CtoS    = 0xEE00,
580         OP_VMOV_StoC    = 0xEE10,
581         OP_VMUL_T2      = 0xEE20,
582         OP_VADD_T2      = 0xEE30,
583         OP_VSUB_T2      = 0xEE30,
584         OP_VDIV         = 0xEE80,
585         OP_VABS_T2      = 0xEEB0,
586         OP_VCMP         = 0xEEB0,
587         OP_VCVT_FPIVFP  = 0xEEB0,
588         OP_VMOV_T2      = 0xEEB0,
589         OP_VMOV_IMM_T2  = 0xEEB0,
590         OP_VMRS         = 0xEEB0,
591         OP_VNEG_T2      = 0xEEB0,
592         OP_VSQRT_T1     = 0xEEB0,
593         OP_VCVTSD_T1    = 0xEEB0,
594         OP_VCVTDS_T1    = 0xEEB0,
595         OP_B_T3a        = 0xF000,
596         OP_B_T4a        = 0xF000,
597         OP_AND_imm_T1   = 0xF000,
598         OP_TST_imm      = 0xF010,
599         OP_ORR_imm_T1   = 0xF040,
600         OP_MOV_imm_T2   = 0xF040,
601         OP_MVN_imm      = 0xF060,
602         OP_EOR_imm_T1   = 0xF080,
603         OP_ADD_imm_T3   = 0xF100,
604         OP_ADD_S_imm_T3 = 0xF110,
605         OP_CMN_imm      = 0xF110,
606         OP_ADC_imm      = 0xF140,
607         OP_SUB_imm_T3   = 0xF1A0,
608         OP_SUB_S_imm_T3 = 0xF1B0,
609         OP_CMP_imm_T2   = 0xF1B0,
610         OP_RSB_imm_T2   = 0xF1C0,
611         OP_RSB_S_imm_T2 = 0xF1D0,
612         OP_ADD_imm_T4   = 0xF200,
613         OP_MOV_imm_T3   = 0xF240,
614         OP_SUB_imm_T4   = 0xF2A0,
615         OP_MOVT         = 0xF2C0,
616         OP_UBFX_T1      = 0xF3C0,
617         OP_NOP_T2a      = 0xF3AF,
618         OP_STRB_imm_T3  = 0xF800,
619         OP_STRB_reg_T2  = 0xF800,
620         OP_LDRB_imm_T3  = 0xF810,
621         OP_LDRB_reg_T2  = 0xF810,
622         OP_STRH_imm_T3  = 0xF820,
623         OP_STRH_reg_T2  = 0xF820,
624         OP_LDRH_reg_T2  = 0xF830,
625         OP_LDRH_imm_T3  = 0xF830,
626         OP_STR_imm_T4   = 0xF840,
627         OP_STR_reg_T2   = 0xF840,
628         OP_LDR_imm_T4   = 0xF850,
629         OP_LDR_reg_T2   = 0xF850,
630         OP_STRB_imm_T2  = 0xF880,
631         OP_LDRB_imm_T2  = 0xF890,
632         OP_STRH_imm_T2  = 0xF8A0,
633         OP_LDRH_imm_T2  = 0xF8B0,
634         OP_STR_imm_T3   = 0xF8C0,
635         OP_LDR_imm_T3   = 0xF8D0,
636         OP_LDRSB_reg_T2 = 0xF910,
637         OP_LDRSH_reg_T2 = 0xF930,
638         OP_LSL_reg_T2   = 0xFA00,
639         OP_LSR_reg_T2   = 0xFA20,
640         OP_ASR_reg_T2   = 0xFA40,
641         OP_ROR_reg_T2   = 0xFA60,
642         OP_CLZ          = 0xFAB0,
643         OP_SMULL_T1     = 0xFB80,
644     } OpcodeID1;
645
646     typedef enum {
647         OP_VADD_T2b     = 0x0A00,
648         OP_VDIVb        = 0x0A00,
649         OP_FLDSb        = 0x0A00,
650         OP_VLDRb        = 0x0A00,
651         OP_VMOV_IMM_T2b = 0x0A00,
652         OP_VMOV_T2b     = 0x0A40,
653         OP_VMUL_T2b     = 0x0A00,
654         OP_FSTSb        = 0x0A00,
655         OP_VSTRb        = 0x0A00,
656         OP_VMOV_StoCb   = 0x0A10,
657         OP_VMOV_CtoSb   = 0x0A10,
658         OP_VMOV_DtoCb   = 0x0A10,
659         OP_VMOV_CtoDb   = 0x0A10,
660         OP_VMRSb        = 0x0A10,
661         OP_VABS_T2b     = 0x0A40,
662         OP_VCMPb        = 0x0A40,
663         OP_VCVT_FPIVFPb = 0x0A40,
664         OP_VNEG_T2b     = 0x0A40,
665         OP_VSUB_T2b     = 0x0A40,
666         OP_VSQRT_T1b    = 0x0A40,
667         OP_VCVTSD_T1b   = 0x0A40,
668         OP_VCVTDS_T1b   = 0x0A40,
669         OP_NOP_T2b      = 0x8000,
670         OP_B_T3b        = 0x8000,
671         OP_B_T4b        = 0x9000,
672     } OpcodeID2;
673
674     struct FourFours {
675         FourFours(unsigned f3, unsigned f2, unsigned f1, unsigned f0)
676         {
677             m_u.f0 = f0;
678             m_u.f1 = f1;
679             m_u.f2 = f2;
680             m_u.f3 = f3;
681         }
682
683         union {
684             unsigned value;
685             struct {
686                 unsigned f0 : 4;
687                 unsigned f1 : 4;
688                 unsigned f2 : 4;
689                 unsigned f3 : 4;
690             };
691         } m_u;
692     };
693
694     class ARMInstructionFormatter;
695
696     // false means else!
697     bool ifThenElseConditionBit(Condition condition, bool isIf)
698     {
699         return isIf ? (condition & 1) : !(condition & 1);
700     }
701     uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if, bool inst4if)
702     {
703         int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
704             | (ifThenElseConditionBit(condition, inst3if) << 2)
705             | (ifThenElseConditionBit(condition, inst4if) << 1)
706             | 1;
707         ASSERT((condition != ConditionAL) || !(mask & (mask - 1)));
708         return (condition << 4) | mask;
709     }
710     uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if)
711     {
712         int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
713             | (ifThenElseConditionBit(condition, inst3if) << 2)
714             | 2;
715         ASSERT((condition != ConditionAL) || !(mask & (mask - 1)));
716         return (condition << 4) | mask;
717     }
718     uint8_t ifThenElse(Condition condition, bool inst2if)
719     {
720         int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
721             | 4;
722         ASSERT((condition != ConditionAL) || !(mask & (mask - 1)));
723         return (condition << 4) | mask;
724     }
725
726     uint8_t ifThenElse(Condition condition)
727     {
728         int mask = 8;
729         return (condition << 4) | mask;
730     }
731
732 public:
733     
734     void adc(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
735     {
736         // Rd can only be SP if Rn is also SP.
737         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
738         ASSERT(rd != ARMRegisters::pc);
739         ASSERT(rn != ARMRegisters::pc);
740         ASSERT(imm.isEncodedImm());
741
742         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADC_imm, rn, rd, imm);
743     }
744
745     void add(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
746     {
747         // Rd can only be SP if Rn is also SP.
748         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
749         ASSERT(rd != ARMRegisters::pc);
750         ASSERT(rn != ARMRegisters::pc);
751         ASSERT(imm.isValid());
752
753         if (rn == ARMRegisters::sp) {
754             ASSERT(!(imm.getUInt16() & 3));
755             if (!(rd & 8) && imm.isUInt10()) {
756                 m_formatter.oneWordOp5Reg3Imm8(OP_ADD_SP_imm_T1, rd, static_cast<uint8_t>(imm.getUInt10() >> 2));
757                 return;
758             } else if ((rd == ARMRegisters::sp) && imm.isUInt9()) {
759                 m_formatter.oneWordOp9Imm7(OP_ADD_SP_imm_T2, static_cast<uint8_t>(imm.getUInt9() >> 2));
760                 return;
761             }
762         } else if (!((rd | rn) & 8)) {
763             if (imm.isUInt3()) {
764                 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
765                 return;
766             } else if ((rd == rn) && imm.isUInt8()) {
767                 m_formatter.oneWordOp5Reg3Imm8(OP_ADD_imm_T2, rd, imm.getUInt8());
768                 return;
769             }
770         }
771
772         if (imm.isEncodedImm())
773             m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADD_imm_T3, rn, rd, imm);
774         else {
775             ASSERT(imm.isUInt12());
776             m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADD_imm_T4, rn, rd, imm);
777         }
778     }
779
780     ALWAYS_INLINE void add(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
781     {
782         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
783         ASSERT(rd != ARMRegisters::pc);
784         ASSERT(rn != ARMRegisters::pc);
785         ASSERT(!BadReg(rm));
786         m_formatter.twoWordOp12Reg4FourFours(OP_ADD_reg_T3, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
787     }
788
789     // NOTE: In an IT block, add doesn't modify the flags register.
790     ALWAYS_INLINE void add(RegisterID rd, RegisterID rn, RegisterID rm)
791     {
792         if (rd == rn)
793             m_formatter.oneWordOp8RegReg143(OP_ADD_reg_T2, rm, rd);
794         else if (rd == rm)
795             m_formatter.oneWordOp8RegReg143(OP_ADD_reg_T2, rn, rd);
796         else if (!((rd | rn | rm) & 8))
797             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_reg_T1, rm, rn, rd);
798         else
799             add(rd, rn, rm, ShiftTypeAndAmount());
800     }
801
802     // Not allowed in an IT (if then) block.
803     ALWAYS_INLINE void add_S(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
804     {
805         // Rd can only be SP if Rn is also SP.
806         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
807         ASSERT(rd != ARMRegisters::pc);
808         ASSERT(rn != ARMRegisters::pc);
809         ASSERT(imm.isEncodedImm());
810
811         if (!((rd | rn) & 8)) {
812             if (imm.isUInt3()) {
813                 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
814                 return;
815             } else if ((rd == rn) && imm.isUInt8()) {
816                 m_formatter.oneWordOp5Reg3Imm8(OP_ADD_imm_T2, rd, imm.getUInt8());
817                 return;
818             }
819         }
820
821         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADD_S_imm_T3, rn, rd, imm);
822     }
823
824     // Not allowed in an IT (if then) block?
825     ALWAYS_INLINE void add_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
826     {
827         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
828         ASSERT(rd != ARMRegisters::pc);
829         ASSERT(rn != ARMRegisters::pc);
830         ASSERT(!BadReg(rm));
831         m_formatter.twoWordOp12Reg4FourFours(OP_ADD_S_reg_T3, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
832     }
833
834     // Not allowed in an IT (if then) block.
835     ALWAYS_INLINE void add_S(RegisterID rd, RegisterID rn, RegisterID rm)
836     {
837         if (!((rd | rn | rm) & 8))
838             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_reg_T1, rm, rn, rd);
839         else
840             add_S(rd, rn, rm, ShiftTypeAndAmount());
841     }
842
843     ALWAYS_INLINE void ARM_and(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
844     {
845         ASSERT(!BadReg(rd));
846         ASSERT(!BadReg(rn));
847         ASSERT(imm.isEncodedImm());
848         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_AND_imm_T1, rn, rd, imm);
849     }
850
851     ALWAYS_INLINE void ARM_and(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
852     {
853         ASSERT(!BadReg(rd));
854         ASSERT(!BadReg(rn));
855         ASSERT(!BadReg(rm));
856         m_formatter.twoWordOp12Reg4FourFours(OP_AND_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
857     }
858
859     ALWAYS_INLINE void ARM_and(RegisterID rd, RegisterID rn, RegisterID rm)
860     {
861         if ((rd == rn) && !((rd | rm) & 8))
862             m_formatter.oneWordOp10Reg3Reg3(OP_AND_reg_T1, rm, rd);
863         else if ((rd == rm) && !((rd | rn) & 8))
864             m_formatter.oneWordOp10Reg3Reg3(OP_AND_reg_T1, rn, rd);
865         else
866             ARM_and(rd, rn, rm, ShiftTypeAndAmount());
867     }
868
869     ALWAYS_INLINE void asr(RegisterID rd, RegisterID rm, int32_t shiftAmount)
870     {
871         ASSERT(!BadReg(rd));
872         ASSERT(!BadReg(rm));
873         ShiftTypeAndAmount shift(SRType_ASR, shiftAmount);
874         m_formatter.twoWordOp16FourFours(OP_ASR_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm));
875     }
876
877     ALWAYS_INLINE void asr(RegisterID rd, RegisterID rn, RegisterID rm)
878     {
879         ASSERT(!BadReg(rd));
880         ASSERT(!BadReg(rn));
881         ASSERT(!BadReg(rm));
882         m_formatter.twoWordOp12Reg4FourFours(OP_ASR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
883     }
884     
885     // Only allowed in IT (if then) block if last instruction.
886     ALWAYS_INLINE AssemblerLabel b()
887     {
888         m_formatter.twoWordOp16Op16(OP_B_T4a, OP_B_T4b);
889         return m_formatter.label();
890     }
891     
892     // Only allowed in IT (if then) block if last instruction.
893     ALWAYS_INLINE AssemblerLabel blx(RegisterID rm)
894     {
895         ASSERT(rm != ARMRegisters::pc);
896         m_formatter.oneWordOp8RegReg143(OP_BLX, rm, (RegisterID)8);
897         return m_formatter.label();
898     }
899
900     // Only allowed in IT (if then) block if last instruction.
901     ALWAYS_INLINE AssemblerLabel bx(RegisterID rm)
902     {
903         m_formatter.oneWordOp8RegReg143(OP_BX, rm, (RegisterID)0);
904         return m_formatter.label();
905     }
906
907     void bkpt(uint8_t imm = 0)
908     {
909         m_formatter.oneWordOp8Imm8(OP_BKPT, imm);
910     }
911
912     ALWAYS_INLINE void clz(RegisterID rd, RegisterID rm)
913     {
914         ASSERT(!BadReg(rd));
915         ASSERT(!BadReg(rm));
916         m_formatter.twoWordOp12Reg4FourFours(OP_CLZ, rm, FourFours(0xf, rd, 8, rm));
917     }
918
919     ALWAYS_INLINE void cmn(RegisterID rn, ARMThumbImmediate imm)
920     {
921         ASSERT(rn != ARMRegisters::pc);
922         ASSERT(imm.isEncodedImm());
923
924         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_CMN_imm, rn, (RegisterID)0xf, imm);
925     }
926
927     ALWAYS_INLINE void cmp(RegisterID rn, ARMThumbImmediate imm)
928     {
929         ASSERT(rn != ARMRegisters::pc);
930         ASSERT(imm.isEncodedImm());
931
932         if (!(rn & 8) && imm.isUInt8())
933             m_formatter.oneWordOp5Reg3Imm8(OP_CMP_imm_T1, rn, imm.getUInt8());
934         else
935             m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_CMP_imm_T2, rn, (RegisterID)0xf, imm);
936     }
937
938     ALWAYS_INLINE void cmp(RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
939     {
940         ASSERT(rn != ARMRegisters::pc);
941         ASSERT(!BadReg(rm));
942         m_formatter.twoWordOp12Reg4FourFours(OP_CMP_reg_T2, rn, FourFours(shift.hi4(), 0xf, shift.lo4(), rm));
943     }
944
945     ALWAYS_INLINE void cmp(RegisterID rn, RegisterID rm)
946     {
947         if ((rn | rm) & 8)
948             cmp(rn, rm, ShiftTypeAndAmount());
949         else
950             m_formatter.oneWordOp10Reg3Reg3(OP_CMP_reg_T1, rm, rn);
951     }
952
953     // xor is not spelled with an 'e'. :-(
954     ALWAYS_INLINE void eor(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
955     {
956         ASSERT(!BadReg(rd));
957         ASSERT(!BadReg(rn));
958         ASSERT(imm.isEncodedImm());
959         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_EOR_imm_T1, rn, rd, imm);
960     }
961
962     // xor is not spelled with an 'e'. :-(
963     ALWAYS_INLINE void eor(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
964     {
965         ASSERT(!BadReg(rd));
966         ASSERT(!BadReg(rn));
967         ASSERT(!BadReg(rm));
968         m_formatter.twoWordOp12Reg4FourFours(OP_EOR_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
969     }
970
971     // xor is not spelled with an 'e'. :-(
972     void eor(RegisterID rd, RegisterID rn, RegisterID rm)
973     {
974         if ((rd == rn) && !((rd | rm) & 8))
975             m_formatter.oneWordOp10Reg3Reg3(OP_EOR_reg_T1, rm, rd);
976         else if ((rd == rm) && !((rd | rn) & 8))
977             m_formatter.oneWordOp10Reg3Reg3(OP_EOR_reg_T1, rn, rd);
978         else
979             eor(rd, rn, rm, ShiftTypeAndAmount());
980     }
981
982     ALWAYS_INLINE void it(Condition cond)
983     {
984         m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond));
985     }
986
987     ALWAYS_INLINE void it(Condition cond, bool inst2if)
988     {
989         m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if));
990     }
991
992     ALWAYS_INLINE void it(Condition cond, bool inst2if, bool inst3if)
993     {
994         m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if, inst3if));
995     }
996
997     ALWAYS_INLINE void it(Condition cond, bool inst2if, bool inst3if, bool inst4if)
998     {
999         m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if, inst3if, inst4if));
1000     }
1001
1002     // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block.
1003     ALWAYS_INLINE void ldr(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
1004     {
1005         ASSERT(rn != ARMRegisters::pc); // LDR (literal)
1006         ASSERT(imm.isUInt12());
1007
1008         if (!((rt | rn) & 8) && imm.isUInt7())
1009             m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDR_imm_T1, imm.getUInt7() >> 2, rn, rt);
1010         else if ((rn == ARMRegisters::sp) && !(rt & 8) && imm.isUInt10())
1011             m_formatter.oneWordOp5Reg3Imm8(OP_LDR_imm_T2, rt, static_cast<uint8_t>(imm.getUInt10() >> 2));
1012         else
1013             m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T3, rn, rt, imm.getUInt12());
1014     }
1015
1016     ALWAYS_INLINE void ldrCompact(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
1017     {
1018         ASSERT(rn != ARMRegisters::pc); // LDR (literal)
1019         ASSERT(imm.isUInt7());
1020         ASSERT(!((rt | rn) & 8));
1021         m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDR_imm_T1, imm.getUInt7() >> 2, rn, rt);
1022     }
1023
1024     // If index is set, this is a regular offset or a pre-indexed load;
1025     // if index is not set then is is a post-index load.
1026     //
1027     // If wback is set rn is updated - this is a pre or post index load,
1028     // if wback is not set this is a regular offset memory access.
1029     //
1030     // (-255 <= offset <= 255)
1031     // _reg = REG[rn]
1032     // _tmp = _reg + offset
1033     // MEM[index ? _tmp : _reg] = REG[rt]
1034     // if (wback) REG[rn] = _tmp
1035     ALWAYS_INLINE void ldr(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
1036     {
1037         ASSERT(rt != ARMRegisters::pc);
1038         ASSERT(rn != ARMRegisters::pc);
1039         ASSERT(index || wback);
1040         ASSERT(!wback | (rt != rn));
1041     
1042         bool add = true;
1043         if (offset < 0) {
1044             add = false;
1045             offset = -offset;
1046         }
1047         ASSERT((offset & ~0xff) == 0);
1048         
1049         offset |= (wback << 8);
1050         offset |= (add   << 9);
1051         offset |= (index << 10);
1052         offset |= (1 << 11);
1053         
1054         m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T4, rn, rt, offset);
1055     }
1056
1057     // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block.
1058     ALWAYS_INLINE void ldr(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
1059     {
1060         ASSERT(rn != ARMRegisters::pc); // LDR (literal)
1061         ASSERT(!BadReg(rm));
1062         ASSERT(shift <= 3);
1063
1064         if (!shift && !((rt | rn | rm) & 8))
1065             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDR_reg_T1, rm, rn, rt);
1066         else
1067             m_formatter.twoWordOp12Reg4FourFours(OP_LDR_reg_T2, rn, FourFours(rt, 0, shift, rm));
1068     }
1069
1070     // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block.
1071     ALWAYS_INLINE void ldrh(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
1072     {
1073         ASSERT(rn != ARMRegisters::pc); // LDR (literal)
1074         ASSERT(imm.isUInt12());
1075
1076         if (!((rt | rn) & 8) && imm.isUInt6())
1077             m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDRH_imm_T1, imm.getUInt6() >> 2, rn, rt);
1078         else
1079             m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRH_imm_T2, rn, rt, imm.getUInt12());
1080     }
1081
1082     // If index is set, this is a regular offset or a pre-indexed load;
1083     // if index is not set then is is a post-index load.
1084     //
1085     // If wback is set rn is updated - this is a pre or post index load,
1086     // if wback is not set this is a regular offset memory access.
1087     //
1088     // (-255 <= offset <= 255)
1089     // _reg = REG[rn]
1090     // _tmp = _reg + offset
1091     // MEM[index ? _tmp : _reg] = REG[rt]
1092     // if (wback) REG[rn] = _tmp
1093     ALWAYS_INLINE void ldrh(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
1094     {
1095         ASSERT(rt != ARMRegisters::pc);
1096         ASSERT(rn != ARMRegisters::pc);
1097         ASSERT(index || wback);
1098         ASSERT(!wback | (rt != rn));
1099     
1100         bool add = true;
1101         if (offset < 0) {
1102             add = false;
1103             offset = -offset;
1104         }
1105         ASSERT((offset & ~0xff) == 0);
1106         
1107         offset |= (wback << 8);
1108         offset |= (add   << 9);
1109         offset |= (index << 10);
1110         offset |= (1 << 11);
1111         
1112         m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRH_imm_T3, rn, rt, offset);
1113     }
1114
1115     ALWAYS_INLINE void ldrh(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
1116     {
1117         ASSERT(!BadReg(rt));   // Memory hint
1118         ASSERT(rn != ARMRegisters::pc); // LDRH (literal)
1119         ASSERT(!BadReg(rm));
1120         ASSERT(shift <= 3);
1121
1122         if (!shift && !((rt | rn | rm) & 8))
1123             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRH_reg_T1, rm, rn, rt);
1124         else
1125             m_formatter.twoWordOp12Reg4FourFours(OP_LDRH_reg_T2, rn, FourFours(rt, 0, shift, rm));
1126     }
1127
1128     void ldrb(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
1129     {
1130         ASSERT(rn != ARMRegisters::pc); // LDR (literal)
1131         ASSERT(imm.isUInt12());
1132
1133         if (!((rt | rn) & 8) && imm.isUInt5())
1134             m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDRB_imm_T1, imm.getUInt5(), rn, rt);
1135         else
1136             m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRB_imm_T2, rn, rt, imm.getUInt12());
1137     }
1138
1139     void ldrb(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
1140     {
1141         ASSERT(rt != ARMRegisters::pc);
1142         ASSERT(rn != ARMRegisters::pc);
1143         ASSERT(index || wback);
1144         ASSERT(!wback | (rt != rn));
1145
1146         bool add = true;
1147         if (offset < 0) {
1148             add = false;
1149             offset = -offset;
1150         }
1151
1152         ASSERT(!(offset & ~0xff));
1153
1154         offset |= (wback << 8);
1155         offset |= (add   << 9);
1156         offset |= (index << 10);
1157         offset |= (1 << 11);
1158
1159         m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRB_imm_T3, rn, rt, offset);
1160     }
1161
1162     ALWAYS_INLINE void ldrb(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
1163     {
1164         ASSERT(rn != ARMRegisters::pc); // LDR (literal)
1165         ASSERT(!BadReg(rm));
1166         ASSERT(shift <= 3);
1167
1168         if (!shift && !((rt | rn | rm) & 8))
1169             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRB_reg_T1, rm, rn, rt);
1170         else
1171             m_formatter.twoWordOp12Reg4FourFours(OP_LDRB_reg_T2, rn, FourFours(rt, 0, shift, rm));
1172     }
1173     
1174     void ldrsb(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
1175     {
1176         ASSERT(rn != ARMRegisters::pc);
1177         ASSERT(!BadReg(rm));
1178         ASSERT(shift <= 3);
1179         
1180         if (!shift && !((rt | rn | rm) & 8))
1181             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRSB_reg_T1, rm, rn, rt);
1182         else
1183             m_formatter.twoWordOp12Reg4FourFours(OP_LDRSB_reg_T2, rn, FourFours(rt, 0, shift, rm));
1184     }
1185
1186     void ldrsh(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
1187     {
1188         ASSERT(rn != ARMRegisters::pc);
1189         ASSERT(!BadReg(rm));
1190         ASSERT(shift <= 3);
1191         
1192         if (!shift && !((rt | rn | rm) & 8))
1193             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRSH_reg_T1, rm, rn, rt);
1194         else
1195             m_formatter.twoWordOp12Reg4FourFours(OP_LDRSH_reg_T2, rn, FourFours(rt, 0, shift, rm));
1196     }
1197
1198     void lsl(RegisterID rd, RegisterID rm, int32_t shiftAmount)
1199     {
1200         ASSERT(!BadReg(rd));
1201         ASSERT(!BadReg(rm));
1202         ShiftTypeAndAmount shift(SRType_LSL, shiftAmount);
1203         m_formatter.twoWordOp16FourFours(OP_LSL_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm));
1204     }
1205
1206     ALWAYS_INLINE void lsl(RegisterID rd, RegisterID rn, RegisterID rm)
1207     {
1208         ASSERT(!BadReg(rd));
1209         ASSERT(!BadReg(rn));
1210         ASSERT(!BadReg(rm));
1211         m_formatter.twoWordOp12Reg4FourFours(OP_LSL_reg_T2, rn, FourFours(0xf, rd, 0, rm));
1212     }
1213
1214     ALWAYS_INLINE void lsr(RegisterID rd, RegisterID rm, int32_t shiftAmount)
1215     {
1216         ASSERT(!BadReg(rd));
1217         ASSERT(!BadReg(rm));
1218         ShiftTypeAndAmount shift(SRType_LSR, shiftAmount);
1219         m_formatter.twoWordOp16FourFours(OP_LSR_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm));
1220     }
1221
1222     ALWAYS_INLINE void lsr(RegisterID rd, RegisterID rn, RegisterID rm)
1223     {
1224         ASSERT(!BadReg(rd));
1225         ASSERT(!BadReg(rn));
1226         ASSERT(!BadReg(rm));
1227         m_formatter.twoWordOp12Reg4FourFours(OP_LSR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
1228     }
1229
1230     ALWAYS_INLINE void movT3(RegisterID rd, ARMThumbImmediate imm)
1231     {
1232         ASSERT(imm.isValid());
1233         ASSERT(!imm.isEncodedImm());
1234         ASSERT(!BadReg(rd));
1235         
1236         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOV_imm_T3, imm.m_value.imm4, rd, imm);
1237     }
1238
1239     ALWAYS_INLINE void mov(RegisterID rd, ARMThumbImmediate imm)
1240     {
1241         ASSERT(imm.isValid());
1242         ASSERT(!BadReg(rd));
1243         
1244         if ((rd < 8) && imm.isUInt8())
1245             m_formatter.oneWordOp5Reg3Imm8(OP_MOV_imm_T1, rd, imm.getUInt8());
1246         else if (imm.isEncodedImm())
1247             m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOV_imm_T2, 0xf, rd, imm);
1248         else
1249             movT3(rd, imm);
1250     }
1251
1252     ALWAYS_INLINE void mov(RegisterID rd, RegisterID rm)
1253     {
1254         m_formatter.oneWordOp8RegReg143(OP_MOV_reg_T1, rm, rd);
1255     }
1256
1257     ALWAYS_INLINE void movt(RegisterID rd, ARMThumbImmediate imm)
1258     {
1259         ASSERT(imm.isUInt16());
1260         ASSERT(!BadReg(rd));
1261         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOVT, imm.m_value.imm4, rd, imm);
1262     }
1263
1264     ALWAYS_INLINE void mvn(RegisterID rd, ARMThumbImmediate imm)
1265     {
1266         ASSERT(imm.isEncodedImm());
1267         ASSERT(!BadReg(rd));
1268         
1269         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MVN_imm, 0xf, rd, imm);
1270     }
1271
1272     ALWAYS_INLINE void mvn(RegisterID rd, RegisterID rm, ShiftTypeAndAmount shift)
1273     {
1274         ASSERT(!BadReg(rd));
1275         ASSERT(!BadReg(rm));
1276         m_formatter.twoWordOp16FourFours(OP_MVN_reg_T2, FourFours(shift.hi4(), rd, shift.lo4(), rm));
1277     }
1278
1279     ALWAYS_INLINE void mvn(RegisterID rd, RegisterID rm)
1280     {
1281         if (!((rd | rm) & 8))
1282             m_formatter.oneWordOp10Reg3Reg3(OP_MVN_reg_T1, rm, rd);
1283         else
1284             mvn(rd, rm, ShiftTypeAndAmount());
1285     }
1286
1287     ALWAYS_INLINE void neg(RegisterID rd, RegisterID rm)
1288     {
1289         ARMThumbImmediate zero = ARMThumbImmediate::makeUInt12(0);
1290         sub(rd, zero, rm);
1291     }
1292
1293     ALWAYS_INLINE void orr(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
1294     {
1295         ASSERT(!BadReg(rd));
1296         ASSERT(!BadReg(rn));
1297         ASSERT(imm.isEncodedImm());
1298         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ORR_imm_T1, rn, rd, imm);
1299     }
1300
1301     ALWAYS_INLINE void orr(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
1302     {
1303         ASSERT(!BadReg(rd));
1304         ASSERT(!BadReg(rn));
1305         ASSERT(!BadReg(rm));
1306         m_formatter.twoWordOp12Reg4FourFours(OP_ORR_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
1307     }
1308
1309     void orr(RegisterID rd, RegisterID rn, RegisterID rm)
1310     {
1311         if ((rd == rn) && !((rd | rm) & 8))
1312             m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rm, rd);
1313         else if ((rd == rm) && !((rd | rn) & 8))
1314             m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rn, rd);
1315         else
1316             orr(rd, rn, rm, ShiftTypeAndAmount());
1317     }
1318
1319     ALWAYS_INLINE void orr_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
1320     {
1321         ASSERT(!BadReg(rd));
1322         ASSERT(!BadReg(rn));
1323         ASSERT(!BadReg(rm));
1324         m_formatter.twoWordOp12Reg4FourFours(OP_ORR_S_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
1325     }
1326
1327     void orr_S(RegisterID rd, RegisterID rn, RegisterID rm)
1328     {
1329         if ((rd == rn) && !((rd | rm) & 8))
1330             m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rm, rd);
1331         else if ((rd == rm) && !((rd | rn) & 8))
1332             m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rn, rd);
1333         else
1334             orr_S(rd, rn, rm, ShiftTypeAndAmount());
1335     }
1336
1337     ALWAYS_INLINE void ror(RegisterID rd, RegisterID rm, int32_t shiftAmount)
1338     {
1339         ASSERT(!BadReg(rd));
1340         ASSERT(!BadReg(rm));
1341         ShiftTypeAndAmount shift(SRType_ROR, shiftAmount);
1342         m_formatter.twoWordOp16FourFours(OP_ROR_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm));
1343     }
1344
1345     ALWAYS_INLINE void ror(RegisterID rd, RegisterID rn, RegisterID rm)
1346     {
1347         ASSERT(!BadReg(rd));
1348         ASSERT(!BadReg(rn));
1349         ASSERT(!BadReg(rm));
1350         m_formatter.twoWordOp12Reg4FourFours(OP_ROR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
1351     }
1352
1353     ALWAYS_INLINE void smull(RegisterID rdLo, RegisterID rdHi, RegisterID rn, RegisterID rm)
1354     {
1355         ASSERT(!BadReg(rdLo));
1356         ASSERT(!BadReg(rdHi));
1357         ASSERT(!BadReg(rn));
1358         ASSERT(!BadReg(rm));
1359         ASSERT(rdLo != rdHi);
1360         m_formatter.twoWordOp12Reg4FourFours(OP_SMULL_T1, rn, FourFours(rdLo, rdHi, 0, rm));
1361     }
1362
1363     // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block.
1364     ALWAYS_INLINE void str(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
1365     {
1366         ASSERT(rt != ARMRegisters::pc);
1367         ASSERT(rn != ARMRegisters::pc);
1368         ASSERT(imm.isUInt12());
1369
1370         if (!((rt | rn) & 8) && imm.isUInt7())
1371             m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STR_imm_T1, imm.getUInt7() >> 2, rn, rt);
1372         else if ((rn == ARMRegisters::sp) && !(rt & 8) && imm.isUInt10())
1373             m_formatter.oneWordOp5Reg3Imm8(OP_STR_imm_T2, rt, static_cast<uint8_t>(imm.getUInt10() >> 2));
1374         else
1375             m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STR_imm_T3, rn, rt, imm.getUInt12());
1376     }
1377
1378     // If index is set, this is a regular offset or a pre-indexed store;
1379     // if index is not set then is is a post-index store.
1380     //
1381     // If wback is set rn is updated - this is a pre or post index store,
1382     // if wback is not set this is a regular offset memory access.
1383     //
1384     // (-255 <= offset <= 255)
1385     // _reg = REG[rn]
1386     // _tmp = _reg + offset
1387     // MEM[index ? _tmp : _reg] = REG[rt]
1388     // if (wback) REG[rn] = _tmp
1389     ALWAYS_INLINE void str(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
1390     {
1391         ASSERT(rt != ARMRegisters::pc);
1392         ASSERT(rn != ARMRegisters::pc);
1393         ASSERT(index || wback);
1394         ASSERT(!wback | (rt != rn));
1395     
1396         bool add = true;
1397         if (offset < 0) {
1398             add = false;
1399             offset = -offset;
1400         }
1401         ASSERT((offset & ~0xff) == 0);
1402         
1403         offset |= (wback << 8);
1404         offset |= (add   << 9);
1405         offset |= (index << 10);
1406         offset |= (1 << 11);
1407         
1408         m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STR_imm_T4, rn, rt, offset);
1409     }
1410
1411     // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block.
1412     ALWAYS_INLINE void str(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
1413     {
1414         ASSERT(rn != ARMRegisters::pc);
1415         ASSERT(!BadReg(rm));
1416         ASSERT(shift <= 3);
1417
1418         if (!shift && !((rt | rn | rm) & 8))
1419             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_STR_reg_T1, rm, rn, rt);
1420         else
1421             m_formatter.twoWordOp12Reg4FourFours(OP_STR_reg_T2, rn, FourFours(rt, 0, shift, rm));
1422     }
1423
1424     // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block.
1425     ALWAYS_INLINE void strb(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
1426     {
1427         ASSERT(rt != ARMRegisters::pc);
1428         ASSERT(rn != ARMRegisters::pc);
1429         ASSERT(imm.isUInt12());
1430
1431         if (!((rt | rn) & 8) && imm.isUInt7())
1432             m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STRB_imm_T1, imm.getUInt7() >> 2, rn, rt);
1433         else
1434             m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRB_imm_T2, rn, rt, imm.getUInt12());
1435     }
1436
1437     // If index is set, this is a regular offset or a pre-indexed store;
1438     // if index is not set then is is a post-index store.
1439     //
1440     // If wback is set rn is updated - this is a pre or post index store,
1441     // if wback is not set this is a regular offset memory access.
1442     //
1443     // (-255 <= offset <= 255)
1444     // _reg = REG[rn]
1445     // _tmp = _reg + offset
1446     // MEM[index ? _tmp : _reg] = REG[rt]
1447     // if (wback) REG[rn] = _tmp
1448     ALWAYS_INLINE void strb(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
1449     {
1450         ASSERT(rt != ARMRegisters::pc);
1451         ASSERT(rn != ARMRegisters::pc);
1452         ASSERT(index || wback);
1453         ASSERT(!wback | (rt != rn));
1454     
1455         bool add = true;
1456         if (offset < 0) {
1457             add = false;
1458             offset = -offset;
1459         }
1460         ASSERT((offset & ~0xff) == 0);
1461         
1462         offset |= (wback << 8);
1463         offset |= (add   << 9);
1464         offset |= (index << 10);
1465         offset |= (1 << 11);
1466         
1467         m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRB_imm_T3, rn, rt, offset);
1468     }
1469
1470     // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block.
1471     ALWAYS_INLINE void strb(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
1472     {
1473         ASSERT(rn != ARMRegisters::pc);
1474         ASSERT(!BadReg(rm));
1475         ASSERT(shift <= 3);
1476
1477         if (!shift && !((rt | rn | rm) & 8))
1478             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_STRB_reg_T1, rm, rn, rt);
1479         else
1480             m_formatter.twoWordOp12Reg4FourFours(OP_STRB_reg_T2, rn, FourFours(rt, 0, shift, rm));
1481     }
1482     
1483     // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block.
1484     ALWAYS_INLINE void strh(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
1485     {
1486         ASSERT(rt != ARMRegisters::pc);
1487         ASSERT(rn != ARMRegisters::pc);
1488         ASSERT(imm.isUInt12());
1489         
1490         if (!((rt | rn) & 8) && imm.isUInt7())
1491             m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STRH_imm_T1, imm.getUInt7() >> 2, rn, rt);
1492         else
1493             m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRH_imm_T2, rn, rt, imm.getUInt12());
1494     }
1495     
1496     // If index is set, this is a regular offset or a pre-indexed store;
1497     // if index is not set then is is a post-index store.
1498     //
1499     // If wback is set rn is updated - this is a pre or post index store,
1500     // if wback is not set this is a regular offset memory access.
1501     //
1502     // (-255 <= offset <= 255)
1503     // _reg = REG[rn]
1504     // _tmp = _reg + offset
1505     // MEM[index ? _tmp : _reg] = REG[rt]
1506     // if (wback) REG[rn] = _tmp
1507     ALWAYS_INLINE void strh(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
1508     {
1509         ASSERT(rt != ARMRegisters::pc);
1510         ASSERT(rn != ARMRegisters::pc);
1511         ASSERT(index || wback);
1512         ASSERT(!wback | (rt != rn));
1513         
1514         bool add = true;
1515         if (offset < 0) {
1516             add = false;
1517             offset = -offset;
1518         }
1519         ASSERT(!(offset & ~0xff));
1520         
1521         offset |= (wback << 8);
1522         offset |= (add   << 9);
1523         offset |= (index << 10);
1524         offset |= (1 << 11);
1525         
1526         m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRH_imm_T3, rn, rt, offset);
1527     }
1528     
1529     // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block.
1530     ALWAYS_INLINE void strh(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
1531     {
1532         ASSERT(rn != ARMRegisters::pc);
1533         ASSERT(!BadReg(rm));
1534         ASSERT(shift <= 3);
1535         
1536         if (!shift && !((rt | rn | rm) & 8))
1537             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_STRH_reg_T1, rm, rn, rt);
1538         else
1539             m_formatter.twoWordOp12Reg4FourFours(OP_STRH_reg_T2, rn, FourFours(rt, 0, shift, rm));
1540     }
1541
1542     ALWAYS_INLINE void sub(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
1543     {
1544         // Rd can only be SP if Rn is also SP.
1545         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
1546         ASSERT(rd != ARMRegisters::pc);
1547         ASSERT(rn != ARMRegisters::pc);
1548         ASSERT(imm.isValid());
1549
1550         if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) {
1551             ASSERT(!(imm.getUInt16() & 3));
1552             m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, static_cast<uint8_t>(imm.getUInt9() >> 2));
1553             return;
1554         } else if (!((rd | rn) & 8)) {
1555             if (imm.isUInt3()) {
1556                 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
1557                 return;
1558             } else if ((rd == rn) && imm.isUInt8()) {
1559                 m_formatter.oneWordOp5Reg3Imm8(OP_SUB_imm_T2, rd, imm.getUInt8());
1560                 return;
1561             }
1562         }
1563
1564         if (imm.isEncodedImm())
1565             m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_imm_T3, rn, rd, imm);
1566         else {
1567             ASSERT(imm.isUInt12());
1568             m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_imm_T4, rn, rd, imm);
1569         }
1570     }
1571
1572     ALWAYS_INLINE void sub(RegisterID rd, ARMThumbImmediate imm, RegisterID rn)
1573     {
1574         ASSERT(rd != ARMRegisters::pc);
1575         ASSERT(rn != ARMRegisters::pc);
1576         ASSERT(imm.isValid());
1577         ASSERT(imm.isUInt12());
1578
1579         if (!((rd | rn) & 8) && !imm.getUInt12())
1580             m_formatter.oneWordOp10Reg3Reg3(OP_RSB_imm_T1, rn, rd);
1581         else
1582             m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_RSB_imm_T2, rn, rd, imm);
1583     }
1584
1585     ALWAYS_INLINE void sub(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
1586     {
1587         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
1588         ASSERT(rd != ARMRegisters::pc);
1589         ASSERT(rn != ARMRegisters::pc);
1590         ASSERT(!BadReg(rm));
1591         m_formatter.twoWordOp12Reg4FourFours(OP_SUB_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
1592     }
1593
1594     // NOTE: In an IT block, add doesn't modify the flags register.
1595     ALWAYS_INLINE void sub(RegisterID rd, RegisterID rn, RegisterID rm)
1596     {
1597         if (!((rd | rn | rm) & 8))
1598             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_reg_T1, rm, rn, rd);
1599         else
1600             sub(rd, rn, rm, ShiftTypeAndAmount());
1601     }
1602
1603     // Not allowed in an IT (if then) block.
1604     void sub_S(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
1605     {
1606         // Rd can only be SP if Rn is also SP.
1607         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
1608         ASSERT(rd != ARMRegisters::pc);
1609         ASSERT(rn != ARMRegisters::pc);
1610         ASSERT(imm.isValid());
1611
1612         if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) {
1613             ASSERT(!(imm.getUInt16() & 3));
1614             m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, static_cast<uint8_t>(imm.getUInt9() >> 2));
1615             return;
1616         } else if (!((rd | rn) & 8)) {
1617             if (imm.isUInt3()) {
1618                 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
1619                 return;
1620             } else if ((rd == rn) && imm.isUInt8()) {
1621                 m_formatter.oneWordOp5Reg3Imm8(OP_SUB_imm_T2, rd, imm.getUInt8());
1622                 return;
1623             }
1624         }
1625
1626         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_S_imm_T3, rn, rd, imm);
1627     }
1628
1629     ALWAYS_INLINE void sub_S(RegisterID rd, ARMThumbImmediate imm, RegisterID rn)
1630     {
1631         ASSERT(rd != ARMRegisters::pc);
1632         ASSERT(rn != ARMRegisters::pc);
1633         ASSERT(imm.isValid());
1634         ASSERT(imm.isUInt12());
1635
1636         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_RSB_S_imm_T2, rn, rd, imm);
1637     }
1638
1639     // Not allowed in an IT (if then) block?
1640     ALWAYS_INLINE void sub_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
1641     {
1642         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
1643         ASSERT(rd != ARMRegisters::pc);
1644         ASSERT(rn != ARMRegisters::pc);
1645         ASSERT(!BadReg(rm));
1646         m_formatter.twoWordOp12Reg4FourFours(OP_SUB_S_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
1647     }
1648
1649     // Not allowed in an IT (if then) block.
1650     ALWAYS_INLINE void sub_S(RegisterID rd, RegisterID rn, RegisterID rm)
1651     {
1652         if (!((rd | rn | rm) & 8))
1653             m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_reg_T1, rm, rn, rd);
1654         else
1655             sub_S(rd, rn, rm, ShiftTypeAndAmount());
1656     }
1657
1658     ALWAYS_INLINE void tst(RegisterID rn, ARMThumbImmediate imm)
1659     {
1660         ASSERT(!BadReg(rn));
1661         ASSERT(imm.isEncodedImm());
1662
1663         m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_TST_imm, rn, (RegisterID)0xf, imm);
1664     }
1665
1666     ALWAYS_INLINE void tst(RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
1667     {
1668         ASSERT(!BadReg(rn));
1669         ASSERT(!BadReg(rm));
1670         m_formatter.twoWordOp12Reg4FourFours(OP_TST_reg_T2, rn, FourFours(shift.hi4(), 0xf, shift.lo4(), rm));
1671     }
1672
1673     ALWAYS_INLINE void tst(RegisterID rn, RegisterID rm)
1674     {
1675         if ((rn | rm) & 8)
1676             tst(rn, rm, ShiftTypeAndAmount());
1677         else
1678             m_formatter.oneWordOp10Reg3Reg3(OP_TST_reg_T1, rm, rn);
1679     }
1680
1681     ALWAYS_INLINE void ubfx(RegisterID rd, RegisterID rn, unsigned lsb, unsigned width)
1682     {
1683         ASSERT(lsb < 32);
1684         ASSERT((width >= 1) && (width <= 32));
1685         ASSERT((lsb + width) <= 32);
1686         m_formatter.twoWordOp12Reg40Imm3Reg4Imm20Imm5(OP_UBFX_T1, rd, rn, (lsb & 0x1c) << 10, (lsb & 0x3) << 6, (width - 1) & 0x1f);
1687     }
1688
1689     void vadd(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
1690     {
1691         m_formatter.vfpOp(OP_VADD_T2, OP_VADD_T2b, true, rn, rd, rm);
1692     }
1693
1694     void vcmp(FPDoubleRegisterID rd, FPDoubleRegisterID rm)
1695     {
1696         m_formatter.vfpOp(OP_VCMP, OP_VCMPb, true, VFPOperand(4), rd, rm);
1697     }
1698
1699     void vcmpz(FPDoubleRegisterID rd)
1700     {
1701         m_formatter.vfpOp(OP_VCMP, OP_VCMPb, true, VFPOperand(5), rd, VFPOperand(0));
1702     }
1703
1704     void vcvt_signedToFloatingPoint(FPDoubleRegisterID rd, FPSingleRegisterID rm)
1705     {
1706         // boolean values are 64bit (toInt, unsigned, roundZero)
1707         m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(false, false, false), rd, rm);
1708     }
1709
1710     void vcvt_floatingPointToSigned(FPSingleRegisterID rd, FPDoubleRegisterID rm)
1711     {
1712         // boolean values are 64bit (toInt, unsigned, roundZero)
1713         m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(true, false, true), rd, rm);
1714     }
1715     
1716     void vcvt_floatingPointToUnsigned(FPSingleRegisterID rd, FPDoubleRegisterID rm)
1717     {
1718         // boolean values are 64bit (toInt, unsigned, roundZero)
1719         m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(true, true, true), rd, rm);
1720     }
1721
1722     void vdiv(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
1723     {
1724         m_formatter.vfpOp(OP_VDIV, OP_VDIVb, true, rn, rd, rm);
1725     }
1726
1727     void vldr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm)
1728     {
1729         m_formatter.vfpMemOp(OP_VLDR, OP_VLDRb, true, rn, rd, imm);
1730     }
1731     
1732     void flds(FPSingleRegisterID rd, RegisterID rn, int32_t imm)
1733     {
1734         m_formatter.vfpMemOp(OP_FLDS, OP_FLDSb, false, rn, rd, imm);
1735     }
1736
1737     void vmov(RegisterID rd, FPSingleRegisterID rn)
1738     {
1739         ASSERT(!BadReg(rd));
1740         m_formatter.vfpOp(OP_VMOV_StoC, OP_VMOV_StoCb, false, rn, rd, VFPOperand(0));
1741     }
1742
1743     void vmov(FPSingleRegisterID rd, RegisterID rn)
1744     {
1745         ASSERT(!BadReg(rn));
1746         m_formatter.vfpOp(OP_VMOV_CtoS, OP_VMOV_CtoSb, false, rd, rn, VFPOperand(0));
1747     }
1748
1749     void vmov(RegisterID rd1, RegisterID rd2, FPDoubleRegisterID rn)
1750     {
1751         ASSERT(!BadReg(rd1));
1752         ASSERT(!BadReg(rd2));
1753         m_formatter.vfpOp(OP_VMOV_DtoC, OP_VMOV_DtoCb, true, rd2, VFPOperand(rd1 | 16), rn);
1754     }
1755
1756     void vmov(FPDoubleRegisterID rd, RegisterID rn1, RegisterID rn2)
1757     {
1758         ASSERT(!BadReg(rn1));
1759         ASSERT(!BadReg(rn2));
1760         m_formatter.vfpOp(OP_VMOV_CtoD, OP_VMOV_CtoDb, true, rn2, VFPOperand(rn1 | 16), rd);
1761     }
1762
1763     void vmov(FPDoubleRegisterID rd, FPDoubleRegisterID rn)
1764     {
1765         m_formatter.vfpOp(OP_VMOV_T2, OP_VMOV_T2b, true, VFPOperand(0), rd, rn);
1766     }
1767
1768     void vmrs(RegisterID reg = ARMRegisters::pc)
1769     {
1770         ASSERT(reg != ARMRegisters::sp);
1771         m_formatter.vfpOp(OP_VMRS, OP_VMRSb, false, VFPOperand(1), VFPOperand(0x10 | reg), VFPOperand(0));
1772     }
1773
1774     void vmul(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
1775     {
1776         m_formatter.vfpOp(OP_VMUL_T2, OP_VMUL_T2b, true, rn, rd, rm);
1777     }
1778
1779     void vstr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm)
1780     {
1781         m_formatter.vfpMemOp(OP_VSTR, OP_VSTRb, true, rn, rd, imm);
1782     }
1783
1784     void fsts(FPSingleRegisterID rd, RegisterID rn, int32_t imm)
1785     {
1786         m_formatter.vfpMemOp(OP_FSTS, OP_FSTSb, false, rn, rd, imm);
1787     }
1788
1789     void vsub(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
1790     {
1791         m_formatter.vfpOp(OP_VSUB_T2, OP_VSUB_T2b, true, rn, rd, rm);
1792     }
1793
1794     void vabs(FPDoubleRegisterID rd, FPDoubleRegisterID rm)
1795     {
1796         m_formatter.vfpOp(OP_VABS_T2, OP_VABS_T2b, true, VFPOperand(16), rd, rm);
1797     }
1798
1799     void vneg(FPDoubleRegisterID rd, FPDoubleRegisterID rm)
1800     {
1801         m_formatter.vfpOp(OP_VNEG_T2, OP_VNEG_T2b, true, VFPOperand(1), rd, rm);
1802     }
1803
1804     void vsqrt(FPDoubleRegisterID rd, FPDoubleRegisterID rm)
1805     {
1806         m_formatter.vfpOp(OP_VSQRT_T1, OP_VSQRT_T1b, true, VFPOperand(17), rd, rm);
1807     }
1808     
1809     void vcvtds(FPDoubleRegisterID rd, FPSingleRegisterID rm)
1810     {
1811         m_formatter.vfpOp(OP_VCVTDS_T1, OP_VCVTDS_T1b, false, VFPOperand(23), rd, rm);
1812     }
1813
1814     void vcvtsd(FPSingleRegisterID rd, FPDoubleRegisterID rm)
1815     {
1816         m_formatter.vfpOp(OP_VCVTSD_T1, OP_VCVTSD_T1b, true, VFPOperand(23), rd, rm);
1817     }
1818
1819     void nop()
1820     {
1821         m_formatter.oneWordOp8Imm8(OP_NOP_T1, 0);
1822     }
1823
1824     AssemblerLabel label()
1825     {
1826         return m_formatter.label();
1827     }
1828     
1829     AssemblerLabel align(int alignment)
1830     {
1831         while (!m_formatter.isAligned(alignment))
1832             bkpt();
1833
1834         return label();
1835     }
1836     
1837     static void* getRelocatedAddress(void* code, AssemblerLabel label)
1838     {
1839         ASSERT(label.isSet());
1840         return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + label.m_offset);
1841     }
1842     
1843     static int getDifferenceBetweenLabels(AssemblerLabel a, AssemblerLabel b)
1844     {
1845         return b.m_offset - a.m_offset;
1846     }
1847
1848     int executableOffsetFor(int location)
1849     {
1850         if (!location)
1851             return 0;
1852         return static_cast<int32_t*>(m_formatter.data())[location / sizeof(int32_t) - 1];
1853     }
1854     
1855     int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return JUMP_ENUM_SIZE(jumpType) - JUMP_ENUM_SIZE(jumpLinkType); }
1856     
1857     // Assembler admin methods:
1858
1859     static ALWAYS_INLINE bool linkRecordSourceComparator(const LinkRecord& a, const LinkRecord& b)
1860     {
1861         return a.from() < b.from();
1862     }
1863
1864     bool canCompact(JumpType jumpType)
1865     {
1866         // The following cannot be compacted:
1867         //   JumpFixed: represents custom jump sequence
1868         //   JumpNoConditionFixedSize: represents unconditional jump that must remain a fixed size
1869         //   JumpConditionFixedSize: represents conditional jump that must remain a fixed size
1870         return (jumpType == JumpNoCondition) || (jumpType == JumpCondition);
1871     }
1872     
1873     JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to)
1874     {
1875         if (jumpType == JumpFixed)
1876             return LinkInvalid;
1877         
1878         // for patchable jump we must leave space for the longest code sequence
1879         if (jumpType == JumpNoConditionFixedSize)
1880             return LinkBX;
1881         if (jumpType == JumpConditionFixedSize)
1882             return LinkConditionalBX;
1883         
1884         const int paddingSize = JUMP_ENUM_SIZE(jumpType);
1885         bool mayTriggerErrata = false;
1886         
1887         if (jumpType == JumpCondition) {
1888             // 2-byte conditional T1
1889             const uint16_t* jumpT1Location = reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT1)));
1890             if (canBeJumpT1(jumpT1Location, to))
1891                 return LinkJumpT1;
1892             // 4-byte conditional T3
1893             const uint16_t* jumpT3Location = reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT3)));
1894             if (canBeJumpT3(jumpT3Location, to, mayTriggerErrata)) {
1895                 if (!mayTriggerErrata)
1896                     return LinkJumpT3;
1897             }
1898             // 4-byte conditional T4 with IT
1899             const uint16_t* conditionalJumpT4Location = 
1900             reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkConditionalJumpT4)));
1901             if (canBeJumpT4(conditionalJumpT4Location, to, mayTriggerErrata)) {
1902                 if (!mayTriggerErrata)
1903                     return LinkConditionalJumpT4;
1904             }
1905         } else {
1906             // 2-byte unconditional T2
1907             const uint16_t* jumpT2Location = reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT2)));
1908             if (canBeJumpT2(jumpT2Location, to))
1909                 return LinkJumpT2;
1910             // 4-byte unconditional T4
1911             const uint16_t* jumpT4Location = reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT4)));
1912             if (canBeJumpT4(jumpT4Location, to, mayTriggerErrata)) {
1913                 if (!mayTriggerErrata)
1914                     return LinkJumpT4;
1915             }
1916             // use long jump sequence
1917             return LinkBX;
1918         }
1919         
1920         ASSERT(jumpType == JumpCondition);
1921         return LinkConditionalBX;
1922     }
1923     
1924     JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to)
1925     {
1926         JumpLinkType linkType = computeJumpType(record.type(), from, to);
1927         record.setLinkType(linkType);
1928         return linkType;
1929     }
1930     
1931     void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset)
1932     {
1933         int32_t ptr = regionStart / sizeof(int32_t);
1934         const int32_t end = regionEnd / sizeof(int32_t);
1935         int32_t* offsets = static_cast<int32_t*>(m_formatter.data());
1936         while (ptr < end)
1937             offsets[ptr++] = offset;
1938     }
1939     
1940     Vector<LinkRecord>& jumpsToLink()
1941     {
1942         std::sort(m_jumpsToLink.begin(), m_jumpsToLink.end(), linkRecordSourceComparator);
1943         return m_jumpsToLink;
1944     }
1945
1946     void ALWAYS_INLINE link(LinkRecord& record, uint8_t* from, uint8_t* to)
1947     {
1948         switch (record.linkType()) {
1949         case LinkJumpT1:
1950             linkJumpT1(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), to);
1951             break;
1952         case LinkJumpT2:
1953             linkJumpT2(reinterpret_cast_ptr<uint16_t*>(from), to);
1954             break;
1955         case LinkJumpT3:
1956             linkJumpT3(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), to);
1957             break;
1958         case LinkJumpT4:
1959             linkJumpT4(reinterpret_cast_ptr<uint16_t*>(from), to);
1960             break;
1961         case LinkConditionalJumpT4:
1962             linkConditionalJumpT4(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), to);
1963             break;
1964         case LinkConditionalBX:
1965             linkConditionalBX(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), to);
1966             break;
1967         case LinkBX:
1968             linkBX(reinterpret_cast_ptr<uint16_t*>(from), to);
1969             break;
1970         default:
1971             ASSERT_NOT_REACHED();
1972             break;
1973         }
1974     }
1975
1976     void* unlinkedCode() { return m_formatter.data(); }
1977     size_t codeSize() const { return m_formatter.codeSize(); }
1978
1979     static unsigned getCallReturnOffset(AssemblerLabel call)
1980     {
1981         ASSERT(call.isSet());
1982         return call.m_offset;
1983     }
1984
1985     // Linking & patching:
1986     //
1987     // 'link' and 'patch' methods are for use on unprotected code - such as the code
1988     // within the AssemblerBuffer, and code being patched by the patch buffer.  Once
1989     // code has been finalized it is (platform support permitting) within a non-
1990     // writable region of memory; to modify the code in an execute-only execuable
1991     // pool the 'repatch' and 'relink' methods should be used.
1992
1993     void linkJump(AssemblerLabel from, AssemblerLabel to, JumpType type, Condition condition)
1994     {
1995         ASSERT(to.isSet());
1996         ASSERT(from.isSet());
1997         m_jumpsToLink.append(LinkRecord(from.m_offset, to.m_offset, type, condition));
1998     }
1999
2000     static void linkJump(void* code, AssemblerLabel from, void* to)
2001     {
2002         ASSERT(from.isSet());
2003         
2004         uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
2005         linkJumpAbsolute(location, to);
2006     }
2007
2008     static void linkCall(void* code, AssemblerLabel from, void* to)
2009     {
2010         ASSERT(!(reinterpret_cast<intptr_t>(code) & 1));
2011         ASSERT(from.isSet());
2012         ASSERT(reinterpret_cast<intptr_t>(to) & 1);
2013
2014         setPointer(reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset) - 1, to);
2015     }
2016
2017     static void linkPointer(void* code, AssemblerLabel where, void* value)
2018     {
2019         setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
2020     }
2021
2022     static void relinkJump(void* from, void* to)
2023     {
2024         ASSERT(!(reinterpret_cast<intptr_t>(from) & 1));
2025         ASSERT(!(reinterpret_cast<intptr_t>(to) & 1));
2026
2027         linkJumpAbsolute(reinterpret_cast<uint16_t*>(from), to);
2028
2029         ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 5, 5 * sizeof(uint16_t));
2030     }
2031     
2032     static void relinkCall(void* from, void* to)
2033     {
2034         ASSERT(!(reinterpret_cast<intptr_t>(from) & 1));
2035         ASSERT(reinterpret_cast<intptr_t>(to) & 1);
2036
2037         setPointer(reinterpret_cast<uint16_t*>(from) - 1, to);
2038     }
2039     
2040     static void* readCallTarget(void* from)
2041     {
2042         return readPointer(reinterpret_cast<uint16_t*>(from) - 1);
2043     }
2044
2045     static void repatchInt32(void* where, int32_t value)
2046     {
2047         ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
2048         
2049         setInt32(where, value);
2050     }
2051     
2052     static void repatchCompact(void* where, int32_t value)
2053     {
2054         ASSERT(value >= 0);
2055         ASSERT(ARMThumbImmediate::makeUInt12(value).isUInt7());
2056         setUInt7ForLoad(where, ARMThumbImmediate::makeUInt12(value));
2057     }
2058
2059     static void repatchPointer(void* where, void* value)
2060     {
2061         ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
2062         
2063         setPointer(where, value);
2064     }
2065
2066     static void* readPointer(void* where)
2067     {
2068         return reinterpret_cast<void*>(readInt32(where));
2069     }
2070
2071     unsigned debugOffset() { return m_formatter.debugOffset(); }
2072
2073 private:
2074     // VFP operations commonly take one or more 5-bit operands, typically representing a
2075     // floating point register number.  This will commonly be encoded in the instruction
2076     // in two parts, with one single bit field, and one 4-bit field.  In the case of
2077     // double precision operands the high bit of the register number will be encoded
2078     // separately, and for single precision operands the high bit of the register number
2079     // will be encoded individually.
2080     // VFPOperand encapsulates a 5-bit VFP operand, with bits 0..3 containing the 4-bit
2081     // field to be encoded together in the instruction (the low 4-bits of a double
2082     // register number, or the high 4-bits of a single register number), and bit 4
2083     // contains the bit value to be encoded individually.
2084     struct VFPOperand {
2085         explicit VFPOperand(uint32_t value)
2086             : m_value(value)
2087         {
2088             ASSERT(!(m_value & ~0x1f));
2089         }
2090
2091         VFPOperand(FPDoubleRegisterID reg)
2092             : m_value(reg)
2093         {
2094         }
2095
2096         VFPOperand(RegisterID reg)
2097             : m_value(reg)
2098         {
2099         }
2100
2101         VFPOperand(FPSingleRegisterID reg)
2102             : m_value(((reg & 1) << 4) | (reg >> 1)) // rotate the lowest bit of 'reg' to the top.
2103         {
2104         }
2105
2106         uint32_t bits1()
2107         {
2108             return m_value >> 4;
2109         }
2110
2111         uint32_t bits4()
2112         {
2113             return m_value & 0xf;
2114         }
2115
2116         uint32_t m_value;
2117     };
2118
2119     VFPOperand vcvtOp(bool toInteger, bool isUnsigned, bool isRoundZero)
2120     {
2121         // Cannot specify rounding when converting to float.
2122         ASSERT(toInteger || !isRoundZero);
2123
2124         uint32_t op = 0x8;
2125         if (toInteger) {
2126             // opc2 indicates both toInteger & isUnsigned.
2127             op |= isUnsigned ? 0x4 : 0x5;
2128             // 'op' field in instruction is isRoundZero
2129             if (isRoundZero)
2130                 op |= 0x10;
2131         } else {
2132             ASSERT(!isRoundZero);
2133             // 'op' field in instruction is isUnsigned
2134             if (!isUnsigned)
2135                 op |= 0x10;
2136         }
2137         return VFPOperand(op);
2138     }
2139
2140     static void setInt32(void* code, uint32_t value)
2141     {
2142         uint16_t* location = reinterpret_cast<uint16_t*>(code);
2143         ASSERT(isMOV_imm_T3(location - 4) && isMOVT(location - 2));
2144
2145         ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value));
2146         ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value >> 16));
2147         location[-4] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16);
2148         location[-3] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-3] >> 8) & 0xf, lo16);
2149         location[-2] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16);
2150         location[-1] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-1] >> 8) & 0xf, hi16);
2151
2152         ExecutableAllocator::cacheFlush(location - 4, 4 * sizeof(uint16_t));
2153     }
2154     
2155     static int32_t readInt32(void* code)
2156     {
2157         uint16_t* location = reinterpret_cast<uint16_t*>(code);
2158         ASSERT(isMOV_imm_T3(location - 4) && isMOVT(location - 2));
2159         
2160         ARMThumbImmediate lo16;
2161         ARMThumbImmediate hi16;
2162         decodeTwoWordOp5i6Imm4Reg4EncodedImmFirst(lo16, location[-4]);
2163         decodeTwoWordOp5i6Imm4Reg4EncodedImmSecond(lo16, location[-3]);
2164         decodeTwoWordOp5i6Imm4Reg4EncodedImmFirst(hi16, location[-2]);
2165         decodeTwoWordOp5i6Imm4Reg4EncodedImmSecond(hi16, location[-1]);
2166         uint32_t result = hi16.asUInt16();
2167         result <<= 16;
2168         result |= lo16.asUInt16();
2169         return static_cast<int32_t>(result);
2170     }
2171
2172     static void setUInt7ForLoad(void* code, ARMThumbImmediate imm)
2173     {
2174         // Requires us to have planted a LDR_imm_T1
2175         ASSERT(imm.isValid());
2176         ASSERT(imm.isUInt7());
2177         uint16_t* location = reinterpret_cast<uint16_t*>(code);
2178         location[0] &= ~((static_cast<uint16_t>(0x7f) >> 2) << 6);
2179         location[0] |= (imm.getUInt7() >> 2) << 6;
2180         ExecutableAllocator::cacheFlush(location, sizeof(uint16_t));
2181     }
2182
2183     static void setPointer(void* code, void* value)
2184     {
2185         setInt32(code, reinterpret_cast<uint32_t>(value));
2186     }
2187
2188     static bool isB(void* address)
2189     {
2190         uint16_t* instruction = static_cast<uint16_t*>(address);
2191         return ((instruction[0] & 0xf800) == OP_B_T4a) && ((instruction[1] & 0xd000) == OP_B_T4b);
2192     }
2193
2194     static bool isBX(void* address)
2195     {
2196         uint16_t* instruction = static_cast<uint16_t*>(address);
2197         return (instruction[0] & 0xff87) == OP_BX;
2198     }
2199
2200     static bool isMOV_imm_T3(void* address)
2201     {
2202         uint16_t* instruction = static_cast<uint16_t*>(address);
2203         return ((instruction[0] & 0xFBF0) == OP_MOV_imm_T3) && ((instruction[1] & 0x8000) == 0);
2204     }
2205
2206     static bool isMOVT(void* address)
2207     {
2208         uint16_t* instruction = static_cast<uint16_t*>(address);
2209         return ((instruction[0] & 0xFBF0) == OP_MOVT) && ((instruction[1] & 0x8000) == 0);
2210     }
2211
2212     static bool isNOP_T1(void* address)
2213     {
2214         uint16_t* instruction = static_cast<uint16_t*>(address);
2215         return instruction[0] == OP_NOP_T1;
2216     }
2217
2218     static bool isNOP_T2(void* address)
2219     {
2220         uint16_t* instruction = static_cast<uint16_t*>(address);
2221         return (instruction[0] == OP_NOP_T2a) && (instruction[1] == OP_NOP_T2b);
2222     }
2223
2224     static bool canBeJumpT1(const uint16_t* instruction, const void* target)
2225     {
2226         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2227         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2228         
2229         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
2230         // It does not appear to be documented in the ARM ARM (big surprise), but
2231         // for OP_B_T1 the branch displacement encoded in the instruction is 2 
2232         // less than the actual displacement.
2233         relative -= 2;
2234         return ((relative << 23) >> 23) == relative;
2235     }
2236     
2237     static bool canBeJumpT2(const uint16_t* instruction, const void* target)
2238     {
2239         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2240         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2241         
2242         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
2243         // It does not appear to be documented in the ARM ARM (big surprise), but
2244         // for OP_B_T2 the branch displacement encoded in the instruction is 2 
2245         // less than the actual displacement.
2246         relative -= 2;
2247         return ((relative << 20) >> 20) == relative;
2248     }
2249     
2250     static bool canBeJumpT3(const uint16_t* instruction, const void* target, bool& mayTriggerErrata)
2251     {
2252         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2253         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2254         
2255         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
2256         // From Cortex-A8 errata:
2257         // If the 32-bit Thumb-2 branch instruction spans two 4KiB regions and
2258         // the target of the branch falls within the first region it is
2259         // possible for the processor to incorrectly determine the branch
2260         // instruction, and it is also possible in some cases for the processor
2261         // to enter a deadlock state.
2262         // The instruction is spanning two pages if it ends at an address ending 0x002
2263         bool spansTwo4K = ((reinterpret_cast<intptr_t>(instruction) & 0xfff) == 0x002);
2264         mayTriggerErrata = spansTwo4K;
2265         // The target is in the first page if the jump branch back by [3..0x1002] bytes
2266         bool targetInFirstPage = (relative >= -0x1002) && (relative < -2);
2267         bool wouldTriggerA8Errata = spansTwo4K && targetInFirstPage;
2268         return ((relative << 11) >> 11) == relative && !wouldTriggerA8Errata;
2269     }
2270     
2271     static bool canBeJumpT4(const uint16_t* instruction, const void* target, bool& mayTriggerErrata)
2272     {
2273         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2274         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2275         
2276         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
2277         // From Cortex-A8 errata:
2278         // If the 32-bit Thumb-2 branch instruction spans two 4KiB regions and
2279         // the target of the branch falls within the first region it is
2280         // possible for the processor to incorrectly determine the branch
2281         // instruction, and it is also possible in some cases for the processor
2282         // to enter a deadlock state.
2283         // The instruction is spanning two pages if it ends at an address ending 0x002
2284         bool spansTwo4K = ((reinterpret_cast<intptr_t>(instruction) & 0xfff) == 0x002);
2285         mayTriggerErrata = spansTwo4K;
2286         // The target is in the first page if the jump branch back by [3..0x1002] bytes
2287         bool targetInFirstPage = (relative >= -0x1002) && (relative < -2);
2288         bool wouldTriggerA8Errata = spansTwo4K && targetInFirstPage;
2289         return ((relative << 7) >> 7) == relative && !wouldTriggerA8Errata;
2290     }
2291     
2292     void linkJumpT1(Condition cond, uint16_t* instruction, void* target)
2293     {
2294         // FIMXE: this should be up in the MacroAssembler layer. :-(        
2295         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2296         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2297         ASSERT(canBeJumpT1(instruction, target));
2298         
2299         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
2300         // It does not appear to be documented in the ARM ARM (big surprise), but
2301         // for OP_B_T1 the branch displacement encoded in the instruction is 2 
2302         // less than the actual displacement.
2303         relative -= 2;
2304         
2305         // All branch offsets should be an even distance.
2306         ASSERT(!(relative & 1));
2307         instruction[-1] = OP_B_T1 | ((cond & 0xf) << 8) | ((relative & 0x1fe) >> 1);
2308     }
2309     
2310     static void linkJumpT2(uint16_t* instruction, void* target)
2311     {
2312         // FIMXE: this should be up in the MacroAssembler layer. :-(        
2313         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2314         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2315         ASSERT(canBeJumpT2(instruction, target));
2316         
2317         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
2318         // It does not appear to be documented in the ARM ARM (big surprise), but
2319         // for OP_B_T2 the branch displacement encoded in the instruction is 2 
2320         // less than the actual displacement.
2321         relative -= 2;
2322         
2323         // All branch offsets should be an even distance.
2324         ASSERT(!(relative & 1));
2325         instruction[-1] = OP_B_T2 | ((relative & 0xffe) >> 1);
2326     }
2327     
2328     void linkJumpT3(Condition cond, uint16_t* instruction, void* target)
2329     {
2330         // FIMXE: this should be up in the MacroAssembler layer. :-(
2331         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2332         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2333         bool scratch;
2334         UNUSED_PARAM(scratch);
2335         ASSERT(canBeJumpT3(instruction, target, scratch));
2336         
2337         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
2338         
2339         // All branch offsets should be an even distance.
2340         ASSERT(!(relative & 1));
2341         instruction[-2] = OP_B_T3a | ((relative & 0x100000) >> 10) | ((cond & 0xf) << 6) | ((relative & 0x3f000) >> 12);
2342         instruction[-1] = OP_B_T3b | ((relative & 0x80000) >> 8) | ((relative & 0x40000) >> 5) | ((relative & 0xffe) >> 1);
2343     }
2344     
2345     static void linkJumpT4(uint16_t* instruction, void* target)
2346     {
2347         // FIMXE: this should be up in the MacroAssembler layer. :-(        
2348         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2349         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2350         bool scratch;
2351         UNUSED_PARAM(scratch);
2352         ASSERT(canBeJumpT4(instruction, target, scratch));
2353         
2354         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
2355         // ARM encoding for the top two bits below the sign bit is 'peculiar'.
2356         if (relative >= 0)
2357             relative ^= 0xC00000;
2358         
2359         // All branch offsets should be an even distance.
2360         ASSERT(!(relative & 1));
2361         instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12);
2362         instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1);
2363     }
2364     
2365     void linkConditionalJumpT4(Condition cond, uint16_t* instruction, void* target)
2366     {
2367         // FIMXE: this should be up in the MacroAssembler layer. :-(        
2368         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2369         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2370         
2371         instruction[-3] = ifThenElse(cond) | OP_IT;
2372         linkJumpT4(instruction, target);
2373     }
2374     
2375     static void linkBX(uint16_t* instruction, void* target)
2376     {
2377         // FIMXE: this should be up in the MacroAssembler layer. :-(
2378         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2379         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2380         
2381         const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip;
2382         ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1));
2383         ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16));
2384         instruction[-5] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16);
2385         instruction[-4] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, lo16);
2386         instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16);
2387         instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16);
2388         instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3);
2389     }
2390     
2391     void linkConditionalBX(Condition cond, uint16_t* instruction, void* target)
2392     {
2393         // FIMXE: this should be up in the MacroAssembler layer. :-(        
2394         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2395         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2396         
2397         linkBX(instruction, target);
2398         instruction[-6] = ifThenElse(cond, true, true) | OP_IT;
2399     }
2400     
2401     static void linkJumpAbsolute(uint16_t* instruction, void* target)
2402     {
2403         // FIMXE: this should be up in the MacroAssembler layer. :-(
2404         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
2405         ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
2406         
2407         ASSERT((isMOV_imm_T3(instruction - 5) && isMOVT(instruction - 3) && isBX(instruction - 1))
2408                || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2)));
2409         
2410         bool scratch;
2411         if (canBeJumpT4(instruction, target, scratch)) {
2412             // There may be a better way to fix this, but right now put the NOPs first, since in the
2413             // case of an conditional branch this will be coming after an ITTT predicating *three*
2414             // instructions!  Looking backwards to modify the ITTT to an IT is not easy, due to
2415             // variable wdith encoding - the previous instruction might *look* like an ITTT but
2416             // actually be the second half of a 2-word op.
2417             instruction[-5] = OP_NOP_T1;
2418             instruction[-4] = OP_NOP_T2a;
2419             instruction[-3] = OP_NOP_T2b;
2420             linkJumpT4(instruction, target);
2421         } else {
2422             const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip;
2423             ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1));
2424             ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16));
2425             instruction[-5] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16);
2426             instruction[-4] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, lo16);
2427             instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16);
2428             instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16);
2429             instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3);
2430         }
2431     }
2432     
2433     static uint16_t twoWordOp5i6Imm4Reg4EncodedImmFirst(uint16_t op, ARMThumbImmediate imm)
2434     {
2435         return op | (imm.m_value.i << 10) | imm.m_value.imm4;
2436     }
2437
2438     static void decodeTwoWordOp5i6Imm4Reg4EncodedImmFirst(ARMThumbImmediate& result, uint16_t value)
2439     {
2440         result.m_value.i = (value >> 10) & 1;
2441         result.m_value.imm4 = value & 15;
2442     }
2443
2444     static uint16_t twoWordOp5i6Imm4Reg4EncodedImmSecond(uint16_t rd, ARMThumbImmediate imm)
2445     {
2446         return (imm.m_value.imm3 << 12) | (rd << 8) | imm.m_value.imm8;
2447     }
2448
2449     static void decodeTwoWordOp5i6Imm4Reg4EncodedImmSecond(ARMThumbImmediate& result, uint16_t value)
2450     {
2451         result.m_value.imm3 = (value >> 12) & 7;
2452         result.m_value.imm8 = value & 255;
2453     }
2454
2455     class ARMInstructionFormatter {
2456     public:
2457         ALWAYS_INLINE void oneWordOp5Reg3Imm8(OpcodeID op, RegisterID rd, uint8_t imm)
2458         {
2459             m_buffer.putShort(op | (rd << 8) | imm);
2460         }
2461         
2462         ALWAYS_INLINE void oneWordOp5Imm5Reg3Reg3(OpcodeID op, uint8_t imm, RegisterID reg1, RegisterID reg2)
2463         {
2464             m_buffer.putShort(op | (imm << 6) | (reg1 << 3) | reg2);
2465         }
2466
2467         ALWAYS_INLINE void oneWordOp7Reg3Reg3Reg3(OpcodeID op, RegisterID reg1, RegisterID reg2, RegisterID reg3)
2468         {
2469             m_buffer.putShort(op | (reg1 << 6) | (reg2 << 3) | reg3);
2470         }
2471
2472         ALWAYS_INLINE void oneWordOp8Imm8(OpcodeID op, uint8_t imm)
2473         {
2474             m_buffer.putShort(op | imm);
2475         }
2476
2477         ALWAYS_INLINE void oneWordOp8RegReg143(OpcodeID op, RegisterID reg1, RegisterID reg2)
2478         {
2479             m_buffer.putShort(op | ((reg2 & 8) << 4) | (reg1 << 3) | (reg2 & 7));
2480         }
2481
2482         ALWAYS_INLINE void oneWordOp9Imm7(OpcodeID op, uint8_t imm)
2483         {
2484             m_buffer.putShort(op | imm);
2485         }
2486
2487         ALWAYS_INLINE void oneWordOp10Reg3Reg3(OpcodeID op, RegisterID reg1, RegisterID reg2)
2488         {
2489             m_buffer.putShort(op | (reg1 << 3) | reg2);
2490         }
2491
2492         ALWAYS_INLINE void twoWordOp12Reg4FourFours(OpcodeID1 op, RegisterID reg, FourFours ff)
2493         {
2494             m_buffer.putShort(op | reg);
2495             m_buffer.putShort(ff.m_u.value);
2496         }
2497         
2498         ALWAYS_INLINE void twoWordOp16FourFours(OpcodeID1 op, FourFours ff)
2499         {
2500             m_buffer.putShort(op);
2501             m_buffer.putShort(ff.m_u.value);
2502         }
2503         
2504         ALWAYS_INLINE void twoWordOp16Op16(OpcodeID1 op1, OpcodeID2 op2)
2505         {
2506             m_buffer.putShort(op1);
2507             m_buffer.putShort(op2);
2508         }
2509
2510         ALWAYS_INLINE void twoWordOp5i6Imm4Reg4EncodedImm(OpcodeID1 op, int imm4, RegisterID rd, ARMThumbImmediate imm)
2511         {
2512             ARMThumbImmediate newImm = imm;
2513             newImm.m_value.imm4 = imm4;
2514
2515             m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmFirst(op, newImm));
2516             m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmSecond(rd, newImm));
2517         }
2518
2519         ALWAYS_INLINE void twoWordOp12Reg4Reg4Imm12(OpcodeID1 op, RegisterID reg1, RegisterID reg2, uint16_t imm)
2520         {
2521             m_buffer.putShort(op | reg1);
2522             m_buffer.putShort((reg2 << 12) | imm);
2523         }
2524
2525         ALWAYS_INLINE void twoWordOp12Reg40Imm3Reg4Imm20Imm5(OpcodeID1 op, RegisterID reg1, RegisterID reg2, uint16_t imm1, uint16_t imm2, uint16_t imm3)
2526         {
2527             m_buffer.putShort(op | reg1);
2528             m_buffer.putShort((imm1 << 12) | (reg2 << 8) | (imm2 << 6) | imm3);
2529         }
2530
2531         // Formats up instructions of the pattern:
2532         //    111111111B11aaaa:bbbb222SA2C2cccc
2533         // Where 1s in the pattern come from op1, 2s in the pattern come from op2, S is the provided size bit.
2534         // Operands provide 5 bit values of the form Aaaaa, Bbbbb, Ccccc.
2535         ALWAYS_INLINE void vfpOp(OpcodeID1 op1, OpcodeID2 op2, bool size, VFPOperand a, VFPOperand b, VFPOperand c)
2536         {
2537             ASSERT(!(op1 & 0x004f));
2538             ASSERT(!(op2 & 0xf1af));
2539             m_buffer.putShort(op1 | b.bits1() << 6 | a.bits4());
2540             m_buffer.putShort(op2 | b.bits4() << 12 | size << 8 | a.bits1() << 7 | c.bits1() << 5 | c.bits4());
2541         }
2542
2543         // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
2544         // (i.e. +/-(0..255) 32-bit words)
2545         ALWAYS_INLINE void vfpMemOp(OpcodeID1 op1, OpcodeID2 op2, bool size, RegisterID rn, VFPOperand rd, int32_t imm)
2546         {
2547             bool up = true;
2548             if (imm < 0) {
2549                 imm = -imm;
2550                 up = false;
2551             }
2552             
2553             uint32_t offset = imm;
2554             ASSERT(!(offset & ~0x3fc));
2555             offset >>= 2;
2556
2557             m_buffer.putShort(op1 | (up << 7) | rd.bits1() << 6 | rn);
2558             m_buffer.putShort(op2 | rd.bits4() << 12 | size << 8 | offset);
2559         }
2560
2561         // Administrative methods:
2562
2563         size_t codeSize() const { return m_buffer.codeSize(); }
2564         AssemblerLabel label() const { return m_buffer.label(); }
2565         bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
2566         void* data() const { return m_buffer.data(); }
2567
2568         unsigned debugOffset() { return m_buffer.debugOffset(); }
2569
2570     private:
2571         AssemblerBuffer m_buffer;
2572     } m_formatter;
2573
2574     Vector<LinkRecord> m_jumpsToLink;
2575     Vector<int32_t> m_offsets;
2576 };
2577
2578 } // namespace JSC
2579
2580 #endif // ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
2581
2582 #endif // ARMAssembler_h