1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/assembler/assembler/MacroAssemblerSparc.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1461 @@ 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 assembler_assembler_MacroAssemblerSparc_h 1.11 +#define assembler_assembler_MacroAssemblerSparc_h 1.12 + 1.13 +#include "assembler/wtf/Platform.h" 1.14 + 1.15 +#if ENABLE_ASSEMBLER && WTF_CPU_SPARC 1.16 + 1.17 +#include "assembler/assembler/SparcAssembler.h" 1.18 +#include "assembler/assembler/AbstractMacroAssembler.h" 1.19 + 1.20 +namespace JSC { 1.21 + 1.22 + class MacroAssemblerSparc : public AbstractMacroAssembler<SparcAssembler> { 1.23 + public: 1.24 + enum Condition { 1.25 + Equal = SparcAssembler::ConditionE, 1.26 + NotEqual = SparcAssembler::ConditionNE, 1.27 + Above = SparcAssembler::ConditionGU, 1.28 + AboveOrEqual = SparcAssembler::ConditionCC, 1.29 + Below = SparcAssembler::ConditionCS, 1.30 + BelowOrEqual = SparcAssembler::ConditionLEU, 1.31 + GreaterThan = SparcAssembler::ConditionG, 1.32 + GreaterThanOrEqual = SparcAssembler::ConditionGE, 1.33 + LessThan = SparcAssembler::ConditionL, 1.34 + LessThanOrEqual = SparcAssembler::ConditionLE, 1.35 + Overflow = SparcAssembler::ConditionVS, 1.36 + Signed = SparcAssembler::ConditionNEG, 1.37 + Zero = SparcAssembler::ConditionE, 1.38 + NonZero = SparcAssembler::ConditionNE 1.39 + }; 1.40 + 1.41 + enum DoubleCondition { 1.42 + // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN. 1.43 + DoubleEqual = SparcAssembler::DoubleConditionE, 1.44 + DoubleNotEqual = SparcAssembler::DoubleConditionNE, 1.45 + DoubleGreaterThan = SparcAssembler::DoubleConditionG, 1.46 + DoubleGreaterThanOrEqual = SparcAssembler::DoubleConditionGE, 1.47 + DoubleLessThan = SparcAssembler::DoubleConditionL, 1.48 + DoubleLessThanOrEqual = SparcAssembler::DoubleConditionLE, 1.49 + // If either operand is NaN, these conditions always evaluate to true. 1.50 + DoubleEqualOrUnordered = SparcAssembler::DoubleConditionUE, 1.51 + DoubleNotEqualOrUnordered = SparcAssembler::DoubleConditionNE, 1.52 + DoubleGreaterThanOrUnordered = SparcAssembler::DoubleConditionUG, 1.53 + DoubleGreaterThanOrEqualOrUnordered = SparcAssembler::DoubleConditionUGE, 1.54 + DoubleLessThanOrUnordered = SparcAssembler::DoubleConditionUL, 1.55 + DoubleLessThanOrEqualOrUnordered = SparcAssembler::DoubleConditionULE 1.56 + }; 1.57 + 1.58 + static const RegisterID stackPointerRegister = SparcRegisters::sp; 1.59 + 1.60 + static const Scale ScalePtr = TimesFour; 1.61 + static const unsigned int TotalRegisters = 24; 1.62 + 1.63 + void add32(RegisterID src, RegisterID dest) 1.64 + { 1.65 + m_assembler.addcc_r(dest, src, dest); 1.66 + } 1.67 + 1.68 + void add32(TrustedImm32 imm, Address address) 1.69 + { 1.70 + load32(address, SparcRegisters::g2); 1.71 + add32(imm, SparcRegisters::g2); 1.72 + store32(SparcRegisters::g2, address); 1.73 + } 1.74 + 1.75 + void add32(TrustedImm32 imm, RegisterID dest) 1.76 + { 1.77 + if (m_assembler.isimm13(imm.m_value)) 1.78 + m_assembler.addcc_imm(dest, imm.m_value, dest); 1.79 + else { 1.80 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3); 1.81 + m_assembler.addcc_r(dest, SparcRegisters::g3, dest); 1.82 + } 1.83 + } 1.84 + 1.85 + void add32(Address src, RegisterID dest) 1.86 + { 1.87 + load32(src, SparcRegisters::g2); 1.88 + m_assembler.addcc_r(dest, SparcRegisters::g2, dest); 1.89 + } 1.90 + 1.91 + void and32(Address src, RegisterID dest) 1.92 + { 1.93 + load32(src, SparcRegisters::g2); 1.94 + m_assembler.andcc_r(dest, SparcRegisters::g2, dest); 1.95 + } 1.96 + 1.97 + void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) 1.98 + { 1.99 + if (m_assembler.isimm13(imm.m_value)) 1.100 + m_assembler.addcc_imm(src, imm.m_value, dest); 1.101 + else { 1.102 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3); 1.103 + m_assembler.addcc_r(src, SparcRegisters::g3, dest); 1.104 + } 1.105 + } 1.106 + 1.107 + void and32(RegisterID src, RegisterID dest) 1.108 + { 1.109 + m_assembler.andcc_r(dest, src, dest); 1.110 + } 1.111 + 1.112 + void and32(Imm32 imm, RegisterID dest) 1.113 + { 1.114 + if (m_assembler.isimm13(imm.m_value)) 1.115 + m_assembler.andcc_imm(dest, imm.m_value, dest); 1.116 + else { 1.117 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3); 1.118 + m_assembler.andcc_r(dest, SparcRegisters::g3, dest); 1.119 + } 1.120 + } 1.121 + 1.122 + 1.123 + void lshift32(RegisterID shift_amount, RegisterID dest) 1.124 + { 1.125 + m_assembler.sll_r(dest, shift_amount, dest); 1.126 + } 1.127 + 1.128 + void lshift32(Imm32 imm, RegisterID dest) 1.129 + { 1.130 + // No need to check if imm.m_value. 1.131 + // The last 5 bit of imm.m_value will be used anyway. 1.132 + m_assembler.sll_imm(dest, imm.m_value, dest); 1.133 + } 1.134 + 1.135 + void mul32(RegisterID src, RegisterID dest) 1.136 + { 1.137 + m_assembler.smulcc_r(dest, src, dest); 1.138 + } 1.139 + 1.140 + void mul32(Imm32 imm, RegisterID src, RegisterID dest) 1.141 + { 1.142 + if (m_assembler.isimm13(imm.m_value)) 1.143 + m_assembler.smulcc_imm(dest, imm.m_value, dest); 1.144 + else { 1.145 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3); 1.146 + m_assembler.smulcc_r(SparcRegisters::g3, dest, dest); 1.147 + } 1.148 + } 1.149 + 1.150 + void neg32(RegisterID srcDest) 1.151 + { 1.152 + m_assembler.subcc_r(SparcRegisters::g0, srcDest, srcDest); 1.153 + } 1.154 + 1.155 + void not32(RegisterID dest) 1.156 + { 1.157 + m_assembler.xnorcc_r(dest, SparcRegisters::g0, dest); 1.158 + } 1.159 + 1.160 + void or32(RegisterID src, RegisterID dest) 1.161 + { 1.162 + m_assembler.orcc_r(dest, src, dest); 1.163 + } 1.164 + 1.165 + void or32(TrustedImm32 imm, RegisterID dest) 1.166 + { 1.167 + if (m_assembler.isimm13(imm.m_value)) 1.168 + m_assembler.orcc_imm(dest, imm.m_value, dest); 1.169 + else { 1.170 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3); 1.171 + m_assembler.or_r(SparcRegisters::g3, dest, dest); 1.172 + } 1.173 + } 1.174 + 1.175 + 1.176 + void or32(Address address, RegisterID dest) 1.177 + { 1.178 + load32(address, SparcRegisters::g2); 1.179 + or32(SparcRegisters::g2, dest); 1.180 + } 1.181 + 1.182 + void rshift32(RegisterID shift_amount, RegisterID dest) 1.183 + { 1.184 + m_assembler.sra_r(dest, shift_amount, dest); 1.185 + } 1.186 + 1.187 + void rshift32(Imm32 imm, RegisterID dest) 1.188 + { 1.189 + // No need to check if imm.m_value. 1.190 + // The last 5 bit of imm.m_value will be used anyway. 1.191 + m_assembler.sra_imm(dest, imm.m_value, dest); 1.192 + } 1.193 + 1.194 + void urshift32(RegisterID shift_amount, RegisterID dest) 1.195 + { 1.196 + m_assembler.srl_r(dest, shift_amount, dest); 1.197 + } 1.198 + 1.199 + void urshift32(Imm32 imm, RegisterID dest) 1.200 + { 1.201 + // No need to check if imm.m_value. 1.202 + // The last 5 bit of imm.m_value will be used anyway. 1.203 + m_assembler.srl_imm(dest, imm.m_value, dest); 1.204 + } 1.205 + 1.206 + void sub32(RegisterID src, RegisterID dest) 1.207 + { 1.208 + m_assembler.subcc_r(dest, src, dest); 1.209 + } 1.210 + 1.211 + void sub32(TrustedImm32 imm, RegisterID dest) 1.212 + { 1.213 + if (m_assembler.isimm13(imm.m_value)) 1.214 + m_assembler.subcc_imm(dest, imm.m_value, dest); 1.215 + else { 1.216 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3); 1.217 + m_assembler.subcc_r(dest, SparcRegisters::g3, dest); 1.218 + } 1.219 + } 1.220 + 1.221 + void sub32(TrustedImm32 imm, Address address) 1.222 + { 1.223 + load32(address, SparcRegisters::g2); 1.224 + sub32(imm, SparcRegisters::g2); 1.225 + store32(SparcRegisters::g2, address); 1.226 + } 1.227 + 1.228 + void sub32(Address src, RegisterID dest) 1.229 + { 1.230 + load32(src, SparcRegisters::g2); 1.231 + sub32(SparcRegisters::g2, dest); 1.232 + } 1.233 + 1.234 + void xor32(RegisterID src, RegisterID dest) 1.235 + { 1.236 + m_assembler.xorcc_r(src, dest, dest); 1.237 + } 1.238 + 1.239 + void xor32(TrustedImm32 imm, RegisterID dest) 1.240 + { 1.241 + if (m_assembler.isimm13(imm.m_value)) 1.242 + m_assembler.xorcc_imm(dest, imm.m_value, dest); 1.243 + else { 1.244 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3); 1.245 + m_assembler.xorcc_r(dest, SparcRegisters::g3, dest); 1.246 + } 1.247 + } 1.248 + 1.249 + void xor32(Address src, RegisterID dest) 1.250 + { 1.251 + load32(src, SparcRegisters::g2); 1.252 + xor32(SparcRegisters::g2, dest); 1.253 + } 1.254 + 1.255 + void load8(ImplicitAddress address, RegisterID dest) 1.256 + { 1.257 + if (m_assembler.isimm13(address.offset)) 1.258 + m_assembler.ldub_imm(address.base, address.offset, dest); 1.259 + else { 1.260 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.261 + m_assembler.ldub_r(address.base, SparcRegisters::g3, dest); 1.262 + } 1.263 + } 1.264 + 1.265 + void load32(ImplicitAddress address, RegisterID dest) 1.266 + { 1.267 + if (m_assembler.isimm13(address.offset)) 1.268 + m_assembler.lduw_imm(address.base, address.offset, dest); 1.269 + else { 1.270 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.271 + m_assembler.lduw_r(address.base, SparcRegisters::g3, dest); 1.272 + } 1.273 + } 1.274 + 1.275 + void load32(BaseIndex address, RegisterID dest) 1.276 + { 1.277 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.278 + add32(Imm32(address.offset), SparcRegisters::g2); 1.279 + m_assembler.lduw_r(address.base, SparcRegisters::g2, dest); 1.280 + } 1.281 + 1.282 + void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest) 1.283 + { 1.284 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.285 + add32(Imm32(address.offset+3), SparcRegisters::g2); 1.286 + m_assembler.ldub_r(address.base, SparcRegisters::g2, dest); 1.287 + m_assembler.subcc_imm(SparcRegisters::g2, 1, SparcRegisters::g2); 1.288 + m_assembler.ldub_r(address.base, SparcRegisters::g2, SparcRegisters::g3); 1.289 + m_assembler.sll_imm(SparcRegisters::g3, 8, SparcRegisters::g3); 1.290 + m_assembler.or_r(SparcRegisters::g3, dest, dest); 1.291 + m_assembler.subcc_imm(SparcRegisters::g2, 1, SparcRegisters::g2); 1.292 + m_assembler.ldub_r(address.base, SparcRegisters::g2, SparcRegisters::g3); 1.293 + m_assembler.sll_imm(SparcRegisters::g3, 16, SparcRegisters::g3); 1.294 + m_assembler.or_r(SparcRegisters::g3, dest, dest); 1.295 + m_assembler.subcc_imm(SparcRegisters::g2, 1, SparcRegisters::g2); 1.296 + m_assembler.ldub_r(address.base, SparcRegisters::g2, SparcRegisters::g3); 1.297 + m_assembler.sll_imm(SparcRegisters::g3, 24, SparcRegisters::g3); 1.298 + m_assembler.or_r(SparcRegisters::g3, dest, dest); 1.299 + } 1.300 + 1.301 + DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest) 1.302 + { 1.303 + DataLabel32 dataLabel(this); 1.304 + m_assembler.move_nocheck(0, SparcRegisters::g3); 1.305 + m_assembler.lduw_r(address.base, SparcRegisters::g3, dest); 1.306 + return dataLabel; 1.307 + } 1.308 + 1.309 + DataLabel32 load64WithAddressOffsetPatch(Address address, RegisterID hi, RegisterID lo) 1.310 + { 1.311 + DataLabel32 dataLabel(this); 1.312 + m_assembler.move_nocheck(0, SparcRegisters::g3); 1.313 + m_assembler.add_imm(SparcRegisters::g3, 4, SparcRegisters::g2); 1.314 + m_assembler.lduw_r(address.base, SparcRegisters::g3, hi); 1.315 + m_assembler.lduw_r(address.base, SparcRegisters::g2, lo); 1.316 + return dataLabel; 1.317 + } 1.318 + 1.319 + Label loadPtrWithPatchToLEA(Address address, RegisterID dest) 1.320 + { 1.321 + Label label(this); 1.322 + load32(address, dest); 1.323 + return label; 1.324 + } 1.325 + 1.326 + void load16(BaseIndex address, RegisterID dest) 1.327 + { 1.328 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.329 + add32(Imm32(address.offset), SparcRegisters::g2); 1.330 + m_assembler.lduh_r(address.base, SparcRegisters::g2, dest); 1.331 + } 1.332 + 1.333 + void load16(ImplicitAddress address, RegisterID dest) 1.334 + { 1.335 + if (m_assembler.isimm13(address.offset)) 1.336 + m_assembler.lduh_imm(address.base, address.offset, dest); 1.337 + else { 1.338 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.339 + m_assembler.lduh_r(address.base, SparcRegisters::g3, dest); 1.340 + } 1.341 + } 1.342 + 1.343 + void store8(RegisterID src, ImplicitAddress address) 1.344 + { 1.345 + if (m_assembler.isimm13(address.offset)) 1.346 + m_assembler.stb_imm(src, address.base, address.offset); 1.347 + else { 1.348 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.349 + m_assembler.stb_r(src, address.base, SparcRegisters::g3); 1.350 + } 1.351 + } 1.352 + 1.353 + void store8(RegisterID src, BaseIndex address) 1.354 + { 1.355 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.356 + add32(Imm32(address.offset), SparcRegisters::g2); 1.357 + m_assembler.stb_r(src, address.base, SparcRegisters::g2); 1.358 + } 1.359 + 1.360 + void store8(Imm32 imm, ImplicitAddress address) 1.361 + { 1.362 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g2); 1.363 + store8(SparcRegisters::g2, address); 1.364 + } 1.365 + 1.366 + void store8(Imm32 imm, BaseIndex address) 1.367 + { 1.368 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.369 + add32(Imm32(address.offset), SparcRegisters::g2); 1.370 + move(imm, SparcRegisters::g3); 1.371 + m_assembler.stb_r(SparcRegisters::g3, SparcRegisters::g2, address.base); 1.372 + } 1.373 + 1.374 + void store16(RegisterID src, ImplicitAddress address) 1.375 + { 1.376 + if (m_assembler.isimm13(address.offset)) 1.377 + m_assembler.sth_imm(src, address.base, address.offset); 1.378 + else { 1.379 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.380 + m_assembler.sth_r(src, address.base, SparcRegisters::g3); 1.381 + } 1.382 + } 1.383 + 1.384 + void store16(RegisterID src, BaseIndex address) 1.385 + { 1.386 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.387 + add32(Imm32(address.offset), SparcRegisters::g2); 1.388 + m_assembler.sth_r(src, address.base, SparcRegisters::g2); 1.389 + } 1.390 + 1.391 + void store16(Imm32 imm, ImplicitAddress address) 1.392 + { 1.393 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g2); 1.394 + store16(SparcRegisters::g2, address); 1.395 + } 1.396 + 1.397 + void store16(Imm32 imm, BaseIndex address) 1.398 + { 1.399 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.400 + add32(Imm32(address.offset), SparcRegisters::g2); 1.401 + move(imm, SparcRegisters::g3); 1.402 + m_assembler.sth_r(SparcRegisters::g3, SparcRegisters::g2, address.base); 1.403 + } 1.404 + 1.405 + void load8ZeroExtend(BaseIndex address, RegisterID dest) 1.406 + { 1.407 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.408 + add32(Imm32(address.offset), SparcRegisters::g2); 1.409 + m_assembler.ldub_r(address.base, SparcRegisters::g2, dest); 1.410 + } 1.411 + 1.412 + void load8ZeroExtend(Address address, RegisterID dest) 1.413 + { 1.414 + if (m_assembler.isimm13(address.offset)) 1.415 + m_assembler.ldub_imm(address.base, address.offset, dest); 1.416 + else { 1.417 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.418 + m_assembler.ldub_r(address.base, SparcRegisters::g3, dest); 1.419 + } 1.420 + } 1.421 + 1.422 + void load8SignExtend(BaseIndex address, RegisterID dest) 1.423 + { 1.424 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.425 + add32(Imm32(address.offset), SparcRegisters::g2); 1.426 + m_assembler.ldsb_r(address.base, SparcRegisters::g2, dest); 1.427 + } 1.428 + 1.429 + void load8SignExtend(Address address, RegisterID dest) 1.430 + { 1.431 + if (m_assembler.isimm13(address.offset)) 1.432 + m_assembler.ldsb_imm(address.base, address.offset, dest); 1.433 + else { 1.434 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.435 + m_assembler.ldsb_r(address.base, SparcRegisters::g3, dest); 1.436 + } 1.437 + } 1.438 + 1.439 + void load16SignExtend(BaseIndex address, RegisterID dest) 1.440 + { 1.441 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.442 + add32(Imm32(address.offset), SparcRegisters::g2); 1.443 + m_assembler.ldsh_r(address.base, SparcRegisters::g2, dest); 1.444 + } 1.445 + 1.446 + void load16SignExtend(Address address, RegisterID dest) 1.447 + { 1.448 + if (m_assembler.isimm13(address.offset)) 1.449 + m_assembler.ldsh_imm(address.base, address.offset, dest); 1.450 + else { 1.451 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.452 + m_assembler.ldsh_r(address.base, SparcRegisters::g3, dest); 1.453 + } 1.454 + } 1.455 + 1.456 + DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address) 1.457 + { 1.458 + DataLabel32 dataLabel(this); 1.459 + // Since this is for patch, we don't check is offset is imm13. 1.460 + m_assembler.move_nocheck(0, SparcRegisters::g3); 1.461 + m_assembler.stw_r(src, address.base, SparcRegisters::g3); 1.462 + return dataLabel; 1.463 + } 1.464 + 1.465 + 1.466 + DataLabel32 store64WithAddressOffsetPatch(RegisterID hi, RegisterID lo, Address address) 1.467 + { 1.468 + DataLabel32 dataLabel(this); 1.469 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.470 + m_assembler.add_r(SparcRegisters::g3, address.base, SparcRegisters::g3); 1.471 + m_assembler.stw_imm(lo, SparcRegisters::g3, 4); 1.472 + m_assembler.stw_imm(hi, SparcRegisters::g3, 0); 1.473 + return dataLabel; 1.474 + } 1.475 + 1.476 + DataLabel32 store64WithAddressOffsetPatch(Imm32 hi, RegisterID lo, Address address) 1.477 + { 1.478 + DataLabel32 dataLabel(this); 1.479 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.480 + m_assembler.add_r(SparcRegisters::g3, address.base, SparcRegisters::g3); 1.481 + m_assembler.stw_imm(lo, SparcRegisters::g3, 4); 1.482 + move(hi, SparcRegisters::g2); 1.483 + m_assembler.stw_imm(SparcRegisters::g2, SparcRegisters::g3, 0); 1.484 + 1.485 + return dataLabel; 1.486 + } 1.487 + 1.488 + DataLabel32 store64WithAddressOffsetPatch(Imm32 hi, Imm32 lo, Address address) 1.489 + { 1.490 + DataLabel32 dataLabel(this); 1.491 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.492 + m_assembler.add_r(SparcRegisters::g3, address.base, SparcRegisters::g3); 1.493 + move(lo, SparcRegisters::g2); 1.494 + m_assembler.stw_imm(SparcRegisters::g2, SparcRegisters::g3, 4); 1.495 + move(hi, SparcRegisters::g2); 1.496 + m_assembler.stw_imm(SparcRegisters::g2, SparcRegisters::g3, 0); 1.497 + 1.498 + return dataLabel; 1.499 + } 1.500 + 1.501 + 1.502 + void store32(RegisterID src, ImplicitAddress address) 1.503 + { 1.504 + if (m_assembler.isimm13(address.offset)) 1.505 + m_assembler.stw_imm(src, address.base, address.offset); 1.506 + else { 1.507 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.508 + m_assembler.stw_r(src, address.base, SparcRegisters::g3); 1.509 + } 1.510 + } 1.511 + 1.512 + void store32(RegisterID src, BaseIndex address) 1.513 + { 1.514 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.515 + add32(Imm32(address.offset), SparcRegisters::g2); 1.516 + m_assembler.stw_r(src, address.base, SparcRegisters::g2); 1.517 + } 1.518 + 1.519 + void store32(TrustedImm32 imm, BaseIndex address) 1.520 + { 1.521 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.522 + add32(Imm32(address.offset), SparcRegisters::g2); 1.523 + move(imm, SparcRegisters::g3); 1.524 + m_assembler.stw_r(SparcRegisters::g3, SparcRegisters::g2, address.base); 1.525 + } 1.526 + 1.527 + void store32(TrustedImm32 imm, ImplicitAddress address) 1.528 + { 1.529 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g2); 1.530 + store32(SparcRegisters::g2, address); 1.531 + } 1.532 + 1.533 + void store32(RegisterID src, void* address) 1.534 + { 1.535 + m_assembler.move_nocheck((int)address, SparcRegisters::g3); 1.536 + m_assembler.stw_r(src, SparcRegisters::g0, SparcRegisters::g3); 1.537 + } 1.538 + 1.539 + void store32(TrustedImm32 imm, void* address) 1.540 + { 1.541 + move(imm, SparcRegisters::g2); 1.542 + store32(SparcRegisters::g2, address); 1.543 + } 1.544 + 1.545 + void pop(RegisterID dest) 1.546 + { 1.547 + m_assembler.lduw_imm(SparcRegisters::sp, 0x68, dest); 1.548 + m_assembler.addcc_imm(SparcRegisters::sp, 4, SparcRegisters::sp); 1.549 + } 1.550 + 1.551 + void push(RegisterID src) 1.552 + { 1.553 + m_assembler.subcc_imm(SparcRegisters::sp, 4, SparcRegisters::sp); 1.554 + m_assembler.stw_imm(src, SparcRegisters::sp, 0x68); 1.555 + } 1.556 + 1.557 + void push(Address address) 1.558 + { 1.559 + load32(address, SparcRegisters::g2); 1.560 + push(SparcRegisters::g2); 1.561 + } 1.562 + 1.563 + void push(Imm32 imm) 1.564 + { 1.565 + move(imm, SparcRegisters::g2); 1.566 + push(SparcRegisters::g2); 1.567 + } 1.568 + 1.569 + void move(TrustedImm32 imm, RegisterID dest) 1.570 + { 1.571 + if (m_assembler.isimm13(imm.m_value)) 1.572 + m_assembler.or_imm(SparcRegisters::g0, imm.m_value, dest); 1.573 + else 1.574 + m_assembler.move_nocheck(imm.m_value, dest); 1.575 + } 1.576 + 1.577 + void move(RegisterID src, RegisterID dest) 1.578 + { 1.579 + m_assembler.or_r(src, SparcRegisters::g0, dest); 1.580 + } 1.581 + 1.582 + void move(TrustedImmPtr imm, RegisterID dest) 1.583 + { 1.584 + move(Imm32(imm), dest); 1.585 + } 1.586 + 1.587 + void swap(RegisterID reg1, RegisterID reg2) 1.588 + { 1.589 + m_assembler.or_r(reg1, SparcRegisters::g0, SparcRegisters::g3); 1.590 + m_assembler.or_r(reg2, SparcRegisters::g0, reg1); 1.591 + m_assembler.or_r(SparcRegisters::g3, SparcRegisters::g0, reg2); 1.592 + } 1.593 + 1.594 + void signExtend32ToPtr(RegisterID src, RegisterID dest) 1.595 + { 1.596 + if (src != dest) 1.597 + move(src, dest); 1.598 + } 1.599 + 1.600 + void zeroExtend32ToPtr(RegisterID src, RegisterID dest) 1.601 + { 1.602 + if (src != dest) 1.603 + move(src, dest); 1.604 + } 1.605 + 1.606 + Jump branch8(Condition cond, Address left, Imm32 right) 1.607 + { 1.608 + load8(left, SparcRegisters::g2); 1.609 + return branch32(cond, SparcRegisters::g2, right); 1.610 + } 1.611 + 1.612 + Jump branch32_force32(Condition cond, RegisterID left, TrustedImm32 right) 1.613 + { 1.614 + m_assembler.move_nocheck(right.m_value, SparcRegisters::g3); 1.615 + m_assembler.subcc_r(left, SparcRegisters::g3, SparcRegisters::g0); 1.616 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.617 + } 1.618 + 1.619 + Jump branch32FixedLength(Condition cond, RegisterID left, TrustedImm32 right) 1.620 + { 1.621 + m_assembler.move_nocheck(right.m_value, SparcRegisters::g2); 1.622 + return branch32(cond, left, SparcRegisters::g2); 1.623 + } 1.624 + 1.625 + Jump branch32WithPatch(Condition cond, RegisterID left, TrustedImm32 right, DataLabel32 &dataLabel) 1.626 + { 1.627 + // Always use move_nocheck, since the value is to be patched. 1.628 + dataLabel = DataLabel32(this); 1.629 + m_assembler.move_nocheck(right.m_value, SparcRegisters::g3); 1.630 + m_assembler.subcc_r(left, SparcRegisters::g3, SparcRegisters::g0); 1.631 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.632 + } 1.633 + 1.634 + Jump branch32(Condition cond, RegisterID left, RegisterID right) 1.635 + { 1.636 + m_assembler.subcc_r(left, right, SparcRegisters::g0); 1.637 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.638 + } 1.639 + 1.640 + Jump branch32(Condition cond, RegisterID left, TrustedImm32 right) 1.641 + { 1.642 + if (m_assembler.isimm13(right.m_value)) 1.643 + m_assembler.subcc_imm(left, right.m_value, SparcRegisters::g0); 1.644 + else { 1.645 + m_assembler.move_nocheck(right.m_value, SparcRegisters::g3); 1.646 + m_assembler.subcc_r(left, SparcRegisters::g3, SparcRegisters::g0); 1.647 + } 1.648 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.649 + } 1.650 + 1.651 + Jump branch32(Condition cond, RegisterID left, Address right) 1.652 + { 1.653 + load32(right, SparcRegisters::g2); 1.654 + return branch32(cond, left, SparcRegisters::g2); 1.655 + } 1.656 + 1.657 + Jump branch32(Condition cond, Address left, RegisterID right) 1.658 + { 1.659 + load32(left, SparcRegisters::g2); 1.660 + return branch32(cond, SparcRegisters::g2, right); 1.661 + } 1.662 + 1.663 + Jump branch32(Condition cond, Address left, TrustedImm32 right) 1.664 + { 1.665 + load32(left, SparcRegisters::g2); 1.666 + return branch32(cond, SparcRegisters::g2, right); 1.667 + } 1.668 + 1.669 + Jump branch32(Condition cond, BaseIndex left, TrustedImm32 right) 1.670 + { 1.671 + 1.672 + load32(left, SparcRegisters::g2); 1.673 + return branch32(cond, SparcRegisters::g2, right); 1.674 + } 1.675 + 1.676 + Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, TrustedImm32 right) 1.677 + { 1.678 + load32WithUnalignedHalfWords(left, SparcRegisters::g4); 1.679 + return branch32(cond, SparcRegisters::g4, right); 1.680 + } 1.681 + 1.682 + Jump branch16(Condition cond, BaseIndex left, RegisterID right) 1.683 + { 1.684 + (void)(cond); 1.685 + (void)(left); 1.686 + (void)(right); 1.687 + ASSERT_NOT_REACHED(); 1.688 + return jump(); 1.689 + } 1.690 + 1.691 + Jump branch16(Condition cond, BaseIndex left, Imm32 right) 1.692 + { 1.693 + load16(left, SparcRegisters::g3); 1.694 + move(right, SparcRegisters::g2); 1.695 + m_assembler.subcc_r(SparcRegisters::g3, SparcRegisters::g2, SparcRegisters::g0); 1.696 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.697 + } 1.698 + 1.699 + Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1)) 1.700 + { 1.701 + load8(address, SparcRegisters::g2); 1.702 + return branchTest32(cond, SparcRegisters::g2, mask); 1.703 + } 1.704 + 1.705 + Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask) 1.706 + { 1.707 + m_assembler.andcc_r(reg, mask, SparcRegisters::g0); 1.708 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.709 + } 1.710 + 1.711 + Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1)) 1.712 + { 1.713 + if (m_assembler.isimm13(mask.m_value)) 1.714 + m_assembler.andcc_imm(reg, mask.m_value, SparcRegisters::g0); 1.715 + else { 1.716 + m_assembler.move_nocheck(mask.m_value, SparcRegisters::g3); 1.717 + m_assembler.andcc_r(reg, SparcRegisters::g3, SparcRegisters::g0); 1.718 + } 1.719 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.720 + } 1.721 + 1.722 + Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1)) 1.723 + { 1.724 + load32(address, SparcRegisters::g2); 1.725 + return branchTest32(cond, SparcRegisters::g2, mask); 1.726 + } 1.727 + 1.728 + Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1)) 1.729 + { 1.730 + // FIXME. branchTest32 only used by PolyIC. 1.731 + // PolyIC is not enabled for sparc now. 1.732 + ASSERT(0); 1.733 + return jump(); 1.734 + } 1.735 + 1.736 + Jump jump() 1.737 + { 1.738 + return Jump(m_assembler.jmp()); 1.739 + } 1.740 + 1.741 + void jump(RegisterID target) 1.742 + { 1.743 + m_assembler.jmpl_r(SparcRegisters::g0, target, SparcRegisters::g0); 1.744 + m_assembler.nop(); 1.745 + } 1.746 + 1.747 + void jump(Address address) 1.748 + { 1.749 + load32(address, SparcRegisters::g2); 1.750 + m_assembler.jmpl_r(SparcRegisters::g2, SparcRegisters::g0, SparcRegisters::g0); 1.751 + m_assembler.nop(); 1.752 + } 1.753 + 1.754 + void jump(BaseIndex address) 1.755 + { 1.756 + load32(address, SparcRegisters::g2); 1.757 + m_assembler.jmpl_r(SparcRegisters::g2, SparcRegisters::g0, SparcRegisters::g0); 1.758 + m_assembler.nop(); 1.759 + } 1.760 + 1.761 + Jump branchAdd32(Condition cond, RegisterID src, RegisterID dest) 1.762 + { 1.763 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.764 + m_assembler.addcc_r(src, dest, dest); 1.765 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.766 + } 1.767 + 1.768 + Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest) 1.769 + { 1.770 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.771 + if (m_assembler.isimm13(imm.m_value)) 1.772 + m_assembler.addcc_imm(dest, imm.m_value, dest); 1.773 + else { 1.774 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3); 1.775 + m_assembler.addcc_r(dest, SparcRegisters::g3, dest); 1.776 + } 1.777 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.778 + } 1.779 + 1.780 + Jump branchAdd32(Condition cond, Address src, RegisterID dest) 1.781 + { 1.782 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.783 + load32(src, SparcRegisters::g2); 1.784 + return branchAdd32(cond, SparcRegisters::g2, dest); 1.785 + } 1.786 + 1.787 + void mull32(RegisterID src1, RegisterID src2, RegisterID dest) 1.788 + { 1.789 + m_assembler.smulcc_r(src1, src2, dest); 1.790 + } 1.791 + 1.792 + Jump branchMul32(Condition cond, RegisterID src, RegisterID dest) 1.793 + { 1.794 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.795 + m_assembler.smulcc_r(src, dest, dest); 1.796 + if (cond == Overflow) { 1.797 + m_assembler.rdy(SparcRegisters::g2); 1.798 + m_assembler.sra_imm(dest, 31, SparcRegisters::g3); 1.799 + m_assembler.subcc_r(SparcRegisters::g2, SparcRegisters::g3, SparcRegisters::g2); 1.800 + cond = NotEqual; 1.801 + } 1.802 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.803 + } 1.804 + 1.805 + Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest) 1.806 + { 1.807 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.808 + if (m_assembler.isimm13(imm.m_value)) 1.809 + m_assembler.smulcc_imm(src, imm.m_value, dest); 1.810 + else { 1.811 + m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3); 1.812 + m_assembler.smulcc_r(src, SparcRegisters::g3, dest); 1.813 + } 1.814 + if (cond == Overflow) { 1.815 + m_assembler.rdy(SparcRegisters::g2); 1.816 + m_assembler.sra_imm(dest, 31, SparcRegisters::g3); 1.817 + m_assembler.subcc_r(SparcRegisters::g2, SparcRegisters::g3, SparcRegisters::g2); 1.818 + cond = NotEqual; 1.819 + } 1.820 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.821 + } 1.822 + 1.823 + Jump branchMul32(Condition cond, Address src, RegisterID dest) 1.824 + { 1.825 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.826 + load32(src, SparcRegisters::g2); 1.827 + return branchMul32(cond, SparcRegisters::g2, dest); 1.828 + } 1.829 + 1.830 + Jump branchSub32(Condition cond, RegisterID src, RegisterID dest) 1.831 + { 1.832 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.833 + m_assembler.subcc_r(dest, src, dest); 1.834 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.835 + } 1.836 + 1.837 + Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest) 1.838 + { 1.839 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.840 + sub32(imm, dest); 1.841 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.842 + } 1.843 + 1.844 + Jump branchSub32(Condition cond, Address src, RegisterID dest) 1.845 + { 1.846 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.847 + load32(src, SparcRegisters::g2); 1.848 + return branchSub32(cond, SparcRegisters::g2, dest); 1.849 + } 1.850 + 1.851 + Jump branchSub32(Condition cond, Imm32 imm, Address dest) 1.852 + { 1.853 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.854 + sub32(imm, dest); 1.855 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.856 + } 1.857 + 1.858 + Jump branchNeg32(Condition cond, RegisterID srcDest) 1.859 + { 1.860 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.861 + neg32(srcDest); 1.862 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.863 + } 1.864 + 1.865 + Jump branchOr32(Condition cond, RegisterID src, RegisterID dest) 1.866 + { 1.867 + ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero)); 1.868 + m_assembler.orcc_r(src, dest, dest); 1.869 + return Jump(m_assembler.branch(SparcCondition(cond))); 1.870 + } 1.871 + 1.872 + void breakpoint() 1.873 + { 1.874 + m_assembler.ta_imm(8); 1.875 + } 1.876 + 1.877 + Call nearCall() 1.878 + { 1.879 + return Call(m_assembler.call(), Call::LinkableNear); 1.880 + } 1.881 + 1.882 + Call call(RegisterID target) 1.883 + { 1.884 + m_assembler.jmpl_r(target, SparcRegisters::g0, SparcRegisters::o7); 1.885 + m_assembler.nop(); 1.886 + JmpSrc jmpSrc; 1.887 + return Call(jmpSrc, Call::None); 1.888 + } 1.889 + 1.890 + void call(Address address) 1.891 + { 1.892 + if (m_assembler.isimm13(address.offset)) { 1.893 + m_assembler.jmpl_imm(address.base, address.offset, SparcRegisters::o7); 1.894 + m_assembler.nop(); 1.895 + } else { 1.896 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.897 + m_assembler.jmpl_r(address.base, SparcRegisters::g3, SparcRegisters::o7); 1.898 + m_assembler.nop(); 1.899 + } 1.900 + } 1.901 + 1.902 + void ret() 1.903 + { 1.904 + m_assembler.jmpl_imm(SparcRegisters::i7, 8, SparcRegisters::g0); 1.905 + m_assembler.nop(); 1.906 + } 1.907 + 1.908 + void ret_and_restore() 1.909 + { 1.910 + m_assembler.jmpl_imm(SparcRegisters::i7, 8, SparcRegisters::g0); 1.911 + m_assembler.restore_r(SparcRegisters::g0, SparcRegisters::g0, SparcRegisters::g0); 1.912 + } 1.913 + 1.914 + void save(Imm32 size) 1.915 + { 1.916 + if (m_assembler.isimm13(size.m_value)) { 1.917 + m_assembler.save_imm(SparcRegisters::sp, size.m_value, SparcRegisters::sp); 1.918 + } else { 1.919 + m_assembler.move_nocheck(size.m_value, SparcRegisters::g3); 1.920 + m_assembler.save_r(SparcRegisters::sp, SparcRegisters::g3, SparcRegisters::sp); 1.921 + } 1.922 + } 1.923 + 1.924 + void set32(Condition cond, Address left, RegisterID right, RegisterID dest) 1.925 + { 1.926 + load32(left, SparcRegisters::g2); 1.927 + set32(cond, SparcRegisters::g2, right, dest); 1.928 + } 1.929 + 1.930 + void set32(Condition cond, RegisterID left, Address right, RegisterID dest) 1.931 + { 1.932 + load32(right, SparcRegisters::g2); 1.933 + set32(cond, left, SparcRegisters::g2, dest); 1.934 + } 1.935 + 1.936 + void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest) 1.937 + { 1.938 + m_assembler.subcc_r(left, right, SparcRegisters::g0); 1.939 + m_assembler.or_imm(SparcRegisters::g0, 0, dest); 1.940 + m_assembler.movcc_imm(1, dest, SparcCondition(cond)); 1.941 + } 1.942 + 1.943 + void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest) 1.944 + { 1.945 + if (m_assembler.isimm13(right.m_value)) 1.946 + m_assembler.subcc_imm(left, right.m_value, SparcRegisters::g0); 1.947 + else { 1.948 + m_assembler.move_nocheck(right.m_value, SparcRegisters::g3); 1.949 + m_assembler.subcc_r(left, SparcRegisters::g3, SparcRegisters::g0); 1.950 + } 1.951 + m_assembler.or_imm(SparcRegisters::g0, 0, dest); 1.952 + m_assembler.movcc_imm(1, dest, SparcCondition(cond)); 1.953 + } 1.954 + 1.955 + void set32(Condition cond, Address left, Imm32 right, RegisterID dest) 1.956 + { 1.957 + load32(left, SparcRegisters::g2); 1.958 + set32(cond, SparcRegisters::g2, right, dest); 1.959 + } 1.960 + 1.961 + void set8(Condition cond, RegisterID left, RegisterID right, RegisterID dest) 1.962 + { 1.963 + // Sparc does not have byte register. 1.964 + set32(cond, left, right, dest); 1.965 + } 1.966 + 1.967 + void set8(Condition cond, Address left, RegisterID right, RegisterID dest) 1.968 + { 1.969 + // Sparc doesn't have byte registers 1.970 + load32(left, SparcRegisters::g2); 1.971 + set32(cond, SparcRegisters::g2, right, dest); 1.972 + } 1.973 + 1.974 + void set8(Condition cond, RegisterID left, Imm32 right, RegisterID dest) 1.975 + { 1.976 + // Sparc does not have byte register. 1.977 + set32(cond, left, right, dest); 1.978 + } 1.979 + 1.980 + void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest) 1.981 + { 1.982 + load32(address, SparcRegisters::g2); 1.983 + if (m_assembler.isimm13(mask.m_value)) 1.984 + m_assembler.andcc_imm(SparcRegisters::g2, mask.m_value, SparcRegisters::g0); 1.985 + else { 1.986 + m_assembler.move_nocheck(mask.m_value, SparcRegisters::g3); 1.987 + m_assembler.andcc_r(SparcRegisters::g3, SparcRegisters::g2, SparcRegisters::g0); 1.988 + } 1.989 + m_assembler.or_imm(SparcRegisters::g0, 0, dest); 1.990 + m_assembler.movcc_imm(1, dest, SparcCondition(cond)); 1.991 + } 1.992 + 1.993 + void setTest8(Condition cond, Address address, Imm32 mask, RegisterID dest) 1.994 + { 1.995 + // Sparc does not have byte register. 1.996 + setTest32(cond, address, mask, dest); 1.997 + } 1.998 + 1.999 + void lea(Address address, RegisterID dest) 1.1000 + { 1.1001 + if (m_assembler.isimm13(address.offset)) 1.1002 + m_assembler.add_imm(address.base, address.offset, dest); 1.1003 + else { 1.1004 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.1005 + m_assembler.add_r(address.base, SparcRegisters::g3, dest); 1.1006 + } 1.1007 + } 1.1008 + 1.1009 + void lea(BaseIndex address, RegisterID dest) 1.1010 + { 1.1011 + // lea only used by PolyIC. 1.1012 + // PolyIC is not enabled for sparc now. 1.1013 + ASSERT(0); 1.1014 + } 1.1015 + 1.1016 + void add32(Imm32 imm, AbsoluteAddress address) 1.1017 + { 1.1018 + load32(address.m_ptr, SparcRegisters::g2); 1.1019 + add32(imm, SparcRegisters::g2); 1.1020 + store32(SparcRegisters::g2, address.m_ptr); 1.1021 + } 1.1022 + 1.1023 + void sub32(TrustedImm32 imm, AbsoluteAddress address) 1.1024 + { 1.1025 + load32(address.m_ptr, SparcRegisters::g2); 1.1026 + sub32(imm, SparcRegisters::g2); 1.1027 + store32(SparcRegisters::g2, address.m_ptr); 1.1028 + } 1.1029 + 1.1030 + void load32(const void* address, RegisterID dest) 1.1031 + { 1.1032 + m_assembler.move_nocheck((int)address, SparcRegisters::g3); 1.1033 + m_assembler.lduw_r(SparcRegisters::g3, SparcRegisters::g0, dest); 1.1034 + } 1.1035 + 1.1036 + Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right) 1.1037 + { 1.1038 + load32(left.m_ptr, SparcRegisters::g2); 1.1039 + return branch32(cond, SparcRegisters::g2, right); 1.1040 + } 1.1041 + 1.1042 + Jump branch32(Condition cond, AbsoluteAddress left, TrustedImm32 right) 1.1043 + { 1.1044 + load32(left.m_ptr, SparcRegisters::g2); 1.1045 + return branch32(cond, SparcRegisters::g2, right); 1.1046 + } 1.1047 + 1.1048 + Call call() 1.1049 + { 1.1050 + m_assembler.rdpc(SparcRegisters::g2); 1.1051 + m_assembler.add_imm(SparcRegisters::g2, 32, SparcRegisters::g2); 1.1052 + m_assembler.stw_imm(SparcRegisters::g2, SparcRegisters::fp, -8); 1.1053 + Call cl = Call(m_assembler.call(), Call::Linkable); 1.1054 + m_assembler.lduw_imm(SparcRegisters::fp, -8, SparcRegisters::g2); 1.1055 + m_assembler.jmpl_imm(SparcRegisters::g2, 0, SparcRegisters::g0); 1.1056 + m_assembler.nop(); 1.1057 + return cl; 1.1058 + } 1.1059 + 1.1060 + Call tailRecursiveCall() 1.1061 + { 1.1062 + return Call::fromTailJump(jump()); 1.1063 + } 1.1064 + 1.1065 + Call makeTailRecursiveCall(Jump oldJump) 1.1066 + { 1.1067 + return Call::fromTailJump(oldJump); 1.1068 + } 1.1069 + 1.1070 + DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest) 1.1071 + { 1.1072 + DataLabelPtr dataLabel(this); 1.1073 + Imm32 imm = Imm32(initialValue); 1.1074 + m_assembler.move_nocheck(imm.m_value, dest); 1.1075 + return dataLabel; 1.1076 + } 1.1077 + 1.1078 + DataLabel32 moveWithPatch(TrustedImm32 initialValue, RegisterID dest) 1.1079 + { 1.1080 + DataLabel32 dataLabel(this); 1.1081 + m_assembler.move_nocheck(initialValue.m_value, dest); 1.1082 + return dataLabel; 1.1083 + } 1.1084 + 1.1085 + Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0)) 1.1086 + { 1.1087 + dataLabel = moveWithPatch(initialRightValue, SparcRegisters::g2); 1.1088 + Jump jump = branch32(cond, left, SparcRegisters::g2); 1.1089 + return jump; 1.1090 + } 1.1091 + 1.1092 + Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0)) 1.1093 + { 1.1094 + load32(left, SparcRegisters::g2); 1.1095 + dataLabel = moveWithPatch(initialRightValue, SparcRegisters::g3); 1.1096 + Jump jump = branch32(cond, SparcRegisters::g3, SparcRegisters::g2); 1.1097 + return jump; 1.1098 + } 1.1099 + 1.1100 + DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address) 1.1101 + { 1.1102 + DataLabelPtr dataLabel = moveWithPatch(initialValue, SparcRegisters::g2); 1.1103 + store32(SparcRegisters::g2, address); 1.1104 + return dataLabel; 1.1105 + } 1.1106 + 1.1107 + DataLabelPtr storePtrWithPatch(ImplicitAddress address) 1.1108 + { 1.1109 + return storePtrWithPatch(ImmPtr(0), address); 1.1110 + } 1.1111 + 1.1112 + // Floating point operators 1.1113 + static bool supportsFloatingPoint() 1.1114 + { 1.1115 + return true; 1.1116 + } 1.1117 + 1.1118 + static bool supportsFloatingPointTruncate() 1.1119 + { 1.1120 + return true; 1.1121 + } 1.1122 + 1.1123 + static bool supportsFloatingPointSqrt() 1.1124 + { 1.1125 + return true; 1.1126 + } 1.1127 + 1.1128 + void moveDouble(FPRegisterID src, FPRegisterID dest) 1.1129 + { 1.1130 + m_assembler.fmovd_r(src, dest); 1.1131 + } 1.1132 + 1.1133 + void loadFloat(BaseIndex address, FPRegisterID dest) 1.1134 + { 1.1135 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.1136 + add32(Imm32(address.offset), SparcRegisters::g2); 1.1137 + m_assembler.ldf_r(address.base, SparcRegisters::g2, dest); 1.1138 + m_assembler.fstod_r(dest, dest); 1.1139 + } 1.1140 + 1.1141 + void loadFloat(ImplicitAddress address, FPRegisterID dest) 1.1142 + { 1.1143 + if (m_assembler.isimm13(address.offset)) 1.1144 + m_assembler.ldf_imm(address.base, address.offset, dest); 1.1145 + else { 1.1146 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.1147 + m_assembler.ldf_r(address.base, SparcRegisters::g3, dest); 1.1148 + } 1.1149 + m_assembler.fstod_r(dest, dest); 1.1150 + } 1.1151 + 1.1152 + void loadFloat(const void* address, FPRegisterID dest) 1.1153 + { 1.1154 + m_assembler.move_nocheck((int)address, SparcRegisters::g3); 1.1155 + m_assembler.ldf_r(SparcRegisters::g3, SparcRegisters::g0, dest); 1.1156 + m_assembler.fstod_r(dest, dest); 1.1157 + } 1.1158 + 1.1159 + void loadDouble(BaseIndex address, FPRegisterID dest) 1.1160 + { 1.1161 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.1162 + add32(Imm32(address.offset), SparcRegisters::g2); 1.1163 + m_assembler.ldf_r(address.base, SparcRegisters::g2, dest); 1.1164 + m_assembler.add_imm(SparcRegisters::g2, 4, SparcRegisters::g2); 1.1165 + m_assembler.ldf_r(address.base, SparcRegisters::g2, dest + 1); 1.1166 + } 1.1167 + 1.1168 + void loadDouble(ImplicitAddress address, FPRegisterID dest) 1.1169 + { 1.1170 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.1171 + m_assembler.ldf_r(address.base, SparcRegisters::g3, dest); 1.1172 + m_assembler.add_imm(SparcRegisters::g3, 4, SparcRegisters::g3); 1.1173 + m_assembler.ldf_r(address.base, SparcRegisters::g3, dest + 1); 1.1174 + } 1.1175 + 1.1176 + DataLabelPtr loadDouble(const void* address, FPRegisterID dest) 1.1177 + { 1.1178 + DataLabelPtr dataLabel(this); 1.1179 + m_assembler.move_nocheck((int)address, SparcRegisters::g3); 1.1180 + m_assembler.ldf_imm(SparcRegisters::g3, 0, dest); 1.1181 + m_assembler.ldf_imm(SparcRegisters::g3, 4, dest + 1); 1.1182 + return dataLabel; 1.1183 + } 1.1184 + 1.1185 + void storeFloat(FPRegisterID src, BaseIndex address) 1.1186 + { 1.1187 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.1188 + add32(Imm32(address.offset), SparcRegisters::g2); 1.1189 + m_assembler.stf_r(src, address.base, SparcRegisters::g2); 1.1190 + } 1.1191 + 1.1192 + void storeFloat(FPRegisterID src, ImplicitAddress address) 1.1193 + { 1.1194 + if (m_assembler.isimm13(address.offset)) 1.1195 + m_assembler.stf_imm(src, address.base, address.offset); 1.1196 + else { 1.1197 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.1198 + m_assembler.stf_r(src, address.base, SparcRegisters::g3); 1.1199 + } 1.1200 + } 1.1201 + 1.1202 + void storeFloat(ImmDouble imm, Address address) 1.1203 + { 1.1204 + union { 1.1205 + float f; 1.1206 + uint32_t u32; 1.1207 + } u; 1.1208 + u.f = imm.u.d; 1.1209 + store32(Imm32(u.u32), address); 1.1210 + } 1.1211 + 1.1212 + void storeFloat(ImmDouble imm, BaseIndex address) 1.1213 + { 1.1214 + union { 1.1215 + float f; 1.1216 + uint32_t u32; 1.1217 + } u; 1.1218 + u.f = imm.u.d; 1.1219 + store32(Imm32(u.u32), address); 1.1220 + } 1.1221 + 1.1222 + void storeDouble(FPRegisterID src, BaseIndex address) 1.1223 + { 1.1224 + m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2); 1.1225 + add32(Imm32(address.offset), SparcRegisters::g2); 1.1226 + m_assembler.stf_r(src, address.base, SparcRegisters::g2); 1.1227 + m_assembler.add_imm(SparcRegisters::g2, 4, SparcRegisters::g2); 1.1228 + m_assembler.stf_r(src + 1, address.base, SparcRegisters::g2); 1.1229 + } 1.1230 + 1.1231 + void storeDouble(FPRegisterID src, ImplicitAddress address) 1.1232 + { 1.1233 + if (m_assembler.isimm13(address.offset + 4)) { 1.1234 + m_assembler.stf_imm(src, address.base, address.offset); 1.1235 + m_assembler.stf_imm(src + 1, address.base, address.offset + 4); 1.1236 + } else { 1.1237 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.1238 + m_assembler.stf_r(src, address.base, SparcRegisters::g3); 1.1239 + m_assembler.add_imm(SparcRegisters::g3, 4, SparcRegisters::g3); 1.1240 + m_assembler.stf_r(src + 1, address.base, SparcRegisters::g3); 1.1241 + } 1.1242 + } 1.1243 + 1.1244 + void storeDouble(ImmDouble imm, Address address) 1.1245 + { 1.1246 + store32(Imm32(imm.u.s.msb), address); 1.1247 + store32(Imm32(imm.u.s.lsb), Address(address.base, address.offset + 4)); 1.1248 + } 1.1249 + 1.1250 + void storeDouble(ImmDouble imm, BaseIndex address) 1.1251 + { 1.1252 + store32(Imm32(imm.u.s.msb), address); 1.1253 + store32(Imm32(imm.u.s.lsb), 1.1254 + BaseIndex(address.base, address.index, address.scale, address.offset + 4)); 1.1255 + } 1.1256 + 1.1257 + void addDouble(FPRegisterID src, FPRegisterID dest) 1.1258 + { 1.1259 + m_assembler.faddd_r(src, dest, dest); 1.1260 + } 1.1261 + 1.1262 + void addDouble(Address src, FPRegisterID dest) 1.1263 + { 1.1264 + loadDouble(src, SparcRegisters::f30); 1.1265 + m_assembler.faddd_r(SparcRegisters::f30, dest, dest); 1.1266 + } 1.1267 + 1.1268 + void divDouble(FPRegisterID src, FPRegisterID dest) 1.1269 + { 1.1270 + m_assembler.fdivd_r(dest, src, dest); 1.1271 + } 1.1272 + 1.1273 + void divDouble(Address src, FPRegisterID dest) 1.1274 + { 1.1275 + loadDouble(src, SparcRegisters::f30); 1.1276 + m_assembler.fdivd_r(dest, SparcRegisters::f30, dest); 1.1277 + } 1.1278 + 1.1279 + void subDouble(FPRegisterID src, FPRegisterID dest) 1.1280 + { 1.1281 + m_assembler.fsubd_r(dest, src, dest); 1.1282 + } 1.1283 + 1.1284 + void subDouble(Address src, FPRegisterID dest) 1.1285 + { 1.1286 + loadDouble(src, SparcRegisters::f30); 1.1287 + m_assembler.fsubd_r(dest, SparcRegisters::f30, dest); 1.1288 + } 1.1289 + 1.1290 + void mulDouble(FPRegisterID src, FPRegisterID dest) 1.1291 + { 1.1292 + m_assembler.fmuld_r(src, dest, dest); 1.1293 + } 1.1294 + 1.1295 + void mulDouble(Address src, FPRegisterID dest) 1.1296 + { 1.1297 + loadDouble(src, SparcRegisters::f30); 1.1298 + m_assembler.fmuld_r(SparcRegisters::f30, dest, dest); 1.1299 + } 1.1300 + 1.1301 + void absDouble(FPRegisterID src, FPRegisterID dest) 1.1302 + { 1.1303 + m_assembler.fabsd_r(src, dest); 1.1304 + } 1.1305 + 1.1306 + void sqrtDouble(FPRegisterID src, FPRegisterID dest) 1.1307 + { 1.1308 + m_assembler.fsqrtd_r(src, dest); 1.1309 + } 1.1310 + 1.1311 + void negDouble(FPRegisterID src, FPRegisterID dest) 1.1312 + { 1.1313 + m_assembler.fnegd_r(src, dest); 1.1314 + } 1.1315 + 1.1316 + void convertUInt32ToDouble(RegisterID src, FPRegisterID dest) 1.1317 + { 1.1318 + m_assembler.move_nocheck(0x43300000, SparcRegisters::g1); 1.1319 + m_assembler.stw_imm(SparcRegisters::g1, SparcRegisters::sp, 0x60); 1.1320 + m_assembler.stw_imm(src, SparcRegisters::sp, 0x64); 1.1321 + m_assembler.ldf_imm(SparcRegisters::sp, 0x60, SparcRegisters::f30); 1.1322 + m_assembler.ldf_imm(SparcRegisters::sp, 0x64, SparcRegisters::f31); 1.1323 + m_assembler.stw_imm(SparcRegisters::g0, SparcRegisters::sp, 0x64); 1.1324 + m_assembler.ldf_imm(SparcRegisters::sp, 0x60, dest); 1.1325 + m_assembler.ldf_imm(SparcRegisters::sp, 0x64, dest + 1); 1.1326 + m_assembler.fsubd_r(SparcRegisters::f30, dest, dest); 1.1327 + m_assembler.fabss_r(dest, dest); 1.1328 + } 1.1329 + 1.1330 + void convertInt32ToDouble(RegisterID src, FPRegisterID dest) 1.1331 + { 1.1332 + m_assembler.stw_imm(src, SparcRegisters::sp, 0x60); 1.1333 + m_assembler.ldf_imm(SparcRegisters::sp, 0x60, dest); 1.1334 + m_assembler.fitod_r(dest, dest); 1.1335 + } 1.1336 + 1.1337 + void convertInt32ToDouble(Address address, FPRegisterID dest) 1.1338 + { 1.1339 + if (m_assembler.isimm13(address.offset)) 1.1340 + m_assembler.ldf_imm(address.base, address.offset, dest); 1.1341 + else { 1.1342 + m_assembler.move_nocheck(address.offset, SparcRegisters::g3); 1.1343 + m_assembler.ldf_r(address.base, SparcRegisters::g3, dest); 1.1344 + } 1.1345 + m_assembler.fitod_r(dest, dest); 1.1346 + } 1.1347 + 1.1348 + void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest) 1.1349 + { 1.1350 + m_assembler.move_nocheck((int)src.m_ptr, SparcRegisters::g3); 1.1351 + m_assembler.ldf_r(SparcRegisters::g3, SparcRegisters::g0, dest); 1.1352 + m_assembler.fitod_r(dest, dest); 1.1353 + } 1.1354 + 1.1355 + void fastLoadDouble(RegisterID lo, RegisterID hi, FPRegisterID fpReg) 1.1356 + { 1.1357 + m_assembler.stw_imm(lo, SparcRegisters::sp, 0x64); 1.1358 + m_assembler.stw_imm(hi, SparcRegisters::sp, 0x60); 1.1359 + m_assembler.ldf_imm(SparcRegisters::sp, 0x60, fpReg); 1.1360 + m_assembler.ldf_imm(SparcRegisters::sp, 0x64, fpReg + 1); 1.1361 + } 1.1362 + 1.1363 + void convertDoubleToFloat(FPRegisterID src, FPRegisterID dest) 1.1364 + { 1.1365 + m_assembler.fdtos_r(src, dest); 1.1366 + } 1.1367 + 1.1368 + void breakDoubleTo32(FPRegisterID srcDest, RegisterID typeReg, RegisterID dataReg) { 1.1369 + // We don't assume stack is aligned to 8. 1.1370 + // Always using stf, ldf instead of stdf, lddf. 1.1371 + m_assembler.stf_imm(srcDest, SparcRegisters::sp, 0x60); 1.1372 + m_assembler.stf_imm(srcDest + 1, SparcRegisters::sp, 0x64); 1.1373 + m_assembler.lduw_imm(SparcRegisters::sp, 0x60, typeReg); 1.1374 + m_assembler.lduw_imm(SparcRegisters::sp, 0x64, dataReg); 1.1375 + } 1.1376 + 1.1377 + Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right) 1.1378 + { 1.1379 + m_assembler.fcmpd_r(left, right); 1.1380 + return Jump(m_assembler.fbranch(SparcDoubleCondition(cond))); 1.1381 + } 1.1382 + 1.1383 + // Truncates 'src' to an integer, and places the resulting 'dest'. 1.1384 + // If the result is not representable as a 32 bit value, branch. 1.1385 + // May also branch for some values that are representable in 32 bits 1.1386 + // (specifically, in this case, INT_MIN). 1.1387 + Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest) 1.1388 + { 1.1389 + m_assembler.fdtoi_r(src, SparcRegisters::f30); 1.1390 + m_assembler.stf_imm(SparcRegisters::f30, SparcRegisters::sp, 0x60); 1.1391 + m_assembler.lduw_imm(SparcRegisters::sp, 0x60, dest); 1.1392 + 1.1393 + m_assembler.or_r(SparcRegisters::g0, SparcRegisters::g0, SparcRegisters::g2); 1.1394 + m_assembler.move_nocheck(0x80000000, SparcRegisters::g3); 1.1395 + m_assembler.subcc_r(SparcRegisters::g3, dest, SparcRegisters::g0); 1.1396 + m_assembler.movcc_imm(1, SparcRegisters::g2, SparcCondition(Equal)); 1.1397 + m_assembler.move_nocheck(0x7fffffff, SparcRegisters::g3); 1.1398 + m_assembler.subcc_r(SparcRegisters::g3, dest, SparcRegisters::g0); 1.1399 + m_assembler.movcc_imm(1, SparcRegisters::g2, SparcCondition(Equal)); 1.1400 + 1.1401 + return branch32(Equal, SparcRegisters::g2, Imm32(1)); 1.1402 + } 1.1403 + 1.1404 + // Convert 'src' to an integer, and places the resulting 'dest'. 1.1405 + // If the result is not representable as a 32 bit value, branch. 1.1406 + // May also branch for some values that are representable in 32 bits 1.1407 + // (specifically, in this case, 0). 1.1408 + void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp) 1.1409 + { 1.1410 + m_assembler.fdtoi_r(src, SparcRegisters::f30); 1.1411 + m_assembler.stf_imm(SparcRegisters::f30, SparcRegisters::sp, 0x60); 1.1412 + m_assembler.lduw_imm(SparcRegisters::sp, 0x60, dest); 1.1413 + 1.1414 + // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump. 1.1415 + m_assembler.fitod_r(SparcRegisters::f30, SparcRegisters::f30); 1.1416 + failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, SparcRegisters::f30)); 1.1417 + 1.1418 + // If the result is zero, it might have been -0.0, and 0.0 equals to -0.0 1.1419 + failureCases.append(branchTest32(Zero, dest)); 1.1420 + } 1.1421 + 1.1422 + void zeroDouble(FPRegisterID srcDest) 1.1423 + { 1.1424 + fastLoadDouble(SparcRegisters::g0, SparcRegisters::g0, srcDest); 1.1425 + } 1.1426 + 1.1427 + protected: 1.1428 + SparcAssembler::Condition SparcCondition(Condition cond) 1.1429 + { 1.1430 + return static_cast<SparcAssembler::Condition>(cond); 1.1431 + } 1.1432 + 1.1433 + SparcAssembler::DoubleCondition SparcDoubleCondition(DoubleCondition cond) 1.1434 + { 1.1435 + return static_cast<SparcAssembler::DoubleCondition>(cond); 1.1436 + } 1.1437 + 1.1438 + private: 1.1439 + friend class LinkBuffer; 1.1440 + friend class RepatchBuffer; 1.1441 + 1.1442 + static void linkCall(void* code, Call call, FunctionPtr function) 1.1443 + { 1.1444 + SparcAssembler::linkCall(code, call.m_jmp, function.value()); 1.1445 + } 1.1446 + 1.1447 + static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) 1.1448 + { 1.1449 + SparcAssembler::relinkCall(call.dataLocation(), destination.executableAddress()); 1.1450 + } 1.1451 + 1.1452 + static void repatchCall(CodeLocationCall call, FunctionPtr destination) 1.1453 + { 1.1454 + SparcAssembler::relinkCall(call.dataLocation(), destination.executableAddress()); 1.1455 + } 1.1456 + 1.1457 + }; 1.1458 + 1.1459 +} 1.1460 + 1.1461 + 1.1462 +#endif // ENABLE(ASSEMBLER) && CPU(SPARC) 1.1463 + 1.1464 +#endif /* assembler_assembler_MacroAssemblerSparc_h */