Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef jit_x64_LIR_x64_h
8 : #define jit_x64_LIR_x64_h
9 :
10 : namespace js {
11 : namespace jit {
12 :
13 : // Given an untyped input, guards on whether it's a specific type and returns
14 : // the unboxed payload.
15 : class LUnboxBase : public LInstructionHelper<1, 1, 0>
16 : {
17 : public:
18 109 : explicit LUnboxBase(const LAllocation& input) {
19 109 : setOperand(0, input);
20 109 : }
21 :
22 : static const size_t Input = 0;
23 :
24 218 : MUnbox* mir() const {
25 218 : return mir_->toUnbox();
26 : }
27 : };
28 :
29 : class LUnbox : public LUnboxBase {
30 : public:
31 16225 : LIR_HEADER(Unbox)
32 :
33 109 : explicit LUnbox(const LAllocation& input)
34 109 : : LUnboxBase(input)
35 109 : { }
36 :
37 109 : const char* extraName() const {
38 109 : return StringFromMIRType(mir()->type());
39 : }
40 : };
41 :
42 : class LUnboxFloatingPoint : public LUnboxBase {
43 : MIRType type_;
44 :
45 : public:
46 0 : LIR_HEADER(UnboxFloatingPoint)
47 :
48 0 : LUnboxFloatingPoint(const LAllocation& input, MIRType type)
49 0 : : LUnboxBase(input),
50 0 : type_(type)
51 0 : { }
52 :
53 0 : MIRType type() const {
54 0 : return type_;
55 : }
56 0 : const char* extraName() const {
57 0 : return StringFromMIRType(type_);
58 : }
59 : };
60 :
61 : // Convert a 32-bit unsigned integer to a double.
62 : class LWasmUint32ToDouble : public LInstructionHelper<1, 1, 0>
63 : {
64 : public:
65 0 : LIR_HEADER(WasmUint32ToDouble)
66 :
67 0 : explicit LWasmUint32ToDouble(const LAllocation& input) {
68 0 : setOperand(0, input);
69 0 : }
70 : };
71 :
72 : // Convert a 32-bit unsigned integer to a float32.
73 : class LWasmUint32ToFloat32 : public LInstructionHelper<1, 1, 0>
74 : {
75 : public:
76 0 : LIR_HEADER(WasmUint32ToFloat32)
77 :
78 0 : explicit LWasmUint32ToFloat32(const LAllocation& input) {
79 0 : setOperand(0, input);
80 0 : }
81 : };
82 :
83 : class LDivOrModI64 : public LBinaryMath<1>
84 : {
85 : public:
86 0 : LIR_HEADER(DivOrModI64)
87 :
88 0 : LDivOrModI64(const LAllocation& lhs, const LAllocation& rhs, const LDefinition& temp) {
89 0 : setOperand(0, lhs);
90 0 : setOperand(1, rhs);
91 0 : setTemp(0, temp);
92 0 : }
93 :
94 0 : const LDefinition* remainder() {
95 0 : return getTemp(0);
96 : }
97 :
98 0 : MBinaryArithInstruction* mir() const {
99 0 : MOZ_ASSERT(mir_->isDiv() || mir_->isMod());
100 0 : return static_cast<MBinaryArithInstruction*>(mir_);
101 : }
102 0 : bool canBeDivideByZero() const {
103 0 : if (mir_->isMod())
104 0 : return mir_->toMod()->canBeDivideByZero();
105 0 : return mir_->toDiv()->canBeDivideByZero();
106 : }
107 0 : bool canBeNegativeOverflow() const {
108 0 : if (mir_->isMod())
109 0 : return mir_->toMod()->canBeNegativeDividend();
110 0 : return mir_->toDiv()->canBeNegativeOverflow();
111 : }
112 0 : wasm::BytecodeOffset bytecodeOffset() const {
113 0 : MOZ_ASSERT(mir_->isDiv() || mir_->isMod());
114 0 : if (mir_->isMod())
115 0 : return mir_->toMod()->bytecodeOffset();
116 0 : return mir_->toDiv()->bytecodeOffset();
117 : }
118 : };
119 :
120 : // This class performs a simple x86 'div', yielding either a quotient or
121 : // remainder depending on whether this instruction is defined to output
122 : // rax (quotient) or rdx (remainder).
123 : class LUDivOrModI64 : public LBinaryMath<1>
124 : {
125 : public:
126 0 : LIR_HEADER(UDivOrModI64);
127 :
128 0 : LUDivOrModI64(const LAllocation& lhs, const LAllocation& rhs, const LDefinition& temp) {
129 0 : setOperand(0, lhs);
130 0 : setOperand(1, rhs);
131 0 : setTemp(0, temp);
132 0 : }
133 :
134 0 : const LDefinition* remainder() {
135 0 : return getTemp(0);
136 : }
137 :
138 0 : const char* extraName() const {
139 0 : return mir()->isTruncated() ? "Truncated" : nullptr;
140 : }
141 :
142 0 : MBinaryArithInstruction* mir() const {
143 0 : MOZ_ASSERT(mir_->isDiv() || mir_->isMod());
144 0 : return static_cast<MBinaryArithInstruction*>(mir_);
145 : }
146 :
147 0 : bool canBeDivideByZero() const {
148 0 : if (mir_->isMod())
149 0 : return mir_->toMod()->canBeDivideByZero();
150 0 : return mir_->toDiv()->canBeDivideByZero();
151 : }
152 :
153 0 : wasm::BytecodeOffset bytecodeOffset() const {
154 0 : MOZ_ASSERT(mir_->isDiv() || mir_->isMod());
155 0 : if (mir_->isMod())
156 0 : return mir_->toMod()->bytecodeOffset();
157 0 : return mir_->toDiv()->bytecodeOffset();
158 : }
159 : };
160 :
161 : class LWasmTruncateToInt64 : public LInstructionHelper<1, 1, 1>
162 : {
163 : public:
164 0 : LIR_HEADER(WasmTruncateToInt64);
165 :
166 0 : LWasmTruncateToInt64(const LAllocation& in, const LDefinition& temp) {
167 0 : setOperand(0, in);
168 0 : setTemp(0, temp);
169 0 : }
170 :
171 0 : MWasmTruncateToInt64* mir() const {
172 0 : return mir_->toWasmTruncateToInt64();
173 : }
174 :
175 0 : const LDefinition* temp() {
176 0 : return getTemp(0);
177 : }
178 : };
179 :
180 : } // namespace jit
181 : } // namespace js
182 :
183 : #endif /* jit_x64_LIR_x64_h */
|