~ubuntu-branches/ubuntu/saucy/mozjs17/saucy

« back to all changes in this revision

Viewing changes to js/src/assembler/assembler/MacroAssemblerX86_64.h

  • Committer: Package Import Robot
  • Author(s): Rico Tzschichholz
  • Date: 2013-05-25 12:24:23 UTC
  • Revision ID: package-import@ubuntu.com-20130525122423-zmxucrhtensw90xy
Tags: upstream-17.0.0
ImportĀ upstreamĀ versionĀ 17.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 
2
 * vim: set ts=8 sw=4 et tw=79:
 
3
 *
 
4
 * ***** BEGIN LICENSE BLOCK *****
 
5
 * Copyright (C) 2008 Apple Inc. All rights reserved.
 
6
 *
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted provided that the following conditions
 
9
 * are met:
 
10
 * 1. Redistributions of source code must retain the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer.
 
12
 * 2. Redistributions in binary form must reproduce the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer in the
 
14
 *    documentation and/or other materials provided with the distribution.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 
17
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
19
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 
20
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
21
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
22
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
23
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 
24
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
26
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
27
 * 
 
28
 * ***** END LICENSE BLOCK ***** */
 
29
 
 
30
#ifndef MacroAssemblerX86_64_h
 
31
#define MacroAssemblerX86_64_h
 
32
 
 
33
#include "assembler/wtf/Platform.h"
 
34
 
 
35
#if ENABLE_ASSEMBLER && WTF_CPU_X86_64
 
36
 
 
37
#include "MacroAssemblerX86Common.h"
 
38
 
 
39
#define REPTACH_OFFSET_CALL_R11 3
 
40
 
 
41
#include "mozilla/Util.h"
 
