10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/*
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2009 University of Szeged
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * All rights reserved.
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Redistribution and use in source and binary forms, with or without
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * modification, are permitted provided that the following conditions
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * are met:
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 1. Redistributions of source code must retain the above copyright
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer.
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    documentation and/or other materials provided with the distribution.
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "config.h"
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
29d0825bca7fe65beaee391d30da42e937db621564Steve Block#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "ARMAssembler.h"
320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace JSC {
340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// Patching helpers
360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid ARMAssembler::patchConstantPoolLoad(void* loadAddr, void* constPoolAddr)
380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ARMWord *ldr = reinterpret_cast<ARMWord*>(loadAddr);
400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ARMWord diff = reinterpret_cast<ARMWord*>(constPoolAddr) - ldr;
410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ARMWord index = (*ldr & 0xfff) >> 1;
420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(diff >= 1);
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (diff >= 2 || index > 0) {
450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        diff = (diff + index - 2) * sizeof(ARMWord);
460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(diff <= 0xfff);
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        *ldr = (*ldr & ~0xfff) | diff;
480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        *ldr = (*ldr & ~(0xfff | ARMAssembler::DT_UP)) | sizeof(ARMWord);
500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// Handle immediates
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochARMWord ARMAssembler::getOp2(ARMWord imm)
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int rol;
570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (imm <= 0xff)
590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return OP2_IMM | imm;
600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if ((imm & 0xff000000) == 0) {
620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm <<= 8;
630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        rol = 8;
640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else {
660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm = (imm << 24) | (imm >> 8);
670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        rol = 0;
680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if ((imm & 0xff000000) == 0) {
710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm <<= 8;
720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        rol += 4;
730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if ((imm & 0xf0000000) == 0) {
760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm <<= 4;
770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        rol += 2;
780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if ((imm & 0xc0000000) == 0) {
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm <<= 2;
820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        rol += 1;
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if ((imm & 0x00ffffff) == 0)
860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return OP2_IMM | (imm >> 24) | (rol << 8);
870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return INVALID_IMM;
890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochint ARMAssembler::genInt(int reg, ARMWord imm, bool positive)
920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Step1: Search a non-immediate part
940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ARMWord mask;
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ARMWord imm1;
960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ARMWord imm2;
970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int rol;
980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    mask = 0xff000000;
1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    rol = 8;
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    while(1) {
1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & mask) == 0) {
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm = (imm << rol) | (imm >> (32 - rol));
1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            rol = 4 + (rol >> 1);
1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            break;
1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        rol += 2;
1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        mask >>= 2;
1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (mask & 0x3) {
1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // rol 8
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm = (imm << 8) | (imm >> 24);
1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            mask = 0xff00;
1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            rol = 24;
1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            while (1) {
1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if ((imm & mask) == 0) {
1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    imm = (imm << rol) | (imm >> (32 - rol));
1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    rol = (rol >> 1) - 8;
1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    break;
1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                }
1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                rol += 2;
1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                mask >>= 2;
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (mask & 0x3)
1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    return 0;
1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            break;
1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT((imm & 0xff) == 0);
1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if ((imm & 0xff000000) == 0) {
1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm1 = OP2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);
1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm2 = OP2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);
1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else if (imm & 0xc0000000) {
1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm1 = OP2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm <<= 8;
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        rol += 4;
1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & 0xff000000) == 0) {
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm <<= 8;
1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            rol += 4;
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & 0xf0000000) == 0) {
1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm <<= 4;
1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            rol += 2;
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & 0xc0000000) == 0) {
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm <<= 2;
1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            rol += 1;
1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & 0x00ffffff) == 0)
1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm2 = OP2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else
1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return 0;
1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else {
1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & 0xf0000000) == 0) {
1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm <<= 4;
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            rol += 2;
1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & 0xc0000000) == 0) {
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm <<= 2;
1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            rol += 1;
1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm1 = OP2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        imm <<= 8;
1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        rol += 4;
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & 0xf0000000) == 0) {
1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm <<= 4;
1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            rol += 2;
1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & 0xc0000000) == 0) {
1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm <<= 2;
1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            rol += 1;
1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if ((imm & 0x00ffffff) == 0)
1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            imm2 = OP2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else
1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return 0;
1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (positive) {
1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        mov_r(reg, imm1);
1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        orr_r(reg, reg, imm2);
1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else {
1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        mvn_r(reg, imm1);
1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        bic_r(reg, reg, imm2);
1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return 1;
1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochARMWord ARMAssembler::getImm(ARMWord imm, int tmpReg, bool invert)
2010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ARMWord tmp;
2030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Do it by 1 instruction
2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    tmp = getOp2(imm);
206643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (tmp != INVALID_IMM)
2070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return tmp;
2080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    tmp = getOp2(~imm);
210643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (tmp != INVALID_IMM) {
2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (invert)
2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return tmp | OP2_INV_IMM;
2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        mvn_r(tmpReg, tmp);
2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return tmpReg;
2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
217643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return encodeComplexImm(imm, tmpReg);
2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid ARMAssembler::moveImm(ARMWord imm, int dest)
2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ARMWord tmp;
2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Do it by 1 instruction
2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    tmp = getOp2(imm);
226643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (tmp != INVALID_IMM) {
2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        mov_r(dest, tmp);
2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    tmp = getOp2(~imm);
232643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (tmp != INVALID_IMM) {
2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        mvn_r(dest, tmp);
2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
2350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
237643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    encodeComplexImm(imm, dest);
238643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
239643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
240643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockARMWord ARMAssembler::encodeComplexImm(ARMWord imm, int dest)
241643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
242d0825bca7fe65beaee391d30da42e937db621564Steve Block#if WTF_ARM_ARCH_AT_LEAST(7)
243d0825bca7fe65beaee391d30da42e937db621564Steve Block    ARMWord tmp = getImm16Op2(imm);
244643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (tmp != INVALID_IMM) {
245643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        movw_r(dest, tmp);
246643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return dest;
247643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
248643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    movw_r(dest, getImm16Op2(imm & 0xffff));
249643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    movt_r(dest, getImm16Op2(imm >> 16));
250643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return dest;
251643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#else
2520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Do it by 2 instruction
2530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (genInt(dest, imm, true))
254643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return dest;
2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (genInt(dest, ~imm, false))
256643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return dest;
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ldr_imm(dest, imm);
259643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return dest;
260643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif
2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// Memory load/store helpers
2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset, bool bytes)
2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
267dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ARMWord transferFlag = bytes ? DT_BYTE : 0;
2680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (offset >= 0) {
2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (offset <= 0xfff)
270dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            dtr_u(isLoad, srcDst, base, offset | transferFlag);
2710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else if (offset <= 0xfffff) {
272231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
273dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            dtr_u(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff) | transferFlag);
2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        } else {
275967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            moveImm(offset, ARMRegisters::S0);
276967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            dtr_ur(isLoad, srcDst, base, ARMRegisters::S0 | transferFlag);
2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else {
2790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        offset = -offset;
2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (offset <= 0xfff)
281dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            dtr_d(isLoad, srcDst, base, offset | transferFlag);
2820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else if (offset <= 0xfffff) {
283231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
284dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            dtr_d(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff) | transferFlag);
2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        } else {
286967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            moveImm(offset, ARMRegisters::S0);
287967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            dtr_dr(isLoad, srcDst, base, ARMRegisters::S0 | transferFlag);
2880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid ARMAssembler::baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset)
2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ARMWord op2;
2950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(scale >= 0 && scale <= 3);
2970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    op2 = lsl(index, scale);
2980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (offset >= 0 && offset <= 0xfff) {
300231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        add_r(ARMRegisters::S0, base, op2);
301231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        dtr_u(isLoad, srcDst, ARMRegisters::S0, offset);
3020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
3030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (offset <= 0 && offset >= -0xfff) {
305231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        add_r(ARMRegisters::S0, base, op2);
306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        dtr_d(isLoad, srcDst, ARMRegisters::S0, -offset);
3070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
3080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
310231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ldr_un_imm(ARMRegisters::S0, offset);
311231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    add_r(ARMRegisters::S0, ARMRegisters::S0, op2);
312231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    dtr_ur(isLoad, srcDst, base, ARMRegisters::S0);
3130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
3140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid ARMAssembler::doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset)
3160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
3170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (offset & 0x3) {
3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (offset <= 0x3ff && offset >= 0) {
3190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            fdtr_u(isLoad, srcDst, base, offset >> 2);
3200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return;
3210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (offset <= 0x3ffff && offset >= 0) {
323231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 10) | (11 << 8));
324231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            fdtr_u(isLoad, srcDst, ARMRegisters::S0, (offset >> 2) & 0xff);
3250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return;
3260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        offset = -offset;
3280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (offset <= 0x3ff && offset >= 0) {
3300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            fdtr_d(isLoad, srcDst, base, offset >> 2);
3310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return;
3320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (offset <= 0x3ffff && offset >= 0) {
334231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 10) | (11 << 8));
335231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            fdtr_d(isLoad, srcDst, ARMRegisters::S0, (offset >> 2) & 0xff);
3360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return;
3370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        offset = -offset;
3390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
341231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ldr_un_imm(ARMRegisters::S0, offset);
342231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    add_r(ARMRegisters::S0, ARMRegisters::S0, base);
343231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    fdtr_u(isLoad, srcDst, ARMRegisters::S0, 0);
3440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
3450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid* ARMAssembler::executableCopy(ExecutablePool* allocator)
3470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
348231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // 64-bit alignment is required for next constant pool and JIT code as well
349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_buffer.flushWithoutBarrier(true);
350231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_buffer.uncheckedSize() & 0x7)
351231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        bkpt(0);
352231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    char* data = reinterpret_cast<char*>(m_buffer.executableCopy(allocator));
3540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    for (Jumps::Iterator iter = m_jumps.begin(); iter != m_jumps.end(); ++iter) {
356231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // The last bit is set if the constant must be placed on constant pool.
357231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        int pos = (*iter) & (~0x1);
358f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        ARMWord* ldrAddr = reinterpret_cast_ptr<ARMWord*>(data + pos);
359d0825bca7fe65beaee391d30da42e937db621564Steve Block        ARMWord* addr = getLdrImmAddress(ldrAddr);
36021939df44de1705786c545cd1bf519d47250322dBen Murdoch        if (*addr != InvalidBranchTarget) {
361d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!(*iter & 1)) {
362f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                int diff = reinterpret_cast_ptr<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetching);
363d0825bca7fe65beaee391d30da42e937db621564Steve Block
364d0825bca7fe65beaee391d30da42e937db621564Steve Block                if ((diff <= BOFFSET_MAX && diff >= BOFFSET_MIN)) {
365d0825bca7fe65beaee391d30da42e937db621564Steve Block                    *ldrAddr = B | getConditionalField(*ldrAddr) | (diff & BRANCH_MASK);
366d0825bca7fe65beaee391d30da42e937db621564Steve Block                    continue;
367d0825bca7fe65beaee391d30da42e937db621564Steve Block                }
368d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
369d0825bca7fe65beaee391d30da42e937db621564Steve Block            *addr = reinterpret_cast<ARMWord>(data + *addr);
370231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
3710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return data;
3740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
3750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} // namespace JSC
3770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
378d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
379