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 MacroAssemblerX86() 38 : m_isSSE2Present(isSSE2Present()) 39 { 40 } 41 42 static const Scale ScalePtr = TimesFour; 43 44 using MacroAssemblerX86Common::add32; 45 using MacroAssemblerX86Common::and32; 46 using MacroAssemblerX86Common::sub32; 47 using MacroAssemblerX86Common::or32; 48 using MacroAssemblerX86Common::load32; 49 using MacroAssemblerX86Common::store32; 50 using MacroAssemblerX86Common::branch32; 51 using MacroAssemblerX86Common::call; 52 using MacroAssemblerX86Common::loadDouble; 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 addWithCarry32(TrustedImm32 imm, AbsoluteAddress address) 66 { 67 m_assembler.adcl_im(imm.m_value, address.m_ptr); 68 } 69 70 void and32(TrustedImm32 imm, AbsoluteAddress address) 71 { 72 m_assembler.andl_im(imm.m_value, address.m_ptr); 73 } 74 75 void or32(TrustedImm32 imm, AbsoluteAddress address) 76 { 77 m_assembler.orl_im(imm.m_value, address.m_ptr); 78 } 79 80 void sub32(TrustedImm32 imm, AbsoluteAddress address) 81 { 82 m_assembler.subl_im(imm.m_value, address.m_ptr); 83 } 84 85 void load32(void* address, RegisterID dest) 86 { 87 m_assembler.movl_mr(address, dest); 88 } 89 90 void loadDouble(const void* address, FPRegisterID dest) 91 { 92 ASSERT(isSSE2Present()); 93 m_assembler.movsd_mr(address, dest); 94 } 95 96 void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest) 97 { 98 m_assembler.cvtsi2sd_mr(src.m_ptr, dest); 99 } 100 101 void store32(TrustedImm32 imm, void* address) 102 { 103 m_assembler.movl_i32m(imm.m_value, address); 104 } 105 106 void store32(RegisterID src, void* address) 107 { 108 m_assembler.movl_rm(src, address); 109 } 110 111 Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right) 112 { 113 m_assembler.cmpl_rm(right, left.m_ptr); 114 return Jump(m_assembler.jCC(x86Condition(cond))); 115 } 116 117 Jump branch32(Condition cond, AbsoluteAddress left, TrustedImm32 right) 118 { 119 m_assembler.cmpl_im(right.m_value, left.m_ptr); 120 return Jump(m_assembler.jCC(x86Condition(cond))); 121 } 122 123 Call call() 124 { 125 return Call(m_assembler.call(), Call::Linkable); 126 } 127 128 Call tailRecursiveCall() 129 { 130 return Call::fromTailJump(jump()); 131 } 132 133 Call makeTailRecursiveCall(Jump oldJump) 134 { 135 return Call::fromTailJump(oldJump); 136 } 137 138 139 DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest) 140 { 141 m_assembler.movl_i32r(initialValue.asIntptr(), dest); 142 return DataLabelPtr(this); 143 } 144 145 Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) 146 { 147 m_assembler.cmpl_ir_force32(initialRightValue.asIntptr(), left); 148 dataLabel = DataLabelPtr(this); 149 return Jump(m_assembler.jCC(x86Condition(cond))); 150 } 151 152 Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) 153 { 154 m_assembler.cmpl_im_force32(initialRightValue.asIntptr(), left.offset, left.base); 155 dataLabel = DataLabelPtr(this); 156 return Jump(m_assembler.jCC(x86Condition(cond))); 157 } 158 159 DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address) 160 { 161 m_assembler.movl_i32m(initialValue.asIntptr(), address.offset, address.base); 162 return DataLabelPtr(this); 163 } 164 165 bool supportsFloatingPoint() const { return m_isSSE2Present; } 166 // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate() 167 bool supportsFloatingPointTruncate() const { return m_isSSE2Present; } 168 bool supportsFloatingPointSqrt() const { return m_isSSE2Present; } 169 170 private: 171 const bool m_isSSE2Present; 172 173 friend class LinkBuffer; 174 friend class RepatchBuffer; 175 176 static void linkCall(void* code, Call call, FunctionPtr function) 177 { 178 X86Assembler::linkCall(code, call.m_jmp, function.value()); 179 } 180 181 static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) 182 { 183 X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); 184 } 185 186 static void repatchCall(CodeLocationCall call, FunctionPtr destination) 187 { 188 X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); 189 } 190 }; 191 192 } // namespace JSC 193 194 #endif // ENABLE(ASSEMBLER) 195 196 #endif // MacroAssemblerX86_h 197