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