2 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #include "ThunkGenerators.h"
29 #include "CodeBlock.h"
30 #include <wtf/text/StringImpl.h>
31 #include "SpecializedThunkJIT.h"
37 static void stringCharLoad(SpecializedThunkJIT
& jit
)
40 jit
.loadJSStringArgument(SpecializedThunkJIT::ThisArgument
, SpecializedThunkJIT::regT0
);
41 // regT0 now contains this, and is a non-rope JSString*
43 // Load string length to regT2, and start the process of loading the data pointer into regT0
44 jit
.load32(MacroAssembler::Address(SpecializedThunkJIT::regT0
, ThunkHelpers::jsStringLengthOffset()), SpecializedThunkJIT::regT2
);
45 jit
.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0
, ThunkHelpers::jsStringValueOffset()), SpecializedThunkJIT::regT0
);
46 jit
.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0
, ThunkHelpers::stringImplDataOffset()), SpecializedThunkJIT::regT0
);
49 jit
.loadInt32Argument(0, SpecializedThunkJIT::regT1
); // regT1 contains the index
51 // Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large
52 jit
.appendFailure(jit
.branch32(MacroAssembler::AboveOrEqual
, SpecializedThunkJIT::regT1
, SpecializedThunkJIT::regT2
));
55 jit
.load16(MacroAssembler::BaseIndex(SpecializedThunkJIT::regT0
, SpecializedThunkJIT::regT1
, MacroAssembler::TimesTwo
, 0), SpecializedThunkJIT::regT0
);
58 static void charToString(SpecializedThunkJIT
& jit
, JSGlobalData
* globalData
, MacroAssembler::RegisterID src
, MacroAssembler::RegisterID dst
, MacroAssembler::RegisterID scratch
)
60 jit
.appendFailure(jit
.branch32(MacroAssembler::AboveOrEqual
, src
, MacroAssembler::Imm32(0x100)));
61 jit
.move(MacroAssembler::ImmPtr(globalData
->smallStrings
.singleCharacterStrings()), scratch
);
62 jit
.loadPtr(MacroAssembler::BaseIndex(scratch
, src
, MacroAssembler::ScalePtr
, 0), dst
);
63 jit
.appendFailure(jit
.branchTestPtr(MacroAssembler::Zero
, dst
));
66 PassRefPtr
<NativeExecutable
> charCodeAtThunkGenerator(JSGlobalData
* globalData
, ExecutablePool
* pool
)
68 SpecializedThunkJIT
jit(1, globalData
, pool
);
70 jit
.returnInt32(SpecializedThunkJIT::regT0
);
71 return jit
.finalize();
74 PassRefPtr
<NativeExecutable
> charAtThunkGenerator(JSGlobalData
* globalData
, ExecutablePool
* pool
)
76 SpecializedThunkJIT
jit(1, globalData
, pool
);
78 charToString(jit
, globalData
, SpecializedThunkJIT::regT0
, SpecializedThunkJIT::regT0
, SpecializedThunkJIT::regT1
);
79 jit
.returnJSCell(SpecializedThunkJIT::regT0
);
80 return jit
.finalize();
83 PassRefPtr
<NativeExecutable
> fromCharCodeThunkGenerator(JSGlobalData
* globalData
, ExecutablePool
* pool
)
85 SpecializedThunkJIT
jit(1, globalData
, pool
);
87 jit
.loadInt32Argument(0, SpecializedThunkJIT::regT0
);
88 charToString(jit
, globalData
, SpecializedThunkJIT::regT0
, SpecializedThunkJIT::regT0
, SpecializedThunkJIT::regT1
);
89 jit
.returnJSCell(SpecializedThunkJIT::regT0
);
90 return jit
.finalize();
93 PassRefPtr
<NativeExecutable
> sqrtThunkGenerator(JSGlobalData
* globalData
, ExecutablePool
* pool
)
95 #if USE(JSVALUE64) || USE(JSVALUE32_64)
96 SpecializedThunkJIT
jit(1, globalData
, pool
);
97 if (!jit
.supportsFloatingPointSqrt())
98 return globalData
->jitStubs
->ctiNativeCallThunk();
100 jit
.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::regT0
);
101 jit
.sqrtDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT0
);
102 jit
.returnDouble(SpecializedThunkJIT::fpRegT0
);
103 return jit
.finalize();
106 return globalData
->jitStubs
.ctiNativeCallThunk();
110 static const double oneConstant
= 1.0;
111 static const double negativeHalfConstant
= -0.5;
113 PassRefPtr
<NativeExecutable
> powThunkGenerator(JSGlobalData
* globalData
, ExecutablePool
* pool
)
115 #if USE(JSVALUE64) || USE(JSVALUE32_64)
116 SpecializedThunkJIT
jit(2, globalData
, pool
);
117 if (!jit
.supportsFloatingPoint())
118 return globalData
->jitStubs
->ctiNativeCallThunk();
120 jit
.loadDouble(&oneConstant
, SpecializedThunkJIT::fpRegT1
);
121 jit
.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::regT0
);
122 MacroAssembler::Jump nonIntExponent
;
123 jit
.loadInt32Argument(1, SpecializedThunkJIT::regT0
, nonIntExponent
);
124 jit
.appendFailure(jit
.branch32(MacroAssembler::LessThan
, SpecializedThunkJIT::regT0
, MacroAssembler::Imm32(0)));
126 MacroAssembler::Jump exponentIsZero
= jit
.branchTest32(MacroAssembler::Zero
, SpecializedThunkJIT::regT0
);
127 MacroAssembler::Label
startLoop(jit
.label());
129 MacroAssembler::Jump exponentIsEven
= jit
.branchTest32(MacroAssembler::Zero
, SpecializedThunkJIT::regT0
, MacroAssembler::Imm32(1));
130 jit
.mulDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT1
);
131 exponentIsEven
.link(&jit
);
132 jit
.mulDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT0
);
133 jit
.rshift32(MacroAssembler::Imm32(1), SpecializedThunkJIT::regT0
);
134 jit
.branchTest32(MacroAssembler::NonZero
, SpecializedThunkJIT::regT0
).linkTo(startLoop
, &jit
);
136 exponentIsZero
.link(&jit
);
137 jit
.returnDouble(SpecializedThunkJIT::fpRegT1
);
139 if (jit
.supportsFloatingPointSqrt()) {
140 nonIntExponent
.link(&jit
);
141 jit
.loadDouble(&negativeHalfConstant
, SpecializedThunkJIT::fpRegT3
);
142 jit
.loadDoubleArgument(1, SpecializedThunkJIT::fpRegT2
, SpecializedThunkJIT::regT0
);
143 jit
.appendFailure(jit
.branchDouble(MacroAssembler::DoubleLessThanOrEqual
, SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT1
));
144 jit
.appendFailure(jit
.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered
, SpecializedThunkJIT::fpRegT2
, SpecializedThunkJIT::fpRegT3
));
145 jit
.sqrtDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT0
);
146 jit
.divDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT1
);
147 jit
.returnDouble(SpecializedThunkJIT::fpRegT1
);
149 jit
.appendFailure(nonIntExponent
);
151 return jit
.finalize();
154 return globalData
->jitStubs
.ctiNativeCallThunk();
160 #endif // ENABLE(JIT)