42
 
 
43
namespace JSC {
 
44
 
 
45
class MacroAssemblerX86_64 : public MacroAssemblerX86Common {
 
46
protected:
 
47
    static const intptr_t MinInt32 = 0xFFFFFFFF80000000;
 
48
    static const intptr_t MaxInt32 = 0x000000007FFFFFFF;
 
49
 
 
50
public:
 
51
    static const Scale ScalePtr = TimesEight;
 
52
    static const unsigned int TotalRegisters = 16;
 
53
 
 
54
    using MacroAssemblerX86Common::add32;
 
55
    using MacroAssemblerX86Common::and32;
 
56
    using MacroAssemblerX86Common::or32;
 
57
    using MacroAssemblerX86Common::sub32;
 
58
    using MacroAssemblerX86Common::load32;
 
59
    using MacroAssemblerX86Common::store32;
 
60
    using MacroAssemblerX86Common::call;
 
61
    using MacroAssemblerX86Common::loadDouble;
 
62
    using MacroAssemblerX86Common::storeDouble;
 
63
    using MacroAssemblerX86Common::convertInt32ToDouble;
 
64
 
 
65
    void add32(TrustedImm32 imm, AbsoluteAddress address)
 
66
    {
 
67
        move(ImmPtr(address.m_ptr), scratchRegister);
 
68
        add32(imm, Address(scratchRegister));
 
69
    }
 
70
    
 
71
    void and32(Imm32 imm, AbsoluteAddress address)
 
72
    {
 
73
        move(ImmPtr(address.m_ptr), scratchRegister);
 
74
        and32(imm, Address(scratchRegister));
 
75
    }
 
76
    
 
77
    void or32(TrustedImm32 imm, AbsoluteAddress address)
 
78
    {
 
79
        move(ImmPtr(address.m_ptr), scratchRegister);
 
80
        or32(imm, Address(scratchRegister));
 
81
    }
 
82
 
 
83
    void sub32(TrustedImm32 imm, AbsoluteAddress address)
 
84
    {
 
85
        move(ImmPtr(address.m_ptr), scratchRegister);
 
86
        sub32(imm, Address(scratchRegister));
 
87
    }
 
88
 
 
89
    void load32(void* address, RegisterID dest)
 
90
    {
 
91
        if (dest == X86Registers::eax)
 
92
            m_assembler.movl_mEAX(address);
 
93
        else {
 
94
            move(ImmPtr(address), scratchRegister);
 
95
            load32(ImplicitAddress(scratchRegister), dest);
 
96
        }
 
97
    }
 
98
 
 
99
    DataLabelPtr loadDouble(const void* address, FPRegisterID dest)
 
100
    {
 
101
        DataLabelPtr label = moveWithPatch(ImmPtr(address), scratchRegister);
 
102
        loadDouble(scratchRegister, dest);
 
103
        return label;
 
104
    }
 
105
 
 
106
    void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
 
107
    {
 
108
        move(Imm32(*static_cast<int32_t*>(src.m_ptr)), scratchRegister);
 
109
        m_assembler.cvtsi2sd_rr(scratchRegister, dest);
 
110
    }
 
111
 
 
112
    void convertUInt32ToDouble(RegisterID srcDest, FPRegisterID dest)
 
113
    {
 
114
        zeroExtend32ToPtr(srcDest, srcDest);
 
115
        zeroDouble(dest); // break dependency chains
 
116
        m_assembler.cvtsq2sd_rr(srcDest, dest);
 
117
    }
 
118
 
 
119
    void store32(TrustedImm32 imm, void* address)
 
120
    {
 
121
        move(X86Registers::eax, scratchRegister);
 
122
        move(imm, X86Registers::eax);
 
123
        m_assembler.movl_EAXm(address);
 
124
        move(scratchRegister, X86Registers::eax);
 
125
    }
 
126
 
 
127
    Call call()
 
128
    {
 
129
        js::DebugOnly<DataLabelPtr> label = moveWithPatch(ImmPtr(0), scratchRegister);
 
130
        Call result = Call(m_assembler.call(scratchRegister), Call::Linkable);
 
131
        ASSERT(differenceBetween(label, result) == REPTACH_OFFSET_CALL_R11);
 
132
        return result;
 
133
    }
 
134
 
 
135
    Call tailRecursiveCall()
 
136
    {
 
137
        js::DebugOnly<DataLabelPtr> label = moveWithPatch(ImmPtr(0), scratchRegister);
 
138
        Jump newJump = Jump(m_assembler.jmp_r(scratchRegister));
 
139
        ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11);
 
140
        return Call::fromTailJump(newJump);
 
141
    }
 
142
 
 
143
    Call makeTailRecursiveCall(Jump oldJump)
 
144
    {
 
145
        oldJump.link(this);
 
146
        js::DebugOnly<DataLabelPtr> label = moveWithPatch(ImmPtr(0), scratchRegister);
 
147
        Jump newJump = Jump(m_assembler.jmp_r(scratchRegister));
 
148
        ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11);
 
149
        return Call::fromTailJump(newJump);
 
150
    }
 
151
 
 
152
 
 
153
    void addPtr(RegisterID src, RegisterID dest)
 
154
    {
 
155
        m_assembler.addq_rr(src, dest);
 
156
    }
 
157
 
 
158
    void lea(BaseIndex address, RegisterID dest)
 
159
    {
 
160
        m_assembler.leaq_mr(address.offset, address.base, address.index, address.scale, dest);
 
161
    }
 
162
 
 
163
    void lea(Address address, RegisterID dest)
 
164
    {
 
165
        m_assembler.leaq_mr(address.offset, address.base, dest);
 
166
    }
 
167
 
 
168
    void addPtr(Imm32 imm, RegisterID srcDest)
 
169
    {
 
170
        m_assembler.addq_ir(imm.m_value, srcDest);
 
171
    }
 
172
 
 
173
    void addPtr(ImmPtr imm, RegisterID dest)
 
174
    {
 
175
        move(imm, scratchRegister);
 
176
        m_assembler.addq_rr(scratchRegister, dest);
 
177
    }
 
178
 
 
179
    void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
 
180
    {
 
181
        m_assembler.leaq_mr(imm.m_value, src, dest);
 
182
    }
 
183
 
 
184
    void addPtr(Imm32 imm, Address address)
 
185
    {
 
186
        m_assembler.addq_im(imm.m_value, address.offset, address.base);
 
187
    }
 
