• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/compiler/lcr_circuit_builder.h"
17 #include "ecmascript/compiler/common_stubs.h"
18 
19 namespace panda::ecmascript::kungfu {
20 
BinaryCmp(const GateMetaData * meta,GateRef left,GateRef right,const char * comment)21 GateRef CircuitBuilder::BinaryCmp(const GateMetaData* meta, GateRef left, GateRef right, const char* comment)
22 {
23     return GetCircuit()->NewGate(meta, MachineType::I1, { left, right }, GateType::NJSValue(), comment);
24 }
25 
GetMachineTypeFromVariableType(VariableType type)26 MachineType CircuitBuilder::GetMachineTypeFromVariableType(VariableType type)
27 {
28     return type.GetMachineType();
29 }
30 
Sqrt(GateRef param)31 GateRef CircuitBuilder::Sqrt(GateRef param)
32 {
33     return GetCircuit()->NewGate(circuit_->Sqrt(), MachineType::F64, {param}, GateType::DoubleType());
34 }
35 
AddWithOverflow(GateRef left,GateRef right)36 GateRef CircuitBuilder::AddWithOverflow(GateRef left, GateRef right)
37 {
38     return GetCircuit()->NewGate(circuit_->AddWithOverflow(), MachineType::I64, {left, right}, GateType::AnyType());
39 }
40 
SubWithOverflow(GateRef left,GateRef right)41 GateRef CircuitBuilder::SubWithOverflow(GateRef left, GateRef right)
42 {
43     return GetCircuit()->NewGate(circuit_->SubWithOverflow(), MachineType::I64, {left, right}, GateType::AnyType());
44 }
45 
MulWithOverflow(GateRef left,GateRef right)46 GateRef CircuitBuilder::MulWithOverflow(GateRef left, GateRef right)
47 {
48     return GetCircuit()->NewGate(circuit_->MulWithOverflow(), MachineType::I64, {left, right}, GateType::AnyType());
49 }
50 
ExtractValue(MachineType mt,GateRef pointer,GateRef index)51 GateRef CircuitBuilder::ExtractValue(MachineType mt, GateRef pointer, GateRef index)
52 {
53     ASSERT(acc_.GetOpCode(index) == OpCode::CONSTANT);
54     ASSERT(acc_.GetMachineType(index) == MachineType::I32);
55     return GetCircuit()->NewGate(circuit_->ExtractValue(), mt, {pointer, index}, GateType::NJSValue());
56 }
57 
ReadSp()58 GateRef CircuitBuilder::ReadSp()
59 {
60     return circuit_->NewGate(circuit_->ReadSp(), MachineType::I64, GateType::NJSValue());
61 }
62 
GetMachineTypeOfValueType(ValueType type)63 MachineType CircuitBuilder::GetMachineTypeOfValueType(ValueType type)
64 {
65     switch (type) {
66         case ValueType::BOOL:
67             return MachineType::I1;
68         case ValueType::INT32:
69             return MachineType::I32;
70         case ValueType::FLOAT64:
71             return MachineType::F64;
72         case ValueType::TAGGED_BOOLEAN:
73         case ValueType::TAGGED_INT:
74         case ValueType::TAGGED_DOUBLE:
75         case ValueType::TAGGED_NUMBER:
76             return MachineType::I64;
77         default:
78             return MachineType::NOVALUE;
79     }
80 }
81 
BinaryArithmetic(const GateMetaData * meta,MachineType machineType,GateRef left,GateRef right,GateType gateType,const char * comment)82 GateRef CircuitBuilder::BinaryArithmetic(const GateMetaData* meta, MachineType machineType,
83                                          GateRef left, GateRef right, GateType gateType, const char* comment)
84 {
85     auto circuit = GetCircuit();
86     if (gateType == GateType::Empty()) {
87         gateType = acc_.GetGateType(left);
88     }
89     return circuit->NewGate(meta, machineType, { left, right }, gateType, comment);
90 }
91 
Alloca(size_t size)92 GateRef CircuitBuilder::Alloca(size_t size)
93 {
94     return GetCircuit()->NewGate(circuit_->Alloca(size), MachineType::ARCH, GateType::NJSValue());
95 }
96 
StoreWithNoBarrier(VariableType type,GateRef base,GateRef offset,GateRef value,MemoryOrder order)97 void CircuitBuilder::StoreWithNoBarrier(VariableType type, GateRef base, GateRef offset, GateRef value,
98     MemoryOrder order)
99 {
100     auto label = GetCurrentLabel();
101     auto depend = label->GetDepend();
102     GateRef ptr = PtrAdd(base, offset);
103     auto bit = LoadStoreAccessor::ToValue(order);
104     GateRef result = GetCircuit()->NewGate(circuit_->Store(bit),
105         MachineType::NOVALUE, { depend, value, ptr }, type.GetGateType());
106     label->SetDepend(result);
107 }
108 
109 // memory
Store(VariableType type,GateRef glue,GateRef base,GateRef offset,GateRef value,MemoryOrder order)110 void CircuitBuilder::Store(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef value,
111     MemoryOrder order)
112 {
113     StoreWithNoBarrier(type, base, offset, value, order);
114     if (type == VariableType::JS_POINTER() || type == VariableType::JS_ANY()) {
115         Label entry(env_);
116         SubCfgEntry(&entry);
117         Label exit(env_);
118         Label isHeapObject(env_);
119         Branch(TaggedIsHeapObject(value), &isHeapObject, &exit);
120         Bind(&isHeapObject);
121         {
122             CallStub(glue, base, CommonStubCSigns::SetValueWithBarrier, { glue, base, offset, value });
123             Jump(&exit);
124         }
125         Bind(&exit);
126         SubCfgExit();
127     }
128 }
129 
130 // memory
Load(VariableType type,GateRef base,GateRef offset,MemoryOrder order)131 GateRef CircuitBuilder::Load(VariableType type, GateRef base, GateRef offset, MemoryOrder order)
132 {
133     auto label = GetCurrentLabel();
134     auto depend = label->GetDepend();
135     GateRef val = PtrAdd(base, offset);
136     auto bits = LoadStoreAccessor::ToValue(order);
137     GateRef result = GetCircuit()->NewGate(GetCircuit()->Load(bits), type.GetMachineType(),
138                                            { depend, val }, type.GetGateType());
139     label->SetDepend(result);
140     return result;
141 }
142 
Load(VariableType type,GateRef base,GateRef offset,GateRef depend,MemoryOrder order)143 GateRef CircuitBuilder::Load(VariableType type, GateRef base, GateRef offset, GateRef depend,
144     MemoryOrder order)
145 {
146     GateRef val = PtrAdd(base, offset);
147     auto bits = LoadStoreAccessor::ToValue(order);
148     GateRef result = GetCircuit()->NewGate(GetCircuit()->Load(bits), type.GetMachineType(),
149                                            { depend, val }, type.GetGateType());
150     return result;
151 }
152 }
153