LCOV - code coverage report
Current view: directory - js/src/methodjit - MachineRegs.h (source / functions) Found Hit Coverage
Test: app.info Lines: 100 96 96.0 %
Date: 2012-06-02 Functions: 35 34 97.1 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=4 sw=4 et tw=99:
       3                 :  *
       4                 :  * ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
      18                 :  * May 28, 2008.
      19                 :  *
      20                 :  * The Initial Developer of the Original Code is
      21                 :  *   Brendan Eich <brendan@mozilla.org>
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   David Anderson <danderson@mozilla.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #if !defined jsjaeger_regstate_h__ && defined JS_METHODJIT
      41                 : #define jsjaeger_regstate_h__
      42                 : 
      43                 : #include "mozilla/Util.h"
      44                 : 
      45                 : #include "assembler/assembler/MacroAssembler.h"
      46                 : 
      47                 : namespace js {
      48                 : 
      49                 : namespace mjit {
      50                 : 
      51                 : /* Common handling for both general purpose and floating point registers. */
      52                 : 
      53                 : struct AnyRegisterID {
      54                 :     unsigned reg_;
      55                 : 
      56       110217522 :     AnyRegisterID()
      57       110217522 :         : reg_((unsigned)-1)
      58       110217522 :     { pin(); }
      59                 : 
      60      1544616473 :     AnyRegisterID(const AnyRegisterID &o)
      61      1544616473 :         : reg_(o.reg_)
      62      1544616473 :     { pin(); }
      63                 : 
      64       282758876 :     AnyRegisterID(JSC::MacroAssembler::RegisterID reg)
      65       282758876 :         : reg_((unsigned)reg)
      66       282758876 :     { pin(); }
      67                 : 
      68       123079388 :     AnyRegisterID(JSC::MacroAssembler::FPRegisterID reg)
      69       123079388 :         : reg_(JSC::MacroAssembler::TotalRegisters + (unsigned)reg)
      70       123079388 :     { pin(); }
      71                 : 
      72                 :     static inline AnyRegisterID fromRaw(unsigned reg);
      73                 : 
      74                 :     inline JSC::MacroAssembler::RegisterID reg();
      75                 :     inline JSC::MacroAssembler::FPRegisterID fpreg();
      76                 : 
      77          643661 :     bool isSet() { return reg_ != unsigned(-1); }
      78         1317806 :     bool isReg() { return reg_ < JSC::MacroAssembler::TotalRegisters; }
      79          342882 :     bool isFPReg() { return isSet() && !isReg(); }
      80                 : 
      81                 :     inline const char * name();
      82                 : 
      83                 :   private:
      84      2060672259 :     unsigned * pin() {
      85                 :         /*
      86                 :          * Workaround for apparent compiler bug in GCC 4.2. If GCC thinks that reg_
      87                 :          * cannot escape then it compiles isReg() and other accesses to reg_ incorrectly.
      88                 :          */
      89                 :         static unsigned *v;
      90      2060672259 :         v = &reg_;
      91      2060672259 :         return v;
      92                 :     }
      93                 : };
      94                 : 
      95                 : struct Registers {
      96                 : 
      97                 :     /* General purpose registers. */
      98                 : 
      99                 :     static const uint32_t TotalRegisters = JSC::MacroAssembler::TotalRegisters;
     100                 : 
     101                 :     enum CallConvention {
     102                 :         NormalCall,
     103                 :         FastCall
     104                 :     };
     105                 : 
     106                 :     typedef JSC::MacroAssembler::RegisterID RegisterID;
     107                 : 
     108                 :     // Homed and scratch registers for working with Values on x64.
     109                 : #if defined(JS_CPU_X64)
     110                 :     static const RegisterID TypeMaskReg = JSC::X86Registers::r13;
     111                 :     static const RegisterID PayloadMaskReg = JSC::X86Registers::r14;
     112                 :     static const RegisterID ValueReg = JSC::X86Registers::r10;
     113                 :     static const RegisterID ScratchReg = JSC::X86Registers::r11;
     114                 : #endif
     115                 : 
     116                 :     // Register that homes the current JSStackFrame.
     117                 : #if defined(JS_CPU_X86)
     118                 :     static const RegisterID JSFrameReg = JSC::X86Registers::ebp;
     119                 : #elif defined(JS_CPU_X64)
     120                 :     static const RegisterID JSFrameReg = JSC::X86Registers::ebx;
     121                 : #elif defined(JS_CPU_ARM)
     122                 :     static const RegisterID JSFrameReg = JSC::ARMRegisters::r10;
     123                 : #elif defined(JS_CPU_SPARC)
     124                 :     static const RegisterID JSFrameReg = JSC::SparcRegisters::l0;
     125                 : #elif defined(JS_CPU_MIPS)
     126                 :     static const RegisterID JSFrameReg = JSC::MIPSRegisters::s0;
     127                 : #endif
     128                 : 
     129                 : #if defined(JS_CPU_X86) || defined(JS_CPU_X64)
     130                 :     static const RegisterID ReturnReg = JSC::X86Registers::eax;
     131                 : # if defined(JS_CPU_X86) || defined(_WIN64)
     132                 :     static const RegisterID ArgReg0 = JSC::X86Registers::ecx;
     133                 :     static const RegisterID ArgReg1 = JSC::X86Registers::edx;
     134                 : #  if defined(JS_CPU_X64)
     135                 :     static const RegisterID ArgReg2 = JSC::X86Registers::r8;
     136                 :     static const RegisterID ArgReg3 = JSC::X86Registers::r9;
     137                 : #  endif
     138                 : # else
     139                 :     static const RegisterID ArgReg0 = JSC::X86Registers::edi;
     140                 :     static const RegisterID ArgReg1 = JSC::X86Registers::esi;
     141                 :     static const RegisterID ArgReg2 = JSC::X86Registers::edx;
     142                 :     static const RegisterID ArgReg3 = JSC::X86Registers::ecx;
     143                 : # endif
     144                 : #elif JS_CPU_ARM
     145                 :     static const RegisterID ReturnReg = JSC::ARMRegisters::r0;
     146                 :     static const RegisterID ArgReg0 = JSC::ARMRegisters::r0;
     147                 :     static const RegisterID ArgReg1 = JSC::ARMRegisters::r1;
     148                 :     static const RegisterID ArgReg2 = JSC::ARMRegisters::r2;
     149                 : #elif JS_CPU_SPARC
     150                 :     static const RegisterID ReturnReg = JSC::SparcRegisters::o0;
     151                 :     static const RegisterID ArgReg0 = JSC::SparcRegisters::o0;
     152                 :     static const RegisterID ArgReg1 = JSC::SparcRegisters::o1;
     153                 :     static const RegisterID ArgReg2 = JSC::SparcRegisters::o2;
     154                 :     static const RegisterID ArgReg3 = JSC::SparcRegisters::o3;
     155                 :     static const RegisterID ArgReg4 = JSC::SparcRegisters::o4;
     156                 :     static const RegisterID ArgReg5 = JSC::SparcRegisters::o5;
     157                 : #elif JS_CPU_MIPS
     158                 :     static const RegisterID ReturnReg = JSC::MIPSRegisters::v0;
     159                 :     static const RegisterID ArgReg0 = JSC::MIPSRegisters::a0;
     160                 :     static const RegisterID ArgReg1 = JSC::MIPSRegisters::a1;
     161                 :     static const RegisterID ArgReg2 = JSC::MIPSRegisters::a2;
     162                 :     static const RegisterID ArgReg3 = JSC::MIPSRegisters::a3;
     163                 : #endif
     164                 : 
     165                 :     static const RegisterID StackPointer = JSC::MacroAssembler::stackPointerRegister;
     166                 : 
     167          906698 :     static inline uint32_t maskReg(RegisterID reg) {
     168          906698 :         return (1 << reg);
     169                 :     }
     170                 : 
     171               0 :     static inline uint32_t mask2Regs(RegisterID reg1, RegisterID reg2) {
     172               0 :         return maskReg(reg1) | maskReg(reg2);
     173                 :     }
     174                 : 
     175                 :     static inline uint32_t mask3Regs(RegisterID reg1, RegisterID reg2, RegisterID reg3) {
     176                 :         return maskReg(reg1) | maskReg(reg2) | maskReg(reg3);
     177                 :     }
     178                 : 
     179                 : #if defined(JS_CPU_X86) || defined(JS_CPU_X64)
     180                 :     static const uint32_t TempRegs =
     181                 :           (1 << JSC::X86Registers::eax)
     182                 : # if defined(JS_CPU_X86)
     183                 :         | (1 << JSC::X86Registers::ebx)
     184                 : # endif
     185                 :         | (1 << JSC::X86Registers::ecx)
     186                 :         | (1 << JSC::X86Registers::edx)
     187                 : # if defined(JS_CPU_X64)
     188                 :         | (1 << JSC::X86Registers::r8)
     189                 :         | (1 << JSC::X86Registers::r9)
     190                 : #  if !defined(_WIN64)
     191                 :         | (1 << JSC::X86Registers::esi)
     192                 :         | (1 << JSC::X86Registers::edi)
     193                 : #  endif
     194                 : # endif
     195                 :         ;
     196                 : 
     197                 : # if defined(JS_CPU_X64)
     198                 :     static const uint32_t SavedRegs =
     199                 :         /* r11 is scratchRegister, used by JSC. */
     200                 :           (1 << JSC::X86Registers::r12)
     201                 :     // r13 is TypeMaskReg.
     202                 :     // r14 is PayloadMaskReg.
     203                 :         | (1 << JSC::X86Registers::r15)
     204                 : #  if defined(_WIN64)
     205                 :         | (1 << JSC::X86Registers::esi)
     206                 :         | (1 << JSC::X86Registers::edi)
     207                 : #  endif
     208                 : # else
     209                 :     static const uint32_t SavedRegs =
     210                 :           (1 << JSC::X86Registers::esi)
     211                 :         | (1 << JSC::X86Registers::edi)
     212                 : # endif
     213                 :         ;
     214                 : 
     215                 : # if defined(JS_CPU_X86)
     216                 :     static const uint32_t SingleByteRegs = (TempRegs | SavedRegs) &
     217                 :         ~((1 << JSC::X86Registers::esi) |
     218                 :           (1 << JSC::X86Registers::edi) |
     219                 :           (1 << JSC::X86Registers::ebp) |
     220                 :           (1 << JSC::X86Registers::esp));
     221                 : # elif defined(JS_CPU_X64)
     222                 :     static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
     223                 : # endif
     224                 : 
     225                 : #elif defined(JS_CPU_ARM)
     226                 :     static const uint32_t TempRegs =
     227                 :           (1 << JSC::ARMRegisters::r0)
     228                 :         | (1 << JSC::ARMRegisters::r1)
     229                 :         | (1 << JSC::ARMRegisters::r2);
     230                 :     // r3 is reserved as a scratch register for the assembler.
     231                 :     // r12 is IP, and is used for stub calls.
     232                 : 
     233                 :     static const uint32_t SavedRegs =
     234                 :           (1 << JSC::ARMRegisters::r4)
     235                 :         | (1 << JSC::ARMRegisters::r5)
     236                 :         | (1 << JSC::ARMRegisters::r6)
     237                 :         | (1 << JSC::ARMRegisters::r7)
     238                 :     // r8 is reserved as a scratch register for the assembler.
     239                 :         | (1 << JSC::ARMRegisters::r9);
     240                 :     // r10 is reserved for JSFrameReg.
     241                 :     // r13 is SP and must always point to VMFrame whilst in generated code.
     242                 :     // r14 is LR and is used for return sequences.
     243                 :     // r15 is PC (program counter).
     244                 : 
     245                 :     static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
     246                 : #elif defined(JS_CPU_SPARC)
     247                 :     static const uint32_t TempRegs =
     248                 :           (1 << JSC::SparcRegisters::o0)
     249                 :         | (1 << JSC::SparcRegisters::o1)
     250                 :         | (1 << JSC::SparcRegisters::o2)
     251                 :         | (1 << JSC::SparcRegisters::o3)
     252                 :         | (1 << JSC::SparcRegisters::o4)
     253                 :         | (1 << JSC::SparcRegisters::o5);
     254                 : 
     255                 :     static const uint32_t SavedRegs =
     256                 :           (1 << JSC::SparcRegisters::l2)
     257                 :         | (1 << JSC::SparcRegisters::l3)
     258                 :         | (1 << JSC::SparcRegisters::l4)
     259                 :         | (1 << JSC::SparcRegisters::l5)
     260                 :         | (1 << JSC::SparcRegisters::l6)
     261                 :         | (1 << JSC::SparcRegisters::l7);
     262                 : 
     263                 :     static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
     264                 : #elif defined(JS_CPU_MIPS)
     265                 :     static const uint32_t TempRegs =
     266                 :           (1 << JSC::MIPSRegisters::at)
     267                 :         | (1 << JSC::MIPSRegisters::v0)
     268                 :         | (1 << JSC::MIPSRegisters::v1)
     269                 :         | (1 << JSC::MIPSRegisters::a0)
     270                 :         | (1 << JSC::MIPSRegisters::a1)
     271                 :         | (1 << JSC::MIPSRegisters::a2)
     272                 :         | (1 << JSC::MIPSRegisters::a3)
     273                 :         | (1 << JSC::MIPSRegisters::t5)
     274                 :         | (1 << JSC::MIPSRegisters::t6)
     275                 :         | (1 << JSC::MIPSRegisters::t7);
     276                 :     /* t0-t4,t9 is reserved as a scratch register for the assembler.
     277                 :        We don't use t8 ($24), as we limit ourselves within $0 to $23 to
     278                 :        leave the bitmask for 8 FP registers. */
     279                 : 
     280                 :     static const uint32_t SavedRegs =
     281                 :           (1 << JSC::MIPSRegisters::s1)
     282                 :         | (1 << JSC::MIPSRegisters::s2)
     283                 :         | (1 << JSC::MIPSRegisters::s3)
     284                 :         | (1 << JSC::MIPSRegisters::s4)
     285                 :         | (1 << JSC::MIPSRegisters::s5)
     286                 :         | (1 << JSC::MIPSRegisters::s6)
     287                 :         | (1 << JSC::MIPSRegisters::s7);
     288                 :     // s0 is reserved for JSFrameReg.
     289                 : 
     290                 :     static const uint32_t SingleByteRegs = TempRegs | SavedRegs;
     291                 : #else
     292                 : # error "Unsupported platform"
     293                 : #endif
     294                 : 
     295                 :     static const uint32_t AvailRegs = SavedRegs | TempRegs;
     296                 : 
     297                 :     static bool isAvail(RegisterID reg) {
     298                 :         uint32_t mask = maskReg(reg);
     299                 :         return bool(mask & AvailRegs);
     300                 :     }
     301                 : 
     302            1670 :     static bool isSaved(RegisterID reg) {
     303            1670 :         uint32_t mask = maskReg(reg);
     304            1670 :         JS_ASSERT(mask & AvailRegs);
     305            1670 :         return bool(mask & SavedRegs);
     306                 :     }
     307                 : 
     308        14753743 :     static inline uint32_t numArgRegs(CallConvention convention) {
     309                 : #if defined(JS_CPU_X86)
     310                 : # if defined(JS_NO_FASTCALL)
     311                 :         return 0;
     312                 : # else
     313        14753743 :         return (convention == FastCall) ? 2 : 0;
     314                 : # endif
     315                 : #elif defined(JS_CPU_X64)
     316                 : # ifdef _WIN64
     317                 :         return 4;
     318                 : # else
     319                 :         return 6;
     320                 : # endif
     321                 : #elif defined(JS_CPU_ARM)
     322                 :         return 4;
     323                 : #elif defined(JS_CPU_SPARC)
     324                 :         return 6;
     325                 : #elif defined(JS_CPU_MIPS)
     326                 :         return 4;
     327                 : #endif
     328                 :     }
     329                 : 
     330         9848128 :     static inline bool regForArg(CallConvention conv, uint32_t i, RegisterID *reg) {
     331                 : #if defined(JS_CPU_X86)
     332                 :         static const RegisterID regs[] = {
     333                 :             JSC::X86Registers::ecx,
     334                 :             JSC::X86Registers::edx
     335                 :         };
     336                 : 
     337                 : # if defined(JS_NO_FASTCALL)
     338                 :         return false;
     339                 : # else
     340         9848128 :         if (conv == NormalCall)
     341          107940 :             return false;
     342                 : # endif
     343                 : #elif defined(JS_CPU_X64)
     344                 : # ifdef _WIN64
     345                 :         static const RegisterID regs[] = {
     346                 :             JSC::X86Registers::ecx,
     347                 :             JSC::X86Registers::edx,
     348                 :             JSC::X86Registers::r8,
     349                 :             JSC::X86Registers::r9
     350                 :         };
     351                 : # else
     352                 :         static const RegisterID regs[] = {
     353                 :             JSC::X86Registers::edi,
     354                 :             JSC::X86Registers::esi,
     355                 :             JSC::X86Registers::edx,
     356                 :             JSC::X86Registers::ecx,
     357                 :             JSC::X86Registers::r8,
     358                 :             JSC::X86Registers::r9
     359                 :         };
     360                 : # endif
     361                 : #elif defined(JS_CPU_ARM)
     362                 :         static const RegisterID regs[] = {
     363                 :             JSC::ARMRegisters::r0,
     364                 :             JSC::ARMRegisters::r1,
     365                 :             JSC::ARMRegisters::r2,
     366                 :             JSC::ARMRegisters::r3
     367                 :         };
     368                 : #elif defined(JS_CPU_SPARC)
     369                 :         static const RegisterID regs[] = {
     370                 :             JSC::SparcRegisters::o0,
     371                 :             JSC::SparcRegisters::o1,
     372                 :             JSC::SparcRegisters::o2,
     373                 :             JSC::SparcRegisters::o3,
     374                 :             JSC::SparcRegisters::o4,
     375                 :             JSC::SparcRegisters::o5
     376                 :         };
     377                 : #elif defined(JS_CPU_MIPS)
     378                 :         static const RegisterID regs[] = {
     379                 :             JSC::MIPSRegisters::a0,
     380                 :             JSC::MIPSRegisters::a1,
     381                 :             JSC::MIPSRegisters::a2,
     382                 :             JSC::MIPSRegisters::a3,
     383                 :         };
     384                 : #endif
     385         9740188 :         JS_ASSERT(numArgRegs(conv) == mozilla::ArrayLength(regs));
     386         9740188 :         if (i > mozilla::ArrayLength(regs))
     387               0 :             return false;
     388         9740188 :         *reg = regs[i];
     389         9740188 :         return true;
     390                 :     }
     391                 : 
     392                 :     /* Floating point registers. */
     393                 : 
     394                 :     typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
     395                 : 
     396                 : #if defined(JS_CPU_X86) || defined(JS_CPU_X64)
     397                 : #ifdef _WIN64
     398                 :     /* xmm0-xmm5 are scratch register on Win64 ABI */
     399                 :     static const uint32_t TotalFPRegisters = 5;
     400                 :     static const FPRegisterID FPConversionTemp = JSC::X86Registers::xmm5;
     401                 : #else
     402                 :     static const uint32_t TotalFPRegisters = 7;
     403                 :     static const FPRegisterID FPConversionTemp = JSC::X86Registers::xmm7;
     404                 : #endif
     405                 :     static const uint32_t TempFPRegs = (
     406                 :           (1 << JSC::X86Registers::xmm0)
     407                 :         | (1 << JSC::X86Registers::xmm1)
     408                 :         | (1 << JSC::X86Registers::xmm2)
     409                 :         | (1 << JSC::X86Registers::xmm3)
     410                 :         | (1 << JSC::X86Registers::xmm4)
     411                 : #ifndef _WIN64
     412                 :         | (1 << JSC::X86Registers::xmm5)
     413                 :         | (1 << JSC::X86Registers::xmm6)
     414                 : #endif
     415                 :         ) << TotalRegisters;
     416                 : #elif defined(JS_CPU_ARM)
     417                 :     static const uint32_t TotalFPRegisters = 3;
     418                 :     static const uint32_t TempFPRegs = (
     419                 :           (1 << JSC::ARMRegisters::d0)
     420                 :         | (1 << JSC::ARMRegisters::d1)
     421                 :         | (1 << JSC::ARMRegisters::d2)
     422                 :         ) << TotalRegisters;
     423                 :     static const FPRegisterID FPConversionTemp = JSC::ARMRegisters::d3;
     424                 : #elif defined(JS_CPU_SPARC)
     425                 :     static const uint32_t TotalFPRegisters = 8;
     426                 :     static const uint32_t TempFPRegs = (uint32_t)(
     427                 :           (1 << JSC::SparcRegisters::f0)
     428                 :         | (1 << JSC::SparcRegisters::f2)
     429                 :         | (1 << JSC::SparcRegisters::f4)
     430                 :         | (1 << JSC::SparcRegisters::f6)
     431                 :         ) << TotalRegisters;
     432                 :     static const FPRegisterID FPConversionTemp = JSC::SparcRegisters::f8;
     433                 : #elif defined(JS_CPU_MIPS)
     434                 :     /* TotalRegisters is 24, so TotalFPRegisters can be 8 to have a 32-bit
     435                 :        bit mask.
     436                 :        Note that the O32 ABI can access only even FP registers. */
     437                 :     static const uint32_t TotalFPRegisters = 8;
     438                 :     static const uint32_t TempFPRegs = (uint32_t)(
     439                 :           (1 << JSC::MIPSRegisters::f0)
     440                 :         | (1 << JSC::MIPSRegisters::f2)
     441                 :         | (1 << JSC::MIPSRegisters::f4)
     442                 :         | (1 << JSC::MIPSRegisters::f6)
     443                 :         ) << TotalRegisters;
     444                 :     // f16 is reserved as a scratch register for the assembler.
     445                 :     static const FPRegisterID FPConversionTemp = JSC::MIPSRegisters::f18;
     446                 : #else
     447                 : # error "Unsupported platform"
     448                 : #endif
     449                 : 
     450                 :     /* Temp reg that can be clobbered when setting up a fallible fast or ABI call. */
     451                 : #if defined(JS_CPU_X86) || defined(JS_CPU_X64)
     452                 :     static const RegisterID ClobberInCall = JSC::X86Registers::ecx;
     453                 : #elif defined(JS_CPU_ARM)
     454                 :     static const RegisterID ClobberInCall = JSC::ARMRegisters::r2;
     455                 : #elif defined(JS_CPU_SPARC)
     456                 :     static const RegisterID ClobberInCall = JSC::SparcRegisters::l1;
     457                 : #elif defined(JS_CPU_MIPS)
     458                 :     static const RegisterID ClobberInCall = JSC::MIPSRegisters::at;
     459                 : #endif
     460                 : 
     461                 :     static const uint32_t AvailFPRegs = TempFPRegs;
     462                 : 
     463                 :     static inline uint32_t maskReg(FPRegisterID reg) {
     464                 :         return (1 << reg) << TotalRegisters;
     465                 :     }
     466                 : 
     467                 :     /* Common code. */
     468                 : 
     469                 :     static const uint32_t TotalAnyRegisters = TotalRegisters + TotalFPRegisters;
     470                 :     static const uint32_t TempAnyRegs = TempRegs | TempFPRegs;
     471                 :     static const uint32_t AvailAnyRegs = AvailRegs | AvailFPRegs;
     472                 : 
     473         4444050 :     static inline uint32_t maskReg(AnyRegisterID reg) {
     474         4444050 :         return (1 << reg.reg_);
     475                 :     }
     476                 : 
     477                 :     /* Get a register which is not live before a FASTCALL. */
     478         4765013 :     static inline RegisterID tempCallReg() {
     479         4765013 :         Registers regs(TempRegs);
     480         4765013 :         regs.takeReg(Registers::ArgReg0);
     481         4765013 :         regs.takeReg(Registers::ArgReg1);
     482         4765013 :         return regs.takeAnyReg().reg();
     483                 :     }
     484                 : 
     485                 :     /* Get a register which is not live before a normal ABI call with at most four args. */
     486           35521 :     static inline Registers tempCallRegMask() {
     487           35521 :         Registers regs(AvailRegs);
     488                 : #ifndef JS_CPU_X86
     489                 :         regs.takeReg(ArgReg0);
     490                 :         regs.takeReg(ArgReg1);
     491                 :         regs.takeReg(ArgReg2);
     492                 : #if defined(JS_CPU_SPARC) || defined(JS_CPU_X64)
     493                 :         regs.takeReg(ArgReg3);
     494                 : #endif
     495                 : #endif
     496                 :         return regs;
     497                 :     }
     498                 : 
     499        51805399 :     Registers(uint32_t freeMask)
     500        51805399 :       : freeMask(freeMask)
     501        51805399 :     { }
     502                 : 
     503         1870165 :     Registers(const Registers &other)
     504         1870165 :       : freeMask(other.freeMask)
     505         1870165 :     { }
     506                 : 
     507         8202707 :     Registers & operator =(const Registers &other)
     508                 :     {
     509         8202707 :         freeMask = other.freeMask;
     510         8202707 :         return *this;
     511                 :     }
     512                 : 
     513       100742101 :     bool empty(uint32_t mask) const {
     514       100742101 :         return !(freeMask & mask);
     515                 :     }
     516                 : 
     517        82493417 :     bool empty() const {
     518        82493417 :         return !freeMask;
     519                 :     }
     520                 : 
     521        90262055 :     AnyRegisterID peekReg(uint32_t mask) {
     522        90262055 :         JS_ASSERT(!empty(mask));
     523                 :         unsigned ireg;
     524        90262055 :         JS_FLOOR_LOG2(ireg, freeMask & mask);
     525        90262055 :         return AnyRegisterID::fromRaw(ireg);
     526                 :     }
     527                 : 
     528                 :     AnyRegisterID peekReg() {
     529                 :         return peekReg(freeMask);
     530                 :     }
     531                 : 
     532        85984861 :     AnyRegisterID takeAnyReg(uint32_t mask) {
     533        85984861 :         AnyRegisterID reg = peekReg(mask);
     534        85984861 :         takeReg(reg);
     535                 :         return reg;
     536                 :     }
     537                 : 
     538        78393971 :     AnyRegisterID takeAnyReg() {
     539        78393971 :         return takeAnyReg(freeMask);
     540                 :     }
     541                 : 
     542       194754032 :     bool hasReg(AnyRegisterID reg) const {
     543       194754032 :         return !!(freeMask & (1 << reg.reg_));
     544                 :     }
     545                 : 
     546         6045981 :     bool hasRegInMask(uint32_t mask) const {
     547         6045981 :         return !!(freeMask & mask);
     548                 :     }
     549                 : 
     550                 :     bool hasAllRegs(uint32_t mask) const {
     551                 :         return (freeMask & mask) == mask;
     552                 :     }
     553                 : 
     554        17207283 :     void putRegUnchecked(AnyRegisterID reg) {
     555        17207283 :         freeMask |= (1 << reg.reg_);
     556        17207283 :     }
     557                 : 
     558        17207283 :     void putReg(AnyRegisterID reg) {
     559        17207283 :         JS_ASSERT(!hasReg(reg));
     560        17207283 :         putRegUnchecked(reg);
     561        17207283 :     }
     562                 : 
     563       132498186 :     void takeReg(AnyRegisterID reg) {
     564       132498186 :         JS_ASSERT(hasReg(reg));
     565       132498186 :         takeRegUnchecked(reg);
     566       132498186 :     }
     567                 : 
     568       142238374 :     void takeRegUnchecked(AnyRegisterID reg) {
     569       142238374 :         freeMask &= ~(1 << reg.reg_);
     570       142238374 :     }
     571                 : 
     572        17343229 :     bool operator ==(const Registers &other) {
     573        17343229 :         return freeMask == other.freeMask;
     574                 :     }
     575                 : 
     576                 :     uint32_t freeMask;
     577                 : };
     578                 : 
     579                 : static const JSC::MacroAssembler::RegisterID JSFrameReg = Registers::JSFrameReg;
     580                 : 
     581                 : AnyRegisterID
     582       107930825 : AnyRegisterID::fromRaw(unsigned reg_)
     583                 : {
     584       107930825 :     JS_ASSERT(reg_ < Registers::TotalAnyRegisters);
     585       107930825 :     AnyRegisterID reg;
     586       107930825 :     reg.reg_ = reg_;
     587                 :     return reg;
     588                 : }
     589                 : 
     590                 : JSC::MacroAssembler::RegisterID
     591        26027638 : AnyRegisterID::reg()
     592                 : {
     593        26027638 :     JS_ASSERT(reg_ < Registers::TotalRegisters);
     594        26027638 :     return (JSC::MacroAssembler::RegisterID) reg_;
     595                 : }
     596                 : 
     597                 : JSC::MacroAssembler::FPRegisterID
     598         1407011 : AnyRegisterID::fpreg()
     599                 : {
     600               0 :     JS_ASSERT(reg_ >= Registers::TotalRegisters &&
     601         1407011 :               reg_ < Registers::TotalAnyRegisters);
     602         1407011 :     return (JSC::MacroAssembler::FPRegisterID) (reg_ - Registers::TotalRegisters);
     603                 : }
     604                 : 
     605                 : const char *
     606          611996 : AnyRegisterID::name()
     607                 : {
     608                 : #if defined(JS_CPU_X86) || defined(JS_CPU_X64)
     609          611996 :     return isReg() ? JSC::X86Registers::nameIReg(reg()) : JSC::X86Registers::nameFPReg(fpreg());
     610                 : #elif defined(JS_CPU_ARM)
     611                 :     return isReg() ? JSC::ARMAssembler::nameGpReg(reg()) : JSC::ARMAssembler::nameFpRegD(fpreg());
     612                 : #else
     613                 :     return "???";
     614                 : #endif
     615                 : }
     616                 : 
     617                 : } /* namespace mjit */
     618                 : 
     619                 : } /* namespace js */
     620                 : 
     621                 : #endif /* jsjaeger_regstate_h__ */
     622                 : 

Generated by: LCOV version 1.7