LCOV - app.info - js/src/methodjit/MachineRegs.h

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-04-07 | 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        68961544 :     AnyRegisterID()
          57        68961544 :         : reg_((unsigned)-1)
          58        68961544 :     { pin(); }
          59                 :
          60       783085200 :     AnyRegisterID(const AnyRegisterID &o)
          61       783085200 :         : reg_(o.reg_)
          62       783085200 :     { pin(); }
          63                 :
          64       128590905 :     AnyRegisterID(JSC::MacroAssembler::RegisterID reg)
          65       128590905 :         : reg_((unsigned)reg)
          66       128590905 :     { pin(); }
          67                 :
          68        58176274 :     AnyRegisterID(JSC::MacroAssembler::FPRegisterID reg)
          69        58176274 :         : reg_(JSC::MacroAssembler::TotalRegisters + (unsigned)reg)
          70        58176274 :     { pin(); }
          71                 :
          72                 :     static inline AnyRegisterID fromRaw(unsigned reg);
          73                 :
          74                 :     inline JSC::MacroAssembler::RegisterID reg();
          75                 :     inline JSC::MacroAssembler::FPRegisterID fpreg();
          76                 :
          77          502310 :     bool isSet() { return reg_ != unsigned(-1); }
          78         1082789 :     bool isReg() { return reg_ < JSC::MacroAssembler::TotalRegisters; }
          79          203074 :     bool isFPReg() { return isSet() && !isReg(); }
          80                 :
          81                 :     inline const char * name();
          82                 :
          83                 :   private:
          84      1038813923 :     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      1038813923 :         v = &reg_;
          91      1038813923 :         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          307586 :     static inline uint32_t maskReg(RegisterID reg) {
         168          307586 :         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            1037 :     static bool isSaved(RegisterID reg) {
         303            1037 :         uint32_t mask = maskReg(reg);
         304            1037 :         JS_ASSERT(mask & AvailRegs);
         305            1037 :         return bool(mask & SavedRegs);
         306                 :     }
         307                 :
         308         8068933 :     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         8068933 :         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         5385091 :     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         5385091 :         if (conv == NormalCall)
         341           51893 :             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         5333198 :         JS_ASSERT(numArgRegs(conv) == mozilla::ArrayLength(regs));
         386         5333198 :         if (i > mozilla::ArrayLength(regs))
         387               0 :             return false;
         388         5333198 :         *reg = regs[i];
         389         5333198 :         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         4692444 :     static inline uint32_t maskReg(AnyRegisterID reg) {
         474         4692444 :         return (1 << reg.reg_);
         475                 :     }
         476                 :
         477                 :     /* Get a register which is not live before a FASTCALL. */
         478         2607715 :     static inline RegisterID tempCallReg() {
         479         2607715 :         Registers regs(TempRegs);
         480         2607715 :         regs.takeReg(Registers::ArgReg0);
         481         2607715 :         regs.takeReg(Registers::ArgReg1);
         482         2607715 :         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           17243 :     static inline Registers tempCallRegMask() {
         487           17243 :         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        26894199 :     Registers(uint32_t freeMask)
         500        26894199 :       : freeMask(freeMask)
         501        26894199 :     { }
         502                 :
         503          865238 :     Registers(const Registers &other)
         504          865238 :       : freeMask(other.freeMask)
         505          865238 :     { }
         506                 :
         507         4531465 :     Registers & operator =(const Registers &other)
         508                 :     {
         509         4531465 :         freeMask = other.freeMask;
         510         4531465 :         return *this;
         511                 :     }
         512                 :
         513        58089123 :     bool empty(uint32_t mask) const {
         514        58089123 :         return !(freeMask & mask);
         515                 :     }
         516                 :
         517        48859398 :     bool empty() const {
         518        48859398 :         return !freeMask;
         519                 :     }
         520                 :
         521        52811592 :     AnyRegisterID peekReg(uint32_t mask) {
         522        52811592 :         JS_ASSERT(!empty(mask));
         523                 :         unsigned ireg;
         524        52811592 :         JS_FLOOR_LOG2(ireg, freeMask & mask);
         525        52811592 :         return AnyRegisterID::fromRaw(ireg);
         526                 :     }
         527                 :
         528                 :     AnyRegisterID peekReg() {
         529                 :         return peekReg(freeMask);
         530                 :     }
         531                 :
         532        50320594 :     AnyRegisterID takeAnyReg(uint32_t mask) {
         533        50320594 :         AnyRegisterID reg = peekReg(mask);
         534        50320594 :         takeReg(reg);
         535                 :         return reg;
         536                 :     }
         537                 :
         538        46519260 :     AnyRegisterID takeAnyReg() {
         539        46519260 :         return takeAnyReg(freeMask);
         540                 :     }
         541                 :
         542       103362040 :     bool hasReg(AnyRegisterID reg) const {
         543       103362040 :         return !!(freeMask & (1 << reg.reg_));
         544                 :     }
         545                 :
         546         3468944 :     bool hasRegInMask(uint32_t mask) const {
         547         3468944 :         return !!(freeMask & mask);
         548                 :     }
         549                 :
         550                 :     bool hasAllRegs(uint32_t mask) const {
         551                 :         return (freeMask & mask) == mask;
         552                 :     }
         553                 :
         554         9697978 :     void putRegUnchecked(AnyRegisterID reg) {
         555         9697978 :         freeMask |= (1 << reg.reg_);
         556         9697978 :     }
         557                 :
         558         9697978 :     void putReg(AnyRegisterID reg) {
         559         9697978 :         JS_ASSERT(!hasReg(reg));
         560         9697978 :         putRegUnchecked(reg);
         561         9697978 :     }
         562                 :
         563        71093088 :     void takeReg(AnyRegisterID reg) {
         564        71093088 :         JS_ASSERT(hasReg(reg));
         565        71093088 :         takeRegUnchecked(reg);
         566        71093088 :     }
         567                 :
         568        76426286 :     void takeRegUnchecked(AnyRegisterID reg) {
         569        76426286 :         freeMask &= ~(1 << reg.reg_);
         570        76426286 :     }
         571                 :
         572         8145898 :     bool operator ==(const Registers &other) {
         573         8145898 :         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        68092457 : AnyRegisterID::fromRaw(unsigned reg_)
         583                 : {
         584        68092457 :     JS_ASSERT(reg_ < Registers::TotalAnyRegisters);
         585        68092457 :     AnyRegisterID reg;
         586        68092457 :     reg.reg_ = reg_;
         587                 :     return reg;
         588                 : }
         589                 :
         590                 : JSC::MacroAssembler::RegisterID
         591        13468399 : AnyRegisterID::reg()
         592                 : {
         593        13468399 :     JS_ASSERT(reg_ < Registers::TotalRegisters);
         594        13468399 :     return (JSC::MacroAssembler::RegisterID) reg_;
         595                 : }
         596                 :
         597                 : JSC::MacroAssembler::FPRegisterID
         598          885222 : AnyRegisterID::fpreg()
         599                 : {
         600               0 :     JS_ASSERT(reg_ >= Registers::TotalRegisters &&
         601          885222 :               reg_ < Registers::TotalAnyRegisters);
         602          885222 :     return (JSC::MacroAssembler::FPRegisterID) (reg_ - Registers::TotalRegisters);
         603                 : }
         604                 :
         605                 : const char *
         606          549668 : AnyRegisterID::name()
         607                 : {
         608                 : #if defined(JS_CPU_X86) || defined(JS_CPU_X64)
         609          549668 :     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