]>
Commit | Line | Data |
---|---|---|
ba379fdc A |
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 MacroAssemblerX86_64_h | |
27 | #define MacroAssemblerX86_64_h | |
28 | ||
f9bf01c6 | 29 | #if ENABLE(ASSEMBLER) && CPU(X86_64) |
ba379fdc A |
30 | |
31 | #include "MacroAssemblerX86Common.h" | |
32 | ||
33 | #define REPTACH_OFFSET_CALL_R11 3 | |
34 | ||
35 | namespace JSC { | |
36 | ||
37 | class MacroAssemblerX86_64 : public MacroAssemblerX86Common { | |
ba379fdc A |
38 | public: |
39 | static const Scale ScalePtr = TimesEight; | |
40 | ||
41 | using MacroAssemblerX86Common::add32; | |
42 | using MacroAssemblerX86Common::and32; | |
6fe7ccc8 | 43 | using MacroAssemblerX86Common::branchAdd32; |
ba379fdc A |
44 | using MacroAssemblerX86Common::or32; |
45 | using MacroAssemblerX86Common::sub32; | |
46 | using MacroAssemblerX86Common::load32; | |
47 | using MacroAssemblerX86Common::store32; | |
48 | using MacroAssemblerX86Common::call; | |
6fe7ccc8 | 49 | using MacroAssemblerX86Common::jump; |
14957cd0 | 50 | using MacroAssemblerX86Common::addDouble; |
ba379fdc A |
51 | using MacroAssemblerX86Common::loadDouble; |
52 | using MacroAssemblerX86Common::convertInt32ToDouble; | |
53 | ||
14957cd0 | 54 | void add32(TrustedImm32 imm, AbsoluteAddress address) |
ba379fdc | 55 | { |
14957cd0 | 56 | move(TrustedImmPtr(address.m_ptr), scratchRegister); |
ba379fdc A |
57 | add32(imm, Address(scratchRegister)); |
58 | } | |
59 | ||
14957cd0 | 60 | void and32(TrustedImm32 imm, AbsoluteAddress address) |
ba379fdc | 61 | { |
14957cd0 | 62 | move(TrustedImmPtr(address.m_ptr), scratchRegister); |
ba379fdc A |
63 | and32(imm, Address(scratchRegister)); |
64 | } | |
65 | ||
14957cd0 | 66 | void or32(TrustedImm32 imm, AbsoluteAddress address) |
ba379fdc | 67 | { |
14957cd0 | 68 | move(TrustedImmPtr(address.m_ptr), scratchRegister); |
ba379fdc A |
69 | or32(imm, Address(scratchRegister)); |
70 | } | |
71 | ||
14957cd0 | 72 | void sub32(TrustedImm32 imm, AbsoluteAddress address) |
ba379fdc | 73 | { |
14957cd0 | 74 | move(TrustedImmPtr(address.m_ptr), scratchRegister); |
ba379fdc A |
75 | sub32(imm, Address(scratchRegister)); |
76 | } | |
77 | ||
6fe7ccc8 | 78 | void load32(const void* address, RegisterID dest) |
ba379fdc | 79 | { |
f9bf01c6 | 80 | if (dest == X86Registers::eax) |
ba379fdc A |
81 | m_assembler.movl_mEAX(address); |
82 | else { | |
6fe7ccc8 A |
83 | move(TrustedImmPtr(address), dest); |
84 | load32(dest, dest); | |
ba379fdc A |
85 | } |
86 | } | |
87 | ||
14957cd0 | 88 | void addDouble(AbsoluteAddress address, FPRegisterID dest) |
ba379fdc | 89 | { |
14957cd0 A |
90 | move(TrustedImmPtr(address.m_ptr), scratchRegister); |
91 | m_assembler.addsd_mr(0, scratchRegister, dest); | |
92 | } | |
93 | ||
94 | void convertInt32ToDouble(TrustedImm32 imm, FPRegisterID dest) | |
95 | { | |
96 | move(imm, scratchRegister); | |
ba379fdc A |
97 | m_assembler.cvtsi2sd_rr(scratchRegister, dest); |
98 | } | |
99 | ||
14957cd0 | 100 | void store32(TrustedImm32 imm, void* address) |
ba379fdc | 101 | { |
6fe7ccc8 A |
102 | move(TrustedImmPtr(address), scratchRegister); |
103 | store32(imm, scratchRegister); | |
ba379fdc A |
104 | } |
105 | ||
106 | Call call() | |
107 | { | |
14957cd0 | 108 | DataLabelPtr label = moveWithPatch(TrustedImmPtr(0), scratchRegister); |
ba379fdc | 109 | Call result = Call(m_assembler.call(scratchRegister), Call::Linkable); |
14957cd0 | 110 | ASSERT_UNUSED(label, differenceBetween(label, result) == REPTACH_OFFSET_CALL_R11); |
ba379fdc A |
111 | return result; |
112 | } | |
113 | ||
6fe7ccc8 A |
114 | // Address is a memory location containing the address to jump to |
115 | void jump(AbsoluteAddress address) | |
116 | { | |
117 | move(TrustedImmPtr(address.m_ptr), scratchRegister); | |
118 | jump(Address(scratchRegister)); | |
119 | } | |
120 | ||
ba379fdc A |
121 | Call tailRecursiveCall() |
122 | { | |
14957cd0 | 123 | DataLabelPtr label = moveWithPatch(TrustedImmPtr(0), scratchRegister); |
ba379fdc | 124 | Jump newJump = Jump(m_assembler.jmp_r(scratchRegister)); |
14957cd0 | 125 | ASSERT_UNUSED(label, differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11); |
ba379fdc A |
126 | return Call::fromTailJump(newJump); |
127 | } | |
128 | ||
129 | Call makeTailRecursiveCall(Jump oldJump) | |
130 | { | |
131 | oldJump.link(this); | |
14957cd0 | 132 | DataLabelPtr label = moveWithPatch(TrustedImmPtr(0), scratchRegister); |
ba379fdc | 133 | Jump newJump = Jump(m_assembler.jmp_r(scratchRegister)); |
14957cd0 | 134 | ASSERT_UNUSED(label, differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11); |
ba379fdc A |
135 | return Call::fromTailJump(newJump); |
136 | } | |
137 | ||
138 | ||
139 | void addPtr(RegisterID src, RegisterID dest) | |
140 | { | |
141 | m_assembler.addq_rr(src, dest); | |
142 | } | |
143 | ||
14957cd0 | 144 | void addPtr(TrustedImm32 imm, RegisterID srcDest) |
ba379fdc A |
145 | { |
146 | m_assembler.addq_ir(imm.m_value, srcDest); | |
147 | } | |
148 | ||
14957cd0 | 149 | void addPtr(TrustedImmPtr imm, RegisterID dest) |
ba379fdc A |
150 | { |
151 | move(imm, scratchRegister); | |
152 | m_assembler.addq_rr(scratchRegister, dest); | |
153 | } | |
154 | ||
14957cd0 | 155 | void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest) |
ba379fdc A |
156 | { |
157 | m_assembler.leaq_mr(imm.m_value, src, dest); | |
158 | } | |
159 | ||
14957cd0 | 160 | void addPtr(TrustedImm32 imm, Address address) |
ba379fdc A |
161 | { |
162 | m_assembler.addq_im(imm.m_value, address.offset, address.base); | |
163 | } | |
164 | ||
14957cd0 | 165 | void addPtr(TrustedImm32 imm, AbsoluteAddress address) |
ba379fdc | 166 | { |
14957cd0 | 167 | move(TrustedImmPtr(address.m_ptr), scratchRegister); |
ba379fdc A |
168 | addPtr(imm, Address(scratchRegister)); |
169 | } | |
6fe7ccc8 A |
170 | |
171 | void add64(TrustedImm32 imm, AbsoluteAddress address) | |
172 | { | |
173 | addPtr(imm, address); | |
174 | } | |
175 | ||
ba379fdc A |
176 | void andPtr(RegisterID src, RegisterID dest) |
177 | { | |
178 | m_assembler.andq_rr(src, dest); | |
179 | } | |
180 | ||
14957cd0 | 181 | void andPtr(TrustedImm32 imm, RegisterID srcDest) |
ba379fdc A |
182 | { |
183 | m_assembler.andq_ir(imm.m_value, srcDest); | |
184 | } | |
185 | ||
186 | void orPtr(RegisterID src, RegisterID dest) | |
187 | { | |
188 | m_assembler.orq_rr(src, dest); | |
189 | } | |
190 | ||
14957cd0 | 191 | void orPtr(TrustedImmPtr imm, RegisterID dest) |
ba379fdc A |
192 | { |
193 | move(imm, scratchRegister); | |
194 | m_assembler.orq_rr(scratchRegister, dest); | |
195 | } | |
196 | ||
14957cd0 | 197 | void orPtr(TrustedImm32 imm, RegisterID dest) |
ba379fdc A |
198 | { |
199 | m_assembler.orq_ir(imm.m_value, dest); | |
200 | } | |
201 | ||
14957cd0 A |
202 | void orPtr(RegisterID op1, RegisterID op2, RegisterID dest) |
203 | { | |
204 | if (op1 == op2) | |
205 | move(op1, dest); | |
206 | else if (op1 == dest) | |
207 | orPtr(op2, dest); | |
208 | else { | |
209 | move(op2, dest); | |
210 | orPtr(op1, dest); | |
211 | } | |
212 | } | |
213 | ||
214 | void orPtr(TrustedImm32 imm, RegisterID src, RegisterID dest) | |
215 | { | |
216 | move(src, dest); | |
217 | orPtr(imm, dest); | |
218 | } | |
6fe7ccc8 A |
219 | |
220 | void rotateRightPtr(TrustedImm32 imm, RegisterID srcDst) | |
221 | { | |
222 | m_assembler.rorq_i8r(imm.m_value, srcDst); | |
223 | } | |
14957cd0 | 224 | |
ba379fdc A |
225 | void subPtr(RegisterID src, RegisterID dest) |
226 | { | |
227 | m_assembler.subq_rr(src, dest); | |
228 | } | |
229 | ||
14957cd0 | 230 | void subPtr(TrustedImm32 imm, RegisterID dest) |
ba379fdc A |
231 | { |
232 | m_assembler.subq_ir(imm.m_value, dest); | |
233 | } | |
234 | ||
14957cd0 | 235 | void subPtr(TrustedImmPtr imm, RegisterID dest) |
ba379fdc A |
236 | { |
237 | move(imm, scratchRegister); | |
238 | m_assembler.subq_rr(scratchRegister, dest); | |
239 | } | |
240 | ||
241 | void xorPtr(RegisterID src, RegisterID dest) | |
242 | { | |
243 | m_assembler.xorq_rr(src, dest); | |
244 | } | |
6fe7ccc8 A |
245 | |
246 | void xorPtr(RegisterID src, Address dest) | |
247 | { | |
248 | m_assembler.xorq_rm(src, dest.offset, dest.base); | |
249 | } | |
ba379fdc | 250 | |
14957cd0 | 251 | void xorPtr(TrustedImm32 imm, RegisterID srcDest) |
ba379fdc A |
252 | { |
253 | m_assembler.xorq_ir(imm.m_value, srcDest); | |
254 | } | |
255 | ||
ba379fdc A |
256 | void loadPtr(ImplicitAddress address, RegisterID dest) |
257 | { | |
258 | m_assembler.movq_mr(address.offset, address.base, dest); | |
259 | } | |
260 | ||
261 | void loadPtr(BaseIndex address, RegisterID dest) | |
262 | { | |
263 | m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest); | |
264 | } | |
265 | ||
14957cd0 | 266 | void loadPtr(const void* address, RegisterID dest) |
ba379fdc | 267 | { |
f9bf01c6 | 268 | if (dest == X86Registers::eax) |
ba379fdc A |
269 | m_assembler.movq_mEAX(address); |
270 | else { | |
6fe7ccc8 A |
271 | move(TrustedImmPtr(address), dest); |
272 | loadPtr(dest, dest); | |
ba379fdc A |
273 | } |
274 | } | |
275 | ||
276 | DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest) | |
277 | { | |
278 | m_assembler.movq_mr_disp32(address.offset, address.base, dest); | |
279 | return DataLabel32(this); | |
280 | } | |
14957cd0 A |
281 | |
282 | DataLabelCompact loadPtrWithCompactAddressOffsetPatch(Address address, RegisterID dest) | |
283 | { | |
284 | m_assembler.movq_mr_disp8(address.offset, address.base, dest); | |
285 | return DataLabelCompact(this); | |
286 | } | |
ba379fdc A |
287 | |
288 | void storePtr(RegisterID src, ImplicitAddress address) | |
289 | { | |
290 | m_assembler.movq_rm(src, address.offset, address.base); | |
291 | } | |
292 | ||
293 | void storePtr(RegisterID src, BaseIndex address) | |
294 | { | |
295 | m_assembler.movq_rm(src, address.offset, address.base, address.index, address.scale); | |
296 | } | |
297 | ||
298 | void storePtr(RegisterID src, void* address) | |
299 | { | |
f9bf01c6 | 300 | if (src == X86Registers::eax) |
ba379fdc A |
301 | m_assembler.movq_EAXm(address); |
302 | else { | |
6fe7ccc8 A |
303 | move(TrustedImmPtr(address), scratchRegister); |
304 | storePtr(src, scratchRegister); | |
ba379fdc A |
305 | } |
306 | } | |
307 | ||
14957cd0 | 308 | void storePtr(TrustedImmPtr imm, ImplicitAddress address) |
ba379fdc | 309 | { |
f9bf01c6 A |
310 | move(imm, scratchRegister); |
311 | storePtr(scratchRegister, address); | |
ba379fdc A |
312 | } |
313 | ||
6fe7ccc8 A |
314 | void storePtr(TrustedImmPtr imm, BaseIndex address) |
315 | { | |
316 | move(imm, scratchRegister); | |
317 | m_assembler.movq_rm(scratchRegister, address.offset, address.base, address.index, address.scale); | |
318 | } | |
319 | ||
ba379fdc A |
320 | DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address) |
321 | { | |
322 | m_assembler.movq_rm_disp32(src, address.offset, address.base); | |
323 | return DataLabel32(this); | |
324 | } | |
325 | ||
326 | void movePtrToDouble(RegisterID src, FPRegisterID dest) | |
327 | { | |
328 | m_assembler.movq_rr(src, dest); | |
329 | } | |
330 | ||
331 | void moveDoubleToPtr(FPRegisterID src, RegisterID dest) | |
332 | { | |
333 | m_assembler.movq_rr(src, dest); | |
334 | } | |
335 | ||
14957cd0 | 336 | void comparePtr(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest) |
ba379fdc A |
337 | { |
338 | if (((cond == Equal) || (cond == NotEqual)) && !right.m_value) | |
339 | m_assembler.testq_rr(left, left); | |
340 | else | |
341 | m_assembler.cmpq_ir(right.m_value, left); | |
342 | m_assembler.setCC_r(x86Condition(cond), dest); | |
343 | m_assembler.movzbl_rr(dest, dest); | |
344 | } | |
6fe7ccc8 A |
345 | |
346 | void comparePtr(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest) | |
347 | { | |
348 | m_assembler.cmpq_rr(right, left); | |
349 | m_assembler.setCC_r(x86Condition(cond), dest); | |
350 | m_assembler.movzbl_rr(dest, dest); | |
351 | } | |
352 | ||
353 | Jump branchAdd32(ResultCondition cond, TrustedImm32 src, AbsoluteAddress dest) | |
354 | { | |
355 | move(TrustedImmPtr(dest.m_ptr), scratchRegister); | |
356 | add32(src, Address(scratchRegister)); | |
357 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
358 | } | |
ba379fdc | 359 | |
14957cd0 | 360 | Jump branchPtr(RelationalCondition cond, RegisterID left, RegisterID right) |
ba379fdc A |
361 | { |
362 | m_assembler.cmpq_rr(right, left); | |
363 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
364 | } | |
365 | ||
14957cd0 | 366 | Jump branchPtr(RelationalCondition cond, RegisterID left, TrustedImmPtr right) |
ba379fdc | 367 | { |
6fe7ccc8 A |
368 | if (((cond == Equal) || (cond == NotEqual)) && !right.m_value) { |
369 | m_assembler.testq_rr(left, left); | |
370 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
371 | } | |
f9bf01c6 A |
372 | move(right, scratchRegister); |
373 | return branchPtr(cond, left, scratchRegister); | |
ba379fdc A |
374 | } |
375 | ||
14957cd0 | 376 | Jump branchPtr(RelationalCondition cond, RegisterID left, Address right) |
ba379fdc A |
377 | { |
378 | m_assembler.cmpq_mr(right.offset, right.base, left); | |
379 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
380 | } | |
381 | ||
14957cd0 | 382 | Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, RegisterID right) |
ba379fdc | 383 | { |
14957cd0 | 384 | move(TrustedImmPtr(left.m_ptr), scratchRegister); |
ba379fdc A |
385 | return branchPtr(cond, Address(scratchRegister), right); |
386 | } | |
387 | ||
14957cd0 | 388 | Jump branchPtr(RelationalCondition cond, Address left, RegisterID right) |
ba379fdc A |
389 | { |
390 | m_assembler.cmpq_rm(right, left.offset, left.base); | |
391 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
392 | } | |
393 | ||
14957cd0 | 394 | Jump branchPtr(RelationalCondition cond, Address left, TrustedImmPtr right) |
ba379fdc A |
395 | { |
396 | move(right, scratchRegister); | |
397 | return branchPtr(cond, left, scratchRegister); | |
398 | } | |
399 | ||
14957cd0 | 400 | Jump branchTestPtr(ResultCondition cond, RegisterID reg, RegisterID mask) |
ba379fdc A |
401 | { |
402 | m_assembler.testq_rr(reg, mask); | |
403 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
404 | } | |
6fe7ccc8 | 405 | |
14957cd0 | 406 | Jump branchTestPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) |
ba379fdc A |
407 | { |
408 | // if we are only interested in the low seven bits, this can be tested with a testb | |
409 | if (mask.m_value == -1) | |
410 | m_assembler.testq_rr(reg, reg); | |
411 | else if ((mask.m_value & ~0x7f) == 0) | |
412 | m_assembler.testb_i8r(mask.m_value, reg); | |
413 | else | |
414 | m_assembler.testq_i32r(mask.m_value, reg); | |
415 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
416 | } | |
417 | ||
6fe7ccc8 A |
418 | void testPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest) |
419 | { | |
420 | if (mask.m_value == -1) | |
421 | m_assembler.testq_rr(reg, reg); | |
422 | else if ((mask.m_value & ~0x7f) == 0) | |
423 | m_assembler.testb_i8r(mask.m_value, reg); | |
424 | else | |
425 | m_assembler.testq_i32r(mask.m_value, reg); | |
426 | set32(x86Condition(cond), dest); | |
427 | } | |
428 | ||
429 | void testPtr(ResultCondition cond, RegisterID reg, RegisterID mask, RegisterID dest) | |
430 | { | |
431 | m_assembler.testq_rr(reg, mask); | |
432 | set32(x86Condition(cond), dest); | |
433 | } | |
434 | ||
14957cd0 A |
435 | Jump branchTestPtr(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1)) |
436 | { | |
437 | loadPtr(address.m_ptr, scratchRegister); | |
438 | return branchTestPtr(cond, scratchRegister, mask); | |
439 | } | |
440 | ||
441 | Jump branchTestPtr(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) | |
ba379fdc A |
442 | { |
443 | if (mask.m_value == -1) | |
444 | m_assembler.cmpq_im(0, address.offset, address.base); | |
445 | else | |
446 | m_assembler.testq_i32m(mask.m_value, address.offset, address.base); | |
447 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
448 | } | |
449 | ||
14957cd0 | 450 | Jump branchTestPtr(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1)) |
ba379fdc A |
451 | { |
452 | if (mask.m_value == -1) | |
453 | m_assembler.cmpq_im(0, address.offset, address.base, address.index, address.scale); | |
454 | else | |
455 | m_assembler.testq_i32m(mask.m_value, address.offset, address.base, address.index, address.scale); | |
456 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
457 | } | |
458 | ||
459 | ||
6fe7ccc8 A |
460 | Jump branchAddPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest) |
461 | { | |
462 | addPtr(imm, dest); | |
463 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
464 | } | |
465 | ||
14957cd0 | 466 | Jump branchAddPtr(ResultCondition cond, RegisterID src, RegisterID dest) |
ba379fdc | 467 | { |
ba379fdc A |
468 | addPtr(src, dest); |
469 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
470 | } | |
471 | ||
14957cd0 | 472 | Jump branchSubPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest) |
ba379fdc | 473 | { |
ba379fdc A |
474 | subPtr(imm, dest); |
475 | return Jump(m_assembler.jCC(x86Condition(cond))); | |
476 | } | |
477 | ||
6fe7ccc8 A |
478 | Jump branchSubPtr(ResultCondition cond, RegisterID src1, TrustedImm32 src2, RegisterID dest) |
479 | { | |
480 | move(src1, dest); | |
481 | return branchSubPtr(cond, src2, dest); | |
482 | } | |
483 | ||
14957cd0 | 484 | DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest) |
ba379fdc A |
485 | { |
486 | m_assembler.movq_i64r(initialValue.asIntptr(), dest); | |
487 | return DataLabelPtr(this); | |
488 | } | |
489 | ||
14957cd0 | 490 | Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) |
ba379fdc A |
491 | { |
492 | dataLabel = moveWithPatch(initialRightValue, scratchRegister); | |
493 | return branchPtr(cond, left, scratchRegister); | |
494 | } | |
495 | ||
14957cd0 | 496 | Jump branchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) |
ba379fdc A |
497 | { |
498 | dataLabel = moveWithPatch(initialRightValue, scratchRegister); | |
499 | return branchPtr(cond, left, scratchRegister); | |
500 | } | |
501 | ||
14957cd0 | 502 | DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address) |
ba379fdc A |
503 | { |
504 | DataLabelPtr label = moveWithPatch(initialValue, scratchRegister); | |
505 | storePtr(scratchRegister, address); | |
506 | return label; | |
507 | } | |
508 | ||
4e4e5a6f | 509 | using MacroAssemblerX86Common::branchTest8; |
14957cd0 | 510 | Jump branchTest8(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1)) |
4e4e5a6f | 511 | { |
14957cd0 | 512 | TrustedImmPtr addr(reinterpret_cast<void*>(address.offset)); |
4e4e5a6f A |
513 | MacroAssemblerX86Common::move(addr, scratchRegister); |
514 | return MacroAssemblerX86Common::branchTest8(cond, BaseIndex(scratchRegister, address.base, TimesOne), mask); | |
515 | } | |
516 | ||
6fe7ccc8 | 517 | static bool supportsFloatingPoint() { return true; } |
ba379fdc | 518 | // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate() |
6fe7ccc8 A |
519 | static bool supportsFloatingPointTruncate() { return true; } |
520 | static bool supportsFloatingPointSqrt() { return true; } | |
521 | static bool supportsFloatingPointAbs() { return true; } | |
522 | ||
523 | static FunctionPtr readCallTarget(CodeLocationCall call) | |
524 | { | |
525 | return FunctionPtr(X86Assembler::readPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation())); | |
526 | } | |
527 | ||
528 | static RegisterID scratchRegisterForBlinding() { return scratchRegister; } | |
ba379fdc A |
529 | |
530 | private: | |
531 | friend class LinkBuffer; | |
532 | friend class RepatchBuffer; | |
533 | ||
534 | static void linkCall(void* code, Call call, FunctionPtr function) | |
535 | { | |
536 | if (!call.isFlagSet(Call::Near)) | |
6fe7ccc8 | 537 | X86Assembler::linkPointer(code, call.m_label.labelAtOffset(-REPTACH_OFFSET_CALL_R11), function.value()); |
ba379fdc | 538 | else |
6fe7ccc8 | 539 | X86Assembler::linkCall(code, call.m_label, function.value()); |
ba379fdc A |
540 | } |
541 | ||
542 | static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) | |
543 | { | |
544 | X86Assembler::repatchPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation(), destination.executableAddress()); | |
545 | } | |
546 | ||
547 | static void repatchCall(CodeLocationCall call, FunctionPtr destination) | |
548 | { | |
549 | X86Assembler::repatchPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation(), destination.executableAddress()); | |
550 | } | |
551 | ||
552 | }; | |
553 | ||
554 | } // namespace JSC | |
555 | ||
556 | #endif // ENABLE(ASSEMBLER) | |
557 | ||
558 | #endif // MacroAssemblerX86_64_h |