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