188
 
 
189
    void addPtr(Imm32 imm, AbsoluteAddress address)
 
190
    {
 
191
        move(ImmPtr(address.m_ptr), scratchRegister);
 
192
        addPtr(imm, Address(scratchRegister));
 
193
    }
 
194
    
 
195
    void andPtr(RegisterID src, RegisterID dest)
 
196
    {
 
197
        m_assembler.andq_rr(src, dest);
 
198
    }
 
199
 
 
200
    void andPtr(Address src, RegisterID dest)
 
201
    {
 
202
        m_assembler.andq_mr(src.offset, src.base, dest);
 
203
    }
 
204
 
 
205
    void andPtr(Imm32 imm, RegisterID srcDest)
 
206
    {
 
207
        m_assembler.andq_ir(imm.m_value, srcDest);
 
208
    }
 
209
 
 
210
    void andPtr(ImmPtr imm, RegisterID srcDest)
 
211
    {
 
212
        intptr_t value = intptr_t(imm.m_value);
 
213
 
 
214
        // 32-bit immediates in 64-bit ALU ops are sign-extended.
 
215
        if (value >= MinInt32 && value <= MaxInt32) {
 
216
            andPtr(Imm32(int(value)), srcDest);
 
217
        } else {
 
218
            move(imm, scratchRegister);
 
219
            m_assembler.andq_rr(scratchRegister, srcDest);
 
220
        }
 
221
    }
 
222
 
 
223
    void negPtr(RegisterID srcDest)
 
224
    {
 
225
        m_assembler.negq_r(srcDest);
 
226
    }
 
227
 
 
228
    void notPtr(RegisterID srcDest)
 
229
    {
 
230
        m_assembler.notq_r(srcDest);
 
231
    }
 
232
 
 
233
    void orPtr(Address src, RegisterID dest)
 
234
    {
 
235
        m_assembler.orq_mr(src.offset, src.base, dest);
 
236
    }
 
237
 
 
238
    void orPtr(RegisterID src, RegisterID dest)
 
239
    {
 
240
        m_assembler.orq_rr(src, dest);
 
241
    }
 
242
 
 
243
    void orPtr(ImmPtr imm, RegisterID dest)
 
244
    {
 
245
        move(imm, scratchRegister);
 
246
        m_assembler.orq_rr(scratchRegister, dest);
 
247
    }
 
248
 
 
249
    void orPtr(Imm32 imm, RegisterID dest)
 
250
    {
 
251
        m_assembler.orq_ir(imm.m_value, dest);
 
252
    }
 
253
 
 
254
    void subPtr(RegisterID src, RegisterID dest)
 
255
    {
 
256
        m_assembler.subq_rr(src, dest);
 
257
    }
 
258
    
 
259
    void subPtr(Imm32 imm, RegisterID dest)
 
260
    {
 
261
        m_assembler.subq_ir(imm.m_value, dest);
 
262
    }
 
263
    
 
264
    void subPtr(ImmPtr imm, RegisterID dest)
 
265
    {
 
266
        move(imm, scratchRegister);
 
267
        m_assembler.subq_rr(scratchRegister, dest);
 
268
    }
 
269
 
 
270
    void xorPtr(RegisterID src, RegisterID dest)
 
271
    {
 
272
        m_assembler.xorq_rr(src, dest);
 
273
    }
 
274
 
 
275
    void xorPtr(Imm32 imm, RegisterID srcDest)
 
276
    {
 
277
        m_assembler.xorq_ir(imm.m_value, srcDest);
 
278
    }
 
279
 
 
280
    void rshiftPtr(Imm32 imm, RegisterID srcDest)
 
281
    {
 
282
        m_assembler.sarq_i8r(imm.m_value, srcDest);
 
283
    }
 
284
 
 
285
    void lshiftPtr(Imm32 imm, RegisterID srcDest)
 
286
    {
 
287
        m_assembler.shlq_i8r(imm.m_value, srcDest);
 
288
    }
 
289
 
 
290
    void loadPtr(ImplicitAddress address, RegisterID dest)
 
