1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sw=4 et tw=79:
4 * ***** BEGIN LICENSE BLOCK *****
5 * Copyright (C) 2008 Apple Inc. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
28 * ***** END LICENSE BLOCK ***** */
30 #ifndef MacroAssemblerX86_h
31 #define MacroAssemblerX86_h
33 #include "assembler/wtf/Platform.h"
35 #if ENABLE_ASSEMBLER && WTF_CPU_X86
37 #include "MacroAssemblerX86Common.h"
41 class MacroAssemblerX86 : public MacroAssemblerX86Common {
44 : m_isSSE2Present(isSSE2Present())
48 static const Scale ScalePtr = TimesFour;
49 static const unsigned int TotalRegisters = 8;
51 using MacroAssemblerX86Common::add32;
52 using MacroAssemblerX86Common::and32;
53 using MacroAssemblerX86Common::sub32;
54 using MacroAssemblerX86Common::or32;
55 using MacroAssemblerX86Common::load32;
56 using MacroAssemblerX86Common::store32;
57 using MacroAssemblerX86Common::branch32;
58 using MacroAssemblerX86Common::call;
59 using MacroAssemblerX86Common::loadDouble;
60 using MacroAssemblerX86Common::storeDouble;
61 using MacroAssemblerX86Common::convertInt32ToDouble;
63 void add32(Imm32 imm, RegisterID src, RegisterID dest)
65 m_assembler.leal_mr(imm.m_value, src, dest);
68 void lea(Address address, RegisterID dest)
70 m_assembler.leal_mr(address.offset, address.base, dest);
73 void lea(BaseIndex address, RegisterID dest)
75 m_assembler.leal_mr(address.offset, address.base, address.index, address.scale, dest);
78 void add32(Imm32 imm, AbsoluteAddress address)
80 m_assembler.addl_im(imm.m_value, address.m_ptr);
83 void addWithCarry32(Imm32 imm, AbsoluteAddress address)
85 m_assembler.adcl_im(imm.m_value, address.m_ptr);
88 void and32(Imm32 imm, AbsoluteAddress address)
90 m_assembler.andl_im(imm.m_value, address.m_ptr);
93 void or32(Imm32 imm, AbsoluteAddress address)
95 m_assembler.orl_im(imm.m_value, address.m_ptr);
98 void sub32(Imm32 imm, AbsoluteAddress address)
100 m_assembler.subl_im(imm.m_value, address.m_ptr);
103 void load32(void* address, RegisterID dest)
105 m_assembler.movl_mr(address, dest);
108 void storeDouble(ImmDouble imm, Address address)
110 store32(Imm32(imm.u.s.lsb), address);
111 store32(Imm32(imm.u.s.msb), Address(address.base, address.offset + 4));
114 void storeDouble(ImmDouble imm, BaseIndex address)
116 store32(Imm32(imm.u.s.lsb), address);
117 store32(Imm32(imm.u.s.msb),
118 BaseIndex(address.base, address.index, address.scale, address.offset + 4));
121 DataLabelPtr loadDouble(const void* address, FPRegisterID dest)
123 ASSERT(isSSE2Present());
124 m_assembler.movsd_mr(address, dest);
125 return DataLabelPtr(this);
128 void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
130 m_assembler.cvtsi2sd_mr(src.m_ptr, dest);
133 void convertUInt32ToDouble(RegisterID srcDest, FPRegisterID dest)
135 // Trick is from nanojit/Nativei386.cpp, asm_ui2d.
136 static const double NegativeOne = 2147483648.0;
138 // src is [0, 2^32-1]
139 sub32(Imm32(0x80000000), srcDest);
141 // Now src is [-2^31, 2^31-1] - int range, but not the same value.
143 convertInt32ToDouble(srcDest, dest);
145 // dest is now a double with the int range.
146 // correct the double value by adding (0x80000000).
147 move(ImmPtr(&NegativeOne), srcDest);
148 addDouble(Address(srcDest), dest);
151 void store32(Imm32 imm, void* address)
153 m_assembler.movl_i32m(imm.m_value, address);
156 void store32(RegisterID src, void* address)
158 m_assembler.movl_rm(src, address);
161 Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right)
163 m_assembler.cmpl_rm(right, left.m_ptr);
164 return Jump(m_assembler.jCC(x86Condition(cond)));
167 Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right)
169 m_assembler.cmpl_im(right.m_value, left.m_ptr);
170 return Jump(m_assembler.jCC(x86Condition(cond)));
175 return Call(m_assembler.call(), Call::Linkable);
178 Call tailRecursiveCall()
180 return Call::fromTailJump(jump());
183 Call makeTailRecursiveCall(Jump oldJump)
185 return Call::fromTailJump(oldJump);
189 DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
191 m_assembler.movl_i32r(initialValue.asIntptr(), dest);
192 return DataLabelPtr(this);
195 Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
197 m_assembler.cmpl_ir_force32(initialRightValue.asIntptr(), left);
198 dataLabel = DataLabelPtr(this);
199 return Jump(m_assembler.jCC(x86Condition(cond)));
202 Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
204 m_assembler.cmpl_im_force32(initialRightValue.asIntptr(), left.offset, left.base);
205 dataLabel = DataLabelPtr(this);
206 return Jump(m_assembler.jCC(x86Condition(cond)));
209 DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
211 m_assembler.movl_i32m(initialValue.asIntptr(), address.offset, address.base);
212 return DataLabelPtr(this);
215 Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
218 load32(address, dest);
232 bool supportsFloatingPoint() const { return m_isSSE2Present; }
233 // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
234 bool supportsFloatingPointTruncate() const { return m_isSSE2Present; }
235 bool supportsFloatingPointSqrt() const { return m_isSSE2Present; }
238 const bool m_isSSE2Present;
240 friend class LinkBuffer;
241 friend class RepatchBuffer;
243 static void linkCall(void* code, Call call, FunctionPtr function)
245 X86Assembler::linkCall(code, call.m_jmp, function.value());
248 static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
250 X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
253 static void repatchCall(CodeLocationCall call, FunctionPtr destination)
255 X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
261 #endif // ENABLE(ASSEMBLER)
263 #endif // MacroAssemblerX86_h