406d7230c9cd5af42db8c9618e336c79281dcfcc
[WebKit-https.git] / JavaScriptCore / masm / X86Assembler.h
1 /*
2  * Copyright (C) 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef X86Assembler_h
27 #define X86Assembler_h
28
29 #if ENABLE(MASM) && PLATFORM(X86)
30
31 #include <wtf/Assertions.h>
32 #include <wtf/AlwaysInline.h>
33 #if HAVE(MMAN)
34 #include <sys/mman.h>
35 #endif
36
37 #include <string.h>
38
39 namespace JSC {
40
41 class JITCodeBuffer {
42 public:
43     JITCodeBuffer(int size)
44         : m_buffer(static_cast<char*>(fastMalloc(size)))
45         , m_size(size)
46         , m_index(0)
47     {
48     }
49
50     ~JITCodeBuffer()
51     {
52         fastFree(m_buffer);
53     }
54
55     void ensureSpace(int space)
56     {
57         if (m_index > m_size - space)
58             growBuffer();
59     }
60
61     void putByteUnchecked(int value)
62     {
63         m_buffer[m_index] = value;
64         m_index++;
65     }
66
67     void putByte(int value)
68     {
69         if (m_index > m_size - 4)
70             growBuffer();
71         putByteUnchecked(value);
72     }
73     
74     void putShortUnchecked(int value)
75     {
76         *(short*)(&m_buffer[m_index]) = value;
77         m_index += 2;
78     }
79
80     void putShort(int value)
81     {
82         if (m_index > m_size - 4)
83             growBuffer();
84         putShortUnchecked(value);
85     }
86     
87     void putIntUnchecked(int value)
88     {
89         *reinterpret_cast<int*>(&m_buffer[m_index]) = value;
90         m_index += 4;
91     }
92
93     void putInt(int value)
94     {
95         if (m_index > m_size - 4)
96             growBuffer();
97         putIntUnchecked(value);
98     }
99
100     void* getEIP()
101     {
102         return m_buffer + m_index;
103     }
104     
105     void* start()
106     {
107         return m_buffer;
108     }
109     
110     int getOffset()
111     {
112         return m_index;
113     }
114     
115     JITCodeBuffer* reset()
116     {
117         m_index = 0;
118         return this;
119     }
120     
121     void* copy()
122     {
123         if (!m_index)
124             return 0;
125
126         void* result = fastMalloc(m_index);
127
128         if (!result)
129             return 0;
130
131         return memcpy(result, m_buffer, m_index);
132     }
133
134 private:
135     void growBuffer()
136     {
137         m_size += m_size / 2;
138         m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_size));
139     }
140
141     char* m_buffer;
142     int m_size;
143     int m_index;
144 };
145
146 #define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm))
147 #define SIB(type, reg, rm) MODRM(type, reg, rm)
148 #define CAN_SIGN_EXTEND_8_32(value) (value == ((int)(signed char)value))
149
150 namespace X86 {
151     typedef enum {
152         eax,
153         ecx,
154         edx,
155         ebx,
156         esp,
157         ebp,
158         esi,
159         edi,
160
161         noBase = ebp,
162         hasSib = esp,
163         noScale = esp,
164     } RegisterID;
165
166     typedef enum {
167         xmm0,
168         xmm1,
169         xmm2,
170         xmm3,
171         xmm4,
172         xmm5,
173         xmm6,
174         xmm7,
175     } XMMRegisterID;
176 }
177
178 class X86Assembler {
179 public:
180     typedef X86::RegisterID RegisterID;
181     typedef X86::XMMRegisterID XMMRegisterID;
182     typedef enum {
183         OP_ADD_EvGv                     = 0x01,
184         OP_ADD_GvEv                     = 0x03,
185         OP_OR_EvGv                      = 0x09,
186         OP_OR_GvEv                      = 0x0B,
187         OP_2BYTE_ESCAPE                 = 0x0F,
188         OP_AND_EvGv                     = 0x21,
189         OP_SUB_EvGv                     = 0x29,
190         OP_SUB_GvEv                     = 0x2B,
191         PRE_PREDICT_BRANCH_NOT_TAKEN    = 0x2E,
192         OP_XOR_EvGv                     = 0x31,
193         OP_CMP_EvGv                     = 0x39,
194         OP_CMP_GvEv                     = 0x3B,
195         OP_PUSH_EAX                     = 0x50,
196         OP_POP_EAX                      = 0x58,
197         PRE_OPERAND_SIZE                = 0x66,
198         PRE_SSE_66                      = 0x66,
199         OP_PUSH_Iz                      = 0x68,
200         OP_IMUL_GvEvIz                  = 0x69,
201         OP_GROUP1_EvIz                  = 0x81,
202         OP_GROUP1_EvIb                  = 0x83,
203         OP_TEST_EvGv                    = 0x85,
204         OP_MOV_EvGv                     = 0x89,
205         OP_MOV_GvEv                     = 0x8B,
206         OP_LEA                          = 0x8D,
207         OP_GROUP1A_Ev                   = 0x8F,
208         OP_CDQ                          = 0x99,
209         OP_SETE                         = 0x94,
210         OP_SETNE                        = 0x95,
211         OP_GROUP2_EvIb                  = 0xC1,
212         OP_RET                          = 0xC3,
213         OP_GROUP11_EvIz                 = 0xC7,
214         OP_INT3                         = 0xCC,
215         OP_GROUP2_Ev1                   = 0xD1,
216         OP_GROUP2_EvCL                  = 0xD3,
217         OP_CALL_rel32                   = 0xE8,
218         OP_JMP_rel32                    = 0xE9,
219         PRE_SSE_F2                      = 0xF2,
220         OP_GROUP3_Ev                    = 0xF7,
221         OP_GROUP3_EvIz                  = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test. 
222         OP_GROUP5_Ev                    = 0xFF,
223
224         OP2_MOVSD_VsdWsd    = 0x10,
225         OP2_MOVSD_WsdVsd    = 0x11,
226         OP2_CVTSI2SD_VsdEd  = 0x2A,
227         OP2_CVTTSD2SI_GdWsd = 0x2C,
228         OP2_UCOMISD_VsdWsd  = 0x2E,
229         OP2_ADDSD_VsdWsd    = 0x58,
230         OP2_MULSD_VsdWsd    = 0x59,
231         OP2_SUBSD_VsdWsd    = 0x5C,
232         OP2_MOVD_EdVd       = 0x7E,
233         OP2_JO_rel32        = 0x80,
234         OP2_JB_rel32        = 0x82,
235         OP2_JAE_rel32       = 0x83,
236         OP2_JE_rel32        = 0x84,
237         OP2_JNE_rel32       = 0x85,
238         OP2_JBE_rel32       = 0x86,
239         OP2_JA_rel32        = 0x87,
240         OP2_JS_rel32        = 0x88,
241         OP2_JP_rel32        = 0x8A,
242         OP2_JL_rel32        = 0x8C,
243         OP2_JGE_rel32       = 0x8D,
244         OP2_JLE_rel32       = 0x8E,
245         OP2_JG_rel32       = 0x8F,
246         OP2_IMUL_GvEv       = 0xAF,
247         OP2_MOVZX_GvEb      = 0xB6,
248         OP2_MOVZX_GvEw      = 0xB7,
249         OP2_PEXTRW_GdUdIb   = 0xC5,
250
251         GROUP1_OP_ADD = 0,
252         GROUP1_OP_OR  = 1,
253         GROUP1_OP_AND = 4,
254         GROUP1_OP_SUB = 5,
255         GROUP1_OP_XOR = 6,
256         GROUP1_OP_CMP = 7,
257
258         GROUP1A_OP_POP = 0,
259
260         GROUP2_OP_SHL = 4,
261         GROUP2_OP_SAR = 7,
262
263         GROUP3_OP_TEST = 0,
264         GROUP3_OP_IDIV = 7,
265
266         GROUP5_OP_CALLN = 2,
267         GROUP5_OP_JMPN  = 4,
268         GROUP5_OP_PUSH  = 6,
269
270         GROUP11_MOV = 0,
271     } OpcodeID;
272     
273     static const int MAX_INSTRUCTION_SIZE = 16;
274
275     X86Assembler(JITCodeBuffer* m_buffer)
276         : m_buffer(m_buffer)
277     {
278         m_buffer->reset();
279     }
280
281     void emitInt3()
282     {
283         m_buffer->putByte(OP_INT3);
284     }
285     
286     void pushl_r(RegisterID reg)
287     {
288         m_buffer->putByte(OP_PUSH_EAX + reg);
289     }
290     
291     void pushl_m(int offset, RegisterID base)
292     {
293         m_buffer->putByte(OP_GROUP5_Ev);
294         emitModRm_opm(GROUP5_OP_PUSH, base, offset);
295     }
296
297     void pushl_i32(int imm)
298     {
299         m_buffer->putByte(OP_PUSH_Iz);
300         m_buffer->putInt(imm);
301     }
302     
303     void popl_r(RegisterID reg)
304     {
305         m_buffer->putByte(OP_POP_EAX + reg);
306     }
307
308     void popl_m(int offset, RegisterID base)
309     {
310         m_buffer->putByte(OP_GROUP1A_Ev);
311         emitModRm_opm(GROUP1A_OP_POP, base, offset);
312     }
313     
314     void movl_rr(RegisterID src, RegisterID dst)
315     {
316         m_buffer->putByte(OP_MOV_EvGv);
317         emitModRm_rr(src, dst);
318     }
319     
320     void addl_rr(RegisterID src, RegisterID dst)
321     {
322         m_buffer->putByte(OP_ADD_EvGv);
323         emitModRm_rr(src, dst);
324     }
325
326     void addl_i8r(int imm, RegisterID dst)
327     {
328         m_buffer->putByte(OP_GROUP1_EvIb);
329         emitModRm_opr(GROUP1_OP_ADD, dst);
330         m_buffer->putByte(imm);
331     }
332
333     void addl_i8m(int imm, void* addr)
334     {
335         m_buffer->putByte(OP_GROUP1_EvIb);
336         emitModRm_opm(GROUP1_OP_ADD, addr);
337         m_buffer->putByte(imm);
338     }
339
340     void addl_i32r(int imm, RegisterID dst)
341     {
342         m_buffer->putByte(OP_GROUP1_EvIz);
343         emitModRm_opr(GROUP1_OP_ADD, dst);
344         m_buffer->putInt(imm);
345     }
346
347     void addl_mr(int offset, RegisterID base, RegisterID dst)
348     {
349         m_buffer->putByte(OP_ADD_GvEv);
350         emitModRm_rm(dst, base, offset);
351     }
352
353     void andl_rr(RegisterID src, RegisterID dst)
354     {
355         m_buffer->putByte(OP_AND_EvGv);
356         emitModRm_rr(src, dst);
357     }
358
359     void andl_i32r(int imm, RegisterID dst)
360     {
361         m_buffer->putByte(OP_GROUP1_EvIz);
362         emitModRm_opr(GROUP1_OP_AND, dst);
363         m_buffer->putInt(imm);
364     }
365
366     void cmpl_i8r(int imm, RegisterID dst)
367     {
368         m_buffer->putByte(OP_GROUP1_EvIb);
369         emitModRm_opr(GROUP1_OP_CMP, dst);
370         m_buffer->putByte(imm);
371     }
372
373     void cmpl_rr(RegisterID src, RegisterID dst)
374     {
375         m_buffer->putByte(OP_CMP_EvGv);
376         emitModRm_rr(src, dst);
377     }
378
379     void cmpl_rm(RegisterID src, int offset, RegisterID base)
380     {
381         m_buffer->putByte(OP_CMP_EvGv);
382         emitModRm_rm(src, base, offset);
383     }
384
385     void cmpl_mr(int offset, RegisterID base, RegisterID dst)
386     {
387         m_buffer->putByte(OP_CMP_GvEv);
388         emitModRm_rm(dst, base, offset);
389     }
390
391     void cmpl_i32r(int imm, RegisterID dst)
392     {
393         m_buffer->putByte(OP_GROUP1_EvIz);
394         emitModRm_opr(GROUP1_OP_CMP, dst);
395         m_buffer->putInt(imm);
396     }
397
398     void cmpl_i32m(int imm, RegisterID dst)
399     {
400         m_buffer->putByte(OP_GROUP1_EvIz);
401         emitModRm_opm(GROUP1_OP_CMP, dst);
402         m_buffer->putInt(imm);
403     }
404
405     void cmpl_i32m(int imm, int offset, RegisterID dst)
406     {
407         m_buffer->putByte(OP_GROUP1_EvIz);
408         emitModRm_opm(GROUP1_OP_CMP, dst, offset);
409         m_buffer->putInt(imm);
410     }
411
412     void cmpl_i32m(int imm, void* addr)
413     {
414         m_buffer->putByte(OP_GROUP1_EvIz);
415         emitModRm_opm(GROUP1_OP_CMP, addr);
416         m_buffer->putInt(imm);
417     }
418
419     void cmpl_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
420     {
421         m_buffer->putByte(OP_GROUP1_EvIb);
422         emitModRm_opmsib(GROUP1_OP_CMP, base, index, scale, offset);
423         m_buffer->putByte(imm);
424     }
425
426     void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
427     {
428         m_buffer->putByte(PRE_OPERAND_SIZE);
429         m_buffer->putByte(OP_CMP_EvGv);
430         emitModRm_rmsib(src, base, index, scale);
431     }
432
433     void sete_r(RegisterID dst)
434     {
435         m_buffer->putByte(OP_2BYTE_ESCAPE);
436         m_buffer->putByte(OP_SETE);
437         m_buffer->putByte(MODRM(3, 0, dst));
438     }
439
440     void setz_r(RegisterID dst)
441     {
442         sete_r(dst);
443     }
444
445     void setne_r(RegisterID dst)
446     {
447         m_buffer->putByte(OP_2BYTE_ESCAPE);
448         m_buffer->putByte(OP_SETNE);
449         m_buffer->putByte(MODRM(3, 0, dst));
450     }
451
452     void setnz_r(RegisterID dst)
453     {
454         setne_r(dst);
455     }
456
457     void orl_rr(RegisterID src, RegisterID dst)
458     {
459         m_buffer->putByte(OP_OR_EvGv);
460         emitModRm_rr(src, dst);
461     }
462
463     void orl_mr(int offset, RegisterID base, RegisterID dst)
464     {
465         m_buffer->putByte(OP_OR_GvEv);
466         emitModRm_rm(dst, base, offset);
467     }
468
469     void orl_i32r(int imm, RegisterID dst)
470     {
471         m_buffer->putByte(OP_GROUP1_EvIb);
472         emitModRm_opr(GROUP1_OP_OR, dst);
473         m_buffer->putByte(imm);
474     }
475
476     void subl_rr(RegisterID src, RegisterID dst)
477     {
478         m_buffer->putByte(OP_SUB_EvGv);
479         emitModRm_rr(src, dst);
480     }
481
482     void subl_i8r(int imm, RegisterID dst)
483     {
484         m_buffer->putByte(OP_GROUP1_EvIb);
485         emitModRm_opr(GROUP1_OP_SUB, dst);
486         m_buffer->putByte(imm);
487     }
488     
489     void subl_i8m(int imm, void* addr)
490     {
491         m_buffer->putByte(OP_GROUP1_EvIb);
492         emitModRm_opm(GROUP1_OP_SUB, addr);
493         m_buffer->putByte(imm);
494     }
495
496     void subl_i32r(int imm, RegisterID dst)
497     {
498         m_buffer->putByte(OP_GROUP1_EvIz);
499         emitModRm_opr(GROUP1_OP_SUB, dst);
500         m_buffer->putInt(imm);
501     }
502
503     void subl_mr(int offset, RegisterID base, RegisterID dst)
504     {
505         m_buffer->putByte(OP_SUB_GvEv);
506         emitModRm_rm(dst, base, offset);
507     }
508
509     void testl_i32r(int imm, RegisterID dst)
510     {
511         m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
512         m_buffer->putByteUnchecked(OP_GROUP3_EvIz);
513         emitModRm_opr_Unchecked(GROUP3_OP_TEST, dst);
514         m_buffer->putIntUnchecked(imm);
515     }
516
517     void testl_i32m(int imm, RegisterID dst)
518     {
519         m_buffer->putByte(OP_GROUP3_EvIz);
520         emitModRm_opm(GROUP3_OP_TEST, dst);
521         m_buffer->putInt(imm);
522     }
523
524     void testl_i32m(int imm, int offset, RegisterID dst)
525     {
526         m_buffer->putByte(OP_GROUP3_EvIz);
527         emitModRm_opm(GROUP3_OP_TEST, dst, offset);
528         m_buffer->putInt(imm);
529     }
530
531     void testl_rr(RegisterID src, RegisterID dst)
532     {
533         m_buffer->putByte(OP_TEST_EvGv);
534         emitModRm_rr(src, dst);
535     }
536     
537     void xorl_i8r(int imm, RegisterID dst)
538     {
539         m_buffer->putByte(OP_GROUP1_EvIb);
540         emitModRm_opr(GROUP1_OP_XOR, dst);
541         m_buffer->putByte(imm);
542     }
543
544     void xorl_rr(RegisterID src, RegisterID dst)
545     {
546         m_buffer->putByte(OP_XOR_EvGv);
547         emitModRm_rr(src, dst);
548     }
549
550     void sarl_i8r(int imm, RegisterID dst)
551     {
552         if (imm == 1) {
553             m_buffer->putByte(OP_GROUP2_Ev1);
554             emitModRm_opr(GROUP2_OP_SAR, dst);
555         } else {
556             m_buffer->putByte(OP_GROUP2_EvIb);
557             emitModRm_opr(GROUP2_OP_SAR, dst);
558             m_buffer->putByte(imm);
559         }
560     }
561
562     void sarl_CLr(RegisterID dst)
563     {
564         m_buffer->putByte(OP_GROUP2_EvCL);
565         emitModRm_opr(GROUP2_OP_SAR, dst);
566     }
567
568     void shl_i8r(int imm, RegisterID dst)
569     {
570         if (imm == 1) {
571             m_buffer->putByte(OP_GROUP2_Ev1);
572             emitModRm_opr(GROUP2_OP_SHL, dst);
573         } else {
574             m_buffer->putByte(OP_GROUP2_EvIb);
575             emitModRm_opr(GROUP2_OP_SHL, dst);
576             m_buffer->putByte(imm);
577         }
578     }
579
580     void shll_CLr(RegisterID dst)
581     {
582         m_buffer->putByte(OP_GROUP2_EvCL);
583         emitModRm_opr(GROUP2_OP_SHL, dst);
584     }
585
586     void imull_rr(RegisterID src, RegisterID dst)
587     {
588         m_buffer->putByte(OP_2BYTE_ESCAPE);
589         m_buffer->putByte(OP2_IMUL_GvEv);
590         emitModRm_rr(dst, src);
591     }
592     
593     void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
594     {
595         m_buffer->putByte(OP_IMUL_GvEvIz);
596         emitModRm_rr(dst, src);
597         m_buffer->putInt(value);
598     }
599
600     void idivl_r(RegisterID dst)
601     {
602         m_buffer->putByte(OP_GROUP3_Ev);
603         emitModRm_opr(GROUP3_OP_IDIV, dst);
604     }
605
606     void cdq()
607     {
608         m_buffer->putByte(OP_CDQ);
609     }
610
611     void movl_mr(RegisterID base, RegisterID dst)
612     {
613         m_buffer->putByte(OP_MOV_GvEv);
614         emitModRm_rm(dst, base);
615     }
616
617     void movl_mr(int offset, RegisterID base, RegisterID dst)
618     {
619         m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
620         m_buffer->putByteUnchecked(OP_MOV_GvEv);
621         emitModRm_rm_Unchecked(dst, base, offset);
622     }
623
624     void movl_mr(void* addr, RegisterID dst)
625     {
626         m_buffer->putByte(OP_MOV_GvEv);
627         emitModRm_rm(dst, addr);
628     }
629
630     void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
631     {
632         m_buffer->putByte(OP_MOV_GvEv);
633         emitModRm_rmsib(dst, base, index, scale, offset);
634     }
635
636     void movzbl_rr(RegisterID src, RegisterID dst)
637     {
638         m_buffer->putByte(OP_2BYTE_ESCAPE);
639         m_buffer->putByte(OP2_MOVZX_GvEb);
640         emitModRm_rr(dst, src);
641     }
642
643     void movzwl_mr(int offset, RegisterID base, RegisterID dst)
644     {
645         m_buffer->putByte(OP_2BYTE_ESCAPE);
646         m_buffer->putByte(OP2_MOVZX_GvEw);
647         emitModRm_rm(dst, base, offset);
648     }
649
650     void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
651     {
652         m_buffer->putByte(OP_2BYTE_ESCAPE);
653         m_buffer->putByte(OP2_MOVZX_GvEw);
654         emitModRm_rmsib(dst, base, index, scale);
655     }
656
657     void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
658     {
659         m_buffer->putByte(OP_2BYTE_ESCAPE);
660         m_buffer->putByte(OP2_MOVZX_GvEw);
661         emitModRm_rmsib(dst, base, index, scale, offset);
662     }
663
664     void movl_rm(RegisterID src, RegisterID base)
665     {
666         m_buffer->putByte(OP_MOV_EvGv);
667         emitModRm_rm(src, base);
668     }
669
670     void movl_rm(RegisterID src, int offset, RegisterID base)
671     {
672         m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
673         m_buffer->putByteUnchecked(OP_MOV_EvGv);
674         emitModRm_rm_Unchecked(src, base, offset);
675     }
676     
677     void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
678     {
679         m_buffer->putByte(OP_MOV_EvGv);
680         emitModRm_rmsib(src, base, index, scale, offset);
681     }
682     
683     void movl_i32r(int imm, RegisterID dst)
684     {
685         m_buffer->putByte(OP_GROUP11_EvIz);
686         emitModRm_opr(GROUP11_MOV, dst);
687         m_buffer->putInt(imm);
688     }
689
690     void movl_i32m(int imm, int offset, RegisterID base)
691     {
692         m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
693         m_buffer->putByteUnchecked(OP_GROUP11_EvIz);
694         emitModRm_opm_Unchecked(GROUP11_MOV, base, offset);
695         m_buffer->putIntUnchecked(imm);
696     }
697
698     void movl_i32m(int imm, void* addr)
699     {
700         m_buffer->putByte(OP_GROUP11_EvIz);
701         emitModRm_opm(GROUP11_MOV, addr);
702         m_buffer->putInt(imm);
703     }
704
705     void leal_mr(int offset, RegisterID base, RegisterID dst)
706     {
707         m_buffer->putByte(OP_LEA);
708         emitModRm_rm(dst, base, offset);
709     }
710
711     void leal_mr(int offset, RegisterID index, int scale, RegisterID dst)
712     {
713         m_buffer->putByte(OP_LEA);
714         emitModRm_rmsib(dst, X86::noBase, index, scale, offset);
715     }
716
717     void ret()
718     {
719         m_buffer->putByte(OP_RET);
720     }
721     
722     void jmp_r(RegisterID dst)
723     {
724         m_buffer->putByte(OP_GROUP5_Ev);
725         emitModRm_opr(GROUP5_OP_JMPN, dst);
726     }
727     
728     void jmp_m(int offset, RegisterID base)
729     {
730         m_buffer->putByte(OP_GROUP5_Ev);
731         emitModRm_opm(GROUP5_OP_JMPN, base, offset);
732     }
733     
734     void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
735     {
736         m_buffer->putByte(PRE_SSE_F2);
737         m_buffer->putByte(OP_2BYTE_ESCAPE);
738         m_buffer->putByte(OP2_MOVSD_VsdWsd);
739         emitModRm_rm((RegisterID)dst, base, offset);
740     }
741
742     void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
743     {
744         m_buffer->putByte(PRE_SSE_F2);
745         m_buffer->putByte(OP_2BYTE_ESCAPE);
746         m_buffer->putByte(OP2_MOVSD_WsdVsd);
747         emitModRm_rm((RegisterID)src, base, offset);
748     }
749
750     void movd_rr(XMMRegisterID src, RegisterID dst)
751     {
752         m_buffer->putByte(PRE_SSE_66);
753         m_buffer->putByte(OP_2BYTE_ESCAPE);
754         m_buffer->putByte(OP2_MOVD_EdVd);
755         emitModRm_rr((RegisterID)src, dst);
756     }
757
758     void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
759     {
760         m_buffer->putByte(PRE_SSE_F2);
761         m_buffer->putByte(OP_2BYTE_ESCAPE);
762         m_buffer->putByte(OP2_CVTSI2SD_VsdEd);
763         emitModRm_rr((RegisterID)dst, src);
764     }
765
766     void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
767     {
768         m_buffer->putByte(PRE_SSE_F2);
769         m_buffer->putByte(OP_2BYTE_ESCAPE);
770         m_buffer->putByte(OP2_CVTTSD2SI_GdWsd);
771         emitModRm_rr(dst, (RegisterID)src);
772     }
773
774     void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
775     {
776         m_buffer->putByte(PRE_SSE_F2);
777         m_buffer->putByte(OP_2BYTE_ESCAPE);
778         m_buffer->putByte(OP2_ADDSD_VsdWsd);
779         emitModRm_rm((RegisterID)dst, base, offset);
780     }
781
782     void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
783     {
784         m_buffer->putByte(PRE_SSE_F2);
785         m_buffer->putByte(OP_2BYTE_ESCAPE);
786         m_buffer->putByte(OP2_SUBSD_VsdWsd);
787         emitModRm_rm((RegisterID)dst, base, offset);
788     }
789
790     void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
791     {
792         m_buffer->putByte(PRE_SSE_F2);
793         m_buffer->putByte(OP_2BYTE_ESCAPE);
794         m_buffer->putByte(OP2_MULSD_VsdWsd);
795         emitModRm_rm((RegisterID)dst, base, offset);
796     }
797
798     void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
799     {
800         m_buffer->putByte(PRE_SSE_F2);
801         m_buffer->putByte(OP_2BYTE_ESCAPE);
802         m_buffer->putByte(OP2_ADDSD_VsdWsd);
803         emitModRm_rr((RegisterID)dst, (RegisterID)src);
804     }
805
806     void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
807     {
808         m_buffer->putByte(PRE_SSE_F2);
809         m_buffer->putByte(OP_2BYTE_ESCAPE);
810         m_buffer->putByte(OP2_SUBSD_VsdWsd);
811         emitModRm_rr((RegisterID)dst, (RegisterID)src);
812     }
813
814     void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
815     {
816         m_buffer->putByte(PRE_SSE_F2);
817         m_buffer->putByte(OP_2BYTE_ESCAPE);
818         m_buffer->putByte(OP2_MULSD_VsdWsd);
819         emitModRm_rr((RegisterID)dst, (RegisterID)src);
820     }
821
822     void ucomis_rr(XMMRegisterID src, XMMRegisterID dst)
823     {
824         m_buffer->putByte(PRE_SSE_66);
825         m_buffer->putByte(OP_2BYTE_ESCAPE);
826         m_buffer->putByte(OP2_UCOMISD_VsdWsd);
827         emitModRm_rr((RegisterID)dst, (RegisterID)src);
828     }
829
830     void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
831     {
832         m_buffer->putByte(PRE_SSE_66);
833         m_buffer->putByte(OP_2BYTE_ESCAPE);
834         m_buffer->putByte(OP2_PEXTRW_GdUdIb);
835         emitModRm_rr(dst, (RegisterID)src);
836         m_buffer->putByte(whichWord);
837     }
838
839     // Opaque label types
840     
841     class JmpSrc {
842         friend class X86Assembler;
843     public:
844         JmpSrc()
845             : m_offset(-1)
846         {
847         }
848
849     private:
850         JmpSrc(int offset)
851             : m_offset(offset)
852         {
853         }
854
855         int m_offset;
856     };
857     
858     class JmpDst {
859         friend class X86Assembler;
860     public:
861         JmpDst()
862             : m_offset(-1)
863         {
864         }
865
866     private:
867         JmpDst(int offset)
868             : m_offset(offset)
869         {
870         }
871
872         int m_offset;
873     };
874
875     // FIXME: make this point to a global label, linked later.
876     JmpSrc emitCall()
877     {
878         m_buffer->putByte(OP_CALL_rel32);
879         m_buffer->putInt(0);
880         return JmpSrc(m_buffer->getOffset());
881     }
882     
883     JmpSrc emitCall(RegisterID dst)
884     {
885         m_buffer->putByte(OP_GROUP5_Ev);
886         emitModRm_opr(GROUP5_OP_CALLN, dst);
887         return JmpSrc(m_buffer->getOffset());
888     }
889
890     JmpDst label()
891     {
892         return JmpDst(m_buffer->getOffset());
893     }
894     
895     JmpSrc emitUnlinkedJmp()
896     {
897         m_buffer->putByte(OP_JMP_rel32);
898         m_buffer->putInt(0);
899         return JmpSrc(m_buffer->getOffset());
900     }
901     
902     JmpSrc emitUnlinkedJne()
903     {
904         m_buffer->putByte(OP_2BYTE_ESCAPE);
905         m_buffer->putByte(OP2_JNE_rel32);
906         m_buffer->putInt(0);
907         return JmpSrc(m_buffer->getOffset());
908     }
909     
910     JmpSrc emitUnlinkedJnz()
911     {
912         return emitUnlinkedJne();
913     }
914
915     JmpSrc emitUnlinkedJe()
916     {
917         m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
918         m_buffer->putByteUnchecked(OP_2BYTE_ESCAPE);
919         m_buffer->putByteUnchecked(OP2_JE_rel32);
920         m_buffer->putIntUnchecked(0);
921         return JmpSrc(m_buffer->getOffset());
922     }
923     
924     JmpSrc emitUnlinkedJl()
925     {
926         m_buffer->putByte(OP_2BYTE_ESCAPE);
927         m_buffer->putByte(OP2_JL_rel32);
928         m_buffer->putInt(0);
929         return JmpSrc(m_buffer->getOffset());
930     }
931     
932     JmpSrc emitUnlinkedJb()
933     {
934         m_buffer->putByte(OP_2BYTE_ESCAPE);
935         m_buffer->putByte(OP2_JB_rel32);
936         m_buffer->putInt(0);
937         return JmpSrc(m_buffer->getOffset());
938     }
939     
940     JmpSrc emitUnlinkedJle()
941     {
942         m_buffer->putByte(OP_2BYTE_ESCAPE);
943         m_buffer->putByte(OP2_JLE_rel32);
944         m_buffer->putInt(0);
945         return JmpSrc(m_buffer->getOffset());
946     }
947     
948     JmpSrc emitUnlinkedJbe()
949     {
950         m_buffer->putByte(OP_2BYTE_ESCAPE);
951         m_buffer->putByte(OP2_JBE_rel32);
952         m_buffer->putInt(0);
953         return JmpSrc(m_buffer->getOffset());
954     }
955     
956     JmpSrc emitUnlinkedJge()
957     {
958         m_buffer->putByte(OP_2BYTE_ESCAPE);
959         m_buffer->putByte(OP2_JGE_rel32);
960         m_buffer->putInt(0);
961         return JmpSrc(m_buffer->getOffset());
962     }
963
964     JmpSrc emitUnlinkedJg()
965     {
966         m_buffer->putByte(OP_2BYTE_ESCAPE);
967         m_buffer->putByte(OP2_JG_rel32);
968         m_buffer->putInt(0);
969         return JmpSrc(m_buffer->getOffset());
970     }
971
972     JmpSrc emitUnlinkedJa()
973     {
974         m_buffer->putByte(OP_2BYTE_ESCAPE);
975         m_buffer->putByte(OP2_JA_rel32);
976         m_buffer->putInt(0);
977         return JmpSrc(m_buffer->getOffset());
978     }
979     
980     JmpSrc emitUnlinkedJae()
981     {
982         m_buffer->putByte(OP_2BYTE_ESCAPE);
983         m_buffer->putByte(OP2_JAE_rel32);
984         m_buffer->putInt(0);
985         return JmpSrc(m_buffer->getOffset());
986     }
987     
988     JmpSrc emitUnlinkedJo()
989     {
990         m_buffer->putByte(OP_2BYTE_ESCAPE);
991         m_buffer->putByte(OP2_JO_rel32);
992         m_buffer->putInt(0);
993         return JmpSrc(m_buffer->getOffset());
994     }
995
996     JmpSrc emitUnlinkedJp()
997     {
998         m_buffer->putByte(OP_2BYTE_ESCAPE);
999         m_buffer->putByte(OP2_JP_rel32);
1000         m_buffer->putInt(0);
1001         return JmpSrc(m_buffer->getOffset());
1002     }
1003     
1004     JmpSrc emitUnlinkedJs()
1005     {
1006         m_buffer->putByte(OP_2BYTE_ESCAPE);
1007         m_buffer->putByte(OP2_JS_rel32);
1008         m_buffer->putInt(0);
1009         return JmpSrc(m_buffer->getOffset());
1010     }
1011     
1012     void emitPredictionNotTaken()
1013     {
1014         m_buffer->putByte(PRE_PREDICT_BRANCH_NOT_TAKEN);
1015     }
1016     
1017     void link(JmpSrc from, JmpDst to)
1018     {
1019         ASSERT(to.m_offset != -1);
1020         ASSERT(from.m_offset != -1);
1021         
1022         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_buffer->start()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
1023     }
1024     
1025     static void linkAbsoluteAddress(void* code, JmpDst useOffset, JmpDst address)
1026     {
1027         ASSERT(useOffset.m_offset != -1);
1028         ASSERT(address.m_offset != -1);
1029         
1030         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + useOffset.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(code) + address.m_offset;
1031     }
1032     
1033     static void link(void* code, JmpSrc from, void* to)
1034     {
1035         ASSERT(from.m_offset != -1);
1036         
1037         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
1038     }
1039     
1040     static void* getRelocatedAddress(void* code, JmpSrc jump)
1041     {
1042         return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
1043     }
1044     
1045     static void* getRelocatedAddress(void* code, JmpDst jump)
1046     {
1047         return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
1048     }
1049     
1050     static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
1051     {
1052         return dst.m_offset - src.m_offset;
1053     }
1054     
1055     static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
1056     {
1057         return dst.m_offset - src.m_offset;
1058     }
1059     
1060     static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
1061     {
1062         return dst.m_offset - src.m_offset;
1063     }
1064     
1065     static void repatchImmediate(intptr_t where, int32_t value)
1066     {
1067         reinterpret_cast<int32_t*>(where)[-1] = value;
1068     }
1069     
1070     static void repatchDisplacement(intptr_t where, intptr_t value)
1071     {
1072         reinterpret_cast<intptr_t*>(where)[-1] = value;
1073     }
1074     
1075     static void repatchBranchOffset(intptr_t where, void* destination)
1076     {
1077         reinterpret_cast<intptr_t*>(where)[-1] = (reinterpret_cast<intptr_t>(destination) - where);
1078     }
1079     
1080     void* copy() 
1081     {
1082         return m_buffer->copy();
1083     }
1084
1085 #if COMPILER(MSVC)
1086     void emitConvertToFastCall()
1087     {
1088         movl_mr(4, X86::esp, X86::eax);
1089         movl_mr(8, X86::esp, X86::edx);
1090         movl_mr(12, X86::esp, X86::ecx);
1091     }
1092 #else
1093     void emitConvertToFastCall() {}
1094 #endif
1095
1096 #if USE(CTI_ARGUMENT)
1097     void emitRestoreArgumentReference()
1098     {
1099 #if USE(FAST_CALL_CTI_ARGUMENT)
1100         movl_rr(X86::esp, X86::ecx);
1101 #else
1102         movl_rm(X86::esp, 0, X86::esp);
1103 #endif
1104     }
1105
1106     void emitRestoreArgumentReferenceForTrampoline()
1107     {
1108 #if USE(FAST_CALL_CTI_ARGUMENT)
1109         movl_rr(X86::esp, X86::ecx);
1110         addl_i32r(4, X86::ecx);
1111 #endif
1112     }
1113 #else
1114     void emitRestoreArgumentReference() {}
1115     void emitRestoreArgumentReferenceForTrampoline() {}
1116 #endif
1117
1118 private:
1119     void emitModRm_rr(RegisterID reg, RegisterID rm)
1120     {
1121         m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
1122         emitModRm_rr_Unchecked(reg, rm);
1123     }
1124
1125     void emitModRm_rr_Unchecked(RegisterID reg, RegisterID rm)
1126     {
1127         m_buffer->putByteUnchecked(MODRM(3, reg, rm));
1128     }
1129
1130     void emitModRm_rm(RegisterID reg, void* addr)
1131     {
1132         m_buffer->putByte(MODRM(0, reg, X86::noBase));
1133         m_buffer->putInt((int)addr);
1134     }
1135
1136     void emitModRm_rm(RegisterID reg, RegisterID base)
1137     {
1138         if (base == X86::esp) {
1139             m_buffer->putByte(MODRM(0, reg, X86::hasSib));
1140             m_buffer->putByte(SIB(0, X86::noScale, X86::esp));
1141         } else
1142             m_buffer->putByte(MODRM(0, reg, base));
1143     }
1144
1145     void emitModRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset)
1146     {
1147         if (base == X86::esp) {
1148             if (CAN_SIGN_EXTEND_8_32(offset)) {
1149                 m_buffer->putByteUnchecked(MODRM(1, reg, X86::hasSib));
1150                 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
1151                 m_buffer->putByteUnchecked(offset);
1152             } else {
1153                 m_buffer->putByteUnchecked(MODRM(2, reg, X86::hasSib));
1154                 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
1155                 m_buffer->putIntUnchecked(offset);
1156             }
1157         } else {
1158             if (CAN_SIGN_EXTEND_8_32(offset)) {
1159                 m_buffer->putByteUnchecked(MODRM(1, reg, base));
1160                 m_buffer->putByteUnchecked(offset);
1161             } else {
1162                 m_buffer->putByteUnchecked(MODRM(2, reg, base));
1163                 m_buffer->putIntUnchecked(offset);
1164             }
1165         }
1166     }
1167
1168     void emitModRm_rm(RegisterID reg, RegisterID base, int offset)
1169     {
1170         m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
1171         emitModRm_rm_Unchecked(reg, base, offset);
1172     }
1173
1174     void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale)
1175     {
1176         int shift = 0;
1177         while (scale >>= 1)
1178             shift++;
1179     
1180         m_buffer->putByte(MODRM(0, reg, X86::hasSib));
1181         m_buffer->putByte(SIB(shift, index, base));
1182     }
1183
1184     void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale, int offset)
1185     {
1186         int shift = 0;
1187         while (scale >>= 1)
1188             shift++;
1189     
1190         if (CAN_SIGN_EXTEND_8_32(offset)) {
1191             m_buffer->putByte(MODRM(1, reg, X86::hasSib));
1192             m_buffer->putByte(SIB(shift, index, base));
1193             m_buffer->putByte(offset);
1194         } else {
1195             m_buffer->putByte(MODRM(2, reg, X86::hasSib));
1196             m_buffer->putByte(SIB(shift, index, base));
1197             m_buffer->putInt(offset);
1198         }
1199     }
1200
1201     void emitModRm_opr(OpcodeID opcode, RegisterID rm)
1202     {
1203         m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
1204         emitModRm_opr_Unchecked(opcode, rm);
1205     }
1206
1207     void emitModRm_opr_Unchecked(OpcodeID opcode, RegisterID rm)
1208     {
1209         emitModRm_rr_Unchecked(static_cast<RegisterID>(opcode), rm);
1210     }
1211
1212     void emitModRm_opm(OpcodeID opcode, RegisterID base)
1213     {
1214         emitModRm_rm(static_cast<RegisterID>(opcode), base);
1215     }
1216
1217     void emitModRm_opm_Unchecked(OpcodeID opcode, RegisterID base, int offset)
1218     {
1219         emitModRm_rm_Unchecked(static_cast<RegisterID>(opcode), base, offset);
1220     }
1221
1222     void emitModRm_opm(OpcodeID opcode, RegisterID base, int offset)
1223     {
1224         emitModRm_rm(static_cast<RegisterID>(opcode), base, offset);
1225     }
1226
1227     void emitModRm_opm(OpcodeID opcode, void* addr)
1228     {
1229         emitModRm_rm(static_cast<RegisterID>(opcode), addr);
1230     }
1231
1232     void emitModRm_opmsib(OpcodeID opcode, RegisterID base, RegisterID index, int scale, int offset)
1233     {
1234         emitModRm_rmsib(static_cast<RegisterID>(opcode), base, index, scale, offset);
1235     }
1236
1237     JITCodeBuffer* m_buffer;
1238 };
1239
1240 } // namespace JSC
1241
1242 #endif // ENABLE(MASM) && PLATFORM(X86)
1243
1244 #endif // X86Assembler_h