291
    {
 
292
        m_assembler.movq_mr(address.offset, address.base, dest);
 
293
    }
 
294
 
 
295
    void loadPtr(BaseIndex address, RegisterID dest)
 
296
    {
 
297
        m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest);
 
298
    }
 
299
 
 
300
    void loadPtr(void* address, RegisterID dest)
 
301
    {
 
302
        if (dest == X86Registers::eax)
 
303
            m_assembler.movq_mEAX(address);
 
304
        else {
 
305
            move(ImmPtr(address), scratchRegister);
 
306
            loadPtr(ImplicitAddress(scratchRegister), dest);
 
307
        }
 
308
    }
 
309
 
 
310
    DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
 
311
    {
 
312
        m_assembler.movq_mr_disp32(address.offset, address.base, dest);
 
313
        return DataLabel32(this);
 
314
    }
 
315
 
 
316
    void storePtr(RegisterID src, ImplicitAddress address)
 
317
    {
 
318
        m_assembler.movq_rm(src, address.offset, address.base);
 
319
    }
 
320
 
 
321
    void storePtr(TrustedImmPtr imm, BaseIndex address)
 
322
    {
 
323
        intptr_t value = intptr_t(imm.m_value);
 
324
 
 
325
        // 32-bit immediates in 64-bit stores will be zero-extended, so check
 
326
        // if the value can fit in such a store.
 
327
        if (value >= 0 && value < intptr_t(0x7FFFFFFF)) {
 
328
            m_assembler.movq_i32m(int32_t(value), address.offset, address.base, address.index,
 
329
                                  address.scale);
 
330
        } else {
 
331
            move(imm, scratchRegister);
 
332
            storePtr(scratchRegister, address);
 
333
        }
 
334
    }
 
335
 
 
336
    void storePtr(RegisterID src, BaseIndex address)
 
337
    {
 
338
        m_assembler.movq_rm(src, address.offset, address.base, address.index, address.scale);
 
339
    }
 
340
    
 
341
    void storePtr(RegisterID src, void* address)
 
342
    {
 
343
        if (src == X86Registers::eax)
 
344
            m_assembler.movq_EAXm(address);
 
345
        else {
 
346
            move(ImmPtr(address), scratchRegister);
 
347
            storePtr(src, ImplicitAddress(scratchRegister));
 
348
        }
 
349
    }
 
350
 
 
351
    void storePtr(TrustedImmPtr imm, ImplicitAddress address)
 
352
    {
 
353
        intptr_t value = intptr_t(imm.m_value);
 
354
 
 
355
        // 32-bit immediates in 64-bit stores will be zero-extended, so check
 
356
        // if the value can fit in such a store.
 
357
        if (value >= 0 && value < intptr_t(0x7FFFFFFF)) {
 
358
            m_assembler.movq_i32m(int32_t(value), address.offset, address.base);
 
359
        } else {
 
360
            move(imm, scratchRegister);
 
361
            storePtr(scratchRegister, address);
 
362
        }
 
363
    }
 
364
 
 
365
    DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
 
366
    {
 
367
        m_assembler.movq_rm_disp32(src, address.offset, address.base);
 
368
        return DataLabel32(this);
 
369
    }
 
370
 
 
371
    void movePtrToDouble(RegisterID src, FPRegisterID dest)
 
372
    {
 
373
        m_assembler.movq_rr(src, dest);
 
374
    }
 
375
 
 
376
    void moveDoubleToPtr(FPRegisterID src, RegisterID dest)
 
377
    {
 
378
        m_assembler.movq_rr(src, dest);
 
379
    }
 
