]> git.saurik.com Git - apple/javascriptcore.git/blob - assembler/MacroAssemblerX86.h
JavaScriptCore-1097.13.tar.gz
[apple/javascriptcore.git] / assembler / MacroAssemblerX86.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 MacroAssemblerX86_h
27 #define MacroAssemblerX86_h
28
29 #if ENABLE(ASSEMBLER) && CPU(X86)
30
31 #include "MacroAssemblerX86Common.h"
32
33 namespace JSC {
34
35 class MacroAssemblerX86 : public MacroAssemblerX86Common {
36 public:
37 static const Scale ScalePtr = TimesFour;
38
39 using MacroAssemblerX86Common::add32;
40 using MacroAssemblerX86Common::and32;
41 using MacroAssemblerX86Common::branchAdd32;
42 using MacroAssemblerX86Common::branchSub32;
43 using MacroAssemblerX86Common::sub32;
44 using MacroAssemblerX86Common::or32;
45 using MacroAssemblerX86Common::load32;
46 using MacroAssemblerX86Common::store32;
47 using MacroAssemblerX86Common::branch32;
48 using MacroAssemblerX86Common::call;
49 using MacroAssemblerX86Common::jump;
50 using MacroAssemblerX86Common::addDouble;
51 using MacroAssemblerX86Common::loadDouble;
52 using MacroAssemblerX86Common::storeDouble;
53 using MacroAssemblerX86Common::convertInt32ToDouble;
54
55 void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
56 {
57 m_assembler.leal_mr(imm.m_value, src, dest);
58 }
59
60 void add32(TrustedImm32 imm, AbsoluteAddress address)
61 {
62 m_assembler.addl_im(imm.m_value, address.m_ptr);
63 }
64
65 void add64(TrustedImm32 imm, AbsoluteAddress address)
66 {
67 m_assembler.addl_im(imm.m_value, address.m_ptr);
68 m_assembler.adcl_im(imm.m_value >> 31, reinterpret_cast<const char*>(address.m_ptr) + sizeof(int32_t));
69 }
70
71 void and32(TrustedImm32 imm, AbsoluteAddress address)
72 {
73 m_assembler.andl_im(imm.m_value, address.m_ptr);
74 }
75
76 void or32(TrustedImm32 imm, AbsoluteAddress address)
77 {
78 m_assembler.orl_im(imm.m_value, address.m_ptr);
79 }
80
81 void sub32(TrustedImm32 imm, AbsoluteAddress address)
82 {
83 m_assembler.subl_im(imm.m_value, address.m_ptr);
84 }
85
86 void load32(const void* address, RegisterID dest)
87 {
88 m_assembler.movl_mr(address, dest);
89 }
90
91 void addDouble(AbsoluteAddress address, FPRegisterID dest)
92 {
93 m_assembler.addsd_mr(address.m_ptr, dest);
94 }
95
96 void storeDouble(FPRegisterID src, const void* address)
97 {
98 ASSERT(isSSE2Present());
99 m_assembler.movsd_rm(src, address);
100 }
101
102 void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
103 {
104 m_assembler.cvtsi2sd_mr(src.m_ptr, dest);
105 }
106
107 void store32(TrustedImm32 imm, void* address)
108 {
109 m_assembler.movl_i32m(imm.m_value, address);
110 }
111
112 void store32(RegisterID src, void* address)
113 {
114 m_assembler.movl_rm(src, address);
115 }
116
117 Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
118 {
119 m_assembler.addl_im(imm.m_value, dest.m_ptr);
120 return Jump(m_assembler.jCC(x86Condition(cond)));
121 }
122
123 Jump branchSub32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
124 {
125 m_assembler.subl_im(imm.m_value, dest.m_ptr);
126 return Jump(m_assembler.jCC(x86Condition(cond)));
127 }
128
129 Jump branch32(RelationalCondition cond, AbsoluteAddress left, RegisterID right)
130 {
131 m_assembler.cmpl_rm(right, left.m_ptr);
132 return Jump(m_assembler.jCC(x86Condition(cond)));
133 }
134
135 Jump branch32(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
136 {
137 m_assembler.cmpl_im(right.m_value, left.m_ptr);
138 return Jump(m_assembler.jCC(x86Condition(cond)));
139 }
140
141 Call call()
142 {
143 return Call(m_assembler.call(), Call::Linkable);
144 }
145
146 // Address is a memory location containing the address to jump to
147 void jump(AbsoluteAddress address)
148 {
149 m_assembler.jmp_m(address.m_ptr);
150 }
151
152 Call tailRecursiveCall()
153 {
154 return Call::fromTailJump(jump());
155 }
156
157 Call makeTailRecursiveCall(Jump oldJump)
158 {
159 return Call::fromTailJump(oldJump);
160 }
161
162
163 DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
164 {
165 m_assembler.movl_i32r(initialValue.asIntptr(), dest);
166 return DataLabelPtr(this);
167 }
168
169 Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
170 {
171 m_assembler.cmpl_ir_force32(initialRightValue.asIntptr(), left);
172 dataLabel = DataLabelPtr(this);
173 return Jump(m_assembler.jCC(x86Condition(cond)));
174 }
175
176 Jump branchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
177 {
178 m_assembler.cmpl_im_force32(initialRightValue.asIntptr(), left.offset, left.base);
179 dataLabel = DataLabelPtr(this);
180 return Jump(m_assembler.jCC(x86Condition(cond)));
181 }
182
183 DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
184 {
185 m_assembler.movl_i32m(initialValue.asIntptr(), address.offset, address.base);
186 return DataLabelPtr(this);
187 }
188
189 static bool supportsFloatingPoint() { return isSSE2Present(); }
190 // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
191 static bool supportsFloatingPointTruncate() { return isSSE2Present(); }
192 static bool supportsFloatingPointSqrt() { return isSSE2Present(); }
193 static bool supportsFloatingPointAbs() { return isSSE2Present(); }
194
195 static FunctionPtr readCallTarget(CodeLocationCall call)
196 {
197 intptr_t offset = reinterpret_cast<int32_t*>(call.dataLocation())[-1];
198 return FunctionPtr(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(call.dataLocation()) + offset));
199 }
200
201 private:
202 friend class LinkBuffer;
203 friend class RepatchBuffer;
204
205 static void linkCall(void* code, Call call, FunctionPtr function)
206 {
207 X86Assembler::linkCall(code, call.m_label, function.value());
208 }
209
210 static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
211 {
212 X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
213 }
214
215 static void repatchCall(CodeLocationCall call, FunctionPtr destination)
216 {
217 X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
218 }
219 };
220
221 } // namespace JSC
222
223 #endif // ENABLE(ASSEMBLER)
224
225 #endif // MacroAssemblerX86_h