js/src/assembler/assembler/MacroAssemblerSparc.h

changeset 0
6474c204b198
     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 */

mercurial