380
 
 
381
    void setPtr(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
 
382
    {
 
383
        if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
 
384
            m_assembler.testq_rr(left, left);
 
385
        else
 
386
            m_assembler.cmpq_ir(right.m_value, left);
 
387
        m_assembler.setCC_r(x86Condition(cond), dest);
 
388
        m_assembler.movzbl_rr(dest, dest);
 
389
    }
 
390
 
 
391
    void setPtr(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
 
392
    {
 
393
        m_assembler.cmpq_rr(right, left);
 
394
        m_assembler.setCC_r(x86Condition(cond), dest);
 
395
        m_assembler.movzbl_rr(dest, dest);
 
396
    }
 
397
 
 
398
    void setPtr(Condition cond, RegisterID left, ImmPtr right, RegisterID dest) 
 
399
    {
 
400
        move(right, scratchRegister);
 
401
        setPtr(cond, left, scratchRegister, dest);
 
402
    }
 
403
 
 
404
    Jump branchPtr(Condition cond, RegisterID left, RegisterID right)
 
405
    {
 
406
        m_assembler.cmpq_rr(right, left);
 
407
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
408
    }
 
409
 
 
410
    Jump branchPtr(Condition cond, RegisterID left, Imm32 right)
 
411
    {
 
412
        m_assembler.cmpq_ir(right.m_value, left);
 
413
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
414
    }
 
415
 
 
416
    Jump branchPtr(Condition cond, RegisterID left, ImmPtr right)
 
417
    {
 
418
        move(right, scratchRegister);
 
419
        return branchPtr(cond, left, scratchRegister);
 
420
    }
 
421
 
 
422
    Jump branchPtr(Condition cond, RegisterID left, Address right)
 
423
    {
 
424
        m_assembler.cmpq_mr(right.offset, right.base, left);
 
425
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
426
    }
 
427
 
 
428
    Jump branchPtr(Condition cond, AbsoluteAddress left, RegisterID right)
 
429
    {
 
430
        move(ImmPtr(left.m_ptr), scratchRegister);
 
431
        return branchPtr(cond, Address(scratchRegister), right);
 
432
    }
 
433
 
 
434
    Jump branchPtr(Condition cond, AbsoluteAddress left, ImmPtr right, RegisterID scratch)
 
435
    {
 
436
        move(ImmPtr(left.m_ptr), scratch);
 
437
        return branchPtr(cond, Address(scratch), right);
 
438
    }
 
439
 
 
440
    Jump branchPtr(Condition cond, Address left, RegisterID right)
 
441
    {
 
442
        m_assembler.cmpq_rm(right, left.offset, left.base);
 
443
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
444
    }
 
445
 
 
446
    Jump branchPtr(Condition cond, Address left, ImmPtr right)
 
447
    {
 
448
        move(right, scratchRegister);
 
449
        return branchPtr(cond, left, scratchRegister);
 
450
    }
 
451
 
 
452
    Jump branchTestPtr(Condition cond, RegisterID reg, RegisterID mask)
 
453
    {
 
454
        m_assembler.testq_rr(reg, mask);
 
455
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
456
    }
 
457
 
 
458
    Jump branchTestPtr(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
 
459
    {
 
460
        // if we are only interested in the low seven bits, this can be tested with a testb
 
461
        if (mask.m_value == -1)
 
462
            m_assembler.testq_rr(reg, reg);
 
463
        else if ((mask.m_value & ~0x7f) == 0)
 
464
            m_assembler.testb_i8r(mask.m_value, reg);
 
465
        else
 
466
            m_assembler.testq_i32r(mask.m_value, reg);
 
467
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
468
    }
 
469
 
 
470
    Jump branchTestPtr(Condition cond, Address address, Imm32 mask = Imm32(-1))
 
471
    {
 
472
        if (mask.m_value == -1)
 
473
            m_assembler.cmpq_im(0, address.offset, address.base);
 
474
        else
 
475
            m_assembler.testq_i32m(mask.m_value, address.offset, address.base);
 
476
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
477
    }
 
478
 
 
479
    Jump branchTestPtr(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
 
480
    {
 
481
        if (mask.m_value == -1)
 
482
            m_assembler.cmpq_im(0, address.offset, address.base, address.index, address.scale);
 
483
        else
 
484
            m_assembler.testq_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
 
485
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
486
    }
 
487
 
 
488
 
 
489
    Jump branchAddPtr(Condition cond, RegisterID src, RegisterID dest)
 
490
    {
 
491
        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
 
492
        addPtr(src, dest);
 
493
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
494
    }
 
495
 
 
496
    Jump branchSubPtr(Condition cond, Imm32 imm, RegisterID dest)
 
497
    {
 
498
        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
 
499
        subPtr(imm, dest);
 
500
        return Jump(m_assembler.jCC(x86Condition(cond)));
 
501
    }
 
502
 
 
503
    DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
 
504
    {
 
505
        m_assembler.movq_i64r(initialValue.asIntptr(), dest);
 
506
        return DataLabelPtr(this);
 
507
    }
 
508
 
 
509
    Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
 
510
    {
 
511
        dataLabel = moveWithPatch(initialRightValue, scratchRegister);
 
512
        return branchPtr(cond, left, scratchRegister);
 
513
    }
 
514
 
 
515
    Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
 
516
    {
 
517
        dataLabel = moveWithPatch(initialRightValue, scratchRegister);
 
518
        return branchPtr(cond, left, scratchRegister);
 
519
    }
 
520
 
 
521
    DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
 
522
    {
 
523
        DataLabelPtr label = moveWithPatch(initialValue, scratchRegister);
 
524
        storePtr(scratchRegister, address);
 
525
        return label;
 
526
    }
 
527
 
 
528
    using MacroAssemblerX86Common::branchTest8;
 
529
    Jump branchTest8(Condition cond, ExtendedAddress address, Imm32 mask = Imm32(-1))
 
530
    {
 
531
        ImmPtr addr(reinterpret_cast<void*>(address.offset));
 
532
        MacroAssemblerX86Common::move(addr, scratchRegister);
 
533
        return MacroAssemblerX86Common::branchTest8(cond, BaseIndex(scratchRegister, address.base, TimesOne), mask);
 
534
    }
 
535
 
 
536
    Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
 
537
    {
 
538
        Label label(this);
 
539
        loadPtr(address, dest);
 
540
        return label;
 
541
    }
 
542
 
 
543
    void pushAllRegs()
 
544
    {
 
545
        for (int i = X86Registers::eax; i <= X86Registers::r15; i++)
 
546
            m_assembler.push_r((RegisterID)i);
 
547
    }
 
548
 
 
549
    void popAllRegs()
 
550
    {
 
551
        for (int i = X86Registers::r15; i >= X86Registers::eax; i--)
 
552
            m_assembler.pop_r((RegisterID)i);
 
553
    }
 
554
 
 
555
    void storeDouble(ImmDouble imm, Address address)
 
556
    {
 
557
        storePtr(ImmPtr(reinterpret_cast<void *>(imm.u.u64)), address);
 
558
    }
 
559
 
 
560
    void storeDouble(ImmDouble imm, BaseIndex address)
 
561
    {
 
562
        storePtr(ImmPtr(reinterpret_cast<void *>(imm.u.u64)), address);
 
563
    }
 
564
 
 
565
    bool supportsFloatingPoint() const { return true; }
 
566
    // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
 
567
    bool supportsFloatingPointTruncate() const { return true; }
 
568
    bool supportsFloatingPointSqrt() const { return true; }
 
569
 
 
570
private:
 
571
    friend class LinkBuffer;
 
572
    friend class RepatchBuffer;
 
573
 
 
574
    static void linkCall(void* code, Call call, FunctionPtr function)
 
575
    {
 
576
        if (!call.isFlagSet(Call::Near))
 
577
            X86Assembler::linkPointer(code, X86Assembler::labelFor(call.m_jmp, -REPTACH_OFFSET_CALL_R11), function.value());
 
578
        else
 
579
            X86Assembler::linkCall(code, call.m_jmp, function.value());
 
580
    }
 
581
 
 
582
    static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
 
583
    {
 
584
        X86Assembler::repatchPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation(), destination.executableAddress());
 
585
    }
 
586
 
 
587
    static void repatchCall(CodeLocationCall call, FunctionPtr destination)
 
588
    {
 
589
        X86Assembler::repatchPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation(), destination.executableAddress());
 
590
    }
 
591
 
 
592
};
 
593
 
 
594
} // namespace JSC
 
595
 
 
596
#endif // ENABLE(ASSEMBLER)
 
597
 
 
598
#endif // MacroAssemblerX86_64_h