15f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian/* 2a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. 3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2010 University of Szeged 45f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 55f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * Redistribution and use in source and binary forms, with or without 65f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * modification, are permitted provided that the following conditions 75f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * are met: 85f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 1. Redistributions of source code must retain the above copyright 95f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * notice, this list of conditions and the following disclaimer. 105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 2. Redistributions in binary form must reproduce the above copyright 115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * notice, this list of conditions and the following disclaimer in the 125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * documentation and/or other materials provided with the distribution. 135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#ifndef ARMAssembler_h 285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#define ARMAssembler_h 295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 30d0825bca7fe65beaee391d30da42e937db621564Steve Block#if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2) 315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "AssemblerBuffer.h" 335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <wtf/Assertions.h> 345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <wtf/Vector.h> 355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <stdint.h> 365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qiannamespace JSC { 385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocknamespace ARMRegisters { 405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef enum { 415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r0, 425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r1, 435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r2, 445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r3, 455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r4, 465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r5, 475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r6, 485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r7, wr = r7, // thumb work register 495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r8, 505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r9, sb = r9, // static base 515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r10, sl = r10, // stack limit 525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r11, fp = r11, // frame pointer 535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r12, ip = r12, 545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r13, sp = r13, 555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r14, lr = r14, 565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian r15, pc = r15, 575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } RegisterID; 585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef enum { 60ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s0, 61ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s1, 62ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s2, 63ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s3, 64ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s4, 65ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s5, 66ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s6, 67ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s7, 68ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s8, 69ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s9, 70ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s10, 71ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s11, 72ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s12, 73ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s13, 74ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s14, 75ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s15, 76ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s16, 77ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s17, 78ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s18, 79ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s19, 80ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s20, 81ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s21, 82ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s22, 83ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s23, 84ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s24, 85ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s25, 86ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s26, 87ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s27, 88ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s28, 89ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s29, 90ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s30, 91ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block s31, 92ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } FPSingleRegisterID; 93ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 94ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block typedef enum { 95ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d0, 96ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d1, 97ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d2, 98ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d3, 99ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d4, 100ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d5, 101ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d6, 102ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d7, 103ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d8, 104ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d9, 105ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d10, 106ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d11, 107ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d12, 108ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d13, 109ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d14, 110ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d15, 111ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d16, 112ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d17, 113ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d18, 114ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d19, 115ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d20, 116ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d21, 117ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d22, 118ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d23, 119ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d24, 120ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d25, 121ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d26, 122ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d27, 123ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d28, 124ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d29, 125ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d30, 126ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block d31, 127ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } FPDoubleRegisterID; 128ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 129ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block typedef enum { 130ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q0, 131ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q1, 132ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q2, 133ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q3, 134ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q4, 135ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q5, 136ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q6, 137ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q7, 138ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q8, 139ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q9, 140ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q10, 141ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q11, 142ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q12, 143ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q13, 144ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q14, 145ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q15, 146ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q16, 147ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q17, 148ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q18, 149ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q19, 150ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q20, 151ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q21, 152ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q22, 153ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q23, 154ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q24, 155ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q25, 156ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q26, 157ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q27, 158ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q28, 159ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q29, 160ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q30, 161ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block q31, 162ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } FPQuadRegisterID; 163ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 164ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block inline FPSingleRegisterID asSingle(FPDoubleRegisterID reg) 165ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 166ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(reg < d16); 167ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block return (FPSingleRegisterID)(reg << 1); 168ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 169ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 170ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block inline FPDoubleRegisterID asDouble(FPSingleRegisterID reg) 171ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 172ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!(reg & 1)); 173ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block return (FPDoubleRegisterID)(reg >> 1); 174ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 1765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianclass ARMv7Assembler; 1785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianclass ARMThumbImmediate { 1795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian friend class ARMv7Assembler; 1805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef uint8_t ThumbImmediateType; 1825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static const ThumbImmediateType TypeInvalid = 0; 1835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static const ThumbImmediateType TypeEncoded = 1; 1845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static const ThumbImmediateType TypeUInt16 = 2; 1855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef union { 1875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int16_t asInt; 1885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian struct { 1895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned imm8 : 8; 1905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned imm3 : 3; 1915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned i : 1; 1925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned imm4 : 4; 1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 1945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If this is an encoded immediate, then it may describe a shift, or a pattern. 1955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian struct { 1965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned shiftValue7 : 7; 1975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned shiftAmount : 5; 1985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 1995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian struct { 2005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned immediate : 8; 2015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned pattern : 4; 2025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 2035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } ThumbImmediateValue; 2045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // byte0 contains least significant bit; not using an array to make client code endian agnostic. 2065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef union { 2075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t asInt; 2085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian struct { 2095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t byte0; 2105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t byte1; 2115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t byte2; 2125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t byte3; 2135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 2145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } PatternBytes; 2155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 216231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ALWAYS_INLINE static void countLeadingZerosPartial(uint32_t& value, int32_t& zeros, const int N) 2175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 218d0825bca7fe65beaee391d30da42e937db621564Steve Block if (value & ~((1 << N) - 1)) /* check for any of the top N bits (of 2N bits) are set */ 219d0825bca7fe65beaee391d30da42e937db621564Steve Block value >>= N; /* if any were set, lose the bottom N */ 220d0825bca7fe65beaee391d30da42e937db621564Steve Block else /* if none of the top N bits are set, */ 221d0825bca7fe65beaee391d30da42e937db621564Steve Block zeros += N; /* then we have identified N leading zeros */ 2225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static int32_t countLeadingZeros(uint32_t value) 2255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 2265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!value) 2275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return 32; 2285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t zeros = 0; 2305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian countLeadingZerosPartial(value, zeros, 16); 2315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian countLeadingZerosPartial(value, zeros, 8); 2325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian countLeadingZerosPartial(value, zeros, 4); 2335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian countLeadingZerosPartial(value, zeros, 2); 2345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian countLeadingZerosPartial(value, zeros, 1); 2355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return zeros; 2365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ARMThumbImmediate() 2395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian : m_type(TypeInvalid) 2405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 2415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_value.asInt = 0; 2425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ARMThumbImmediate(ThumbImmediateType type, ThumbImmediateValue value) 2455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian : m_type(type) 2465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_value(value) 2475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 2485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ARMThumbImmediate(ThumbImmediateType type, uint16_t value) 2515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian : m_type(TypeUInt16) 2525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 253643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Make sure this constructor is only reached with type TypeUInt16; 254643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // this extra parameter makes the code a little clearer by making it 255643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // explicit at call sites which type is being constructed 256643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ASSERT_UNUSED(type, type == TypeUInt16); 257643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 2585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_value.asInt = value; 2595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianpublic: 2625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static ARMThumbImmediate makeEncodedImm(uint32_t value) 2635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 2645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ThumbImmediateValue encoding; 2655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.asInt = 0; 2665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // okay, these are easy. 2685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (value < 256) { 2695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.immediate = value; 2705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.pattern = 0; 2715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return ARMThumbImmediate(TypeEncoded, encoding); 2725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t leadingZeros = countLeadingZeros(value); 2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if there were 24 or more leading zeros, then we'd have hit the (value < 256) case. 2765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(leadingZeros < 24); 2775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Given a number with bit fields Z:B:C, where count(Z)+count(B)+count(C) == 32, 2795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Z are the bits known zero, B is the 8-bit immediate, C are the bits to check for 2805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // zero. count(B) == 8, so the count of bits to be checked is 24 - count(Z). 2815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t rightShiftAmount = 24 - leadingZeros; 2825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (value == ((value >> rightShiftAmount) << rightShiftAmount)) { 2835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Shift the value down to the low byte position. The assign to 2845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // shiftValue7 drops the implicit top bit. 2855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.shiftValue7 = value >> rightShiftAmount; 2865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // The endoded shift amount is the magnitude of a right rotate. 2875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.shiftAmount = 8 + leadingZeros; 2885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return ARMThumbImmediate(TypeEncoded, encoding); 2895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian PatternBytes bytes; 2925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bytes.asInt = value; 2935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((bytes.byte0 == bytes.byte1) && (bytes.byte0 == bytes.byte2) && (bytes.byte0 == bytes.byte3)) { 2955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.immediate = bytes.byte0; 2965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.pattern = 3; 2975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return ARMThumbImmediate(TypeEncoded, encoding); 2985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 2995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((bytes.byte0 == bytes.byte2) && !(bytes.byte1 | bytes.byte3)) { 3015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.immediate = bytes.byte0; 3025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.pattern = 1; 3035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return ARMThumbImmediate(TypeEncoded, encoding); 3045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((bytes.byte1 == bytes.byte3) && !(bytes.byte0 | bytes.byte2)) { 307f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch encoding.immediate = bytes.byte1; 3085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian encoding.pattern = 2; 3095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return ARMThumbImmediate(TypeEncoded, encoding); 3105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return ARMThumbImmediate(); 3135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static ARMThumbImmediate makeUInt12(int32_t value) 3165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 3175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return (!(value & 0xfffff000)) 3185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ? ARMThumbImmediate(TypeUInt16, (uint16_t)value) 3195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian : ARMThumbImmediate(); 3205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static ARMThumbImmediate makeUInt12OrEncodedImm(int32_t value) 3235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 3245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If this is not a 12-bit unsigned it, try making an encoded immediate. 3255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return (!(value & 0xfffff000)) 3265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ? ARMThumbImmediate(TypeUInt16, (uint16_t)value) 3275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian : makeEncodedImm(value); 3285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // The 'make' methods, above, return a !isValid() value if the argument 3315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // cannot be represented as the requested type. This methods is called 3325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 'get' since the argument can always be represented. 3335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static ARMThumbImmediate makeUInt16(uint16_t value) 3345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 3355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return ARMThumbImmediate(TypeUInt16, value); 3365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isValid() 3395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 3405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return m_type != TypeInvalid; 3415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // These methods rely on the format of encoded byte values. 3445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt3() { return !(m_value.asInt & 0xfff8); } 3455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt4() { return !(m_value.asInt & 0xfff0); } 3465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt5() { return !(m_value.asInt & 0xffe0); } 3475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt6() { return !(m_value.asInt & 0xffc0); } 3485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt7() { return !(m_value.asInt & 0xff80); } 3495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt8() { return !(m_value.asInt & 0xff00); } 3505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt9() { return (m_type == TypeUInt16) && !(m_value.asInt & 0xfe00); } 3515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt10() { return (m_type == TypeUInt16) && !(m_value.asInt & 0xfc00); } 3525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt12() { return (m_type == TypeUInt16) && !(m_value.asInt & 0xf000); } 3535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUInt16() { return m_type == TypeUInt16; } 3545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t getUInt3() { ASSERT(isUInt3()); return m_value.asInt; } 3555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t getUInt4() { ASSERT(isUInt4()); return m_value.asInt; } 3565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t getUInt5() { ASSERT(isUInt5()); return m_value.asInt; } 3575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t getUInt6() { ASSERT(isUInt6()); return m_value.asInt; } 3585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t getUInt7() { ASSERT(isUInt7()); return m_value.asInt; } 3595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t getUInt8() { ASSERT(isUInt8()); return m_value.asInt; } 3605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t getUInt9() { ASSERT(isUInt9()); return m_value.asInt; } 3615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t getUInt10() { ASSERT(isUInt10()); return m_value.asInt; } 3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint16_t getUInt12() { ASSERT(isUInt12()); return m_value.asInt; } 3635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint16_t getUInt16() { ASSERT(isUInt16()); return m_value.asInt; } 3645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isEncodedImm() { return m_type == TypeEncoded; } 3665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianprivate: 3685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ThumbImmediateType m_type; 3695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ThumbImmediateValue m_value; 3705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}; 3715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qiantypedef enum { 3735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian SRType_LSL, 3745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian SRType_LSR, 3755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian SRType_ASR, 3765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian SRType_ROR, 3775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian SRType_RRX = SRType_ROR 3795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} ARMShiftType; 3805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianclass ShiftTypeAndAmount { 3825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian friend class ARMv7Assembler; 3835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianpublic: 3855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ShiftTypeAndAmount() 3865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 3875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_u.type = (ARMShiftType)0; 3885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_u.amount = 0; 3895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ShiftTypeAndAmount(ARMShiftType type, unsigned amount) 3925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 3935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_u.type = type; 3945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_u.amount = amount & 31; 3955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned lo4() { return m_u.lo4; } 3985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned hi4() { return m_u.hi4; } 3995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianprivate: 4015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian union { 4025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian struct { 4035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned lo4 : 4; 4045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned hi4 : 4; 4055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 4065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian struct { 4075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned type : 2; 408a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch unsigned amount : 6; 4095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 4105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } m_u; 4115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}; 4125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianclass ARMv7Assembler { 4145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianpublic: 415cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ~ARMv7Assembler() 416cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block { 417cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ASSERT(m_jumpsToLink.isEmpty()); 418cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 419cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 420231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block typedef ARMRegisters::RegisterID RegisterID; 421ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block typedef ARMRegisters::FPSingleRegisterID FPSingleRegisterID; 422ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block typedef ARMRegisters::FPDoubleRegisterID FPDoubleRegisterID; 423ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block typedef ARMRegisters::FPQuadRegisterID FPQuadRegisterID; 4245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // (HS, LO, HI, LS) -> (AE, B, A, BE) 4265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // (VS, VC) -> (O, NO) 4275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef enum { 4285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionEQ, 4295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionNE, 430f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ConditionHS, ConditionCS = ConditionHS, 431f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ConditionLO, ConditionCC = ConditionLO, 4325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionMI, 4335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionPL, 4345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionVS, 4355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionVC, 4365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionHI, 4375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionLS, 4385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionGE, 4395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionLT, 4405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionGT, 4415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionLE, 4425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ConditionAL, 443f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ConditionInvalid 4445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } Condition; 4455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 446a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch enum JumpType { JumpFixed, JumpNoCondition, JumpCondition, JumpNoConditionFixedSize, JumpConditionFixedSize, JumpTypeCount }; 447a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch enum JumpLinkType { LinkInvalid, LinkJumpT1, LinkJumpT2, LinkJumpT3, 448a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch LinkJumpT4, LinkConditionalJumpT4, LinkBX, LinkConditionalBX, JumpLinkTypeCount }; 449a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch static const int JumpSizes[JumpLinkTypeCount]; 450a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch static const int JumpPaddingSizes[JumpTypeCount]; 451dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch class LinkRecord { 452dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch public: 453dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch LinkRecord(intptr_t from, intptr_t to, JumpType type, Condition condition) 454dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch : m_from(from) 455dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch , m_to(to) 456dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch , m_type(type) 457dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch , m_linkType(LinkInvalid) 458dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch , m_condition(condition) 459dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 460dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 461dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch intptr_t from() const { return m_from; } 462dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch void setFrom(intptr_t from) { m_from = from; } 463dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch intptr_t to() const { return m_to; } 464dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JumpType type() const { return m_type; } 465dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JumpLinkType linkType() const { return m_linkType; } 466dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch void setLinkType(JumpLinkType linkType) { ASSERT(m_linkType == LinkInvalid); m_linkType = linkType; } 467dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch Condition condition() const { return m_condition; } 468dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch private: 469dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch intptr_t m_from : 31; 470dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch intptr_t m_to : 31; 471a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JumpType m_type : 3; 472a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JumpLinkType m_linkType : 4; 473dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch Condition m_condition : 16; 474dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch }; 475dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 4765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian class JmpSrc { 4775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian friend class ARMv7Assembler; 4785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian friend class ARMInstructionFormatter; 479dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch friend class LinkBuffer; 4805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian public: 4815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JmpSrc() 4825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian : m_offset(-1) 4835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 4845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 4855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian private: 487dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JmpSrc(int offset, JumpType type) 4885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian : m_offset(offset) 489f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick , m_condition(ConditionInvalid) 490dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch , m_type(type) 4915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 492a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(m_type == JumpFixed || m_type == JumpNoCondition || m_type == JumpNoConditionFixedSize); 493dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 494dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 495dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JmpSrc(int offset, JumpType type, Condition condition) 496dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch : m_offset(offset) 497dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch , m_condition(condition) 498dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch , m_type(type) 499dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 500a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(m_type == JumpFixed || m_type == JumpCondition || m_type == JumpConditionFixedSize); 5015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 5025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int m_offset; 504dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch Condition m_condition : 16; 505dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JumpType m_type : 16; 506dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 5075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 5085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian class JmpDst { 5105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian friend class ARMv7Assembler; 5115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian friend class ARMInstructionFormatter; 512dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch friend class LinkBuffer; 5135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian public: 5145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JmpDst() 5155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian : m_offset(-1) 5165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_used(false) 5175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 5185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 5195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isUsed() const { return m_used; } 521f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool isSet() const { return (m_offset != -1); } 5225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void used() { m_used = true; } 5235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian private: 5245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JmpDst(int offset) 5255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian : m_offset(offset) 5265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_used(false) 5275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 5285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(m_offset == offset); 5295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 5305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 53181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch signed int m_offset : 31; 5325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int m_used : 1; 5335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 5345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianprivate: 5365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // ARMv7, Appx-A.6.3 5385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool BadReg(RegisterID reg) 5395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 540231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return (reg == ARMRegisters::sp) || (reg == ARMRegisters::pc); 5415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 5425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 543ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block uint32_t singleRegisterMask(FPSingleRegisterID rdNum, int highBitsShift, int lowBitShift) 5445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 5455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint32_t rdMask = (rdNum >> 1) << highBitsShift; 5465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (rdNum & 1) 5475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian rdMask |= 1 << lowBitShift; 5485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return rdMask; 5495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 5505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 551ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block uint32_t doubleRegisterMask(FPDoubleRegisterID rdNum, int highBitShift, int lowBitsShift) 5525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 5535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint32_t rdMask = (rdNum & 0xf) << lowBitsShift; 5545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (rdNum & 16) 5555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian rdMask |= 1 << highBitShift; 5565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return rdMask; 5575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 5585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef enum { 5605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_reg_T1 = 0x1800, 5615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SUB_reg_T1 = 0x1A00, 5625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_imm_T1 = 0x1C00, 5635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SUB_imm_T1 = 0x1E00, 5645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_MOV_imm_T1 = 0x2000, 5655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_CMP_imm_T1 = 0x2800, 5665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_imm_T2 = 0x3000, 5675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SUB_imm_T2 = 0x3800, 5685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_AND_reg_T1 = 0x4000, 5695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_EOR_reg_T1 = 0x4040, 5705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_TST_reg_T1 = 0x4200, 571ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_RSB_imm_T1 = 0x4240, 5725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_CMP_reg_T1 = 0x4280, 5735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ORR_reg_T1 = 0x4300, 5745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_MVN_reg_T1 = 0x43C0, 5755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_reg_T2 = 0x4400, 5765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_MOV_reg_T1 = 0x4600, 5775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_BLX = 0x4700, 5785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_BX = 0x4700, 5795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_STR_reg_T1 = 0x5000, 5805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDR_reg_T1 = 0x5800, 581dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block OP_LDRH_reg_T1 = 0x5A00, 582dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block OP_LDRB_reg_T1 = 0x5C00, 5835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_STR_imm_T1 = 0x6000, 5845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDR_imm_T1 = 0x6800, 585dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block OP_LDRB_imm_T1 = 0x7800, 5865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDRH_imm_T1 = 0x8800, 5875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_STR_imm_T2 = 0x9000, 5885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDR_imm_T2 = 0x9800, 5895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_SP_imm_T1 = 0xA800, 5905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_SP_imm_T2 = 0xB000, 5915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SUB_SP_imm_T1 = 0xB080, 5925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_BKPT = 0xBE00, 5935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_IT = 0xBF00, 594cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block OP_NOP_T1 = 0xBF00, 5955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } OpcodeID; 5965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef enum { 598a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch OP_B_T1 = 0xD000, 599a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch OP_B_T2 = 0xE000, 6005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_AND_reg_T2 = 0xEA00, 6015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_TST_reg_T2 = 0xEA10, 6025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ORR_reg_T2 = 0xEA40, 603ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_ORR_S_reg_T2 = 0xEA50, 6045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ASR_imm_T1 = 0xEA4F, 6055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LSL_imm_T1 = 0xEA4F, 6065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LSR_imm_T1 = 0xEA4F, 6075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ROR_imm_T1 = 0xEA4F, 6085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_MVN_reg_T2 = 0xEA6F, 6095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_EOR_reg_T2 = 0xEA80, 6105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_reg_T3 = 0xEB00, 6115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_S_reg_T3 = 0xEB10, 6125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SUB_reg_T2 = 0xEBA0, 6135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SUB_S_reg_T2 = 0xEBB0, 6145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_CMP_reg_T2 = 0xEBB0, 615ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VSTR = 0xED00, 616ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VLDR = 0xED10, 617ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMOV_StoC = 0xEE00, 618ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMOV_CtoS = 0xEE10, 619ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMUL_T2 = 0xEE20, 620ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VADD_T2 = 0xEE30, 621ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VSUB_T2 = 0xEE30, 622ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VDIV = 0xEE80, 623cad810f21b803229eb11403f9209855525a25d57Steve Block OP_VCMP = 0xEEB0, 624ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VCVT_FPIVFP = 0xEEB0, 625ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMOV_IMM_T2 = 0xEEB0, 626ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMRS = 0xEEB0, 627a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch OP_B_T3a = 0xF000, 6285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_B_T4a = 0xF000, 6295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_AND_imm_T1 = 0xF000, 6305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_TST_imm = 0xF010, 6315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ORR_imm_T1 = 0xF040, 6325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_MOV_imm_T2 = 0xF040, 6335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_MVN_imm = 0xF060, 6345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_EOR_imm_T1 = 0xF080, 6355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_imm_T3 = 0xF100, 6365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_S_imm_T3 = 0xF110, 6375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_CMN_imm = 0xF110, 6385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SUB_imm_T3 = 0xF1A0, 6395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SUB_S_imm_T3 = 0xF1B0, 6405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_CMP_imm_T2 = 0xF1B0, 641ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_RSB_imm_T2 = 0xF1C0, 6425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ADD_imm_T4 = 0xF200, 6435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_MOV_imm_T3 = 0xF240, 6445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SUB_imm_T4 = 0xF2A0, 6455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_MOVT = 0xF2C0, 646cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block OP_NOP_T2a = 0xF3AF, 647dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block OP_LDRB_imm_T3 = 0xF810, 648dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block OP_LDRB_reg_T2 = 0xF810, 6495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDRH_reg_T2 = 0xF830, 6505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDRH_imm_T3 = 0xF830, 6515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_STR_imm_T4 = 0xF840, 6525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_STR_reg_T2 = 0xF840, 6535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDR_imm_T4 = 0xF850, 6545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDR_reg_T2 = 0xF850, 655dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block OP_LDRB_imm_T2 = 0xF890, 6565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDRH_imm_T2 = 0xF8B0, 6575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_STR_imm_T3 = 0xF8C0, 6585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LDR_imm_T3 = 0xF8D0, 6595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LSL_reg_T2 = 0xFA00, 6605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_LSR_reg_T2 = 0xFA20, 6615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ASR_reg_T2 = 0xFA40, 6625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_ROR_reg_T2 = 0xFA60, 6634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang OP_CLZ = 0xFAB0, 6645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OP_SMULL_T1 = 0xFB80, 6655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } OpcodeID1; 6665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 6675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef enum { 668ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VADD_T2b = 0x0A00, 669ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VDIVb = 0x0A00, 670ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VLDRb = 0x0A00, 671ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMOV_IMM_T2b = 0x0A00, 672ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMUL_T2b = 0x0A00, 673ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VSTRb = 0x0A00, 674ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMOV_CtoSb = 0x0A10, 675ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMOV_StoCb = 0x0A10, 676ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VMRSb = 0x0A10, 677cad810f21b803229eb11403f9209855525a25d57Steve Block OP_VCMPb = 0x0A40, 678ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VCVT_FPIVFPb = 0x0A40, 679ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_VSUB_T2b = 0x0A40, 680cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block OP_NOP_T2b = 0x8000, 681a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch OP_B_T3b = 0x8000, 682ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block OP_B_T4b = 0x9000, 6835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } OpcodeID2; 6845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 6855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian struct FourFours { 6865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian FourFours(unsigned f3, unsigned f2, unsigned f1, unsigned f0) 6875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 6885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_u.f0 = f0; 6895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_u.f1 = f1; 6905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_u.f2 = f2; 6915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_u.f3 = f3; 6925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 6935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 6945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian union { 6955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned value; 6965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian struct { 6975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned f0 : 4; 6985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned f1 : 4; 6995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned f2 : 4; 7005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian unsigned f3 : 4; 7015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 7025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } m_u; 7035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian }; 7045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 7055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian class ARMInstructionFormatter; 7065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 7075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // false means else! 7085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool ifThenElseConditionBit(Condition condition, bool isIf) 7095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 7105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return isIf ? (condition & 1) : !(condition & 1); 7115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if, bool inst4if) 7135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 7145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int mask = (ifThenElseConditionBit(condition, inst2if) << 3) 7155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian | (ifThenElseConditionBit(condition, inst3if) << 2) 7165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian | (ifThenElseConditionBit(condition, inst4if) << 1) 7175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian | 1; 718a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT((condition != ConditionAL) || !(mask & (mask - 1))); 7195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return (condition << 4) | mask; 7205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if) 7225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 7235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int mask = (ifThenElseConditionBit(condition, inst2if) << 3) 7245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian | (ifThenElseConditionBit(condition, inst3if) << 2) 7255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian | 2; 726a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT((condition != ConditionAL) || !(mask & (mask - 1))); 7275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return (condition << 4) | mask; 7285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t ifThenElse(Condition condition, bool inst2if) 7305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 7315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int mask = (ifThenElseConditionBit(condition, inst2if) << 3) 7325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian | 4; 733a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT((condition != ConditionAL) || !(mask & (mask - 1))); 7345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return (condition << 4) | mask; 7355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 7375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint8_t ifThenElse(Condition condition) 7385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 7395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int mask = 8; 7405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return (condition << 4) | mask; 7415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 7435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianpublic: 744dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 7455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void add(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) 7465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 7475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Rd can only be SP if Rn is also SP. 748231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); 749231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rd != ARMRegisters::pc); 750231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 7515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isValid()); 7525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 753231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (rn == ARMRegisters::sp) { 7545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!(rd & 8) && imm.isUInt10()) { 7555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Reg3Imm8(OP_ADD_SP_imm_T1, rd, imm.getUInt10() >> 2); 7565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 757231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } else if ((rd == ARMRegisters::sp) && imm.isUInt9()) { 7585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp9Imm7(OP_ADD_SP_imm_T2, imm.getUInt9() >> 2); 7595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 7605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if (!((rd | rn) & 8)) { 7625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (imm.isUInt3()) { 7635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); 7645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 7655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if ((rd == rn) && imm.isUInt8()) { 7665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Reg3Imm8(OP_ADD_imm_T2, rd, imm.getUInt8()); 7675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 7685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 7715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (imm.isEncodedImm()) 7725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADD_imm_T3, rn, rd, imm); 7735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else { 7745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isUInt12()); 7755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADD_imm_T4, rn, rd, imm); 7765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 7795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void add(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 7805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 781231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); 782231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rd != ARMRegisters::pc); 783231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 7845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 7855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_ADD_reg_T3, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 7865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 7875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 7885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // NOTE: In an IT block, add doesn't modify the flags register. 7895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void add(RegisterID rd, RegisterID rn, RegisterID rm) 7905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 7915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (rd == rn) 7925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8RegReg143(OP_ADD_reg_T2, rm, rd); 7935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else if (rd == rm) 7945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8RegReg143(OP_ADD_reg_T2, rn, rd); 7955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else if (!((rd | rn | rm) & 8)) 7965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_reg_T1, rm, rn, rd); 7975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 7985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian add(rd, rn, rm, ShiftTypeAndAmount()); 7995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Not allowed in an IT (if then) block. 8025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void add_S(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) 8035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 8045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Rd can only be SP if Rn is also SP. 805231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); 806231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rd != ARMRegisters::pc); 807231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 8085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isEncodedImm()); 8095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!((rd | rn) & 8)) { 8115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (imm.isUInt3()) { 812ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); 8135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 8145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if ((rd == rn) && imm.isUInt8()) { 815ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.oneWordOp5Reg3Imm8(OP_ADD_imm_T2, rd, imm.getUInt8()); 8165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 8175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADD_S_imm_T3, rn, rd, imm); 8215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Not allowed in an IT (if then) block? 8245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void add_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 8255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 826231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); 827231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rd != ARMRegisters::pc); 828231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 8295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 8305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_ADD_S_reg_T3, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 8315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Not allowed in an IT (if then) block. 8345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void add_S(RegisterID rd, RegisterID rn, RegisterID rm) 8355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 8365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!((rd | rn | rm) & 8)) 837ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_reg_T1, rm, rn, rd); 8385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 8395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian add_S(rd, rn, rm, ShiftTypeAndAmount()); 8405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ARM_and(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) 8435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 8445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 8455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 8465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isEncodedImm()); 8475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_AND_imm_T1, rn, rd, imm); 8485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ARM_and(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 8515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 8525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 8535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 8545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 8555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_AND_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 8565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ARM_and(RegisterID rd, RegisterID rn, RegisterID rm) 8595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 8605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((rd == rn) && !((rd | rm) & 8)) 8615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp10Reg3Reg3(OP_AND_reg_T1, rm, rd); 8625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else if ((rd == rm) && !((rd | rn) & 8)) 8635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp10Reg3Reg3(OP_AND_reg_T1, rn, rd); 8645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 8655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ARM_and(rd, rn, rm, ShiftTypeAndAmount()); 8665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void asr(RegisterID rd, RegisterID rm, int32_t shiftAmount) 8695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 8705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 8715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 8725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ShiftTypeAndAmount shift(SRType_ASR, shiftAmount); 8735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp16FourFours(OP_ASR_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 8745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void asr(RegisterID rd, RegisterID rn, RegisterID rm) 8775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 8785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 8795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 8805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 8815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_ASR_reg_T2, rn, FourFours(0xf, rd, 0, rm)); 8825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 883dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 8845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Only allowed in IT (if then) block if last instruction. 885dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JmpSrc b(JumpType type) 8865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 8875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp16Op16(OP_B_T4a, OP_B_T4b); 888dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return JmpSrc(m_formatter.size(), type); 8895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Only allowed in IT (if then) block if last instruction. 892dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JmpSrc blx(RegisterID rm, JumpType type) 8935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 894231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rm != ARMRegisters::pc); 8955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8RegReg143(OP_BLX, rm, (RegisterID)8); 896dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return JmpSrc(m_formatter.size(), type); 8975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Only allowed in IT (if then) block if last instruction. 900dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JmpSrc bx(RegisterID rm, JumpType type, Condition condition) 901dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 902dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch m_formatter.oneWordOp8RegReg143(OP_BX, rm, (RegisterID)0); 903dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return JmpSrc(m_formatter.size(), type, condition); 904dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 905dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 906dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JmpSrc bx(RegisterID rm, JumpType type) 9075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 9085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8RegReg143(OP_BX, rm, (RegisterID)0); 909dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return JmpSrc(m_formatter.size(), type); 9105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void bkpt(uint8_t imm=0) 9135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 9145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8Imm8(OP_BKPT, imm); 9155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang void clz(RegisterID rd, RegisterID rm) 9184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang { 9194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(!BadReg(rd)); 9204576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(!BadReg(rm)); 9214576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang m_formatter.twoWordOp12Reg4FourFours(OP_CLZ, rm, FourFours(0xf, rd, 8, rm)); 9224576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 9234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 9245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void cmn(RegisterID rn, ARMThumbImmediate imm) 9255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 926231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 9275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isEncodedImm()); 9285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_CMN_imm, rn, (RegisterID)0xf, imm); 9305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void cmp(RegisterID rn, ARMThumbImmediate imm) 9335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 934231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 9355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isEncodedImm()); 9365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!(rn & 8) && imm.isUInt8()) 9385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Reg3Imm8(OP_CMP_imm_T1, rn, imm.getUInt8()); 9395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 9405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_CMP_imm_T2, rn, (RegisterID)0xf, imm); 9415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void cmp(RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 9445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 945231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 9465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 9475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_CMP_reg_T2, rn, FourFours(shift.hi4(), 0xf, shift.lo4(), rm)); 9485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void cmp(RegisterID rn, RegisterID rm) 9515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 9525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((rn | rm) & 8) 9535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian cmp(rn, rm, ShiftTypeAndAmount()); 9545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 9555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp10Reg3Reg3(OP_CMP_reg_T1, rm, rn); 9565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // xor is not spelled with an 'e'. :-( 9595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void eor(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) 9605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 9615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 9625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 9635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isEncodedImm()); 9645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_EOR_imm_T1, rn, rd, imm); 9655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // xor is not spelled with an 'e'. :-( 9685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void eor(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 9695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 9705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 9715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 9725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 9735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_EOR_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 9745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // xor is not spelled with an 'e'. :-( 9775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void eor(RegisterID rd, RegisterID rn, RegisterID rm) 9785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 9795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((rd == rn) && !((rd | rm) & 8)) 9805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp10Reg3Reg3(OP_EOR_reg_T1, rm, rd); 9815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else if ((rd == rm) && !((rd | rn) & 8)) 9825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp10Reg3Reg3(OP_EOR_reg_T1, rn, rd); 9835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 9845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian eor(rd, rn, rm, ShiftTypeAndAmount()); 9855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void it(Condition cond) 9885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 9895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond)); 9905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void it(Condition cond, bool inst2if) 9935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 9945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if)); 9955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void it(Condition cond, bool inst2if, bool inst3if) 9985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 9995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if, inst3if)); 10005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void it(Condition cond, bool inst2if, bool inst3if, bool inst4if) 10035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 10045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if, inst3if, inst4if)); 10055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1007231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. 10085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ldr(RegisterID rt, RegisterID rn, ARMThumbImmediate imm) 10095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1010231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); // LDR (literal) 10115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isUInt12()); 10125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!((rt | rn) & 8) && imm.isUInt7()) 10145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDR_imm_T1, imm.getUInt7() >> 2, rn, rt); 1015231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block else if ((rn == ARMRegisters::sp) && !(rt & 8) && imm.isUInt10()) 10165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Reg3Imm8(OP_LDR_imm_T2, rt, imm.getUInt10() >> 2); 10175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 10185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T3, rn, rt, imm.getUInt12()); 10195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If index is set, this is a regular offset or a pre-indexed load; 10225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if index is not set then is is a post-index load. 10235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 10245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If wback is set rn is updated - this is a pre or post index load, 10255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if wback is not set this is a regular offset memory access. 10265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 10275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // (-255 <= offset <= 255) 10285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // _reg = REG[rn] 10295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // _tmp = _reg + offset 10305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // MEM[index ? _tmp : _reg] = REG[rt] 10315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if (wback) REG[rn] = _tmp 10325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ldr(RegisterID rt, RegisterID rn, int offset, bool index, bool wback) 10335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1034231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rt != ARMRegisters::pc); 1035231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 10365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(index || wback); 10375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!wback | (rt != rn)); 10385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool add = true; 10405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (offset < 0) { 10415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian add = false; 10425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset = -offset; 10435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT((offset & ~0xff) == 0); 10455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (wback << 8); 10475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (add << 9); 10485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (index << 10); 10495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (1 << 11); 10505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T4, rn, rt, offset); 10525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1054231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. 10555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ldr(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift=0) 10565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1057231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); // LDR (literal) 10585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 10595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(shift <= 3); 10605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!shift && !((rt | rn | rm) & 8)) 10625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDR_reg_T1, rm, rn, rt); 10635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 10645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_LDR_reg_T2, rn, FourFours(rt, 0, shift, rm)); 10655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1067231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. 10685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ldrh(RegisterID rt, RegisterID rn, ARMThumbImmediate imm) 10695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1070231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); // LDR (literal) 10715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isUInt12()); 10725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!((rt | rn) & 8) && imm.isUInt6()) 10745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDRH_imm_T1, imm.getUInt6() >> 2, rn, rt); 10755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 10765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRH_imm_T2, rn, rt, imm.getUInt12()); 10775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If index is set, this is a regular offset or a pre-indexed load; 10805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if index is not set then is is a post-index load. 10815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 10825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If wback is set rn is updated - this is a pre or post index load, 10835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if wback is not set this is a regular offset memory access. 10845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 10855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // (-255 <= offset <= 255) 10865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // _reg = REG[rn] 10875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // _tmp = _reg + offset 10885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // MEM[index ? _tmp : _reg] = REG[rt] 10895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if (wback) REG[rn] = _tmp 10905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ldrh(RegisterID rt, RegisterID rn, int offset, bool index, bool wback) 10915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1092231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rt != ARMRegisters::pc); 1093231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 10945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(index || wback); 10955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!wback | (rt != rn)); 10965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool add = true; 10985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (offset < 0) { 10995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian add = false; 11005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset = -offset; 11015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 11025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT((offset & ~0xff) == 0); 11035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 11045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (wback << 8); 11055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (add << 9); 11065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (index << 10); 11075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (1 << 11); 11085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 11095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRH_imm_T3, rn, rt, offset); 11105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 11115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 11125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ldrh(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift=0) 11135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 11145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rt)); // Memory hint 1115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); // LDRH (literal) 11165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 11175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(shift <= 3); 11185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 11195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!shift && !((rt | rn | rm) & 8)) 11205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRH_reg_T1, rm, rn, rt); 11215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 11225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_LDRH_reg_T2, rn, FourFours(rt, 0, shift, rm)); 11235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 11245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1125dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void ldrb(RegisterID rt, RegisterID rn, ARMThumbImmediate imm) 1126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 1127dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(rn != ARMRegisters::pc); // LDR (literal) 1128dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(imm.isUInt12()); 1129dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1130dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!((rt | rn) & 8) && imm.isUInt5()) 1131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDRB_imm_T1, imm.getUInt5(), rn, rt); 1132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else 1133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRB_imm_T2, rn, rt, imm.getUInt12()); 1134dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1135dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void ldrb(RegisterID rt, RegisterID rn, int offset, bool index, bool wback) 1137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 1138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(rt != ARMRegisters::pc); 1139dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(rn != ARMRegisters::pc); 1140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(index || wback); 1141dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(!wback | (rt != rn)); 1142dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1143dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool add = true; 1144dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (offset < 0) { 1145dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block add = false; 1146dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block offset = -offset; 1147dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(!(offset & ~0xff)); 1150dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block offset |= (wback << 8); 1152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block offset |= (add << 9); 1153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block offset |= (index << 10); 1154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block offset |= (1 << 11); 1155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRB_imm_T3, rn, rt, offset); 1157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block void ldrb(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0) 1160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 1161dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(rn != ARMRegisters::pc); // LDR (literal) 1162dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(!BadReg(rm)); 1163dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(shift <= 3); 1164dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1165dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!shift && !((rt | rn | rm) & 8)) 1166dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRB_reg_T1, rm, rn, rt); 1167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else 1168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_formatter.twoWordOp12Reg4FourFours(OP_LDRB_reg_T2, rn, FourFours(rt, 0, shift, rm)); 1169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 11715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void lsl(RegisterID rd, RegisterID rm, int32_t shiftAmount) 11725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 11735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 11745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 11755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ShiftTypeAndAmount shift(SRType_LSL, shiftAmount); 11765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp16FourFours(OP_LSL_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 11775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 11785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 11795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void lsl(RegisterID rd, RegisterID rn, RegisterID rm) 11805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 11815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 11825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 11835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 11845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_LSL_reg_T2, rn, FourFours(0xf, rd, 0, rm)); 11855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 11865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 11875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void lsr(RegisterID rd, RegisterID rm, int32_t shiftAmount) 11885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 11895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 11905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 11915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ShiftTypeAndAmount shift(SRType_LSR, shiftAmount); 11925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp16FourFours(OP_LSR_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 11935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 11945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 11955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void lsr(RegisterID rd, RegisterID rn, RegisterID rm) 11965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 11975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 11985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 11995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 12005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_LSR_reg_T2, rn, FourFours(0xf, rd, 0, rm)); 12015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void movT3(RegisterID rd, ARMThumbImmediate imm) 12045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isValid()); 12065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!imm.isEncodedImm()); 12075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 12085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOV_imm_T3, imm.m_value.imm4, rd, imm); 12105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void mov(RegisterID rd, ARMThumbImmediate imm) 12135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isValid()); 12155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 12165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((rd < 8) && imm.isUInt8()) 12185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Reg3Imm8(OP_MOV_imm_T1, rd, imm.getUInt8()); 12195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else if (imm.isEncodedImm()) 12205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOV_imm_T2, 0xf, rd, imm); 12215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 12225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian movT3(rd, imm); 12235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void mov(RegisterID rd, RegisterID rm) 12265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp8RegReg143(OP_MOV_reg_T1, rm, rd); 12285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void movt(RegisterID rd, ARMThumbImmediate imm) 12315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isUInt16()); 12335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 12345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOVT, imm.m_value.imm4, rd, imm); 12355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void mvn(RegisterID rd, ARMThumbImmediate imm) 12385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isEncodedImm()); 12405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 12415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MVN_imm, 0xf, rd, imm); 12435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void mvn(RegisterID rd, RegisterID rm, ShiftTypeAndAmount shift) 12465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 12485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 12495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp16FourFours(OP_MVN_reg_T2, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 12505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void mvn(RegisterID rd, RegisterID rm) 12535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!((rd | rm) & 8)) 12555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp10Reg3Reg3(OP_MVN_reg_T1, rm, rd); 12565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 12575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian mvn(rd, rm, ShiftTypeAndAmount()); 12585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1260ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void neg(RegisterID rd, RegisterID rm) 1261ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1262ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ARMThumbImmediate zero = ARMThumbImmediate::makeUInt12(0); 1263ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block sub(rd, zero, rm); 1264ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1265ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 12665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void orr(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) 12675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 12695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 12705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isEncodedImm()); 12715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ORR_imm_T1, rn, rd, imm); 12725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void orr(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 12755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 12775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 12785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 12795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_ORR_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 12805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 12825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void orr(RegisterID rd, RegisterID rn, RegisterID rm) 12835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 12845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((rd == rn) && !((rd | rm) & 8)) 12855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rm, rd); 12865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else if ((rd == rm) && !((rd | rn) & 8)) 12875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rn, rd); 12885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 12895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian orr(rd, rn, rm, ShiftTypeAndAmount()); 12905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 12915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1292ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void orr_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 1293ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1294ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!BadReg(rd)); 1295ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!BadReg(rn)); 1296ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!BadReg(rm)); 1297ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.twoWordOp12Reg4FourFours(OP_ORR_S_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 1298ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1299ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 1300ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void orr_S(RegisterID rd, RegisterID rn, RegisterID rm) 1301ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1302ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block if ((rd == rn) && !((rd | rm) & 8)) 1303ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rm, rd); 1304ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block else if ((rd == rm) && !((rd | rn) & 8)) 1305ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rn, rd); 1306ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block else 1307ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block orr_S(rd, rn, rm, ShiftTypeAndAmount()); 1308ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1309ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 13105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ror(RegisterID rd, RegisterID rm, int32_t shiftAmount) 13115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 13125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 13135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 13145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ShiftTypeAndAmount shift(SRType_ROR, shiftAmount); 13155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp16FourFours(OP_ROR_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 13165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void ror(RegisterID rd, RegisterID rn, RegisterID rm) 13195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 13205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rd)); 13215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 13225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 13235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_ROR_reg_T2, rn, FourFours(0xf, rd, 0, rm)); 13245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void smull(RegisterID rdLo, RegisterID rdHi, RegisterID rn, RegisterID rm) 13275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 13285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rdLo)); 13295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rdHi)); 13305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 13315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 13325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(rdLo != rdHi); 13335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_SMULL_T1, rn, FourFours(rdLo, rdHi, 0, rm)); 13345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1336231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. 13375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void str(RegisterID rt, RegisterID rn, ARMThumbImmediate imm) 13385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1339231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rt != ARMRegisters::pc); 1340231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 13415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isUInt12()); 13425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!((rt | rn) & 8) && imm.isUInt7()) 13445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STR_imm_T1, imm.getUInt7() >> 2, rn, rt); 1345231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block else if ((rn == ARMRegisters::sp) && !(rt & 8) && imm.isUInt10()) 13465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Reg3Imm8(OP_STR_imm_T2, rt, imm.getUInt10() >> 2); 13475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 13485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STR_imm_T3, rn, rt, imm.getUInt12()); 13495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If index is set, this is a regular offset or a pre-indexed store; 13525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if index is not set then is is a post-index store. 13535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 13545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // If wback is set rn is updated - this is a pre or post index store, 13555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if wback is not set this is a regular offset memory access. 13565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 13575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // (-255 <= offset <= 255) 13585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // _reg = REG[rn] 13595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // _tmp = _reg + offset 13605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // MEM[index ? _tmp : _reg] = REG[rt] 13615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // if (wback) REG[rn] = _tmp 13625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void str(RegisterID rt, RegisterID rn, int offset, bool index, bool wback) 13635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1364231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rt != ARMRegisters::pc); 1365231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 13665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(index || wback); 13675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!wback | (rt != rn)); 13685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool add = true; 13705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (offset < 0) { 13715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian add = false; 13725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset = -offset; 13735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT((offset & ~0xff) == 0); 13755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (wback << 8); 13775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (add << 9); 13785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (index << 10); 13795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian offset |= (1 << 11); 13805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STR_imm_T4, rn, rt, offset); 13825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1384231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. 13855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void str(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift=0) 13865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1387231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 13885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 13895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(shift <= 3); 13905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!shift && !((rt | rn | rm) & 8)) 13925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp7Reg3Reg3Reg3(OP_STR_reg_T1, rm, rn, rt); 13935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 13945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_STR_reg_T2, rn, FourFours(rt, 0, shift, rm)); 13955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void sub(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) 13985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 13995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Rd can only be SP if Rn is also SP. 1400231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); 1401231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rd != ARMRegisters::pc); 1402231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 14035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isValid()); 14045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1405231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) { 14065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, imm.getUInt9() >> 2); 14075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 14085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if (!((rd | rn) & 8)) { 14095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (imm.isUInt3()) { 14105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); 14115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 14125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if ((rd == rn) && imm.isUInt8()) { 14135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp5Reg3Imm8(OP_SUB_imm_T2, rd, imm.getUInt8()); 14145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 14155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 14185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (imm.isEncodedImm()) 14195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_imm_T3, rn, rd, imm); 14205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else { 14215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isUInt12()); 14225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_imm_T4, rn, rd, imm); 14235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1426ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void sub(RegisterID rd, ARMThumbImmediate imm, RegisterID rn) 1427ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1428ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(rd != ARMRegisters::pc); 1429ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(rn != ARMRegisters::pc); 1430ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(imm.isValid()); 1431ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(imm.isUInt12()); 1432ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 1433ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block if (!((rd | rn) & 8) && !imm.getUInt12()) 1434ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.oneWordOp10Reg3Reg3(OP_RSB_imm_T1, rn, rd); 1435ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block else 1436ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_RSB_imm_T2, rn, rd, imm); 1437ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1438ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 14395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void sub(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 14405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1441231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); 1442231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rd != ARMRegisters::pc); 1443231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 14445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 14455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_SUB_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 14465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 14485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // NOTE: In an IT block, add doesn't modify the flags register. 14495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void sub(RegisterID rd, RegisterID rn, RegisterID rm) 14505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 14515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!((rd | rn | rm) & 8)) 14525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_reg_T1, rm, rn, rd); 14535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 14545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian sub(rd, rn, rm, ShiftTypeAndAmount()); 14555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 14575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Not allowed in an IT (if then) block. 14585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void sub_S(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) 14595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 14605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Rd can only be SP if Rn is also SP. 1461231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); 1462231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rd != ARMRegisters::pc); 1463231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 14645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isValid()); 14655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1466231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) { 14675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, imm.getUInt9() >> 2); 14685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 14695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if (!((rd | rn) & 8)) { 14705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (imm.isUInt3()) { 1471ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); 14725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 14735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if ((rd == rn) && imm.isUInt8()) { 1474ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.oneWordOp5Reg3Imm8(OP_SUB_imm_T2, rd, imm.getUInt8()); 14755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return; 14765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 14795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_S_imm_T3, rn, rd, imm); 14805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 14825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Not allowed in an IT (if then) block? 14835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void sub_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 14845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1485231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); 1486231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rd != ARMRegisters::pc); 1487231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(rn != ARMRegisters::pc); 14885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 14895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_SUB_S_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 14905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 14915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 14925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Not allowed in an IT (if then) block. 14935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void sub_S(RegisterID rd, RegisterID rn, RegisterID rm) 14945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 14955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!((rd | rn | rm) & 8)) 1496ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_reg_T1, rm, rn, rd); 14975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 14985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian sub_S(rd, rn, rm, ShiftTypeAndAmount()); 14995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 15015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void tst(RegisterID rn, ARMThumbImmediate imm) 15025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 15035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 15045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(imm.isEncodedImm()); 15055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 15065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_TST_imm, rn, (RegisterID)0xf, imm); 15075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 15095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void tst(RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 15105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 15115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rn)); 15125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!BadReg(rm)); 15135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.twoWordOp12Reg4FourFours(OP_TST_reg_T2, rn, FourFours(shift.hi4(), 0xf, shift.lo4(), rm)); 15145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 15165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void tst(RegisterID rn, RegisterID rm) 15175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 15185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ((rn | rm) & 8) 15195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian tst(rn, rm, ShiftTypeAndAmount()); 15205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian else 15215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_formatter.oneWordOp10Reg3Reg3(OP_TST_reg_T1, rm, rn); 15225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1524ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vadd_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1525ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1526ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpOp(OP_VADD_T2, OP_VADD_T2b, true, rn, rd, rm); 1527ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1528ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 1529ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vcmp_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rm) 15305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1531cad810f21b803229eb11403f9209855525a25d57Steve Block m_formatter.vfpOp(OP_VCMP, OP_VCMPb, true, VFPOperand(4), rd, rm); 1532cad810f21b803229eb11403f9209855525a25d57Steve Block } 1533cad810f21b803229eb11403f9209855525a25d57Steve Block 1534cad810f21b803229eb11403f9209855525a25d57Steve Block void vcmpz_F64(FPDoubleRegisterID rd) 1535cad810f21b803229eb11403f9209855525a25d57Steve Block { 1536cad810f21b803229eb11403f9209855525a25d57Steve Block m_formatter.vfpOp(OP_VCMP, OP_VCMPb, true, VFPOperand(5), rd, VFPOperand(0)); 15375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1539ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vcvt_F64_S32(FPDoubleRegisterID rd, FPSingleRegisterID rm) 15405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1541ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // boolean values are 64bit (toInt, unsigned, roundZero) 1542ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(false, false, false), rd, rm); 15435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1545ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vcvtr_S32_F64(FPSingleRegisterID rd, FPDoubleRegisterID rm) 15465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1547ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // boolean values are 64bit (toInt, unsigned, roundZero) 1548ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(true, false, true), rd, rm); 15495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1551ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vdiv_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 15525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1553ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpOp(OP_VDIV, OP_VDIVb, true, rn, rd, rm); 15545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1556ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vldr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm) 15575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1558ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpMemOp(OP_VLDR, OP_VLDRb, true, rn, rd, imm); 15595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1561ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vmov(RegisterID rd, FPSingleRegisterID rn) 15625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1563ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!BadReg(rd)); 1564ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpOp(OP_VMOV_CtoS, OP_VMOV_CtoSb, false, rn, rd, VFPOperand(0)); 15655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1567ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vmov(FPSingleRegisterID rd, RegisterID rn) 15685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1569ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!BadReg(rn)); 1570ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpOp(OP_VMOV_StoC, OP_VMOV_StoCb, false, rd, rn, VFPOperand(0)); 15715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1573ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vmrs(RegisterID reg = ARMRegisters::pc) 15745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1575ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(reg != ARMRegisters::sp); 1576ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpOp(OP_VMRS, OP_VMRSb, false, VFPOperand(1), VFPOperand(0x10 | reg), VFPOperand(0)); 15775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1579ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vmul_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 15805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1581ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpOp(OP_VMUL_T2, OP_VMUL_T2b, true, rn, rd, rm); 15825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1584ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vstr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm) 15855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1586ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpMemOp(OP_VSTR, OP_VSTRb, true, rn, rd, imm); 15875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1589ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vsub_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1590ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1591ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_formatter.vfpOp(OP_VSUB_T2, OP_VSUB_T2b, true, rn, rd, rm); 1592ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 15935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 15945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JmpDst label() 15955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 15965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return JmpDst(m_formatter.size()); 15975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 15985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 15995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JmpDst align(int alignment) 16005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 16015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian while (!m_formatter.isAligned(alignment)) 16025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bkpt(); 16035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return label(); 16055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 16065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static void* getRelocatedAddress(void* code, JmpSrc jump) 16085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 16095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(jump.m_offset != -1); 16105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset); 16125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 16135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static void* getRelocatedAddress(void* code, JmpDst destination) 16155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 16165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(destination.m_offset != -1); 16175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + destination.m_offset); 16195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 16205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst) 16225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 16235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return dst.m_offset - src.m_offset; 16245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 16255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst) 16275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 16285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return dst.m_offset - src.m_offset; 16295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 16305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst) 16325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 16335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return dst.m_offset - src.m_offset; 16345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 1635dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 1636dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int executableOffsetFor(int location) 1637dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 1638dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch if (!location) 1639dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return 0; 1640dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return static_cast<int32_t*>(m_formatter.data())[location / sizeof(int32_t) - 1]; 1641dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 1642dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 1643a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return JumpPaddingSizes[jumpType] - JumpSizes[jumpLinkType]; } 16445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Assembler admin methods: 16465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 16475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian size_t size() const 16485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 16495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return m_formatter.size(); 16505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 16515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1652dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch static bool linkRecordSourceComparator(const LinkRecord& a, const LinkRecord& b) 16535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1654dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return a.from() < b.from(); 1655dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 1656cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 1657a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool canCompact(JumpType jumpType) 1658dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 1659a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The following cannot be compacted: 1660a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // JumpFixed: represents custom jump sequence 1661a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // JumpNoConditionFixedSize: represents unconditional jump that must remain a fixed size 1662a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // JumpConditionFixedSize: represents conditional jump that must remain a fixed size 1663a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return (jumpType == JumpNoCondition) || (jumpType == JumpCondition); 1664a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1665a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1666a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) 1667a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 1668a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (jumpType == JumpFixed) 1669a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkInvalid; 1670a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1671a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // for patchable jump we must leave space for the longest code sequence 1672a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (jumpType == JumpNoConditionFixedSize) 1673a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkBX; 1674a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (jumpType == JumpConditionFixedSize) 1675a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkConditionalBX; 1676a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1677a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const int paddingSize = JumpPaddingSizes[jumpType]; 1678dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch bool mayTriggerErrata = false; 1679a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1680a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (jumpType == JumpCondition) { 1681a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // 2-byte conditional T1 1682a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const uint16_t* jumpT1Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT1])); 1683a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (canBeJumpT1(jumpT1Location, to)) 1684a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkJumpT1; 1685a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // 4-byte conditional T3 1686a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const uint16_t* jumpT3Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT3])); 1687a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (canBeJumpT3(jumpT3Location, to, mayTriggerErrata)) { 1688a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!mayTriggerErrata) 1689a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkJumpT3; 1690a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1691a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // 4-byte conditional T4 with IT 1692a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const uint16_t* conditionalJumpT4Location = 1693a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkConditionalJumpT4])); 1694a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (canBeJumpT4(conditionalJumpT4Location, to, mayTriggerErrata)) { 1695a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!mayTriggerErrata) 1696a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkConditionalJumpT4; 1697a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1698a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else { 1699a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // 2-byte unconditional T2 1700a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const uint16_t* jumpT2Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT2])); 1701a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (canBeJumpT2(jumpT2Location, to)) 1702a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkJumpT2; 1703a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // 4-byte unconditional T4 1704a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const uint16_t* jumpT4Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JumpSizes[LinkJumpT4])); 1705a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (canBeJumpT4(jumpT4Location, to, mayTriggerErrata)) { 1706a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!mayTriggerErrata) 1707a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkJumpT4; 1708a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1709a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // use long jump sequence 1710a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkBX; 1711dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 1712a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1713a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(jumpType == JumpCondition); 1714a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return LinkConditionalBX; 1715dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 1716a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1717a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) 1718a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 1719a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JumpLinkType linkType = computeJumpType(record.type(), from, to); 1720a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch record.setLinkType(linkType); 1721a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return linkType; 1722a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1723a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1724dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset) 1725dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 1726dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int32_t ptr = regionStart / sizeof(int32_t); 1727dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch const int32_t end = regionEnd / sizeof(int32_t); 1728dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int32_t* offsets = static_cast<int32_t*>(m_formatter.data()); 1729dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch while (ptr < end) 1730dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch offsets[ptr++] = offset; 1731dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 1732dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 1733dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch Vector<LinkRecord>& jumpsToLink() 1734dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 1735dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch std::sort(m_jumpsToLink.begin(), m_jumpsToLink.end(), linkRecordSourceComparator); 1736dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return m_jumpsToLink; 1737dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 1738dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 1739dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch void link(LinkRecord& record, uint8_t* from, uint8_t* to) 1740dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 1741a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch switch (record.linkType()) { 1742a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LinkJumpT1: 1743a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkJumpT1(record.condition(), reinterpret_cast<uint16_t*>(from), to); 1744a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 1745a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LinkJumpT2: 1746a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkJumpT2(reinterpret_cast<uint16_t*>(from), to); 1747a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 1748a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LinkJumpT3: 1749a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkJumpT3(record.condition(), reinterpret_cast<uint16_t*>(from), to); 1750a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 1751a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LinkJumpT4: 1752a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkJumpT4(reinterpret_cast<uint16_t*>(from), to); 1753a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 1754a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LinkConditionalJumpT4: 1755a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkConditionalJumpT4(record.condition(), reinterpret_cast<uint16_t*>(from), to); 1756a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 1757a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LinkConditionalBX: 1758a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkConditionalBX(record.condition(), reinterpret_cast<uint16_t*>(from), to); 1759a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 1760a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch case LinkBX: 1761a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkBX(reinterpret_cast<uint16_t*>(from), to); 1762a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 1763a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch default: 1764a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT_NOT_REACHED(); 1765a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch break; 1766dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 17675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 17685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1769dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch void* unlinkedCode() { return m_formatter.data(); } 1770dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 17715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static unsigned getCallReturnOffset(JmpSrc call) 17725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 17735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(call.m_offset >= 0); 17745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return call.m_offset; 17755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 17765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 17775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Linking & patching: 17785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 17795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 'link' and 'patch' methods are for use on unprotected code - such as the code 17805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // within the AssemblerBuffer, and code being patched by the patch buffer. Once 17815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // code has been finalized it is (platform support permitting) within a non- 17825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // writable region of memory; to modify the code in an execute-only execuable 17835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // pool the 'repatch' and 'relink' methods should be used. 17845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 17855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void linkJump(JmpSrc from, JmpDst to) 17865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 17875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(to.m_offset != -1); 17885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(from.m_offset != -1); 1789dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch m_jumpsToLink.append(LinkRecord(from.m_offset, to.m_offset, from.m_type, from.m_condition)); 17905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 17915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 17925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static void linkJump(void* code, JmpSrc from, void* to) 17935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 17945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(from.m_offset != -1); 17955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 17965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset); 1797cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block linkJumpAbsolute(location, to); 17985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 17995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // bah, this mathod should really be static, since it is used by the LinkBuffer. 18015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // return a bool saying whether the link was successful? 18025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static void linkCall(void* code, JmpSrc from, void* to) 18035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 18045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!(reinterpret_cast<intptr_t>(code) & 1)); 18055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(from.m_offset != -1); 18065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(reinterpret_cast<intptr_t>(to) & 1); 18075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch setPointer(reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset) - 1, to); 18095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 18105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void linkPointer(void* code, JmpDst where, void* value) 18125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 18130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch setPointer(reinterpret_cast<char*>(code) + where.m_offset, value); 18145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 18155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static void relinkJump(void* from, void* to) 18175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 18185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!(reinterpret_cast<intptr_t>(from) & 1)); 18195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!(reinterpret_cast<intptr_t>(to) & 1)); 18205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1821cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block linkJumpAbsolute(reinterpret_cast<uint16_t*>(from), to); 18220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1823cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 5, 5 * sizeof(uint16_t)); 18245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 18255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static void relinkCall(void* from, void* to) 18275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 18285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!(reinterpret_cast<intptr_t>(from) & 1)); 18295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(reinterpret_cast<intptr_t>(to) & 1); 18305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch setPointer(reinterpret_cast<uint16_t*>(from) - 1, to); 18325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 18335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static void repatchInt32(void* where, int32_t value) 18355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 18365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!(reinterpret_cast<intptr_t>(where) & 1)); 18375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch setInt32(where, value); 18395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 18405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian static void repatchPointer(void* where, void* value) 18425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 18435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!(reinterpret_cast<intptr_t>(where) & 1)); 18445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch setPointer(where, value); 18465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 18475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianprivate: 1849ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // VFP operations commonly take one or more 5-bit operands, typically representing a 1850ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // floating point register number. This will commonly be encoded in the instruction 1851ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // in two parts, with one single bit field, and one 4-bit field. In the case of 1852ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // double precision operands the high bit of the register number will be encoded 1853ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // separately, and for single precision operands the high bit of the register number 1854ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // will be encoded individually. 1855ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // VFPOperand encapsulates a 5-bit VFP operand, with bits 0..3 containing the 4-bit 1856ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // field to be encoded together in the instruction (the low 4-bits of a double 1857ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // register number, or the high 4-bits of a single register number), and bit 4 1858ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // contains the bit value to be encoded individually. 1859ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block struct VFPOperand { 1860ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block explicit VFPOperand(uint32_t value) 1861ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block : m_value(value) 1862ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1863ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!(m_value & ~0x1f)); 1864ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 18655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1866ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block VFPOperand(FPDoubleRegisterID reg) 1867ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block : m_value(reg) 1868ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1869ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1870ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 1871ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block VFPOperand(RegisterID reg) 1872ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block : m_value(reg) 1873ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 18745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 18755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1876ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block VFPOperand(FPSingleRegisterID reg) 1877ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block : m_value(((reg & 1) << 4) | (reg >> 1)) // rotate the lowest bit of 'reg' to the top. 1878ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1879ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1880ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 1881ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block uint32_t bits1() 1882ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1883ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block return m_value >> 4; 1884ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 18855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1886ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block uint32_t bits4() 1887ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1888ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block return m_value & 0xf; 1889ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1890ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 1891ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block uint32_t m_value; 1892ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block }; 1893ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 1894ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block VFPOperand vcvtOp(bool toInteger, bool isUnsigned, bool isRoundZero) 1895ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 1896ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // Cannot specify rounding when converting to float. 1897ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(toInteger || !isRoundZero); 1898ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 1899ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block uint32_t op = 0x8; 1900ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block if (toInteger) { 1901ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // opc2 indicates both toInteger & isUnsigned. 1902ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block op |= isUnsigned ? 0x4 : 0x5; 1903ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // 'op' field in instruction is isRoundZero 1904ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block if (isRoundZero) 1905ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block op |= 0x10; 1906ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } else { 1907ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // 'op' field in instruction is isUnsigned 1908ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block if (!isUnsigned) 1909ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block op |= 0x10; 1910ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 1911ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block return VFPOperand(op); 19125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 19135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 19140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void setInt32(void* code, uint32_t value) 19155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 19165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian uint16_t* location = reinterpret_cast<uint16_t*>(code); 1917cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ASSERT(isMOV_imm_T3(location - 4) && isMOVT(location - 2)); 19185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1919cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value)); 1920cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value >> 16)); 1921cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block location[-4] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16); 1922cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block location[-3] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-3] >> 8) & 0xf, lo16); 1923cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block location[-2] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); 1924cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block location[-1] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-1] >> 8) & 0xf, hi16); 19250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 19260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ExecutableAllocator::cacheFlush(location - 4, 4 * sizeof(uint16_t)); 19275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 19285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 19290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void setPointer(void* code, void* value) 19305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 19310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch setInt32(code, reinterpret_cast<uint32_t>(value)); 19325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 19335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1934cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block static bool isB(void* address) 1935cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block { 1936cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block uint16_t* instruction = static_cast<uint16_t*>(address); 1937cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return ((instruction[0] & 0xf800) == OP_B_T4a) && ((instruction[1] & 0xd000) == OP_B_T4b); 1938cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 1939cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 1940cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block static bool isBX(void* address) 1941cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block { 1942cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block uint16_t* instruction = static_cast<uint16_t*>(address); 1943cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return (instruction[0] & 0xff87) == OP_BX; 1944cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 19455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1946cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block static bool isMOV_imm_T3(void* address) 1947cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block { 1948cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block uint16_t* instruction = static_cast<uint16_t*>(address); 1949cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return ((instruction[0] & 0xFBF0) == OP_MOV_imm_T3) && ((instruction[1] & 0x8000) == 0); 1950cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 19515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1952cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block static bool isMOVT(void* address) 1953cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block { 1954cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block uint16_t* instruction = static_cast<uint16_t*>(address); 1955cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return ((instruction[0] & 0xFBF0) == OP_MOVT) && ((instruction[1] & 0x8000) == 0); 1956cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 19575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1958cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block static bool isNOP_T1(void* address) 1959cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block { 1960cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block uint16_t* instruction = static_cast<uint16_t*>(address); 1961cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return instruction[0] == OP_NOP_T1; 19625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 19635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1964cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block static bool isNOP_T2(void* address) 19655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1966cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block uint16_t* instruction = static_cast<uint16_t*>(address); 1967cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return (instruction[0] == OP_NOP_T2a) && (instruction[1] == OP_NOP_T2b); 19685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 1969cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 1970a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch static bool canBeJumpT1(const uint16_t* instruction, const void* target) 1971a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 1972a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 1973a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 1974a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1975a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 1976a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // It does not appear to be documented in the ARM ARM (big surprise), but 1977a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // for OP_B_T1 the branch displacement encoded in the instruction is 2 1978a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // less than the actual displacement. 1979a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch relative -= 2; 1980a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return ((relative << 23) >> 23) == relative; 1981a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1982a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1983a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch static bool canBeJumpT2(const uint16_t* instruction, const void* target) 1984a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 1985a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 1986a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 1987a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1988a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 1989a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // It does not appear to be documented in the ARM ARM (big surprise), but 1990a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // for OP_B_T2 the branch displacement encoded in the instruction is 2 1991a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // less than the actual displacement. 1992a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch relative -= 2; 1993a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return ((relative << 20) >> 20) == relative; 1994a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1995a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1996a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch static bool canBeJumpT3(const uint16_t* instruction, const void* target, bool& mayTriggerErrata) 1997a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 1998a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 1999a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2000a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2001a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2002a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // From Cortex-A8 errata: 2003a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // If the 32-bit Thumb-2 branch instruction spans two 4KiB regions and 2004a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // the target of the branch falls within the first region it is 2005a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // possible for the processor to incorrectly determine the branch 2006a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // instruction, and it is also possible in some cases for the processor 2007a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // to enter a deadlock state. 2008a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The instruction is spanning two pages if it ends at an address ending 0x002 2009a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool spansTwo4K = ((reinterpret_cast<intptr_t>(instruction) & 0xfff) == 0x002); 2010a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch mayTriggerErrata = spansTwo4K; 2011a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // The target is in the first page if the jump branch back by [3..0x1002] bytes 2012a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool targetInFirstPage = (relative >= -0x1002) && (relative < -2); 2013a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool wouldTriggerA8Errata = spansTwo4K && targetInFirstPage; 2014a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return ((relative << 11) >> 11) == relative && !wouldTriggerA8Errata; 2015a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2016a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2017a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch static bool canBeJumpT4(const uint16_t* instruction, const void* target, bool& mayTriggerErrata) 20185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 2019cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2020cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2021dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 2022cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 20236c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // From Cortex-A8 errata: 20246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // If the 32-bit Thumb-2 branch instruction spans two 4KiB regions and 20256c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // the target of the branch falls within the first region it is 20266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // possible for the processor to incorrectly determine the branch 20276c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // instruction, and it is also possible in some cases for the processor 20286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // to enter a deadlock state. 20296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // The instruction is spanning two pages if it ends at an address ending 0x002 20306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool spansTwo4K = ((reinterpret_cast<intptr_t>(instruction) & 0xfff) == 0x002); 2031dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch mayTriggerErrata = spansTwo4K; 20326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // The target is in the first page if the jump branch back by [3..0x1002] bytes 20336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool targetInFirstPage = (relative >= -0x1002) && (relative < -2); 20346c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool wouldTriggerA8Errata = spansTwo4K && targetInFirstPage; 2035dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch return ((relative << 7) >> 7) == relative && !wouldTriggerA8Errata; 2036dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 2037a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2038a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch void linkJumpT1(Condition cond, uint16_t* instruction, void* target) 2039dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 2040a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIMXE: this should be up in the MacroAssembler layer. :-( 2041a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2042a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2043a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(canBeJumpT1(instruction, target)); 2044a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2045a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2046a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // It does not appear to be documented in the ARM ARM (big surprise), but 2047a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // for OP_B_T1 the branch displacement encoded in the instruction is 2 2048a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // less than the actual displacement. 2049a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch relative -= 2; 2050a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2051a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // All branch offsets should be an even distance. 2052a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(relative & 1)); 2053a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-1] = OP_B_T1 | ((cond & 0xf) << 8) | ((relative & 0x1fe) >> 1); 2054dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 2055dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 2056a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch static void linkJumpT2(uint16_t* instruction, void* target) 2057dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 2058dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch // FIMXE: this should be up in the MacroAssembler layer. :-( 2059dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2060dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2061a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(canBeJumpT2(instruction, target)); 2062dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 2063dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2064a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // It does not appear to be documented in the ARM ARM (big surprise), but 2065a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // for OP_B_T2 the branch displacement encoded in the instruction is 2 2066a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // less than the actual displacement. 2067a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch relative -= 2; 2068a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2069a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // All branch offsets should be an even distance. 2070a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(relative & 1)); 2071a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-1] = OP_B_T2 | ((relative & 0xffe) >> 1); 2072a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2073a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2074a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch void linkJumpT3(Condition cond, uint16_t* instruction, void* target) 2075a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 2076a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIMXE: this should be up in the MacroAssembler layer. :-( 2077a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2078a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2079dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch bool scratch; 2080dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch UNUSED_PARAM(scratch); 2081a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(canBeJumpT3(instruction, target, scratch)); 2082a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2083a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2084a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2085a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // All branch offsets should be an even distance. 2086a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(relative & 1)); 2087a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-2] = OP_B_T3a | ((relative & 0x100000) >> 10) | ((cond & 0xf) << 6) | ((relative & 0x3f000) >> 12); 2088a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-1] = OP_B_T3b | ((relative & 0x80000) >> 8) | ((relative & 0x40000) >> 5) | ((relative & 0xffe) >> 1); 2089a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2090a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2091a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch static void linkJumpT4(uint16_t* instruction, void* target) 2092a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 2093a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIMXE: this should be up in the MacroAssembler layer. :-( 2094a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2095a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2096a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool scratch; 2097a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch UNUSED_PARAM(scratch); 2098a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(canBeJumpT4(instruction, target, scratch)); 2099a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2101dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch // ARM encoding for the top two bits below the sign bit is 'peculiar'. 2102dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch if (relative >= 0) 2103dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch relative ^= 0xC00000; 2104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2105dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch // All branch offsets should be an even distance. 2106dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch ASSERT(!(relative & 1)); 2107dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12); 2108dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); 2109dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } 2110a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch void linkConditionalJumpT4(Condition cond, uint16_t* instruction, void* target) 2112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 2113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIMXE: this should be up in the MacroAssembler layer. :-( 2114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2116a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-3] = ifThenElse(cond) | OP_IT; 2118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkJumpT4(instruction, target); 2119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch static void linkBX(uint16_t* instruction, void* target) 2122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 2123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIMXE: this should be up in the MacroAssembler layer. :-( 2124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip; 2128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1)); 2129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16)); 2130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-5] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16); 2131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-4] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, lo16); 2132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); 2133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16); 2134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3); 2135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch void linkConditionalBX(Condition cond, uint16_t* instruction, void* target) 2138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch { 2139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIMXE: this should be up in the MacroAssembler layer. :-( 2140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2143a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkBX(instruction, target); 2144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instruction[-6] = ifThenElse(cond, true, true) | OP_IT; 2145a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2147dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch static void linkJumpAbsolute(uint16_t* instruction, void* target) 2148dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch { 2149dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch // FIMXE: this should be up in the MacroAssembler layer. :-( 2150dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2151dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2153dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch ASSERT((isMOV_imm_T3(instruction - 5) && isMOVT(instruction - 3) && isBX(instruction - 1)) 2154a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2))); 2155a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2156dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch bool scratch; 2157a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (canBeJumpT4(instruction, target, scratch)) { 2158cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // There may be a better way to fix this, but right now put the NOPs first, since in the 2159cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // case of an conditional branch this will be coming after an ITTT predicating *three* 2160cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // instructions! Looking backwards to modify the ITTT to an IT is not easy, due to 2161cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // variable wdith encoding - the previous instruction might *look* like an ITTT but 2162cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // actually be the second half of a 2-word op. 2163cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instruction[-5] = OP_NOP_T1; 2164cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instruction[-4] = OP_NOP_T2a; 2165cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instruction[-3] = OP_NOP_T2b; 2166a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch linkJumpT4(instruction, target); 2167cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } else { 2168dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip; 2169cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1)); 2170cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16)); 2171cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instruction[-5] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16); 2172cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instruction[-4] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, lo16); 2173cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); 2174cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16); 2175cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3); 2176cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 2177cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 2178a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2179cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block static uint16_t twoWordOp5i6Imm4Reg4EncodedImmFirst(uint16_t op, ARMThumbImmediate imm) 2180cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block { 2181cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return op | (imm.m_value.i << 10) | imm.m_value.imm4; 2182cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 2183dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch 2184cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block static uint16_t twoWordOp5i6Imm4Reg4EncodedImmSecond(uint16_t rd, ARMThumbImmediate imm) 2185cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block { 2186cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return (imm.m_value.imm3 << 12) | (rd << 8) | imm.m_value.imm8; 21875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 21885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 21895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian class ARMInstructionFormatter { 21905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian public: 21915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void oneWordOp5Reg3Imm8(OpcodeID op, RegisterID rd, uint8_t imm) 21925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 21935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op | (rd << 8) | imm); 21945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 21955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 21965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void oneWordOp5Imm5Reg3Reg3(OpcodeID op, uint8_t imm, RegisterID reg1, RegisterID reg2) 21975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 21985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op | (imm << 6) | (reg1 << 3) | reg2); 21995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void oneWordOp7Reg3Reg3Reg3(OpcodeID op, RegisterID reg1, RegisterID reg2, RegisterID reg3) 22025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 22035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op | (reg1 << 6) | (reg2 << 3) | reg3); 22045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void oneWordOp8Imm8(OpcodeID op, uint8_t imm) 22075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 22085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op | imm); 22095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void oneWordOp8RegReg143(OpcodeID op, RegisterID reg1, RegisterID reg2) 22125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 22135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op | ((reg2 & 8) << 4) | (reg1 << 3) | (reg2 & 7)); 22145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void oneWordOp9Imm7(OpcodeID op, uint8_t imm) 22165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 22175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op | imm); 22185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void oneWordOp10Reg3Reg3(OpcodeID op, RegisterID reg1, RegisterID reg2) 22215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 22225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op | (reg1 << 3) | reg2); 22235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void twoWordOp12Reg4FourFours(OpcodeID1 op, RegisterID reg, FourFours ff) 22265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 22275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op | reg); 22285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(ff.m_u.value); 22295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void twoWordOp16FourFours(OpcodeID1 op, FourFours ff) 22325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 22335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op); 22345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(ff.m_u.value); 22355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void twoWordOp16Op16(OpcodeID1 op1, OpcodeID2 op2) 22385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 22395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op1); 22405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op2); 22415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void twoWordOp5i6Imm4Reg4EncodedImm(OpcodeID1 op, int imm4, RegisterID rd, ARMThumbImmediate imm) 22445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 2245cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ARMThumbImmediate newImm = imm; 2246cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block newImm.m_value.imm4 = imm4; 2247cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 2248cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmFirst(op, newImm)); 2249cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmSecond(rd, newImm)); 22505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void twoWordOp12Reg4Reg4Imm12(OpcodeID1 op, RegisterID reg1, RegisterID reg2, uint16_t imm) 22535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 22545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort(op | reg1); 22555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_buffer.putShort((reg2 << 12) | imm); 22565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2258ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // Formats up instructions of the pattern: 2259ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // 111111111B11aaaa:bbbb222SA2C2cccc 2260ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // Where 1s in the pattern come from op1, 2s in the pattern come from op2, S is the provided size bit. 2261ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // Operands provide 5 bit values of the form Aaaaa, Bbbbb, Ccccc. 2262ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vfpOp(OpcodeID1 op1, OpcodeID2 op2, bool size, VFPOperand a, VFPOperand b, VFPOperand c) 22635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 2264ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!(op1 & 0x004f)); 2265ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!(op2 & 0xf1af)); 2266ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_buffer.putShort(op1 | b.bits1() << 6 | a.bits4()); 2267ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_buffer.putShort(op2 | b.bits4() << 12 | size << 8 | a.bits1() << 7 | c.bits1() << 5 | c.bits4()); 22685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 22695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2270ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2. 2271ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block // (i.e. +/-(0..255) 32-bit words) 2272ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block void vfpMemOp(OpcodeID1 op1, OpcodeID2 op2, bool size, RegisterID rn, VFPOperand rd, int32_t imm) 2273ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block { 2274ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block bool up = true; 2275ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block if (imm < 0) { 2276ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block imm = -imm; 2277ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block up = false; 2278ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 2279ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 2280ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block uint32_t offset = imm; 2281ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block ASSERT(!(offset & ~0x3fc)); 2282ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block offset >>= 2; 2283ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 2284ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_buffer.putShort(op1 | (up << 7) | rd.bits1() << 6 | rn); 2285ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block m_buffer.putShort(op2 | rd.bits4() << 12 | size << 8 | offset); 2286ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 22875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Administrative methods: 22895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian size_t size() const { return m_buffer.size(); } 22915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); } 22925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void* data() const { return m_buffer.data(); } 22935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian void* executableCopy(ExecutablePool* allocator) { return m_buffer.executableCopy(allocator); } 22945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 22952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#ifndef NDEBUG 22962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned debugOffset() { return m_formatter.debugOffset(); } 22972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif 22982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 22995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian private: 23005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian AssemblerBuffer m_buffer; 23015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } m_formatter; 2302cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 2303cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block Vector<LinkRecord> m_jumpsToLink; 2304dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch Vector<int32_t> m_offsets; 23055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}; 23065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 23075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} // namespace JSC 23085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2309d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // ENABLE(ASSEMBLER) && CPU(ARM_THUMB2) 23105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 23115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif // ARMAssembler_h 2312