1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jit/shared/LIR-x86-shared.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,332 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef jit_shared_LIR_x86_shared_h 1.11 +#define jit_shared_LIR_x86_shared_h 1.12 + 1.13 +namespace js { 1.14 +namespace jit { 1.15 + 1.16 +class LDivI : public LBinaryMath<1> 1.17 +{ 1.18 + public: 1.19 + LIR_HEADER(DivI) 1.20 + 1.21 + LDivI(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) { 1.22 + setOperand(0, lhs); 1.23 + setOperand(1, rhs); 1.24 + setTemp(0, temp); 1.25 + } 1.26 + 1.27 + const char *extraName() const { 1.28 + if (mir()->isTruncated()) { 1.29 + if (mir()->canBeNegativeZero()) { 1.30 + return mir()->canBeNegativeOverflow() 1.31 + ? "Truncate_NegativeZero_NegativeOverflow" 1.32 + : "Truncate_NegativeZero"; 1.33 + } 1.34 + return mir()->canBeNegativeOverflow() ? "Truncate_NegativeOverflow" : "Truncate"; 1.35 + } 1.36 + if (mir()->canBeNegativeZero()) 1.37 + return mir()->canBeNegativeOverflow() ? "NegativeZero_NegativeOverflow" : "NegativeZero"; 1.38 + return mir()->canBeNegativeOverflow() ? "NegativeOverflow" : nullptr; 1.39 + } 1.40 + 1.41 + const LDefinition *remainder() { 1.42 + return getTemp(0); 1.43 + } 1.44 + MDiv *mir() const { 1.45 + return mir_->toDiv(); 1.46 + } 1.47 +}; 1.48 + 1.49 +// Signed division by a power-of-two constant. 1.50 +class LDivPowTwoI : public LBinaryMath<0> 1.51 +{ 1.52 + const int32_t shift_; 1.53 + const bool negativeDivisor_; 1.54 + 1.55 + public: 1.56 + LIR_HEADER(DivPowTwoI) 1.57 + 1.58 + LDivPowTwoI(const LAllocation &lhs, const LAllocation &lhsCopy, int32_t shift, bool negativeDivisor) 1.59 + : shift_(shift), negativeDivisor_(negativeDivisor) 1.60 + { 1.61 + setOperand(0, lhs); 1.62 + setOperand(1, lhsCopy); 1.63 + } 1.64 + 1.65 + const LAllocation *numerator() { 1.66 + return getOperand(0); 1.67 + } 1.68 + const LAllocation *numeratorCopy() { 1.69 + return getOperand(1); 1.70 + } 1.71 + int32_t shift() const { 1.72 + return shift_; 1.73 + } 1.74 + bool negativeDivisor() const { 1.75 + return negativeDivisor_; 1.76 + } 1.77 + MDiv *mir() const { 1.78 + return mir_->toDiv(); 1.79 + } 1.80 +}; 1.81 + 1.82 +class LDivOrModConstantI : public LInstructionHelper<1, 1, 1> 1.83 +{ 1.84 + const int32_t denominator_; 1.85 + 1.86 + public: 1.87 + LIR_HEADER(DivOrModConstantI) 1.88 + 1.89 + LDivOrModConstantI(const LAllocation &lhs, int32_t denominator, const LDefinition& temp) 1.90 + : denominator_(denominator) 1.91 + { 1.92 + setOperand(0, lhs); 1.93 + setTemp(0, temp); 1.94 + } 1.95 + 1.96 + const LAllocation *numerator() { 1.97 + return getOperand(0); 1.98 + } 1.99 + int32_t denominator() const { 1.100 + return denominator_; 1.101 + } 1.102 + MBinaryArithInstruction *mir() const { 1.103 + JS_ASSERT(mir_->isDiv() || mir_->isMod()); 1.104 + return static_cast<MBinaryArithInstruction *>(mir_); 1.105 + } 1.106 + bool canBeNegativeDividend() const { 1.107 + if (mir_->isMod()) 1.108 + return mir_->toMod()->canBeNegativeDividend(); 1.109 + return mir_->toDiv()->canBeNegativeDividend(); 1.110 + } 1.111 +}; 1.112 + 1.113 +class LModI : public LBinaryMath<1> 1.114 +{ 1.115 + public: 1.116 + LIR_HEADER(ModI) 1.117 + 1.118 + LModI(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) { 1.119 + setOperand(0, lhs); 1.120 + setOperand(1, rhs); 1.121 + setTemp(0, temp); 1.122 + } 1.123 + 1.124 + const char *extraName() const { 1.125 + return mir()->isTruncated() ? "Truncated" : nullptr; 1.126 + } 1.127 + 1.128 + const LDefinition *remainder() { 1.129 + return getDef(0); 1.130 + } 1.131 + MMod *mir() const { 1.132 + return mir_->toMod(); 1.133 + } 1.134 +}; 1.135 + 1.136 +// This class performs a simple x86 'div', yielding either a quotient or remainder depending on 1.137 +// whether this instruction is defined to output eax (quotient) or edx (remainder). 1.138 +class LUDivOrMod : public LBinaryMath<1> 1.139 +{ 1.140 + public: 1.141 + LIR_HEADER(UDivOrMod); 1.142 + 1.143 + LUDivOrMod(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) { 1.144 + setOperand(0, lhs); 1.145 + setOperand(1, rhs); 1.146 + setTemp(0, temp); 1.147 + } 1.148 + 1.149 + const LDefinition *remainder() { 1.150 + return getTemp(0); 1.151 + } 1.152 + 1.153 + const char *extraName() const { 1.154 + return mir()->isTruncated() ? "Truncated" : nullptr; 1.155 + } 1.156 + 1.157 + MBinaryArithInstruction *mir() const { 1.158 + JS_ASSERT(mir_->isDiv() || mir_->isMod()); 1.159 + return static_cast<MBinaryArithInstruction *>(mir_); 1.160 + } 1.161 + 1.162 + bool canBeDivideByZero() const { 1.163 + if (mir_->isMod()) 1.164 + return mir_->toMod()->canBeDivideByZero(); 1.165 + return mir_->toDiv()->canBeDivideByZero(); 1.166 + } 1.167 +}; 1.168 + 1.169 +class LModPowTwoI : public LInstructionHelper<1,1,0> 1.170 +{ 1.171 + const int32_t shift_; 1.172 + 1.173 + public: 1.174 + LIR_HEADER(ModPowTwoI) 1.175 + 1.176 + LModPowTwoI(const LAllocation &lhs, int32_t shift) 1.177 + : shift_(shift) 1.178 + { 1.179 + setOperand(0, lhs); 1.180 + } 1.181 + 1.182 + int32_t shift() const { 1.183 + return shift_; 1.184 + } 1.185 + const LDefinition *remainder() { 1.186 + return getDef(0); 1.187 + } 1.188 + MMod *mir() const { 1.189 + return mir_->toMod(); 1.190 + } 1.191 +}; 1.192 + 1.193 +// Double raised to a half power. 1.194 +class LPowHalfD : public LInstructionHelper<1, 1, 0> 1.195 +{ 1.196 + public: 1.197 + LIR_HEADER(PowHalfD) 1.198 + LPowHalfD(const LAllocation &input) { 1.199 + setOperand(0, input); 1.200 + } 1.201 + 1.202 + const LAllocation *input() { 1.203 + return getOperand(0); 1.204 + } 1.205 + const LDefinition *output() { 1.206 + return getDef(0); 1.207 + } 1.208 + MPowHalf *mir() const { 1.209 + return mir_->toPowHalf(); 1.210 + } 1.211 +}; 1.212 + 1.213 +// Takes a tableswitch with an integer to decide 1.214 +class LTableSwitch : public LInstructionHelper<0, 1, 2> 1.215 +{ 1.216 + public: 1.217 + LIR_HEADER(TableSwitch) 1.218 + 1.219 + LTableSwitch(const LAllocation &in, const LDefinition &inputCopy, 1.220 + const LDefinition &jumpTablePointer, MTableSwitch *ins) 1.221 + { 1.222 + setOperand(0, in); 1.223 + setTemp(0, inputCopy); 1.224 + setTemp(1, jumpTablePointer); 1.225 + setMir(ins); 1.226 + } 1.227 + 1.228 + MTableSwitch *mir() const { 1.229 + return mir_->toTableSwitch(); 1.230 + } 1.231 + 1.232 + const LAllocation *index() { 1.233 + return getOperand(0); 1.234 + } 1.235 + const LDefinition *tempInt() { 1.236 + return getTemp(0); 1.237 + } 1.238 + const LDefinition *tempPointer() { 1.239 + return getTemp(1); 1.240 + } 1.241 +}; 1.242 + 1.243 +// Takes a tableswitch with a value to decide 1.244 +class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 3> 1.245 +{ 1.246 + public: 1.247 + LIR_HEADER(TableSwitchV) 1.248 + 1.249 + LTableSwitchV(const LDefinition &inputCopy, const LDefinition &floatCopy, 1.250 + const LDefinition &jumpTablePointer, MTableSwitch *ins) 1.251 + { 1.252 + setTemp(0, inputCopy); 1.253 + setTemp(1, floatCopy); 1.254 + setTemp(2, jumpTablePointer); 1.255 + setMir(ins); 1.256 + } 1.257 + 1.258 + MTableSwitch *mir() const { 1.259 + return mir_->toTableSwitch(); 1.260 + } 1.261 + 1.262 + static const size_t InputValue = 0; 1.263 + 1.264 + const LDefinition *tempInt() { 1.265 + return getTemp(0); 1.266 + } 1.267 + const LDefinition *tempFloat() { 1.268 + return getTemp(1); 1.269 + } 1.270 + const LDefinition *tempPointer() { 1.271 + return getTemp(2); 1.272 + } 1.273 +}; 1.274 + 1.275 +class LGuardShape : public LInstructionHelper<0, 1, 0> 1.276 +{ 1.277 + public: 1.278 + LIR_HEADER(GuardShape) 1.279 + 1.280 + LGuardShape(const LAllocation &in) { 1.281 + setOperand(0, in); 1.282 + } 1.283 + const MGuardShape *mir() const { 1.284 + return mir_->toGuardShape(); 1.285 + } 1.286 +}; 1.287 + 1.288 +class LGuardObjectType : public LInstructionHelper<0, 1, 0> 1.289 +{ 1.290 + public: 1.291 + LIR_HEADER(GuardObjectType) 1.292 + 1.293 + LGuardObjectType(const LAllocation &in) { 1.294 + setOperand(0, in); 1.295 + } 1.296 + const MGuardObjectType *mir() const { 1.297 + return mir_->toGuardObjectType(); 1.298 + } 1.299 +}; 1.300 + 1.301 +class LInterruptCheck : public LInstructionHelper<0, 0, 0> 1.302 +{ 1.303 + public: 1.304 + LIR_HEADER(InterruptCheck) 1.305 +}; 1.306 + 1.307 +class LMulI : public LBinaryMath<0, 1> 1.308 +{ 1.309 + public: 1.310 + LIR_HEADER(MulI) 1.311 + 1.312 + LMulI(const LAllocation &lhs, const LAllocation &rhs, const LAllocation &lhsCopy) { 1.313 + setOperand(0, lhs); 1.314 + setOperand(1, rhs); 1.315 + setOperand(2, lhsCopy); 1.316 + } 1.317 + 1.318 + const char *extraName() const { 1.319 + return (mir()->mode() == MMul::Integer) 1.320 + ? "Integer" 1.321 + : (mir()->canBeNegativeZero() ? "CanBeNegativeZero" : nullptr); 1.322 + } 1.323 + 1.324 + MMul *mir() const { 1.325 + return mir_->toMul(); 1.326 + } 1.327 + const LAllocation *lhsCopy() { 1.328 + return this->getOperand(2); 1.329 + } 1.330 +}; 1.331 + 1.332 +} // namespace jit 1.333 +} // namespace js 1.334 + 1.335 +#endif /* jit_shared_LIR_x86_shared_h */