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::TrustedImm32(0x100)));
61 jit
.move(MacroAssembler::TrustedImmPtr(globalData
->smallStrings
.singleCharacterStrings()), scratch
);
62 jit
.loadPtr(MacroAssembler::BaseIndex(scratch
, src
, MacroAssembler::ScalePtr
, 0), dst
);
63 jit
.appendFailure(jit
.branchTestPtr(MacroAssembler::Zero
, dst
));
66 MacroAssemblerCodePtr
charCodeAtThunkGenerator(JSGlobalData
* globalData
, ExecutablePool
* pool
)
68 SpecializedThunkJIT
jit(1, globalData
, pool
);
70 jit
.returnInt32(SpecializedThunkJIT::regT0
);
71 return jit
.finalize(*globalData
, globalData
->jitStubs
->ctiNativeCall());
74 MacroAssemblerCodePtr
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(*globalData
, globalData
->jitStubs
->ctiNativeCall());
83 MacroAssemblerCodePtr
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(*globalData
, globalData
->jitStubs
->ctiNativeCall());
93 MacroAssemblerCodePtr
sqrtThunkGenerator(JSGlobalData
* globalData
, ExecutablePool
* pool
)
95 SpecializedThunkJIT
jit(1, globalData
, pool
);
96 if (!jit
.supportsFloatingPointSqrt())
97 return globalData
->jitStubs
->ctiNativeCall();
99 jit
.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::regT0
);
100 jit
.sqrtDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT0
);
101 jit
.returnDouble(SpecializedThunkJIT::fpRegT0
);
102 return jit
.finalize(*globalData
, globalData
->jitStubs
->ctiNativeCall());
105 static const double oneConstant
= 1.0;
106 static const double negativeHalfConstant
= -0.5;
108 MacroAssemblerCodePtr
powThunkGenerator(JSGlobalData
* globalData
, ExecutablePool
* pool
)
110 SpecializedThunkJIT
jit(2, globalData
, pool
);
111 if (!jit
.supportsFloatingPoint())
112 return globalData
->jitStubs
->ctiNativeCall();
114 jit
.loadDouble(&oneConstant
, SpecializedThunkJIT::fpRegT1
);
115 jit
.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::regT0
);
116 MacroAssembler::Jump nonIntExponent
;
117 jit
.loadInt32Argument(1, SpecializedThunkJIT::regT0
, nonIntExponent
);
118 jit
.appendFailure(jit
.branch32(MacroAssembler::LessThan
, SpecializedThunkJIT::regT0
, MacroAssembler::TrustedImm32(0)));
120 MacroAssembler::Jump exponentIsZero
= jit
.branchTest32(MacroAssembler::Zero
, SpecializedThunkJIT::regT0
);
121 MacroAssembler::Label
startLoop(jit
.label());
123 MacroAssembler::Jump exponentIsEven
= jit
.branchTest32(MacroAssembler::Zero
, SpecializedThunkJIT::regT0
, MacroAssembler::TrustedImm32(1));
124 jit
.mulDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT1
);
125 exponentIsEven
.link(&jit
);
126 jit
.mulDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT0
);
127 jit
.rshift32(MacroAssembler::TrustedImm32(1), SpecializedThunkJIT::regT0
);
128 jit
.branchTest32(MacroAssembler::NonZero
, SpecializedThunkJIT::regT0
).linkTo(startLoop
, &jit
);
130 exponentIsZero
.link(&jit
);
133 SpecializedThunkJIT::JumpList doubleResult
;
134 jit
.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT1
, SpecializedThunkJIT::regT0
, doubleResult
, SpecializedThunkJIT::fpRegT0
);
135 jit
.returnInt32(SpecializedThunkJIT::regT0
);
136 doubleResult
.link(&jit
);
137 jit
.returnDouble(SpecializedThunkJIT::fpRegT1
);
140 if (jit
.supportsFloatingPointSqrt()) {
141 nonIntExponent
.link(&jit
);
142 jit
.loadDouble(&negativeHalfConstant
, SpecializedThunkJIT::fpRegT3
);
143 jit
.loadDoubleArgument(1, SpecializedThunkJIT::fpRegT2
, SpecializedThunkJIT::regT0
);
144 jit
.appendFailure(jit
.branchDouble(MacroAssembler::DoubleLessThanOrEqual
, SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT1
));
145 jit
.appendFailure(jit
.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered
, SpecializedThunkJIT::fpRegT2
, SpecializedThunkJIT::fpRegT3
));
146 jit
.sqrtDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT0
);
147 jit
.divDouble(SpecializedThunkJIT::fpRegT0
, SpecializedThunkJIT::fpRegT1
);
149 SpecializedThunkJIT::JumpList doubleResult
;
150 jit
.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT1
, SpecializedThunkJIT::regT0
, doubleResult
, SpecializedThunkJIT::fpRegT0
);
151 jit
.returnInt32(SpecializedThunkJIT::regT0
);
152 doubleResult
.link(&jit
);
153 jit
.returnDouble(SpecializedThunkJIT::fpRegT1
);
155 jit
.appendFailure(nonIntExponent
);
157 return jit
.finalize(*globalData
, globalData
->jitStubs
->ctiNativeCall());
162 #endif // ENABLE(JIT)