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

LCOV - code coverage report
| Current view: | directory - js/src/methodjit - NunboxAssembler.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 213 | 212 | 99.5 %
| Date: | 2012-04-07 | Functions: | 65 | 65 | 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         5167650 :     ImmTag(JSValueTag mask)
          55         5167650 :       : Imm32(int32_t(mask))
          56         5167650 :     { }
          57                 : };
          58                 :
          59                 : struct ImmType : ImmTag
          60                 : {
          61         1047915 :     ImmType(JSValueType type)
          62         1047915 :       : ImmTag(JSVAL_TYPE_TO_TAG(type))
          63                 :     {
          64         1047915 :         JS_ASSERT(type > JSVAL_TYPE_DOUBLE);
          65         1047915 :     }
          66                 : };
          67                 :
          68                 : struct ImmPayload : JSC::MacroAssembler::Imm32
          69                 : {
          70         1228493 :     ImmPayload(uint32_t payload)
          71         1228493 :       : Imm32(payload)
          72         1228493 :     { }
          73                 : };
          74                 :
          75                 : class NunboxAssembler : public JSC::MacroAssembler
          76          695302 : {
          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        10049990 :     Address payloadOf(Address address) {
          90        10049990 :         return Address(address.base, address.offset + PAYLOAD_OFFSET);
          91                 :     }
          92                 :
          93           39383 :     BaseIndex payloadOf(BaseIndex address) {
          94           39383 :         return BaseIndex(address.base, address.index, address.scale, address.offset + PAYLOAD_OFFSET);
          95                 :     }
          96                 :
          97         7494494 :     Address tagOf(Address address) {
          98         7494494 :         return Address(address.base, address.offset + TAG_OFFSET);
          99                 :     }
         100                 :
         101           40418 :     BaseIndex tagOf(BaseIndex address) {
         102           40418 :         return BaseIndex(address.base, address.index, address.scale, address.offset + TAG_OFFSET);
         103                 :     }
         104                 :
         105            6717 :     void loadInlineSlot(RegisterID objReg, uint32_t slot,
         106                 :                         RegisterID typeReg, RegisterID dataReg) {
         107            6717 :         Address address(objReg, JSObject::getFixedSlotOffset(slot));
         108            6717 :         if (objReg == typeReg) {
         109             847 :             loadPayload(address, dataReg);
         110             847 :             loadTypeTag(address, typeReg);
         111                 :         } else {
         112            5870 :             loadTypeTag(address, typeReg);
         113            5870 :             loadPayload(address, dataReg);
         114                 :         }
         115            6717 :     }
         116                 :
         117                 :     template <typename T>
         118         2588238 :     void loadTypeTag(T address, RegisterID reg) {
         119         2588238 :         load32(tagOf(address), reg);
         120         2588238 :     }
         121                 :
         122                 :     template <typename T>
         123         2233173 :     void storeTypeTag(ImmTag imm, T address) {
         124         2233173 :         store32(imm, tagOf(address));
         125         2233173 :     }
         126                 :
         127                 :     template <typename T>
         128         2272850 :     void storeTypeTag(RegisterID reg, T address) {
         129         2272850 :         store32(reg, tagOf(address));
         130         2272850 :     }
         131                 :
         132                 :     template <typename T>
         133         4394504 :     void loadPayload(T address, RegisterID reg) {
         134         4394504 :         load32(payloadOf(address), reg);
         135         4394504 :     }
         136                 :
         137                 :     template <typename T>
         138         4156633 :     void storePayload(RegisterID reg, T address) {
         139         4156633 :         store32(reg, payloadOf(address));
         140         4156633 :     }
         141                 :
         142                 :     template <typename T>
         143         1228493 :     void storePayload(ImmPayload imm, T address) {
         144         1228493 :         store32(imm, payloadOf(address));
         145         1228493 :     }
         146                 :
         147             101 :     bool addressUsesRegister(BaseIndex address, RegisterID reg) {
         148             101 :         return (address.base == reg) || (address.index == reg);
         149                 :     }
         150                 :
         151         1277688 :     bool addressUsesRegister(Address address, RegisterID reg) {
         152         1277688 :         return address.base == reg;
         153                 :     }
         154                 :
         155                 :     /* Loads type first, then payload, returning label after type load. */
         156                 :     template <typename T>
         157         1277789 :     Label loadValueAsComponents(T address, RegisterID type, RegisterID payload) {
         158         1277789 :         JS_ASSERT(!addressUsesRegister(address, type));
         159         1277789 :         loadTypeTag(address, type);
         160         1277789 :         Label l = label();
         161         1277789 :         loadPayload(address, payload);
         162                 :         return l;
         163                 :     }
         164                 :
         165          136194 :     void loadValueAsComponents(const Value &val, RegisterID type, RegisterID payload) {
         166          136194 :         jsval_layout jv = JSVAL_TO_IMPL(val);
         167          136194 :         move(ImmTag(jv.s.tag), type);
         168          136194 :         move(Imm32(jv.s.payload.u32), payload);
         169          136194 :     }
         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          458747 :     Label loadValueWithAddressOffsetPatch(Address address, RegisterID treg, RegisterID dreg) {
         186          458747 :         JS_ASSERT(address.base != treg); /* treg is clobbered first. */
         187                 :
         188          458747 :         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          458747 :         loadTypeTag(address, treg);
         195          458747 :         DBGLABEL_NOMASM(endType);
         196          458747 :         loadPayload(address, dreg);
         197          458747 :         DBGLABEL_NOMASM(endPayload);
         198          458747 :         JS_ASSERT(differenceBetween(start, endType) == 6);
         199          458747 :         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           14511 :     DataLabel32 storeValueWithAddressOffsetPatch(RegisterID treg, RegisterID dreg, Address address) {
         226           14511 :         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           14511 :         storeTypeTag(treg, address);
         233           14511 :         DBGLABEL_NOMASM(endType);
         234           14511 :         storePayload(dreg, address);
         235           14511 :         DBGLABEL_NOMASM(endPayload);
         236           14511 :         JS_ASSERT(differenceBetween(start, endType) == 6);
         237           14511 :         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           30724 :     DataLabel32 storeValueWithAddressOffsetPatch(ImmType type, RegisterID dreg, Address address) {
         252           30724 :         DataLabel32 start = dataLabel32();
         253                 : #if defined JS_CPU_X86
         254           30724 :         storeTypeTag(type, address);
         255           30724 :         DBGLABEL_NOMASM(endType);
         256           30724 :         storePayload(dreg, address);
         257           30724 :         DBGLABEL_NOMASM(endPayload);
         258           30724 :         JS_ASSERT(differenceBetween(start, endType) == 10);
         259           30724 :         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           10115 :     DataLabel32 storeValueWithAddressOffsetPatch(const Value &v, Address address) {
         274           10115 :         jsval_layout jv = JSVAL_TO_IMPL(v);
         275           10115 :         ImmTag type(jv.s.tag);
         276           10115 :         Imm32 payload(jv.s.payload.u32);
         277           10115 :         DataLabel32 start = dataLabel32();
         278                 : #if defined JS_CPU_X86
         279           10115 :         store32(type, tagOf(address));
         280           10115 :         DBGLABEL_NOMASM(endType);
         281           10115 :         store32(payload, payloadOf(address));
         282           10115 :         DBGLABEL_NOMASM(endPayload);
         283           10115 :         JS_ASSERT(differenceBetween(start, endType) == 10);
         284           10115 :         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           15850 :     DataLabel32 storeValueWithAddressOffsetPatch(const ValueRemat &vr, Address address) {
         299           15850 :         JS_ASSERT(!vr.isFPRegister());
         300           15850 :         if (vr.isConstant()) {
         301            3834 :             return storeValueWithAddressOffsetPatch(vr.value(), address);
         302           12016 :         } else if (vr.isTypeKnown()) {
         303            6895 :             ImmType type(vr.knownType());
         304            6895 :             RegisterID data(vr.dataReg());
         305            6895 :             return storeValueWithAddressOffsetPatch(type, data, address);
         306                 :         } else {
         307            5121 :             RegisterID type(vr.typeReg());
         308            5121 :             RegisterID data(vr.dataReg());
         309            5121 :             return storeValueWithAddressOffsetPatch(type, data, address);
         310                 :         }
         311                 :     }
         312                 :
         313                 :     /*
         314                 :      * Stores type first, then payload.
         315                 :      */
         316                 :     template <typename T>
         317          274456 :     Label storeValue(const Value &v, T address) {
         318          274456 :         jsval_layout jv = JSVAL_TO_IMPL(v);
         319          274456 :         store32(ImmTag(jv.s.tag), tagOf(address));
         320          274456 :         Label l = label();
         321          274456 :         store32(Imm32(jv.s.payload.u32), payloadOf(address));
         322                 :         return l;
         323                 :     }
         324                 :
         325                 :     template <typename T>
         326          207399 :     void storeValueFromComponents(RegisterID type, RegisterID payload, T address) {
         327          207399 :         storeTypeTag(type, address);
         328          207399 :         storePayload(payload, address);
         329          207399 :     }
         330                 :
         331                 :     template <typename T>
         332            6022 :     void storeValueFromComponents(ImmType type, RegisterID payload, T address) {
         333            6022 :         storeTypeTag(type, address);
         334            6022 :         storePayload(payload, address);
         335            6022 :     }
         336                 :
         337                 :     template <typename T>
         338           18598 :     Label storeValue(const ValueRemat &vr, T address) {
         339           18598 :         if (vr.isConstant()) {
         340            3293 :             return storeValue(vr.value(), address);
         341           15305 :         } else if (vr.isFPRegister()) {
         342            1308 :             Label l = label();
         343            1308 :             storeDouble(vr.fpReg(), address);
         344            1308 :             return l;
         345                 :         } else {
         346           13997 :             if (vr.isTypeKnown())
         347            6498 :                 storeTypeTag(ImmType(vr.knownType()), address);
         348                 :             else
         349            7499 :                 storeTypeTag(vr.typeReg(), address);
         350           13997 :             Label l = label();
         351           13997 :             storePayload(vr.dataReg(), address);
         352           13997 :             return l;
         353                 :         }
         354                 :     }
         355                 :
         356                 :     template <typename T>
         357            5725 :     Jump guardNotHole(T address) {
         358            5725 :         return branch32(Equal, tagOf(address), ImmType(JSVAL_TYPE_MAGIC));
         359                 :     }
         360                 :
         361                 :     void loadPrivate(Address privAddr, RegisterID to) {
         362                 :         loadPtr(payloadOf(privAddr), to);
         363                 :     }
         364                 :
         365           23413 :     void loadObjPrivate(RegisterID base, RegisterID to, uint32_t nfixed) {
         366           23413 :         Address priv(base, JSObject::getPrivateDataOffset(nfixed));
         367           23413 :         loadPtr(priv, to);
         368           23413 :     }
         369                 :
         370            6189 :     Jump testNull(Condition cond, RegisterID reg) {
         371            6189 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_NULL));
         372                 :     }
         373                 :
         374            4203 :     Jump testNull(Condition cond, Address address) {
         375            4203 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_NULL));
         376                 :     }
         377                 :
         378           14082 :     Jump testUndefined(Condition cond, RegisterID reg) {
         379           14082 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_UNDEFINED));
         380                 :     }
         381                 :
         382            4187 :     Jump testUndefined(Condition cond, Address address) {
         383            4187 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_UNDEFINED));
         384                 :     }
         385                 :
         386         1053960 :     Jump testInt32(Condition cond, RegisterID reg) {
         387         1053960 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_INT32));
         388                 :     }
         389                 :
         390           40994 :     Jump testInt32(Condition cond, Address address) {
         391           40994 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_INT32));
         392                 :     }
         393                 :
         394           12901 :     Jump testNumber(Condition cond, RegisterID reg) {
         395           12901 :         cond = (cond == Equal) ? BelowOrEqual : Above;
         396           12901 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_INT32));
         397                 :     }
         398                 :
         399           10293 :     Jump testNumber(Condition cond, Address address) {
         400           10293 :         cond = (cond == Equal) ? BelowOrEqual : Above;
         401           10293 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_INT32));
         402                 :     }
         403                 :
         404            3645 :     Jump testPrimitive(Condition cond, RegisterID reg) {
         405            3645 :         cond = (cond == NotEqual) ? AboveOrEqual : Below;
         406            3645 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_OBJECT));
         407                 :     }
         408                 :
         409             261 :     Jump testPrimitive(Condition cond, Address address) {
         410             261 :         cond = (cond == NotEqual) ? AboveOrEqual : Below;
         411             261 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_OBJECT));
         412                 :     }
         413                 :
         414          203412 :     Jump testObject(Condition cond, RegisterID reg) {
         415          203412 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_OBJECT));
         416                 :     }
         417                 :
         418           54696 :     Jump testObject(Condition cond, Address address) {
         419           54696 :         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          999718 :     Jump testDouble(Condition cond, RegisterID reg) {
         431                 :         Condition opcond;
         432          999718 :         if (cond == Equal)
         433          316303 :             opcond = Below;
         434                 :         else
         435          683415 :             opcond = AboveOrEqual;
         436          999718 :         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            8347 :     Jump testBoolean(Condition cond, RegisterID reg) {
         449            8347 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_BOOLEAN));
         450                 :     }
         451                 :
         452           26360 :     Jump testBoolean(Condition cond, Address address) {
         453           26360 :         return branch32(cond, tagOf(address), ImmTag(JSVAL_TAG_BOOLEAN));
         454                 :     }
         455                 :
         456           18952 :     Jump testString(Condition cond, RegisterID reg) {
         457           18952 :         return branch32(cond, reg, ImmTag(JSVAL_TAG_STRING));
         458                 :     }
         459                 :
         460            8409 :     Jump testString(Condition cond, Address address) {
         461            8409 :         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            1115 :     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            1115 :         m_assembler.movd_rr(srcDest, dataReg);
         490            1115 :         m_assembler.psrldq_rr(srcDest, 4);
         491            1115 :         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            1115 :     }
         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           45013 :     Jump fastArrayLoadSlot(T address, bool holeCheck,
         515                 :                            MaybeRegisterID typeReg, RegisterID dataReg)
         516                 :     {
         517           45013 :         Jump notHole;
         518           45013 :         if (typeReg.isSet()) {
         519           40223 :             loadTypeTag(address, typeReg.reg());
         520           40223 :             if (holeCheck)
         521           21617 :                 notHole = branch32(Equal, typeReg.reg(), ImmType(JSVAL_TYPE_MAGIC));
         522            4790 :         } else if (holeCheck) {
         523             809 :             notHole = branch32(Equal, tagOf(address), ImmType(JSVAL_TYPE_MAGIC));
         524                 :         }
         525           45013 :         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