LCOV - code coverage report
Current view: directory - js/src/methodjit - NunboxAssembler.h (source / functions) Found Hit Coverage
Test: app.info Lines: 216 215 99.5 %
Date: 2012-06-02 Functions: 66 66 100.0 %

       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                 :  *   David Mandelin <dmandelin@mozilla.com>
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      29                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : #if !defined jsjaeger_assembler_h__ && defined JS_METHODJIT && defined JS_NUNBOX32
      42                 : #define jsjaeger_assembler_h__
      43                 : 
      44                 : #include "assembler/assembler/MacroAssembler.h"
      45                 : #include "methodjit/CodeGenIncludes.h"
      46                 : #include "methodjit/RematInfo.h"
      47                 : 
      48                 : namespace js {
      49                 : namespace mjit {
      50                 : 
      51                 : /* Don't use ImmTag. Use ImmType instead. */
      52                 : struct ImmTag : JSC::MacroAssembler::Imm32
      53                 : {
      54         8319554 :     ImmTag(JSValueTag mask)
      55         8319554 :       : Imm32(int32_t(mask))
      56         8319554 :     { }
      57                 : };
      58                 : 
      59                 : struct ImmType : ImmTag
      60                 : {
      61         1512643 :     ImmType(JSValueType type)
      62         1512643 :       : ImmTag(JSVAL_TYPE_TO_TAG(type))
      63                 :     {
      64         1512643 :         JS_ASSERT(type > JSVAL_TYPE_DOUBLE);
      65         1512643 :     }
      66                 : };
      67                 : 
      68                 : struct ImmPayload : JSC::MacroAssembler::Imm32
      69                 : {
      70         2375341 :     ImmPayload(uint32_t payload)
      71         2375341 :       : Imm32(payload)
      72         2375341 :     { }
      73                 : };
      74                 : 
      75                 : class NunboxAssembler : public JSC::MacroAssembler
      76         1385242 : {
      77                 :   public:
      78                 : #ifdef IS_BIG_ENDIAN
      79                 :     static const uint32_t PAYLOAD_OFFSET = 4;
      80                 :     static const uint32_t TAG_OFFSET     = 0;
      81                 : #else
      82                 :     static const uint32_t PAYLOAD_OFFSET = 0;
      83                 :     static const uint32_t TAG_OFFSET     = 4;
      84                 : #endif
      85                 : 
      86                 :   public:
      87                 :     static const JSC::MacroAssembler::Scale JSVAL_SCALE = JSC::MacroAssembler::TimesEight;
      88                 : 
      89        18236345 :     Address payloadOf(Address address) {
      90        18236345 :         return Address(address.base, address.offset + PAYLOAD_OFFSET);
      91                 :     }
      92                 :   
      93           39705 :     BaseIndex payloadOf(BaseIndex address) {
      94           39705 :         return BaseIndex(address.base, address.index, address.scale, address.offset + PAYLOAD_OFFSET);
      95                 :     }
      96                 : 
      97        15675809 :     Address tagOf(Address address) {
      98        15675809 :         return Address(address.base, address.offset + TAG_OFFSET);
      99                 :     }
     100                 : 
     101           40921 :     BaseIndex tagOf(BaseIndex address) {
     102           40921 :         return BaseIndex(address.base, address.index, address.scale, address.offset + TAG_OFFSET);
     103                 :     }
     104                 : 
     105           15948 :     void loadInlineSlot(RegisterID objReg, uint32_t slot,
     106                 :                         RegisterID typeReg, RegisterID dataReg) {
     107           15948 :         Address address(objReg, JSObject::getFixedSlotOffset(slot));
     108           15948 :         if (objReg == typeReg) {
     109            5277 :             loadPayload(address, dataReg);
     110            5277 :             loadTypeTag(address, typeReg);
     111                 :         } else {
     112           10671 :             loadTypeTag(address, typeReg);
     113           10671 :             loadPayload(address, dataReg);
     114                 :         }
     115           15948 :     }
     116                 : 
     117                 :     template <typename T>
     118         5618028 :     void loadTypeTag(T address, RegisterID reg) {
     119         5618028 :         load32(tagOf(address), reg);
     120         5618028 :     }
     121                 : 
     122                 :     template <typename T>
     123         3824786 :     void storeTypeTag(ImmTag imm, T address) {
     124         3824786 :         store32(imm, tagOf(address));
     125         3824786 :     }
     126                 : 
     127                 :     template <typename T>
     128         5509127 :     void storeTypeTag(RegisterID reg, T address) {
     129         5509127 :         store32(reg, tagOf(address));
     130         5509127 :     }
     131                 : 
     132                 :     template <typename T>
     133         7973548 :     void loadPayload(T address, RegisterID reg) {
     134         7973548 :         load32(payloadOf(address), reg);
     135         7973548 :     }
     136                 : 
     137                 :     template <typename T>
     138         7526288 :     void storePayload(RegisterID reg, T address) {
     139         7526288 :         store32(reg, payloadOf(address));
     140         7526288 :     }
     141                 : 
     142                 :     template <typename T>
     143         2375341 :     void storePayload(ImmPayload imm, T address) {
     144         2375341 :         store32(imm, payloadOf(address));
     145         2375341 :     }
     146                 : 
     147             417 :     bool addressUsesRegister(BaseIndex address, RegisterID reg) {
     148             417 :         return (address.base == reg) || (address.index == reg);
     149                 :     }
     150                 : 
     151         2909184 :     bool addressUsesRegister(Address address, RegisterID reg) {
     152         2909184 :         return address.base == reg;
     153                 :     }
     154                 : 
     155                 :     /* Loads type first, then payload, returning label after type load. */
     156                 :     template <typename T>
     157         2909601 :     Label loadValueAsComponents(T address, RegisterID type, RegisterID payload) {
     158         2909601 :         JS_ASSERT(!addressUsesRegister(address, type));
     159         2909601 :         loadTypeTag(address, type);
     160         2909601 :         Label l = label();
     161         2909601 :         loadPayload(address, payload);
     162                 :         return l;
     163                 :     }
     164                 : 
     165          215280 :     void loadValueAsComponents(const Value &val, RegisterID type, RegisterID payload) {
     166          215280 :         jsval_layout jv = JSVAL_TO_IMPL(val);
     167          215280 :         move(ImmTag(jv.s.tag), type);
     168          215280 :         move(Imm32(jv.s.payload.u32), payload);
     169          215280 :     }
     170                 : 
     171             347 :     void loadValuePayload(const Value &val, RegisterID payload) {
     172             347 :         jsval_layout jv = JSVAL_TO_IMPL(val);
     173             347 :         move(Imm32(jv.s.payload.u32), payload);
     174             347 :     }
     175                 : 
     176                 :     /*
     177                 :      * Load a (64b) js::Value from 'address' into 'type' and 'payload', and
     178                 :      * return a label which can be used by
     179                 :      * ICRepatcher::patchAddressOffsetForValueLoad to patch the address'
     180                 :      * offset.
     181                 :      *
     182                 :      * The data register is guaranteed to be clobbered last. (This makes the
     183                 :      * base register for the address reusable as 'dreg'.)
     184                 :      */
     185          821748 :     Label loadValueWithAddressOffsetPatch(Address address, RegisterID treg, RegisterID dreg) {
     186          821748 :         JS_ASSERT(address.base != treg); /* treg is clobbered first. */
     187                 : 
     188          821748 :         Label start = label();
     189                 : #if defined JS_CPU_X86
     190                 :         /*
     191                 :          * On x86 there are two loads to patch and they both encode the offset
     192                 :          * in-line.
     193                 :          */
     194          821748 :         loadTypeTag(address, treg);
     195          821748 :         DBGLABEL_NOMASM(endType);
     196          821748 :         loadPayload(address, dreg);
     197          821748 :         DBGLABEL_NOMASM(endPayload);
     198          821748 :         JS_ASSERT(differenceBetween(start, endType) == 6);
     199          821748 :         JS_ASSERT(differenceBetween(endType, endPayload) == 6);
     200                 :         return start;
     201                 : #elif defined JS_CPU_ARM || defined JS_CPU_SPARC
     202                 :         /* 
     203                 :          * On ARM, the first instruction loads the offset from a literal pool, so the label
     204                 :          * returned points at that instruction.
     205                 :          */
     206                 :         DataLabel32 load = load64WithAddressOffsetPatch(address, treg, dreg);
     207                 :         JS_ASSERT(differenceBetween(start, load) == 0);
     208                 :         (void) load;
     209                 :         return start;
     210                 : #elif defined JS_CPU_MIPS
     211                 :         /*
     212                 :          * On MIPS there are LUI/ORI to patch.
     213                 :          */
     214                 :         load64WithPatch(address, treg, dreg, TAG_OFFSET, PAYLOAD_OFFSET);
     215                 :         return start;
     216                 : #endif
     217                 :     }
     218                 : 
     219                 :     /*
     220                 :      * Store a (64b) js::Value from type |treg| and payload |dreg| into |address|, and
     221                 :      * return a label which can be used by
     222                 :      * ICRepatcher::patchAddressOffsetForValueStore to patch the address'
     223                 :      * offset.
     224                 :      */
     225           28176 :     DataLabel32 storeValueWithAddressOffsetPatch(RegisterID treg, RegisterID dreg, Address address) {
     226           28176 :         DataLabel32 start = dataLabel32();
     227                 : #if defined JS_CPU_X86
     228                 :         /*
     229                 :          * On x86 there are two stores to patch and they both encode the offset
     230                 :          * in-line.
     231                 :          */
     232           28176 :         storeTypeTag(treg, address);
     233           28176 :         DBGLABEL_NOMASM(endType);
     234           28176 :         storePayload(dreg, address);
     235           28176 :         DBGLABEL_NOMASM(endPayload);
     236           28176 :         JS_ASSERT(differenceBetween(start, endType) == 6);
     237           28176 :         JS_ASSERT(differenceBetween(endType, endPayload) == 6);
     238                 :         return start;
     239                 : #elif defined JS_CPU_ARM || defined JS_CPU_SPARC
     240                 :         return store64WithAddressOffsetPatch(treg, dreg, address);
     241                 : #elif defined JS_CPU_MIPS
     242                 :         /*
     243                 :          * On MIPS there are LUI/ORI to patch.
     244                 :          */
     245                 :         store64WithPatch(address, treg, dreg, TAG_OFFSET, PAYLOAD_OFFSET);
     246                 :         return start;
     247                 : #endif
     248                 :     }
     249                 : 
     250                 :     /* Overloaded for storing a constant type. */
     251           22483 :     DataLabel32 storeValueWithAddressOffsetPatch(ImmType type, RegisterID dreg, Address address) {
     252           22483 :         DataLabel32 start = dataLabel32();
     253                 : #if defined JS_CPU_X86
     254           22483 :         storeTypeTag(type, address);
     255           22483 :         DBGLABEL_NOMASM(endType);
     256           22483 :         storePayload(dreg, address);
     257           22483 :         DBGLABEL_NOMASM(endPayload);
     258           22483 :         JS_ASSERT(differenceBetween(start, endType) == 10);
     259           22483 :         JS_ASSERT(differenceBetween(endType, endPayload) == 6);
     260                 :         return start;
     261                 : #elif defined JS_CPU_ARM || defined JS_CPU_SPARC
     262                 :         return store64WithAddressOffsetPatch(type, dreg, address);
     263                 : #elif defined JS_CPU_MIPS
     264                 :         /*
     265                 :          * On MIPS there are LUI/ORI to patch.
     266                 :          */
     267                 :         store64WithPatch(address, type, dreg, TAG_OFFSET, PAYLOAD_OFFSET);
     268                 :         return start;
     269                 : #endif
     270                 :     }
     271                 : 
     272                 :     /* Overloaded for storing constant type and data. */
     273           13182 :     DataLabel32 storeValueWithAddressOffsetPatch(const Value &v, Address address) {
     274           13182 :         jsval_layout jv = JSVAL_TO_IMPL(v);
     275           13182 :         ImmTag type(jv.s.tag);
     276           13182 :         Imm32 payload(jv.s.payload.u32);
     277           13182 :         DataLabel32 start = dataLabel32();
     278                 : #if defined JS_CPU_X86
     279           13182 :         store32(type, tagOf(address));
     280           13182 :         DBGLABEL_NOMASM(endType);
     281           13182 :         store32(payload, payloadOf(address));
     282           13182 :         DBGLABEL_NOMASM(endPayload);
     283           13182 :         JS_ASSERT(differenceBetween(start, endType) == 10);
     284           13182 :         JS_ASSERT(differenceBetween(endType, endPayload) == 10);
     285                 :         return start;
     286                 : #elif defined JS_CPU_ARM || defined JS_CPU_SPARC
     287                 :         return store64WithAddressOffsetPatch(type, payload, address);
     288                 : #elif defined JS_CPU_MIPS
     289                 :         /*
     290                 :          * On MIPS there are LUI/ORI to patch.
     291                 :          */
     292                 :         store64WithPatch(address, type, payload, TAG_OFFSET, PAYLOAD_OFFSET);
     293                 :         return start;
     294                 : #endif
     295                 :     }
     296                 : 
     297                 :     /* Overloaded for store with value remat info. */
     298           33078 :     DataLabel32 storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) {
     299           33078 :         JS_ASSERT(!vr.isFPRegister());
     300           33078 :         if (vr.isConstant()) {
     301            6909 :             return storeValueWithAddressOffsetPatch(vr.value(), address);
     302           26169 :         } else if (vr.isTypeKnown()) {
     303            7201 :             ImmType type(vr.knownType());
     304            7201 :             RegisterID data(vr.dataReg());
     305            7201 :             return storeValueWithAddressOffsetPatch(type, data, address);
     306                 :         } else {
     307           18968 :             RegisterID type(vr.typeReg());
     308           18968 :             RegisterID data(vr.dataReg());
     309           18968 :             return storeValueWithAddressOffsetPatch(type, data, address);
     310                 :         }
     311                 :     }
     312                 : 
     313                 :     /*
     314                 :      * Stores type first, then payload.
     315                 :      */
     316                 :     template <typename T>
     317          357726 :     Label storeValue(const Value &v, T address) {
     318          357726 :         jsval_layout jv = JSVAL_TO_IMPL(v);
     319          357726 :         store32(ImmTag(jv.s.tag), tagOf(address));
     320          357726 :         Label l = label();
     321          357726 :         store32(Imm32(jv.s.payload.u32), payloadOf(address));
     322                 :         return l;
     323                 :     }
     324                 : 
     325                 :     template <typename T>
     326          205839 :     void storeValueFromComponents(RegisterID type, RegisterID payload, T address) {
     327          205839 :         storeTypeTag(type, address);
     328          205839 :         storePayload(payload, address);
     329          205839 :     }
     330                 : 
     331                 :     template <typename T>
     332           11410 :     void storeValueFromComponents(ImmType type, RegisterID payload, T address) {
     333           11410 :         storeTypeTag(type, address);
     334           11410 :         storePayload(payload, address);
     335           11410 :     }
     336                 : 
     337                 :     template <typename T>
     338           21865 :     Label storeValue(const ValueRemat &vr, T address) {
     339           21865 :         if (vr.isConstant()) {
     340            3366 :             return storeValue(vr.value(), address);
     341           18499 :         } else if (vr.isFPRegister()) {
     342            1307 :             Label l = label();
     343            1307 :             storeDouble(vr.fpReg(), address);
     344            1307 :             return l;
     345                 :         } else {
     346           17192 :             if (vr.isTypeKnown())
     347            6920 :                 storeTypeTag(ImmType(vr.knownType()), address);
     348                 :             else
     349           10272 :                 storeTypeTag(vr.typeReg(), address);
     350           17192 :             Label l = label();
     351           17192 :             storePayload(vr.dataReg(), address);
     352           17192 :             return l;
     353                 :         }
     354                 :     }
     355                 : 
     356                 :     template <typename T>
     357            5714 :     Jump guardNotHole(T address) {
     358            5714 :         return branch32(Equal, tagOf(address), ImmType(JSVAL_TYPE_MAGIC));
     359                 :     }
     360                 : 
     361            3413 :     void loadPrivate(Address privAddr, RegisterID to) {
     362            3413 :         loadPtr(payloadOf(privAddr), to);
     363            3413 :     }
     364                 : 
     365           28252 :     void loadObjPrivate(RegisterID base, RegisterID to, uint32_t nfixed) {
     366           28252 :         Address priv(base, JSObject::getPrivateDataOffset(nfixed));
     367           28252 :         loadPtr(priv, to);
     368           28252 :     }
     369                 : 
     370            6203 :     Jump testNull(Condition cond, RegisterID reg) {
     371            6203 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_NULL));
     372                 :     }
     373                 : 
     374            4213 :     Jump testNull(Condition cond, Address address) {
     375            4213 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_NULL));
     376                 :     }
     377                 : 
     378           13685 :     Jump testUndefined(Condition cond, RegisterID reg) {
     379           13685 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_UNDEFINED));
     380                 :     }
     381                 : 
     382            4169 :     Jump testUndefined(Condition cond, Address address) {
     383            4169 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_UNDEFINED));
     384                 :     }
     385                 : 
     386         1407710 :     Jump testInt32(Condition cond, RegisterID reg) {
     387         1407710 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_INT32));
     388                 :     }
     389                 : 
     390           40984 :     Jump testInt32(Condition cond, Address address) {
     391           40984 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_INT32));
     392                 :     }
     393                 : 
     394           13750 :     Jump testNumber(Condition cond, RegisterID reg) {
     395           13750 :         cond = (cond == Equal) ? BelowOrEqual : Above;
     396           13750 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_INT32));
     397                 :     }
     398                 : 
     399          202913 :     Jump testNumber(Condition cond, Address address) {
     400          202913 :         cond = (cond == Equal) ? BelowOrEqual : Above;
     401          202913 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_INT32));
     402                 :     }
     403                 : 
     404           19187 :     Jump testPrimitive(Condition cond, RegisterID reg) {
     405           19187 :         cond = (cond == NotEqual) ? AboveOrEqual : Below;
     406           19187 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_OBJECT));
     407                 :     }
     408                 : 
     409             334 :     Jump testPrimitive(Condition cond, Address address) {
     410             334 :         cond = (cond == NotEqual) ? AboveOrEqual : Below;
     411             334 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_OBJECT));
     412                 :     }
     413                 : 
     414          634799 :     Jump testObject(Condition cond, RegisterID reg) {
     415          634799 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_OBJECT));
     416                 :     }
     417                 : 
     418           54211 :     Jump testObject(Condition cond, Address address) {
     419           54211 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_OBJECT));
     420                 :     }
     421                 : 
     422                 :     Jump testGCThing(RegisterID reg) {
     423                 :         return branch32(AboveOrEqual, reg, ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET));
     424                 :     }
     425                 : 
     426               4 :     Jump testGCThing(Address address) {
     427               4 :         return branch32(AboveOrEqual, tagOf(address), ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET));
     428                 :     }
     429                 : 
     430         1316933 :     Jump testDouble(Condition cond, RegisterID reg) {
     431                 :         Condition opcond;
     432         1316933 :         if (cond == Equal)
     433          351163 :             opcond = Below;
     434                 :         else
     435          965770 :             opcond = AboveOrEqual;
     436         1316933 :         return branch32(opcond, reg, ImmTag(JSVAL_TAG_CLEAR));
     437                 :     }
     438                 : 
     439              28 :     Jump testDouble(Condition cond, Address address) {
     440                 :         Condition opcond;
     441              28 :         if (cond == Equal)
     442               0 :             opcond = Below;
     443                 :         else
     444              28 :             opcond = AboveOrEqual;
     445              28 :         return branch32(opcond, tagOf(address), ImmTag(JSVAL_TAG_CLEAR));
     446                 :     }
     447                 : 
     448           22399 :     Jump testBoolean(Condition cond, RegisterID reg) {
     449           22399 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_BOOLEAN));
     450                 :     }
     451                 : 
     452           71995 :     Jump testBoolean(Condition cond, Address address) {
     453           71995 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_BOOLEAN));
     454                 :     }
     455                 : 
     456           23725 :     Jump testString(Condition cond, RegisterID reg) {
     457           23725 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_STRING));
     458                 :     }
     459                 : 
     460            8390 :     Jump testString(Condition cond, Address address) {
     461            8390 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_STRING));
     462                 :     }
     463                 : 
     464             110 :     void compareValue(Address one, Address two, RegisterID T0, RegisterID T1,
     465                 :                       Vector<Jump> *mismatches) {
     466             110 :         loadValueAsComponents(one, T0, T1);
     467             110 :         mismatches->append(branch32(NotEqual, T0, tagOf(two)));
     468             110 :         mismatches->append(branch32(NotEqual, T1, payloadOf(two)));
     469             110 :     }
     470                 : 
     471                 : #ifdef JS_CPU_X86
     472                 :     void fastLoadDouble(RegisterID lo, RegisterID hi, FPRegisterID fpReg) {
     473                 :         if (MacroAssemblerX86Common::getSSEState() >= HasSSE4_1) {
     474                 :             m_assembler.movd_rr(lo, fpReg);
     475                 :             m_assembler.pinsrd_rr(hi, fpReg);
     476                 :         } else {
     477                 :             m_assembler.movd_rr(lo, fpReg);
     478                 :             m_assembler.movd_rr(hi, Registers::FPConversionTemp);
     479                 :             m_assembler.unpcklps_rr(Registers::FPConversionTemp, fpReg);
     480                 :         }
     481                 :     }
     482                 : #endif
     483                 : 
     484            1113 :     void breakDouble(FPRegisterID srcDest, RegisterID typeReg, RegisterID dataReg) {
     485                 : #ifdef JS_CPU_X86
     486                 :         // Move the low 32-bits of the 128-bit XMM register into dataReg.
     487                 :         // Then, right shift the 128-bit XMM register by 4 bytes.
     488                 :         // Finally, move the new low 32-bits of the 128-bit XMM register into typeReg.
     489            1113 :         m_assembler.movd_rr(srcDest, dataReg);
     490            1113 :         m_assembler.psrldq_rr(srcDest, 4);
     491            1113 :         m_assembler.movd_rr(srcDest, typeReg);
     492                 : #elif defined JS_CPU_SPARC
     493                 :         breakDoubleTo32(srcDest, typeReg, dataReg);
     494                 : #elif defined JS_CPU_ARM
     495                 :         // Yes, we are backwards from SPARC.
     496                 :         fastStoreDouble(srcDest, dataReg, typeReg);
     497                 : #elif defined JS_CPU_MIPS
     498                 : #if defined(IS_LITTLE_ENDIAN)
     499                 :         fastStoreDouble(srcDest, dataReg, typeReg);
     500                 : #else
     501                 :         fastStoreDouble(srcDest, typeReg, dataReg);
     502                 : #endif
     503                 : #else
     504                 :         JS_NOT_REACHED("implement this - push double, pop pop is easiest");
     505                 : #endif
     506            1113 :     }
     507                 : 
     508             209 :     void loadStaticDouble(const double *dp, FPRegisterID dest, RegisterID scratch) {
     509             209 :         move(ImmPtr(dp), scratch);
     510             209 :         loadDouble(Address(scratch), dest);
     511             209 :     }
     512                 : 
     513                 :     template <typename T>
     514           45053 :     Jump fastArrayLoadSlot(T address, bool holeCheck,
     515                 :                            MaybeRegisterID typeReg, RegisterID dataReg)
     516                 :     {
     517           45053 :         Jump notHole;
     518           45053 :         if (typeReg.isSet()) {
     519           40269 :             loadTypeTag(address, typeReg.reg());
     520           40269 :             if (holeCheck)
     521           21663 :                 notHole = branch32(Equal, typeReg.reg(), ImmType(JSVAL_TYPE_MAGIC));
     522            4784 :         } else if (holeCheck) {
     523             809 :             notHole = branch32(Equal, tagOf(address), ImmType(JSVAL_TYPE_MAGIC));
     524                 :         }
     525           45053 :         loadPayload(address, dataReg);
     526                 :         return notHole;
     527                 :     }
     528                 : };
     529                 : 
     530                 : typedef NunboxAssembler ValueAssembler;
     531                 : 
     532                 : } /* namespace mjit */
     533                 : } /* namespace js */
     534                 : 
     535                 : #endif
     536                 : 

Generated by: LCOV version 1.7