js/src/assembler/assembler/MacroAssemblerSparc.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef assembler_assembler_MacroAssemblerSparc_h
     8 #define assembler_assembler_MacroAssemblerSparc_h
    10 #include "assembler/wtf/Platform.h"
    12 #if ENABLE_ASSEMBLER && WTF_CPU_SPARC
    14 #include "assembler/assembler/SparcAssembler.h"
    15 #include "assembler/assembler/AbstractMacroAssembler.h"
    17 namespace JSC {
    19     class MacroAssemblerSparc : public AbstractMacroAssembler<SparcAssembler> {
    20     public:
    21         enum Condition {
    22             Equal = SparcAssembler::ConditionE,
    23             NotEqual = SparcAssembler::ConditionNE,
    24             Above = SparcAssembler::ConditionGU,
    25             AboveOrEqual = SparcAssembler::ConditionCC,
    26             Below = SparcAssembler::ConditionCS,
    27             BelowOrEqual = SparcAssembler::ConditionLEU,
    28             GreaterThan = SparcAssembler::ConditionG,
    29             GreaterThanOrEqual = SparcAssembler::ConditionGE,
    30             LessThan = SparcAssembler::ConditionL,
    31             LessThanOrEqual = SparcAssembler::ConditionLE,
    32             Overflow = SparcAssembler::ConditionVS,
    33             Signed = SparcAssembler::ConditionNEG,
    34             Zero = SparcAssembler::ConditionE,
    35             NonZero = SparcAssembler::ConditionNE
    36         };
    38         enum DoubleCondition {
    39             // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
    40             DoubleEqual = SparcAssembler::DoubleConditionE,
    41             DoubleNotEqual = SparcAssembler::DoubleConditionNE,
    42             DoubleGreaterThan = SparcAssembler::DoubleConditionG,
    43             DoubleGreaterThanOrEqual = SparcAssembler::DoubleConditionGE,
    44             DoubleLessThan = SparcAssembler::DoubleConditionL,
    45             DoubleLessThanOrEqual = SparcAssembler::DoubleConditionLE,
    46             // If either operand is NaN, these conditions always evaluate to true.
    47             DoubleEqualOrUnordered = SparcAssembler::DoubleConditionUE,
    48             DoubleNotEqualOrUnordered = SparcAssembler::DoubleConditionNE,
    49             DoubleGreaterThanOrUnordered = SparcAssembler::DoubleConditionUG,
    50             DoubleGreaterThanOrEqualOrUnordered = SparcAssembler::DoubleConditionUGE,
    51             DoubleLessThanOrUnordered = SparcAssembler::DoubleConditionUL,
    52             DoubleLessThanOrEqualOrUnordered = SparcAssembler::DoubleConditionULE
    53         };
    55         static const RegisterID stackPointerRegister = SparcRegisters::sp;
    57         static const Scale ScalePtr = TimesFour;
    58         static const unsigned int TotalRegisters = 24;
    60         void add32(RegisterID src, RegisterID dest)
    61         {
    62             m_assembler.addcc_r(dest, src, dest);
    63         }
    65         void add32(TrustedImm32 imm, Address address)
    66         {
    67             load32(address, SparcRegisters::g2);
    68             add32(imm, SparcRegisters::g2);
    69             store32(SparcRegisters::g2, address);
    70         }
    72         void add32(TrustedImm32 imm, RegisterID dest)
    73         {
    74             if (m_assembler.isimm13(imm.m_value))
    75                 m_assembler.addcc_imm(dest, imm.m_value, dest);
    76             else {
    77                 m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3);
    78                 m_assembler.addcc_r(dest, SparcRegisters::g3, dest);
    79             }
    80         }
    82         void add32(Address src, RegisterID dest)
    83         {
    84             load32(src, SparcRegisters::g2);
    85             m_assembler.addcc_r(dest, SparcRegisters::g2, dest);
    86         }
    88         void and32(Address src, RegisterID dest)
    89         {
    90             load32(src, SparcRegisters::g2);
    91             m_assembler.andcc_r(dest, SparcRegisters::g2, dest);
    92         }
    94         void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
    95         {
    96             if (m_assembler.isimm13(imm.m_value))
    97                 m_assembler.addcc_imm(src, imm.m_value, dest);
    98             else {
    99                 m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3);
   100                 m_assembler.addcc_r(src, SparcRegisters::g3, dest);
   101             }
   102         }
   104         void and32(RegisterID src, RegisterID dest)
   105         {
   106             m_assembler.andcc_r(dest, src, dest);
   107         }
   109         void and32(Imm32 imm, RegisterID dest)
   110         {
   111             if (m_assembler.isimm13(imm.m_value))
   112                 m_assembler.andcc_imm(dest, imm.m_value, dest);
   113             else {
   114                 m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3);
   115                 m_assembler.andcc_r(dest, SparcRegisters::g3, dest);
   116             }
   117         }
   120         void lshift32(RegisterID shift_amount, RegisterID dest)
   121         {
   122             m_assembler.sll_r(dest, shift_amount, dest);
   123         }
   125         void lshift32(Imm32 imm, RegisterID dest)
   126         {
   127             // No need to check if imm.m_value.
   128             // The last 5 bit of imm.m_value will be used anyway.
   129             m_assembler.sll_imm(dest, imm.m_value, dest);
   130         }
   132         void mul32(RegisterID src, RegisterID dest)
   133         {
   134             m_assembler.smulcc_r(dest, src, dest);
   135         }
   137         void mul32(Imm32 imm, RegisterID src, RegisterID dest)
   138         {
   139             if (m_assembler.isimm13(imm.m_value))
   140                 m_assembler.smulcc_imm(dest, imm.m_value, dest);
   141             else {
   142                 m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3);
   143                 m_assembler.smulcc_r(SparcRegisters::g3, dest, dest);
   144             }
   145         }
   147         void neg32(RegisterID srcDest)
   148         {
   149             m_assembler.subcc_r(SparcRegisters::g0, srcDest, srcDest);
   150         }
   152         void not32(RegisterID dest)
   153         {
   154             m_assembler.xnorcc_r(dest, SparcRegisters::g0, dest);
   155         }
   157         void or32(RegisterID src, RegisterID dest)
   158         {
   159             m_assembler.orcc_r(dest, src, dest);
   160         }
   162         void or32(TrustedImm32 imm, RegisterID dest)
   163         {
   164             if (m_assembler.isimm13(imm.m_value))
   165                 m_assembler.orcc_imm(dest, imm.m_value, dest);
   166             else {
   167                 m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3);
   168                 m_assembler.or_r(SparcRegisters::g3, dest, dest);
   169             }
   170         }
   173         void or32(Address address, RegisterID dest)
   174         {
   175             load32(address, SparcRegisters::g2);
   176             or32(SparcRegisters::g2, dest);
   177         }
   179         void rshift32(RegisterID shift_amount, RegisterID dest)
   180         {
   181             m_assembler.sra_r(dest, shift_amount, dest);
   182         }
   184         void rshift32(Imm32 imm, RegisterID dest)
   185         {
   186             // No need to check if imm.m_value.
   187             // The last 5 bit of imm.m_value will be used anyway.
   188             m_assembler.sra_imm(dest, imm.m_value, dest);
   189         }
   191         void urshift32(RegisterID shift_amount, RegisterID dest)
   192         {
   193             m_assembler.srl_r(dest, shift_amount, dest);
   194         }
   196         void urshift32(Imm32 imm, RegisterID dest)
   197         {
   198             // No need to check if imm.m_value.
   199             // The last 5 bit of imm.m_value will be used anyway.
   200             m_assembler.srl_imm(dest, imm.m_value, dest);
   201         }
   203         void sub32(RegisterID src, RegisterID dest)
   204         {
   205             m_assembler.subcc_r(dest, src, dest);
   206         }
   208         void sub32(TrustedImm32 imm, RegisterID dest)
   209         {
   210             if (m_assembler.isimm13(imm.m_value))
   211                 m_assembler.subcc_imm(dest, imm.m_value, dest);
   212             else {
   213                 m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3);
   214                 m_assembler.subcc_r(dest, SparcRegisters::g3, dest);
   215             }
   216         }
   218         void sub32(TrustedImm32 imm, Address address)
   219         {
   220             load32(address, SparcRegisters::g2);
   221             sub32(imm, SparcRegisters::g2);
   222             store32(SparcRegisters::g2, address);
   223         }
   225         void sub32(Address src, RegisterID dest)
   226         {
   227             load32(src, SparcRegisters::g2);
   228             sub32(SparcRegisters::g2, dest);
   229         }
   231         void xor32(RegisterID src, RegisterID dest)
   232         {
   233             m_assembler.xorcc_r(src, dest, dest);
   234         }
   236         void xor32(TrustedImm32 imm, RegisterID dest)
   237         {
   238             if (m_assembler.isimm13(imm.m_value))
   239                 m_assembler.xorcc_imm(dest, imm.m_value, dest);
   240             else {
   241                 m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3);
   242                 m_assembler.xorcc_r(dest, SparcRegisters::g3, dest);
   243             }
   244         }
   246         void xor32(Address src, RegisterID dest)
   247         {
   248             load32(src, SparcRegisters::g2);
   249             xor32(SparcRegisters::g2, dest);
   250         }
   252         void load8(ImplicitAddress address, RegisterID dest)
   253         {
   254             if (m_assembler.isimm13(address.offset))
   255                 m_assembler.ldub_imm(address.base, address.offset, dest);
   256             else {
   257                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   258                 m_assembler.ldub_r(address.base, SparcRegisters::g3, dest);
   259             }
   260         }
   262         void load32(ImplicitAddress address, RegisterID dest)
   263         {
   264             if (m_assembler.isimm13(address.offset))
   265                 m_assembler.lduw_imm(address.base, address.offset, dest);
   266             else {
   267                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   268                 m_assembler.lduw_r(address.base, SparcRegisters::g3, dest);
   269             }
   270         }
   272         void load32(BaseIndex address, RegisterID dest)
   273         {
   274             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   275             add32(Imm32(address.offset), SparcRegisters::g2);
   276             m_assembler.lduw_r(address.base, SparcRegisters::g2, dest);
   277         }
   279         void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
   280         {
   281             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   282             add32(Imm32(address.offset+3), SparcRegisters::g2);
   283             m_assembler.ldub_r(address.base, SparcRegisters::g2, dest);
   284             m_assembler.subcc_imm(SparcRegisters::g2, 1, SparcRegisters::g2);
   285             m_assembler.ldub_r(address.base, SparcRegisters::g2, SparcRegisters::g3);
   286             m_assembler.sll_imm(SparcRegisters::g3, 8, SparcRegisters::g3);
   287             m_assembler.or_r(SparcRegisters::g3, dest, dest);
   288             m_assembler.subcc_imm(SparcRegisters::g2, 1, SparcRegisters::g2);
   289             m_assembler.ldub_r(address.base, SparcRegisters::g2, SparcRegisters::g3);
   290             m_assembler.sll_imm(SparcRegisters::g3, 16, SparcRegisters::g3);
   291             m_assembler.or_r(SparcRegisters::g3, dest, dest);
   292             m_assembler.subcc_imm(SparcRegisters::g2, 1, SparcRegisters::g2);
   293             m_assembler.ldub_r(address.base, SparcRegisters::g2, SparcRegisters::g3);
   294             m_assembler.sll_imm(SparcRegisters::g3, 24, SparcRegisters::g3);
   295             m_assembler.or_r(SparcRegisters::g3, dest, dest);
   296         }
   298         DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
   299         {
   300             DataLabel32 dataLabel(this);
   301             m_assembler.move_nocheck(0, SparcRegisters::g3);
   302             m_assembler.lduw_r(address.base, SparcRegisters::g3, dest);
   303             return dataLabel;
   304         }
   306         DataLabel32 load64WithAddressOffsetPatch(Address address, RegisterID hi, RegisterID lo)
   307         {
   308             DataLabel32 dataLabel(this);
   309             m_assembler.move_nocheck(0, SparcRegisters::g3);
   310             m_assembler.add_imm(SparcRegisters::g3, 4, SparcRegisters::g2);
   311             m_assembler.lduw_r(address.base, SparcRegisters::g3, hi);
   312             m_assembler.lduw_r(address.base, SparcRegisters::g2, lo);
   313             return dataLabel;
   314         }
   316         Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
   317         {
   318             Label label(this);
   319             load32(address, dest);
   320             return label;
   321         }
   323         void load16(BaseIndex address, RegisterID dest)
   324         {
   325             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   326             add32(Imm32(address.offset), SparcRegisters::g2);
   327             m_assembler.lduh_r(address.base, SparcRegisters::g2, dest);
   328         }
   330         void load16(ImplicitAddress address, RegisterID dest)
   331         {
   332             if (m_assembler.isimm13(address.offset))
   333                 m_assembler.lduh_imm(address.base, address.offset, dest);
   334             else {
   335                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   336                 m_assembler.lduh_r(address.base, SparcRegisters::g3, dest);
   337             }
   338         }
   340         void store8(RegisterID src, ImplicitAddress address)
   341         {
   342             if (m_assembler.isimm13(address.offset))
   343                 m_assembler.stb_imm(src, address.base, address.offset);
   344             else {
   345                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   346                 m_assembler.stb_r(src, address.base, SparcRegisters::g3);
   347             }
   348         }
   350         void store8(RegisterID src, BaseIndex address)
   351         {
   352             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   353             add32(Imm32(address.offset), SparcRegisters::g2);
   354             m_assembler.stb_r(src, address.base, SparcRegisters::g2);
   355         }
   357         void store8(Imm32 imm, ImplicitAddress address)
   358         {
   359             m_assembler.move_nocheck(imm.m_value, SparcRegisters::g2);
   360             store8(SparcRegisters::g2, address);
   361         }
   363         void store8(Imm32 imm, BaseIndex address)
   364         {
   365             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   366             add32(Imm32(address.offset), SparcRegisters::g2);
   367             move(imm, SparcRegisters::g3);
   368             m_assembler.stb_r(SparcRegisters::g3, SparcRegisters::g2, address.base);
   369         }
   371         void store16(RegisterID src, ImplicitAddress address)
   372         {
   373             if (m_assembler.isimm13(address.offset))
   374                 m_assembler.sth_imm(src, address.base, address.offset);
   375             else {
   376                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   377                 m_assembler.sth_r(src, address.base, SparcRegisters::g3);
   378             }
   379         }
   381         void store16(RegisterID src, BaseIndex address)
   382         {
   383             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   384             add32(Imm32(address.offset), SparcRegisters::g2);
   385             m_assembler.sth_r(src, address.base, SparcRegisters::g2);
   386         }
   388         void store16(Imm32 imm, ImplicitAddress address)
   389         {
   390             m_assembler.move_nocheck(imm.m_value, SparcRegisters::g2);
   391             store16(SparcRegisters::g2, address);
   392         }
   394         void store16(Imm32 imm, BaseIndex address)
   395         {
   396             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   397             add32(Imm32(address.offset), SparcRegisters::g2);
   398             move(imm, SparcRegisters::g3);
   399             m_assembler.sth_r(SparcRegisters::g3, SparcRegisters::g2, address.base);
   400         }
   402         void load8ZeroExtend(BaseIndex address, RegisterID dest)
   403         {
   404             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   405             add32(Imm32(address.offset), SparcRegisters::g2);
   406             m_assembler.ldub_r(address.base, SparcRegisters::g2, dest);
   407         }
   409         void load8ZeroExtend(Address address, RegisterID dest)
   410         {
   411             if (m_assembler.isimm13(address.offset))
   412                 m_assembler.ldub_imm(address.base, address.offset, dest);
   413             else {
   414                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   415                 m_assembler.ldub_r(address.base, SparcRegisters::g3, dest);
   416             }
   417         }
   419         void load8SignExtend(BaseIndex address, RegisterID dest)
   420         {
   421             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   422             add32(Imm32(address.offset), SparcRegisters::g2);
   423             m_assembler.ldsb_r(address.base, SparcRegisters::g2, dest);
   424         }
   426         void load8SignExtend(Address address, RegisterID dest)
   427         {
   428             if (m_assembler.isimm13(address.offset))
   429                 m_assembler.ldsb_imm(address.base, address.offset, dest);
   430             else {
   431                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   432                 m_assembler.ldsb_r(address.base, SparcRegisters::g3, dest);
   433             }
   434         }
   436         void load16SignExtend(BaseIndex address, RegisterID dest)
   437         {
   438             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   439             add32(Imm32(address.offset), SparcRegisters::g2);
   440             m_assembler.ldsh_r(address.base, SparcRegisters::g2, dest);
   441         }
   443         void load16SignExtend(Address address, RegisterID dest)
   444         {
   445             if (m_assembler.isimm13(address.offset))
   446                 m_assembler.ldsh_imm(address.base, address.offset, dest);
   447             else {
   448                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   449                 m_assembler.ldsh_r(address.base, SparcRegisters::g3, dest);
   450             }
   451         }
   453         DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
   454         {
   455             DataLabel32 dataLabel(this);
   456             // Since this is for patch, we don't check is offset is imm13.
   457             m_assembler.move_nocheck(0, SparcRegisters::g3);
   458             m_assembler.stw_r(src, address.base, SparcRegisters::g3);
   459             return dataLabel;
   460         }
   463         DataLabel32 store64WithAddressOffsetPatch(RegisterID hi, RegisterID lo, Address address)
   464         {
   465             DataLabel32 dataLabel(this);
   466             m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   467             m_assembler.add_r(SparcRegisters::g3, address.base, SparcRegisters::g3);
   468             m_assembler.stw_imm(lo, SparcRegisters::g3, 4);
   469             m_assembler.stw_imm(hi, SparcRegisters::g3, 0);
   470             return dataLabel;
   471         }
   473         DataLabel32 store64WithAddressOffsetPatch(Imm32 hi, RegisterID lo, Address address)
   474         {
   475             DataLabel32 dataLabel(this);
   476             m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   477             m_assembler.add_r(SparcRegisters::g3, address.base, SparcRegisters::g3);
   478             m_assembler.stw_imm(lo, SparcRegisters::g3, 4);
   479             move(hi, SparcRegisters::g2);
   480             m_assembler.stw_imm(SparcRegisters::g2, SparcRegisters::g3, 0);
   482             return dataLabel;
   483         }
   485         DataLabel32 store64WithAddressOffsetPatch(Imm32 hi, Imm32 lo, Address address)
   486         {
   487             DataLabel32 dataLabel(this);
   488             m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   489             m_assembler.add_r(SparcRegisters::g3, address.base, SparcRegisters::g3);
   490             move(lo, SparcRegisters::g2);
   491             m_assembler.stw_imm(SparcRegisters::g2, SparcRegisters::g3, 4);
   492             move(hi, SparcRegisters::g2);
   493             m_assembler.stw_imm(SparcRegisters::g2, SparcRegisters::g3, 0);
   495             return dataLabel;
   496         }
   499         void store32(RegisterID src, ImplicitAddress address)
   500         {
   501             if (m_assembler.isimm13(address.offset))
   502                 m_assembler.stw_imm(src, address.base, address.offset);
   503             else {
   504                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   505                 m_assembler.stw_r(src, address.base, SparcRegisters::g3);
   506             }
   507         }
   509         void store32(RegisterID src, BaseIndex address)
   510         {
   511             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   512             add32(Imm32(address.offset), SparcRegisters::g2);
   513             m_assembler.stw_r(src, address.base, SparcRegisters::g2);
   514         }
   516         void store32(TrustedImm32 imm, BaseIndex address)
   517         {
   518             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
   519             add32(Imm32(address.offset), SparcRegisters::g2);
   520             move(imm, SparcRegisters::g3);
   521             m_assembler.stw_r(SparcRegisters::g3, SparcRegisters::g2, address.base);
   522         }
   524         void store32(TrustedImm32 imm, ImplicitAddress address)
   525         {
   526             m_assembler.move_nocheck(imm.m_value, SparcRegisters::g2);
   527             store32(SparcRegisters::g2, address);
   528         }
   530         void store32(RegisterID src, void* address)
   531         {
   532             m_assembler.move_nocheck((int)address, SparcRegisters::g3);
   533             m_assembler.stw_r(src, SparcRegisters::g0, SparcRegisters::g3);
   534         }
   536         void store32(TrustedImm32 imm, void* address)
   537         {
   538             move(imm, SparcRegisters::g2);
   539             store32(SparcRegisters::g2, address);
   540         }
   542         void pop(RegisterID dest)
   543         {
   544             m_assembler.lduw_imm(SparcRegisters::sp, 0x68, dest);
   545             m_assembler.addcc_imm(SparcRegisters::sp, 4, SparcRegisters::sp);
   546         }
   548         void push(RegisterID src)
   549         {
   550             m_assembler.subcc_imm(SparcRegisters::sp, 4, SparcRegisters::sp);
   551             m_assembler.stw_imm(src, SparcRegisters::sp, 0x68);
   552         }
   554         void push(Address address)
   555         {
   556             load32(address, SparcRegisters::g2);
   557             push(SparcRegisters::g2);
   558         }
   560         void push(Imm32 imm)
   561         {
   562             move(imm, SparcRegisters::g2);
   563             push(SparcRegisters::g2);
   564         }
   566         void move(TrustedImm32 imm, RegisterID dest)
   567         {
   568             if (m_assembler.isimm13(imm.m_value))
   569                 m_assembler.or_imm(SparcRegisters::g0, imm.m_value, dest);
   570             else
   571                 m_assembler.move_nocheck(imm.m_value, dest);
   572         }
   574         void move(RegisterID src, RegisterID dest)
   575         {
   576             m_assembler.or_r(src, SparcRegisters::g0, dest);
   577         }
   579         void move(TrustedImmPtr imm, RegisterID dest)
   580         {
   581             move(Imm32(imm), dest);
   582         }
   584         void swap(RegisterID reg1, RegisterID reg2)
   585         {
   586             m_assembler.or_r(reg1, SparcRegisters::g0, SparcRegisters::g3);
   587             m_assembler.or_r(reg2, SparcRegisters::g0, reg1);
   588             m_assembler.or_r(SparcRegisters::g3, SparcRegisters::g0, reg2);
   589         }
   591         void signExtend32ToPtr(RegisterID src, RegisterID dest)
   592         {
   593             if (src != dest)
   594                 move(src, dest);
   595         }
   597         void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
   598         {
   599             if (src != dest)
   600                 move(src, dest);
   601         }
   603         Jump branch8(Condition cond, Address left, Imm32 right)
   604         {
   605             load8(left, SparcRegisters::g2);
   606             return branch32(cond, SparcRegisters::g2, right);
   607         }
   609         Jump branch32_force32(Condition cond, RegisterID left, TrustedImm32 right)
   610         {
   611             m_assembler.move_nocheck(right.m_value, SparcRegisters::g3);
   612             m_assembler.subcc_r(left, SparcRegisters::g3, SparcRegisters::g0);
   613             return Jump(m_assembler.branch(SparcCondition(cond)));
   614         }
   616         Jump branch32FixedLength(Condition cond, RegisterID left, TrustedImm32 right)
   617         {
   618             m_assembler.move_nocheck(right.m_value, SparcRegisters::g2);
   619             return branch32(cond, left, SparcRegisters::g2);
   620         }
   622         Jump branch32WithPatch(Condition cond, RegisterID left, TrustedImm32 right, DataLabel32 &dataLabel)
   623         {
   624             // Always use move_nocheck, since the value is to be patched.
   625             dataLabel = DataLabel32(this);
   626             m_assembler.move_nocheck(right.m_value, SparcRegisters::g3);
   627             m_assembler.subcc_r(left, SparcRegisters::g3, SparcRegisters::g0);
   628             return Jump(m_assembler.branch(SparcCondition(cond)));
   629         }
   631         Jump branch32(Condition cond, RegisterID left, RegisterID right)
   632         {
   633             m_assembler.subcc_r(left, right, SparcRegisters::g0);
   634             return Jump(m_assembler.branch(SparcCondition(cond)));
   635         }
   637         Jump branch32(Condition cond, RegisterID left, TrustedImm32 right)
   638         {
   639             if (m_assembler.isimm13(right.m_value))
   640                 m_assembler.subcc_imm(left, right.m_value, SparcRegisters::g0);
   641             else {
   642                 m_assembler.move_nocheck(right.m_value, SparcRegisters::g3);
   643                 m_assembler.subcc_r(left, SparcRegisters::g3, SparcRegisters::g0);
   644             }
   645             return Jump(m_assembler.branch(SparcCondition(cond)));
   646         }
   648         Jump branch32(Condition cond, RegisterID left, Address right)
   649         {
   650             load32(right, SparcRegisters::g2);
   651             return branch32(cond, left, SparcRegisters::g2);
   652         }
   654         Jump branch32(Condition cond, Address left, RegisterID right)
   655         {
   656             load32(left, SparcRegisters::g2);
   657             return branch32(cond, SparcRegisters::g2, right);
   658         }
   660         Jump branch32(Condition cond, Address left, TrustedImm32 right)
   661         {
   662             load32(left, SparcRegisters::g2);
   663             return branch32(cond, SparcRegisters::g2, right);
   664         }
   666         Jump branch32(Condition cond, BaseIndex left, TrustedImm32 right)
   667         {
   669             load32(left, SparcRegisters::g2);
   670             return branch32(cond, SparcRegisters::g2, right);
   671         }
   673         Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, TrustedImm32 right)
   674         {
   675             load32WithUnalignedHalfWords(left, SparcRegisters::g4);
   676             return branch32(cond, SparcRegisters::g4, right);
   677         }
   679         Jump branch16(Condition cond, BaseIndex left, RegisterID right)
   680         {
   681             (void)(cond);
   682             (void)(left);
   683             (void)(right);
   684             ASSERT_NOT_REACHED();
   685             return jump();
   686         }
   688         Jump branch16(Condition cond, BaseIndex left, Imm32 right)
   689         {
   690             load16(left, SparcRegisters::g3);
   691             move(right, SparcRegisters::g2);
   692             m_assembler.subcc_r(SparcRegisters::g3, SparcRegisters::g2, SparcRegisters::g0);
   693             return Jump(m_assembler.branch(SparcCondition(cond)));
   694         }
   696         Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1))
   697         {
   698             load8(address, SparcRegisters::g2);
   699             return branchTest32(cond, SparcRegisters::g2, mask);
   700         }
   702         Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
   703         {
   704             m_assembler.andcc_r(reg, mask, SparcRegisters::g0);
   705             return Jump(m_assembler.branch(SparcCondition(cond)));
   706         }
   708         Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
   709         {
   710             if (m_assembler.isimm13(mask.m_value))
   711                 m_assembler.andcc_imm(reg, mask.m_value, SparcRegisters::g0);
   712             else {
   713                 m_assembler.move_nocheck(mask.m_value, SparcRegisters::g3);
   714                 m_assembler.andcc_r(reg, SparcRegisters::g3, SparcRegisters::g0);
   715             }
   716             return Jump(m_assembler.branch(SparcCondition(cond)));
   717         }
   719         Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
   720         {
   721             load32(address, SparcRegisters::g2);
   722             return branchTest32(cond, SparcRegisters::g2, mask);
   723         }
   725         Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
   726         {
   727             // FIXME. branchTest32 only used by PolyIC.
   728             // PolyIC is not enabled for sparc now.
   729             ASSERT(0);
   730             return jump();
   731         }
   733         Jump jump()
   734         {
   735             return Jump(m_assembler.jmp());
   736         }
   738         void jump(RegisterID target)
   739         {
   740             m_assembler.jmpl_r(SparcRegisters::g0, target, SparcRegisters::g0);
   741             m_assembler.nop();
   742         }
   744         void jump(Address address)
   745         {
   746             load32(address, SparcRegisters::g2);
   747             m_assembler.jmpl_r(SparcRegisters::g2, SparcRegisters::g0, SparcRegisters::g0);
   748             m_assembler.nop();
   749         }
   751         void jump(BaseIndex address)
   752         {
   753             load32(address, SparcRegisters::g2);
   754             m_assembler.jmpl_r(SparcRegisters::g2, SparcRegisters::g0, SparcRegisters::g0);
   755             m_assembler.nop();
   756         }
   758         Jump branchAdd32(Condition cond, RegisterID src, RegisterID dest)
   759         {
   760             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   761             m_assembler.addcc_r(src, dest, dest);
   762             return Jump(m_assembler.branch(SparcCondition(cond)));
   763         }
   765         Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
   766         {
   767             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   768             if (m_assembler.isimm13(imm.m_value))
   769                 m_assembler.addcc_imm(dest, imm.m_value, dest);
   770             else {
   771                 m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3);
   772                 m_assembler.addcc_r(dest, SparcRegisters::g3, dest);
   773             }
   774             return Jump(m_assembler.branch(SparcCondition(cond)));
   775         }
   777         Jump branchAdd32(Condition cond, Address src, RegisterID dest)
   778         {
   779             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   780             load32(src, SparcRegisters::g2);
   781             return branchAdd32(cond, SparcRegisters::g2, dest);
   782         }
   784         void mull32(RegisterID src1, RegisterID src2, RegisterID dest)
   785         {
   786             m_assembler.smulcc_r(src1, src2, dest);
   787         }
   789         Jump branchMul32(Condition cond, RegisterID src, RegisterID dest)
   790         {
   791             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   792             m_assembler.smulcc_r(src, dest, dest);
   793             if (cond == Overflow) {
   794                 m_assembler.rdy(SparcRegisters::g2);
   795                 m_assembler.sra_imm(dest, 31, SparcRegisters::g3);
   796                 m_assembler.subcc_r(SparcRegisters::g2, SparcRegisters::g3, SparcRegisters::g2);
   797                 cond = NotEqual;
   798             }
   799             return Jump(m_assembler.branch(SparcCondition(cond)));
   800         }
   802         Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
   803         {
   804             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   805             if (m_assembler.isimm13(imm.m_value))
   806                 m_assembler.smulcc_imm(src, imm.m_value, dest);
   807             else {
   808                 m_assembler.move_nocheck(imm.m_value, SparcRegisters::g3);
   809                 m_assembler.smulcc_r(src, SparcRegisters::g3, dest);
   810             }
   811             if (cond == Overflow) {
   812                 m_assembler.rdy(SparcRegisters::g2);
   813                 m_assembler.sra_imm(dest, 31, SparcRegisters::g3);
   814                 m_assembler.subcc_r(SparcRegisters::g2, SparcRegisters::g3, SparcRegisters::g2);
   815                 cond = NotEqual;
   816             }
   817             return Jump(m_assembler.branch(SparcCondition(cond)));
   818         }
   820         Jump branchMul32(Condition cond, Address src, RegisterID dest)
   821         {
   822             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   823             load32(src, SparcRegisters::g2);
   824             return branchMul32(cond, SparcRegisters::g2, dest);
   825         }
   827         Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
   828         {
   829             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   830             m_assembler.subcc_r(dest, src, dest);
   831             return Jump(m_assembler.branch(SparcCondition(cond)));
   832         }
   834         Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
   835         {
   836             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   837             sub32(imm, dest);
   838             return Jump(m_assembler.branch(SparcCondition(cond)));
   839         }
   841         Jump branchSub32(Condition cond, Address src, RegisterID dest)
   842         {
   843             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   844             load32(src, SparcRegisters::g2);
   845             return branchSub32(cond, SparcRegisters::g2, dest);
   846         }
   848         Jump branchSub32(Condition cond, Imm32 imm, Address dest)
   849         {
   850             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   851             sub32(imm, dest);
   852             return Jump(m_assembler.branch(SparcCondition(cond)));
   853         }
   855         Jump branchNeg32(Condition cond, RegisterID srcDest)
   856         {
   857             ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
   858             neg32(srcDest);
   859             return Jump(m_assembler.branch(SparcCondition(cond)));
   860         }
   862         Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
   863         {
   864             ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
   865             m_assembler.orcc_r(src, dest, dest);
   866             return Jump(m_assembler.branch(SparcCondition(cond)));
   867         }
   869         void breakpoint()
   870         {
   871             m_assembler.ta_imm(8);
   872         }
   874         Call nearCall()
   875         {
   876             return Call(m_assembler.call(), Call::LinkableNear);
   877         }
   879         Call call(RegisterID target)
   880         {
   881             m_assembler.jmpl_r(target, SparcRegisters::g0, SparcRegisters::o7);
   882             m_assembler.nop();
   883             JmpSrc jmpSrc;
   884             return Call(jmpSrc, Call::None);
   885         }
   887         void call(Address address)
   888         {
   889             if (m_assembler.isimm13(address.offset)) {
   890                 m_assembler.jmpl_imm(address.base, address.offset, SparcRegisters::o7);
   891                 m_assembler.nop();
   892             } else {
   893                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
   894                 m_assembler.jmpl_r(address.base, SparcRegisters::g3, SparcRegisters::o7);
   895                 m_assembler.nop();
   896             }
   897         }
   899         void ret()
   900         {
   901             m_assembler.jmpl_imm(SparcRegisters::i7, 8, SparcRegisters::g0);
   902             m_assembler.nop();
   903         }
   905         void ret_and_restore()
   906         {
   907             m_assembler.jmpl_imm(SparcRegisters::i7, 8, SparcRegisters::g0);
   908             m_assembler.restore_r(SparcRegisters::g0, SparcRegisters::g0, SparcRegisters::g0);
   909         }
   911         void save(Imm32 size)
   912         {
   913             if (m_assembler.isimm13(size.m_value)) {
   914                 m_assembler.save_imm(SparcRegisters::sp, size.m_value, SparcRegisters::sp);
   915             } else {
   916                 m_assembler.move_nocheck(size.m_value, SparcRegisters::g3);
   917                 m_assembler.save_r(SparcRegisters::sp, SparcRegisters::g3, SparcRegisters::sp);
   918             }
   919         }
   921         void set32(Condition cond, Address left, RegisterID right, RegisterID dest)
   922         {
   923             load32(left, SparcRegisters::g2);
   924             set32(cond, SparcRegisters::g2, right, dest);
   925         }
   927         void set32(Condition cond, RegisterID left, Address right, RegisterID dest)
   928         {
   929             load32(right, SparcRegisters::g2);
   930             set32(cond, left, SparcRegisters::g2, dest);
   931         }
   933         void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
   934         {
   935             m_assembler.subcc_r(left, right, SparcRegisters::g0);
   936             m_assembler.or_imm(SparcRegisters::g0, 0, dest);
   937             m_assembler.movcc_imm(1, dest, SparcCondition(cond));
   938         }
   940         void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
   941         {
   942             if (m_assembler.isimm13(right.m_value))
   943                 m_assembler.subcc_imm(left, right.m_value, SparcRegisters::g0);
   944             else {
   945                 m_assembler.move_nocheck(right.m_value, SparcRegisters::g3);
   946                 m_assembler.subcc_r(left, SparcRegisters::g3, SparcRegisters::g0);
   947             }
   948             m_assembler.or_imm(SparcRegisters::g0, 0, dest);
   949             m_assembler.movcc_imm(1, dest, SparcCondition(cond));
   950         }
   952         void set32(Condition cond, Address left, Imm32 right, RegisterID dest)
   953         {
   954             load32(left, SparcRegisters::g2);
   955             set32(cond, SparcRegisters::g2, right, dest);
   956         }
   958         void set8(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
   959         {
   960             // Sparc does not have byte register.
   961             set32(cond, left, right, dest);
   962         }
   964         void set8(Condition cond, Address left, RegisterID right, RegisterID dest)
   965         {
   966             // Sparc doesn't have byte registers
   967             load32(left, SparcRegisters::g2);
   968             set32(cond, SparcRegisters::g2, right, dest);
   969         }
   971         void set8(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
   972         {
   973             // Sparc does not have byte register.
   974             set32(cond, left, right, dest);
   975         }
   977         void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
   978         {
   979             load32(address, SparcRegisters::g2);
   980             if (m_assembler.isimm13(mask.m_value))
   981                 m_assembler.andcc_imm(SparcRegisters::g2, mask.m_value, SparcRegisters::g0);
   982             else {
   983                 m_assembler.move_nocheck(mask.m_value, SparcRegisters::g3);
   984                 m_assembler.andcc_r(SparcRegisters::g3, SparcRegisters::g2, SparcRegisters::g0);
   985             }
   986             m_assembler.or_imm(SparcRegisters::g0, 0, dest);
   987             m_assembler.movcc_imm(1, dest, SparcCondition(cond));
   988         }
   990         void setTest8(Condition cond, Address address, Imm32 mask, RegisterID dest)
   991         {
   992             // Sparc does not have byte register.
   993             setTest32(cond, address, mask, dest);
   994         }
   996         void lea(Address address, RegisterID dest)
   997         {
   998             if (m_assembler.isimm13(address.offset))
   999                 m_assembler.add_imm(address.base, address.offset, dest);
  1000             else {
  1001                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
  1002                 m_assembler.add_r(address.base, SparcRegisters::g3, dest);
  1006         void lea(BaseIndex address, RegisterID dest)
  1008             // lea only used by PolyIC.
  1009             // PolyIC is not enabled for sparc now.
  1010             ASSERT(0);
  1013         void add32(Imm32 imm, AbsoluteAddress address)
  1015             load32(address.m_ptr, SparcRegisters::g2);
  1016             add32(imm, SparcRegisters::g2);
  1017             store32(SparcRegisters::g2, address.m_ptr);
  1020         void sub32(TrustedImm32 imm, AbsoluteAddress address)
  1022             load32(address.m_ptr, SparcRegisters::g2);
  1023             sub32(imm, SparcRegisters::g2);
  1024             store32(SparcRegisters::g2, address.m_ptr);
  1027         void load32(const void* address, RegisterID dest)
  1029             m_assembler.move_nocheck((int)address, SparcRegisters::g3);
  1030             m_assembler.lduw_r(SparcRegisters::g3, SparcRegisters::g0, dest);
  1033         Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right)
  1035             load32(left.m_ptr, SparcRegisters::g2);
  1036             return branch32(cond, SparcRegisters::g2, right);
  1039         Jump branch32(Condition cond, AbsoluteAddress left, TrustedImm32 right)
  1041             load32(left.m_ptr, SparcRegisters::g2);
  1042             return branch32(cond, SparcRegisters::g2, right);
  1045         Call call()
  1047             m_assembler.rdpc(SparcRegisters::g2);
  1048             m_assembler.add_imm(SparcRegisters::g2, 32, SparcRegisters::g2);
  1049             m_assembler.stw_imm(SparcRegisters::g2, SparcRegisters::fp, -8);
  1050             Call cl = Call(m_assembler.call(), Call::Linkable);
  1051             m_assembler.lduw_imm(SparcRegisters::fp, -8, SparcRegisters::g2);
  1052             m_assembler.jmpl_imm(SparcRegisters::g2, 0, SparcRegisters::g0);
  1053             m_assembler.nop();
  1054             return cl;
  1057         Call tailRecursiveCall()
  1059             return Call::fromTailJump(jump());
  1062         Call makeTailRecursiveCall(Jump oldJump)
  1064             return Call::fromTailJump(oldJump);
  1067         DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
  1069             DataLabelPtr dataLabel(this);
  1070             Imm32 imm = Imm32(initialValue);
  1071             m_assembler.move_nocheck(imm.m_value, dest);
  1072             return dataLabel;
  1075         DataLabel32 moveWithPatch(TrustedImm32 initialValue, RegisterID dest)
  1077             DataLabel32 dataLabel(this);
  1078             m_assembler.move_nocheck(initialValue.m_value, dest);
  1079             return dataLabel;
  1082         Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
  1084             dataLabel = moveWithPatch(initialRightValue, SparcRegisters::g2);
  1085             Jump jump = branch32(cond, left, SparcRegisters::g2);
  1086             return jump;
  1089         Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
  1091             load32(left, SparcRegisters::g2);
  1092             dataLabel = moveWithPatch(initialRightValue, SparcRegisters::g3);
  1093             Jump jump = branch32(cond, SparcRegisters::g3, SparcRegisters::g2);
  1094             return jump;
  1097         DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
  1099             DataLabelPtr dataLabel = moveWithPatch(initialValue, SparcRegisters::g2);
  1100             store32(SparcRegisters::g2, address);
  1101             return dataLabel;
  1104         DataLabelPtr storePtrWithPatch(ImplicitAddress address)
  1106             return storePtrWithPatch(ImmPtr(0), address);
  1109         // Floating point operators
  1110         static bool supportsFloatingPoint()
  1112             return true;
  1115         static bool supportsFloatingPointTruncate()
  1117             return true;
  1120         static bool supportsFloatingPointSqrt()
  1122             return true;
  1125         void moveDouble(FPRegisterID src, FPRegisterID dest)
  1127             m_assembler.fmovd_r(src, dest);
  1130         void loadFloat(BaseIndex address, FPRegisterID dest)
  1132             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
  1133             add32(Imm32(address.offset), SparcRegisters::g2);
  1134             m_assembler.ldf_r(address.base, SparcRegisters::g2, dest);
  1135             m_assembler.fstod_r(dest, dest);
  1138         void loadFloat(ImplicitAddress address, FPRegisterID dest)
  1140             if (m_assembler.isimm13(address.offset))
  1141                 m_assembler.ldf_imm(address.base, address.offset, dest);
  1142             else {
  1143                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
  1144                 m_assembler.ldf_r(address.base, SparcRegisters::g3, dest);
  1146             m_assembler.fstod_r(dest, dest);
  1149         void loadFloat(const void* address, FPRegisterID dest)
  1151             m_assembler.move_nocheck((int)address, SparcRegisters::g3);
  1152             m_assembler.ldf_r(SparcRegisters::g3, SparcRegisters::g0, dest);
  1153             m_assembler.fstod_r(dest, dest);
  1156         void loadDouble(BaseIndex address, FPRegisterID dest)
  1158             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
  1159             add32(Imm32(address.offset), SparcRegisters::g2);
  1160             m_assembler.ldf_r(address.base, SparcRegisters::g2, dest);
  1161             m_assembler.add_imm(SparcRegisters::g2, 4, SparcRegisters::g2);
  1162             m_assembler.ldf_r(address.base, SparcRegisters::g2, dest + 1);
  1165         void loadDouble(ImplicitAddress address, FPRegisterID dest)
  1167             m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
  1168             m_assembler.ldf_r(address.base, SparcRegisters::g3, dest);
  1169             m_assembler.add_imm(SparcRegisters::g3, 4, SparcRegisters::g3);
  1170             m_assembler.ldf_r(address.base, SparcRegisters::g3, dest + 1);
  1173         DataLabelPtr loadDouble(const void* address, FPRegisterID dest)
  1175             DataLabelPtr dataLabel(this);
  1176             m_assembler.move_nocheck((int)address, SparcRegisters::g3);
  1177             m_assembler.ldf_imm(SparcRegisters::g3, 0, dest);
  1178             m_assembler.ldf_imm(SparcRegisters::g3, 4, dest + 1);
  1179             return dataLabel;
  1182         void storeFloat(FPRegisterID src, BaseIndex address)
  1184             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
  1185             add32(Imm32(address.offset), SparcRegisters::g2);
  1186             m_assembler.stf_r(src, address.base, SparcRegisters::g2);
  1189         void storeFloat(FPRegisterID src, ImplicitAddress address)
  1191             if (m_assembler.isimm13(address.offset))
  1192                 m_assembler.stf_imm(src, address.base, address.offset);
  1193             else {
  1194                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
  1195                 m_assembler.stf_r(src, address.base, SparcRegisters::g3);
  1199         void storeFloat(ImmDouble imm, Address address)
  1201             union {
  1202                 float f;
  1203                 uint32_t u32;
  1204             } u;
  1205             u.f = imm.u.d;
  1206             store32(Imm32(u.u32), address);
  1209         void storeFloat(ImmDouble imm, BaseIndex address)
  1211             union {
  1212                 float f;
  1213                 uint32_t u32;
  1214             } u;
  1215             u.f = imm.u.d;
  1216             store32(Imm32(u.u32), address);
  1219         void storeDouble(FPRegisterID src, BaseIndex address)
  1221             m_assembler.sll_imm(address.index, address.scale, SparcRegisters::g2);
  1222             add32(Imm32(address.offset), SparcRegisters::g2);
  1223             m_assembler.stf_r(src, address.base, SparcRegisters::g2);
  1224             m_assembler.add_imm(SparcRegisters::g2, 4, SparcRegisters::g2);
  1225             m_assembler.stf_r(src + 1, address.base, SparcRegisters::g2);
  1228         void storeDouble(FPRegisterID src, ImplicitAddress address)
  1230             if (m_assembler.isimm13(address.offset + 4)) {
  1231                 m_assembler.stf_imm(src, address.base, address.offset);
  1232                 m_assembler.stf_imm(src + 1, address.base, address.offset + 4);
  1233             } else {
  1234                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
  1235                 m_assembler.stf_r(src, address.base, SparcRegisters::g3);
  1236                 m_assembler.add_imm(SparcRegisters::g3, 4, SparcRegisters::g3);
  1237                 m_assembler.stf_r(src + 1, address.base, SparcRegisters::g3);
  1241         void storeDouble(ImmDouble imm, Address address)
  1243             store32(Imm32(imm.u.s.msb), address);
  1244             store32(Imm32(imm.u.s.lsb), Address(address.base, address.offset + 4));
  1247         void storeDouble(ImmDouble imm, BaseIndex address)
  1249             store32(Imm32(imm.u.s.msb), address);
  1250             store32(Imm32(imm.u.s.lsb),
  1251                     BaseIndex(address.base, address.index, address.scale, address.offset + 4));
  1254         void addDouble(FPRegisterID src, FPRegisterID dest)
  1256             m_assembler.faddd_r(src, dest, dest);
  1259         void addDouble(Address src, FPRegisterID dest)
  1261             loadDouble(src, SparcRegisters::f30);
  1262             m_assembler.faddd_r(SparcRegisters::f30, dest, dest);
  1265         void divDouble(FPRegisterID src, FPRegisterID dest)
  1267             m_assembler.fdivd_r(dest, src, dest);
  1270         void divDouble(Address src, FPRegisterID dest)
  1272             loadDouble(src, SparcRegisters::f30);
  1273             m_assembler.fdivd_r(dest, SparcRegisters::f30, dest);
  1276         void subDouble(FPRegisterID src, FPRegisterID dest)
  1278             m_assembler.fsubd_r(dest, src, dest);
  1281         void subDouble(Address src, FPRegisterID dest)
  1283             loadDouble(src, SparcRegisters::f30);
  1284             m_assembler.fsubd_r(dest, SparcRegisters::f30, dest);
  1287         void mulDouble(FPRegisterID src, FPRegisterID dest)
  1289             m_assembler.fmuld_r(src, dest, dest);
  1292         void mulDouble(Address src, FPRegisterID dest)
  1294             loadDouble(src, SparcRegisters::f30);
  1295             m_assembler.fmuld_r(SparcRegisters::f30, dest, dest);
  1298         void absDouble(FPRegisterID src, FPRegisterID dest)
  1300             m_assembler.fabsd_r(src, dest);
  1303         void sqrtDouble(FPRegisterID src, FPRegisterID dest)
  1305             m_assembler.fsqrtd_r(src, dest);
  1308         void negDouble(FPRegisterID src, FPRegisterID dest)
  1310             m_assembler.fnegd_r(src, dest);
  1313         void convertUInt32ToDouble(RegisterID src, FPRegisterID dest)
  1315             m_assembler.move_nocheck(0x43300000, SparcRegisters::g1);
  1316             m_assembler.stw_imm(SparcRegisters::g1, SparcRegisters::sp, 0x60);
  1317             m_assembler.stw_imm(src, SparcRegisters::sp, 0x64);
  1318             m_assembler.ldf_imm(SparcRegisters::sp, 0x60, SparcRegisters::f30);
  1319             m_assembler.ldf_imm(SparcRegisters::sp, 0x64, SparcRegisters::f31);
  1320             m_assembler.stw_imm(SparcRegisters::g0, SparcRegisters::sp, 0x64);
  1321             m_assembler.ldf_imm(SparcRegisters::sp, 0x60, dest);
  1322             m_assembler.ldf_imm(SparcRegisters::sp, 0x64, dest + 1);
  1323             m_assembler.fsubd_r(SparcRegisters::f30, dest, dest);
  1324             m_assembler.fabss_r(dest, dest);
  1327         void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
  1329             m_assembler.stw_imm(src, SparcRegisters::sp, 0x60);
  1330             m_assembler.ldf_imm(SparcRegisters::sp, 0x60, dest);
  1331             m_assembler.fitod_r(dest, dest);
  1334         void convertInt32ToDouble(Address address, FPRegisterID dest)
  1336             if (m_assembler.isimm13(address.offset))
  1337                 m_assembler.ldf_imm(address.base, address.offset, dest);
  1338             else {
  1339                 m_assembler.move_nocheck(address.offset, SparcRegisters::g3);
  1340                 m_assembler.ldf_r(address.base, SparcRegisters::g3, dest);
  1342             m_assembler.fitod_r(dest, dest);
  1345         void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
  1347             m_assembler.move_nocheck((int)src.m_ptr, SparcRegisters::g3);
  1348             m_assembler.ldf_r(SparcRegisters::g3, SparcRegisters::g0, dest);
  1349             m_assembler.fitod_r(dest, dest);
  1352         void fastLoadDouble(RegisterID lo, RegisterID hi, FPRegisterID fpReg)
  1354             m_assembler.stw_imm(lo, SparcRegisters::sp, 0x64);
  1355             m_assembler.stw_imm(hi, SparcRegisters::sp, 0x60);
  1356             m_assembler.ldf_imm(SparcRegisters::sp, 0x60, fpReg);
  1357             m_assembler.ldf_imm(SparcRegisters::sp, 0x64, fpReg + 1);
  1360         void convertDoubleToFloat(FPRegisterID src, FPRegisterID dest)
  1362             m_assembler.fdtos_r(src, dest);
  1365         void breakDoubleTo32(FPRegisterID srcDest, RegisterID typeReg, RegisterID dataReg) {
  1366             // We don't assume stack is aligned to 8.
  1367             // Always using stf, ldf instead of stdf, lddf.
  1368             m_assembler.stf_imm(srcDest, SparcRegisters::sp, 0x60);
  1369             m_assembler.stf_imm(srcDest + 1, SparcRegisters::sp, 0x64);
  1370             m_assembler.lduw_imm(SparcRegisters::sp, 0x60, typeReg);
  1371             m_assembler.lduw_imm(SparcRegisters::sp, 0x64, dataReg);
  1374         Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
  1376             m_assembler.fcmpd_r(left, right);
  1377             return Jump(m_assembler.fbranch(SparcDoubleCondition(cond)));
  1380         // Truncates 'src' to an integer, and places the resulting 'dest'.
  1381         // If the result is not representable as a 32 bit value, branch.
  1382         // May also branch for some values that are representable in 32 bits
  1383         // (specifically, in this case, INT_MIN).
  1384         Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
  1386             m_assembler.fdtoi_r(src, SparcRegisters::f30);
  1387             m_assembler.stf_imm(SparcRegisters::f30, SparcRegisters::sp, 0x60);
  1388             m_assembler.lduw_imm(SparcRegisters::sp, 0x60, dest);
  1390             m_assembler.or_r(SparcRegisters::g0, SparcRegisters::g0, SparcRegisters::g2);
  1391             m_assembler.move_nocheck(0x80000000, SparcRegisters::g3);
  1392             m_assembler.subcc_r(SparcRegisters::g3, dest, SparcRegisters::g0);
  1393             m_assembler.movcc_imm(1, SparcRegisters::g2, SparcCondition(Equal));
  1394             m_assembler.move_nocheck(0x7fffffff, SparcRegisters::g3);
  1395             m_assembler.subcc_r(SparcRegisters::g3, dest, SparcRegisters::g0);
  1396             m_assembler.movcc_imm(1, SparcRegisters::g2, SparcCondition(Equal));
  1398             return branch32(Equal, SparcRegisters::g2, Imm32(1));
  1401         // Convert 'src' to an integer, and places the resulting 'dest'.
  1402         // If the result is not representable as a 32 bit value, branch.
  1403         // May also branch for some values that are representable in 32 bits
  1404         // (specifically, in this case, 0).
  1405         void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
  1407             m_assembler.fdtoi_r(src, SparcRegisters::f30);
  1408             m_assembler.stf_imm(SparcRegisters::f30, SparcRegisters::sp, 0x60);
  1409             m_assembler.lduw_imm(SparcRegisters::sp, 0x60, dest);
  1411             // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
  1412             m_assembler.fitod_r(SparcRegisters::f30, SparcRegisters::f30);
  1413             failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, SparcRegisters::f30));
  1415             // If the result is zero, it might have been -0.0, and 0.0 equals to -0.0
  1416             failureCases.append(branchTest32(Zero, dest));
  1419         void zeroDouble(FPRegisterID srcDest)
  1421             fastLoadDouble(SparcRegisters::g0, SparcRegisters::g0, srcDest);
  1424     protected:
  1425         SparcAssembler::Condition SparcCondition(Condition cond)
  1427             return static_cast<SparcAssembler::Condition>(cond);
  1430         SparcAssembler::DoubleCondition SparcDoubleCondition(DoubleCondition cond)
  1432             return static_cast<SparcAssembler::DoubleCondition>(cond);
  1435     private:
  1436         friend class LinkBuffer;
  1437         friend class RepatchBuffer;
  1439         static void linkCall(void* code, Call call, FunctionPtr function)
  1441             SparcAssembler::linkCall(code, call.m_jmp, function.value());
  1444         static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
  1446             SparcAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
  1449         static void repatchCall(CodeLocationCall call, FunctionPtr destination)
  1451             SparcAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
  1454     };
  1459 #endif // ENABLE(ASSEMBLER) && CPU(SPARC)
  1461 #endif /* assembler_assembler_MacroAssemblerSparc_h */

mercurial