1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5intrinsic %FromConstexpr<To: type, From: type>(b: From): To;
6macro FromConstexpr<To: type, From: type>(o: From): To;
7FromConstexpr<int31, constexpr int31>(i: constexpr int31): int31 {
8  return %FromConstexpr<int31>(i);
9}
10FromConstexpr<int32, constexpr int31>(i: constexpr int31): int32 {
11  return %FromConstexpr<int32>(i);
12}
13FromConstexpr<int32, constexpr int32>(i: constexpr int32): int32 {
14  return %FromConstexpr<int32>(i);
15}
16FromConstexpr<intptr, constexpr int31>(i: constexpr int31): intptr {
17  return %FromConstexpr<intptr>(i);
18}
19FromConstexpr<intptr, constexpr int32>(i: constexpr int32): intptr {
20  return %FromConstexpr<intptr>(i);
21}
22FromConstexpr<intptr, constexpr intptr>(i: constexpr intptr): intptr {
23  return %FromConstexpr<intptr>(i);
24}
25FromConstexpr<uintptr, constexpr uintptr>(i: constexpr uintptr): uintptr {
26  return %FromConstexpr<uintptr>(i);
27}
28FromConstexpr<Smi, constexpr int31>(i: constexpr int31): Smi {
29  return %FromConstexpr<Smi>(i);
30}
31FromConstexpr<PositiveSmi, constexpr int31>(i: constexpr int31): PositiveSmi {
32  dcheck(i >= 0);
33  return %FromConstexpr<PositiveSmi>(i);
34}
35FromConstexpr<String, constexpr string>(s: constexpr string): String {
36  return %FromConstexpr<String>(s);
37}
38FromConstexpr<Number, constexpr uint32>(i: constexpr uint32): Number {
39  return %FromConstexpr<Number>(i);
40}
41FromConstexpr<Number, constexpr int32>(i: constexpr int32): Number {
42  return %FromConstexpr<Number>(i);
43}
44FromConstexpr<Number, constexpr float64>(f: constexpr float64): Number {
45  return %FromConstexpr<Number>(f);
46}
47FromConstexpr<Number, constexpr int31>(i: constexpr int31): Number {
48  return %FromConstexpr<Number>(i);
49}
50FromConstexpr<uint8, constexpr int31>(i: constexpr int31): uint8 {
51  const i: uint32 = i;
52  static_assert(i <= 255);
53  return %RawDownCast<uint8>(i);
54}
55FromConstexpr<int8, constexpr int31>(i: constexpr int31): int8 {
56  const i: int32 = i;
57  static_assert(-128 <= i && i <= 127);
58  return %RawDownCast<int8>(i);
59}
60FromConstexpr<char8, constexpr int31>(i: constexpr int31): char8 {
61  return %RawDownCast<char8>(FromConstexpr<uint8>(i));
62}
63FromConstexpr<Number, constexpr Smi>(s: constexpr Smi): Number {
64  return SmiConstant(s);
65}
66FromConstexpr<Smi, constexpr Smi>(s: constexpr Smi): Smi {
67  return SmiConstant(s);
68}
69FromConstexpr<uint32, constexpr int31>(i: constexpr int31): uint32 {
70  return Unsigned(Int32Constant(i));
71}
72FromConstexpr<uint8, constexpr uint8>(i: constexpr uint8): uint8 {
73  const i: uint32 = i;
74  return %RawDownCast<uint8>(i);
75}
76FromConstexpr<uint32, constexpr uint32>(i: constexpr uint32): uint32 {
77  return Unsigned(%FromConstexpr<int32>(i));
78}
79FromConstexpr<uint64, constexpr uint64>(i: constexpr uint64): uint64 {
80  return Uint64Constant(i);
81}
82FromConstexpr<uint64, constexpr int31>(i: constexpr int31): uint64 {
83  return Convert<uint64>(Unsigned(Int32Constant(i)));
84}
85FromConstexpr<uintptr, constexpr int31>(i: constexpr int31): uintptr {
86  return ChangeUint32ToWord(i);
87}
88FromConstexpr<float64, constexpr int31>(i: constexpr int31): float64 {
89  return Float64Constant(i);
90}
91FromConstexpr<float64, constexpr float64>(i: constexpr float64): float64 {
92  return Float64Constant(i);
93}
94FromConstexpr<bool, constexpr bool>(b: constexpr bool): bool {
95  return BoolConstant(b);
96}
97FromConstexpr<Object, constexpr string>(s: constexpr string): Object {
98  return StringConstant(s);
99}
100FromConstexpr<JSAny, constexpr string>(s: constexpr string): JSAny {
101  return StringConstant(s);
102}
103FromConstexpr<ContextSlot, constexpr ContextSlot>(c: constexpr ContextSlot):
104    ContextSlot {
105  return IntPtrConstant(c);
106}
107FromConstexpr<LanguageModeSmi, constexpr LanguageMode>(
108    c: constexpr LanguageMode): LanguageModeSmi {
109  return %RawDownCast<LanguageModeSmi>(SmiConstant(c));
110}
111FromConstexpr<PromiseState, constexpr PromiseState>(c: constexpr PromiseState):
112    PromiseState {
113  return %RawDownCast<PromiseState>(Int32Constant(c));
114}
115FromConstexpr<InstanceType, constexpr InstanceType>(c: constexpr InstanceType):
116    InstanceType {
117  return %RawDownCast<InstanceType>(Uint16Constant(c));
118}
119
120FromConstexpr<IterationKind, constexpr IterationKind>(
121    c: constexpr IterationKind): IterationKind {
122  return %RawDownCast<IterationKind>(Unsigned(%FromConstexpr<int32>(c)));
123}
124
125FromConstexpr<string::TrimMode, string::constexpr TrimMode>(
126    c: string::constexpr TrimMode): string::TrimMode {
127  return %RawDownCast<string::TrimMode>(Unsigned(%FromConstexpr<int32>(c)));
128}
129
130macro Convert<To: type, From: type>(i: From): To {
131  return i;
132}
133
134macro Convert<To: type, From: type>(i: From): To labels Overflow {
135  return i;
136}
137
138Convert<Boolean, bool>(b: bool): Boolean {
139  return b ? True : False;
140}
141Convert<int32, bool>(b: bool): int32 {
142  return ChangeBoolToInt32(b);
143}
144Convert<Number, int32>(i: int32): Number {
145  return ChangeInt32ToTagged(i);
146}
147Convert<intptr, int32>(i: int32): intptr {
148  return ChangeInt32ToIntPtr(i);
149}
150Convert<intptr, int31>(i: int31): intptr {
151  return ChangeInt32ToIntPtr(i);
152}
153Convert<intptr, uint32>(i: uint32): intptr {
154  return Signed(ChangeUint32ToWord(i));
155}
156Convert<Smi, int32>(i: int32): Smi {
157  return SmiFromInt32(i);
158}
159Convert<Number, uint32>(ui: uint32): Number {
160  return ChangeUint32ToTagged(ui);
161}
162Convert<Smi, uint32>(ui: uint32): Smi {
163  return SmiFromUint32(ui);
164}
165Convert<uintptr, uint32>(ui: uint32): uintptr {
166  return ChangeUint32ToWord(ui);
167}
168Convert<uint64, uint32>(ui: uint32): uint64 {
169  return ChangeUint32ToUint64(ui);
170}
171Convert<intptr, uint16>(ui: uint16): intptr {
172  return Signed(ChangeUint32ToWord(ui));
173}
174Convert<intptr, uint8>(ui: uint8): intptr {
175  return Signed(ChangeUint32ToWord(ui));
176}
177Convert<uint8, intptr>(i: intptr): uint8 {
178  return %RawDownCast<uint8>(Unsigned(TruncateIntPtrToInt32(i)) & 0xFF);
179}
180Convert<int8, intptr>(i: intptr): int8 {
181  return %RawDownCast<int8>(TruncateIntPtrToInt32(i) << 24 >> 24);
182}
183Convert<uint16, uint32>(i: uint32): uint16 {
184  return %RawDownCast<uint16>(i & 0xFFFF);
185}
186Convert<int32, uint8>(i: uint8): int32 {
187  return Signed(Convert<uint32>(i));
188}
189Convert<int32, uint16>(i: uint16): int32 {
190  return Signed(Convert<uint32>(i));
191}
192Convert<int32, char16|char8>(i: char16|char8): int32 {
193  return Signed(Convert<uint32>(i));
194}
195Convert<int32, uint31>(i: uint31): int32 {
196  return Signed(Convert<uint32>(i));
197}
198Convert<int32, intptr>(i: intptr): int32 {
199  return TruncateIntPtrToInt32(i);
200}
201Convert<int32, int64>(i: int64): int32 {
202  return TruncateInt64ToInt32(i);
203}
204Convert<int32, Number>(n: Number): int32 {
205  typeswitch (n) {
206    case (s: Smi): {
207      return Convert<int32>(s);
208    }
209    case (h: HeapNumber): {
210      return TruncateHeapNumberValueToWord32(h);
211    }
212  }
213}
214
215Convert<Smi, intptr>(i: intptr): Smi {
216  return SmiTag(i);
217}
218Convert<uint32, uintptr>(ui: uintptr): uint32 {
219  return Unsigned(TruncateIntPtrToInt32(Signed(ui)));
220}
221Convert<intptr, Smi>(s: Smi): intptr {
222  return SmiUntag(s);
223}
224Convert<uintptr, PositiveSmi>(ps: PositiveSmi): uintptr {
225  return Unsigned(SmiUntag(ps));
226}
227Convert<intptr, TaggedIndex>(ti: TaggedIndex): intptr {
228  return TaggedIndexToIntPtr(ti);
229}
230Convert<TaggedIndex, intptr>(i: intptr): TaggedIndex {
231  return IntPtrToTaggedIndex(i);
232}
233Convert<intptr, uintptr>(ui: uintptr): intptr {
234  const i = Signed(ui);
235  dcheck(i >= 0);
236  return i;
237}
238Convert<PositiveSmi, intptr>(i: intptr): PositiveSmi {
239  dcheck(IsValidPositiveSmi(i));
240  return %RawDownCast<PositiveSmi>(SmiTag(i));
241}
242Convert<PositiveSmi, uintptr>(ui: uintptr): PositiveSmi labels IfOverflow {
243  if (ui > kSmiMaxValue) deferred {
244      goto IfOverflow;
245    }
246  return %RawDownCast<PositiveSmi>(SmiTag(Signed(ui)));
247}
248Convert<PositiveSmi, intptr>(i: intptr): PositiveSmi labels IfOverflow {
249  if (IsValidPositiveSmi(i)) {
250    return %RawDownCast<PositiveSmi>(SmiTag(i));
251  } else
252    deferred {
253      goto IfOverflow;
254    }
255}
256Convert<PositiveSmi, uint32>(ui: uint32): PositiveSmi labels IfOverflow {
257  return Convert<PositiveSmi>(Convert<uintptr>(ui)) otherwise IfOverflow;
258}
259Convert<int32, Smi>(s: Smi): int32 {
260  return SmiToInt32(s);
261}
262Convert<float64, HeapNumber>(h: HeapNumber): float64 {
263  return LoadHeapNumberValue(h);
264}
265Convert<float64, Number>(n: Number): float64 {
266  return ChangeNumberToFloat64(n);
267}
268Convert<uintptr, Number>(n: Number): uintptr {
269  return ChangeUintPtrNumberToUintPtr(n);
270}
271Convert<float64, int32>(f: int32): float64 {
272  return ChangeInt32ToFloat64(f);
273}
274Convert<float64, float32>(f: float32): float64 {
275  return ChangeFloat32ToFloat64(f);
276}
277Convert<float64_or_hole, float64>(f: float64): float64_or_hole {
278  return float64_or_hole{is_hole: false, value: f};
279}
280Convert<float64_or_hole, Number>(n: Number): float64_or_hole {
281  return Convert<float64_or_hole>(Convert<float64>(n));
282}
283Convert<float32, float64>(f: float64): float32 {
284  return TruncateFloat64ToFloat32(f);
285}
286Convert<float32, Number>(n: Number): float32 {
287  return Convert<float32>(ChangeNumberToFloat64(n));
288}
289Convert<Number, float64>(d: float64): Number {
290  return ChangeFloat64ToTagged(d);
291}
292Convert<float64, uintptr>(ui: uintptr): float64 {
293  return ChangeUintPtrToFloat64(ui);
294}
295Convert<Number, uintptr>(ui: uintptr): Number {
296  return ChangeUintPtrToTagged(ui);
297}
298Convert<Number, intptr>(i: intptr): Number {
299  return ChangeUintPtrToTagged(Unsigned(i));
300}
301Convert<uintptr, float64>(d: float64): uintptr {
302  return ChangeFloat64ToUintPtr(d);
303}
304Convert<uintptr, intptr>(i: intptr): uintptr {
305  return Unsigned(i);
306}
307Convert<uintptr, RawPtr>(r: RawPtr): uintptr {
308  return Unsigned(r);
309}
310Convert<intptr, RawPtr>(r: RawPtr): intptr {
311  return Signed(r);
312}
313Convert<intptr, Number>(n: Number): intptr {
314  return ChangeFloat64ToIntPtr(ChangeNumberToFloat64(n));
315}
316Convert<bint, int32>(v: int32): bint {
317  return IntPtrToBInt(Convert<intptr>(v));
318}
319extern macro IntPtrToBInt(intptr): bint;
320Convert<bint, intptr>(v: intptr): bint {
321  return IntPtrToBInt(v);
322}
323extern macro BIntToIntPtr(bint): intptr;
324Convert<intptr, bint>(v: bint): intptr {
325  return BIntToIntPtr(v);
326}
327extern macro SmiToBInt(Smi): bint;
328Convert<bint, Smi>(v: Smi): bint {
329  return SmiToBInt(v);
330}
331extern macro BIntToSmi(bint): Smi;
332Convert<Smi, bint>(v: bint): Smi {
333  return BIntToSmi(v);
334}
335Convert<PromiseState, int32>(s: int32): PromiseState {
336  return %RawDownCast<PromiseState>(s);
337}
338Convert<ScopeFlags, Smi>(s: Smi): ScopeFlags {
339  return %RawDownCast<ScopeFlags>(Unsigned(SmiToInt32(s)));
340}
341Convert<I8X16, Simd128>(s: Simd128): I8X16 {
342  return %RawDownCast<I8X16>(s);
343}
344