1 | /*
|
---|
2 | * Copyright (C) 2010, 2016 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. 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.
|
---|
24 | */
|
---|
25 |
|
---|
26 | #pragma once
|
---|
27 |
|
---|
28 | #include "BytecodeConventions.h"
|
---|
29 | #include "CCallHelpers.h"
|
---|
30 | #include "FPRInfo.h"
|
---|
31 | #include "GPRInfo.h"
|
---|
32 | #include "JSCJSValue.h"
|
---|
33 | #include "JSString.h"
|
---|
34 | #include "MacroAssembler.h"
|
---|
35 |
|
---|
36 | #if ENABLE(JIT)
|
---|
37 |
|
---|
38 | namespace JSC {
|
---|
39 | class JSInterfaceJIT : public CCallHelpers, public GPRInfo, public JSRInfo, public FPRInfo {
|
---|
40 | public:
|
---|
41 |
|
---|
42 | JSInterfaceJIT(VM* vm = nullptr, CodeBlock* codeBlock = nullptr)
|
---|
43 | : CCallHelpers(codeBlock)
|
---|
44 | , m_vm(vm)
|
---|
45 | {
|
---|
46 | }
|
---|
47 |
|
---|
48 | inline Jump emitLoadJSCell(VirtualRegister, RegisterID payload);
|
---|
49 | inline Jump emitLoadInt32(VirtualRegister, RegisterID dst);
|
---|
50 | inline Jump emitLoadDouble(VirtualRegister, FPRegisterID dst, RegisterID scratch);
|
---|
51 |
|
---|
52 | VM* vm() const { return m_vm; }
|
---|
53 |
|
---|
54 | VM* m_vm;
|
---|
55 | };
|
---|
56 |
|
---|
57 | #if USE(JSVALUE32_64)
|
---|
58 | inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(VirtualRegister virtualRegister, RegisterID payload)
|
---|
59 | {
|
---|
60 | ASSERT(virtualRegister < VirtualRegister(FirstConstantRegisterIndex));
|
---|
61 | loadPtr(payloadFor(virtualRegister), payload);
|
---|
62 | return branchIfNotCell(tagFor(virtualRegister));
|
---|
63 | }
|
---|
64 |
|
---|
65 | inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(VirtualRegister virtualRegister, RegisterID dst)
|
---|
66 | {
|
---|
67 | ASSERT(virtualRegister < VirtualRegister(FirstConstantRegisterIndex));
|
---|
68 | loadPtr(payloadFor(virtualRegister), dst);
|
---|
69 | return branch32(NotEqual, tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag));
|
---|
70 | }
|
---|
71 |
|
---|
72 | inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(VirtualRegister virtualRegister, FPRegisterID dst, RegisterID scratch)
|
---|
73 | {
|
---|
74 | ASSERT(virtualRegister < VirtualRegister(FirstConstantRegisterIndex));
|
---|
75 | loadPtr(tagFor(virtualRegister), scratch);
|
---|
76 | Jump isDouble = branch32(Below, scratch, TrustedImm32(JSValue::LowestTag));
|
---|
77 | Jump notInt = branch32(NotEqual, scratch, TrustedImm32(JSValue::Int32Tag));
|
---|
78 | loadPtr(payloadFor(virtualRegister), scratch);
|
---|
79 | convertInt32ToDouble(scratch, dst);
|
---|
80 | Jump done = jump();
|
---|
81 | isDouble.link(this);
|
---|
82 | loadDouble(addressFor(virtualRegister), dst);
|
---|
83 | done.link(this);
|
---|
84 | return notInt;
|
---|
85 | }
|
---|
86 | #elif USE(JSVALUE64)
|
---|
87 | inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(VirtualRegister virtualRegister, RegisterID dst)
|
---|
88 | {
|
---|
89 | load64(addressFor(virtualRegister), dst);
|
---|
90 | return branchIfNotCell(dst);
|
---|
91 | }
|
---|
92 |
|
---|
93 | inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(VirtualRegister virtualRegister, RegisterID dst)
|
---|
94 | {
|
---|
95 | load64(addressFor(virtualRegister), dst);
|
---|
96 | Jump notInt32 = branchIfNotInt32(dst);
|
---|
97 | zeroExtend32ToWord(dst, dst);
|
---|
98 | return notInt32;
|
---|
99 | }
|
---|
100 |
|
---|
101 | inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(VirtualRegister virtualRegister, FPRegisterID dst, RegisterID scratch)
|
---|
102 | {
|
---|
103 | load64(addressFor(virtualRegister), scratch);
|
---|
104 | Jump notNumber = branchIfNotNumber(scratch);
|
---|
105 | Jump notInt = branchIfNotInt32(scratch);
|
---|
106 | convertInt32ToDouble(scratch, dst);
|
---|
107 | Jump done = jump();
|
---|
108 | notInt.link(this);
|
---|
109 | unboxDouble(scratch, scratch, dst);
|
---|
110 | done.link(this);
|
---|
111 | return notNumber;
|
---|
112 | }
|
---|
113 | #endif
|
---|
114 |
|
---|
115 | } // namespace JSC
|
---|
116 |
|
---|
117 | #endif // ENABLE(JIT)
|
---|