Create a super rough prototype of B3
[WebKit-https.git] / Source / JavaScriptCore / b3 / air / AirCCallSpecial.cpp
1 /*
2  * Copyright (C) 2015 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 #include "config.h"
27 #include "AirCCallSpecial.h"
28
29 #if ENABLE(B3_JIT)
30
31 namespace JSC { namespace B3 { namespace Air {
32
33 CCallSpecial::CCallSpecial()
34 {
35     m_clobberedRegs = RegisterSet::allRegisters();
36     m_clobberedRegs.exclude(RegisterSet::stackRegisters());
37     m_clobberedRegs.exclude(RegisterSet::reservedHardwareRegisters());
38     m_clobberedRegs.exclude(RegisterSet::calleeSaveRegisters());
39 }
40
41 CCallSpecial::~CCallSpecial()
42 {
43 }
44
45 void CCallSpecial::forEachArg(Inst& inst, const ScopedLambda<Inst::EachArgCallback>& callback)
46 {
47     callback(inst.args[1], Arg::Use, Arg::GP);
48     
49     for (unsigned i = 2; i < inst.args.size(); ++i) {
50         // For the type, we can just query the arg's type. The arg will have a type, because we
51         // require these args to be argument registers.
52         callback(inst.args[i], Arg::Use, inst.args[i].type());
53     }
54 }
55
56 bool CCallSpecial::isValid(Inst& inst)
57 {
58     if (inst.args.size() < 2)
59         return false;
60
61     switch (inst.args[1].kind()) {
62     case Arg::Imm:
63         if (is32Bit())
64             break;
65         return false;
66     case Arg::Imm64:
67         if (is64Bit())
68             break;
69         return false;
70     case Arg::Tmp:
71     case Arg::Addr:
72     case Arg::Stack:
73     case Arg::CallArg:
74         break;
75     default:
76         return false;
77     }
78
79     if (!inst.args[1].isGP())
80         return false;
81
82     for (unsigned i = 2; i < inst.args.size(); ++i) {
83         if (!inst.args[i].isReg())
84             return false;
85
86         if (inst.args[i] == Tmp(scratchRegister))
87             return false;
88     }
89     return true;
90 }
91
92 bool CCallSpecial::admitsStack(Inst&, unsigned argIndex)
93 {
94     // Arg 1 can be a stack address for sure.
95     if (argIndex == 1)
96         return true;
97     
98     return false;
99 }
100
101 void CCallSpecial::reportUsedRegisters(Inst&, const RegisterSet&)
102 {
103 }
104
105 CCallHelpers::Jump CCallSpecial::generate(Inst& inst, CCallHelpers& jit, GenerationContext&)
106 {
107     switch (inst.args[1].kind()) {
108     case Arg::Imm:
109     case Arg::Imm64:
110         jit.move(inst.args[1].asTrustedImmPtr(), scratchRegister);
111         jit.call(scratchRegister);
112         break;
113     case Arg::Tmp:
114         jit.call(inst.args[1].gpr());
115         break;
116     case Arg::Addr:
117         jit.call(inst.args[1].asAddress());
118         break;
119     default:
120         RELEASE_ASSERT_NOT_REACHED();
121         break;
122     }
123     return CCallHelpers::Jump();
124 }
125
126 const RegisterSet& CCallSpecial::extraClobberedRegs(Inst&)
127 {
128     return m_clobberedRegs;
129 }
130
131 void CCallSpecial::dumpImpl(PrintStream& out) const
132 {
133     out.print("CCall");
134 }
135
136 void CCallSpecial::deepDumpImpl(PrintStream& out) const
137 {
138     out.print("function call that uses the C calling convention.");
139 }
140
141 } } } // namespace JSC::B3::Air
142
143 #endif // ENABLE(B3_JIT)