14f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* libs/pixelflinger/codeflinger/ARMAssembler.cpp
24f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**
34f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** Copyright 2006, The Android Open Source Project
44f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**
54f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
64f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** you may not use this file except in compliance with the License.
74f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** You may obtain a copy of the License at
84f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**
94f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project**
114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** See the License for the specific language governing permissions and
154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project** limitations under the License.
164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project*/
174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#define LOG_TAG "ARMAssembler"
194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdio.h>
214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdlib.h>
224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <cutils/log.h>
234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <cutils/properties.h>
244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if defined(WITH_LIB_HARDWARE)
262eef60297a0ca1433d0824d6d662efd402709cfdThe Android Open Source Project#include <hardware_legacy/qemu_tracing.h>
274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <private/pixelflinger/ggl_context.h>
304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "codeflinger/ARMAssembler.h"
324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "codeflinger/CodeCache.h"
334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "codeflinger/disassem.h"
344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// ----------------------------------------------------------------------------
364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectnamespace android {
384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// ----------------------------------------------------------------------------
404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark -
424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark ARMAssembler...
434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source ProjectARMAssembler::ARMAssembler(const sp<Assembly>& assembly)
464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    :   ARMAssemblerInterface(),
474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        mAssembly(assembly)
484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mBase = mPC = (uint32_t *)assembly->base();
504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mDuration = ggl_system_time();
514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if defined(WITH_LIB_HARDWARE)
524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mQemuTracing = true;
534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source ProjectARMAssembler::~ARMAssembler()
574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectuint32_t* ARMAssembler::pc() const
614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return mPC;
634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectuint32_t* ARMAssembler::base() const
664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return mBase;
684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::reset()
714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mBase = mPC = (uint32_t *)mAssembly->base();
734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mBranchTargets.clear();
744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mLabels.clear();
754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mLabelsInverseMapping.clear();
764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mComments.clear();
774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindint ARMAssembler::getCodegenArch()
802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return CODEGEN_ARCH_ARM;
822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// ----------------------------------------------------------------------------
854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::disassemble(const char* name)
874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (name) {
894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        printf("%s:\n", name);
904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t count = pc()-base();
924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    uint32_t* i = base();
934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    while (count--) {
944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        ssize_t label = mLabelsInverseMapping.indexOfKey(i);
954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (label >= 0) {
964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            printf("%s:\n", mLabelsInverseMapping.valueAt(label));
974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        ssize_t comment = mComments.indexOfKey(i);
994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (comment >= 0) {
1004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            printf("; %s\n", mComments.valueAt(comment));
1014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
1024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        printf("%08x:    %08x    ", int(i), int(i[0]));
1034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        ::disassemble((u_int)i);
1044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        i++;
1054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::comment(const char* string)
1094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mComments.add(mPC, string);
1114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::label(const char* theLabel)
1144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mLabels.add(theLabel, mPC);
1164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mLabelsInverseMapping.add(mPC, theLabel);
1174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::B(int cc, const char* label)
1204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mBranchTargets.add(branch_target_t(label, mPC));
1224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (0xA<<24) | 0;
1234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::BL(int cc, const char* label)
1264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mBranchTargets.add(branch_target_t(label, mPC));
1284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (0xB<<24) | 0;
1294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
1324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark -
1334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark Prolog/Epilog & Generate...
1344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
1354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::prolog()
1384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    // write dummy prolog code
1404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mPrologPC = mPC;
1414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    STM(AL, FD, SP, 1, LSAVED);
1424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::epilog(uint32_t touched)
1454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    touched &= LSAVED;
1474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (touched) {
1484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // write prolog code
1494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        uint32_t* pc = mPC;
1504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        mPC = mPrologPC;
1514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        STM(AL, FD, SP, 1, touched | LLR);
1524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        mPC = pc;
1534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // write epilog code
1544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        LDM(AL, FD, SP, 1, touched | LLR);
1554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        BX(AL, LR);
1564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else {   // heh, no registers to save!
1574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // write prolog code
1584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        uint32_t* pc = mPC;
1594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        mPC = mPrologPC;
1604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        MOV(AL, 0, R0, R0); // NOP
1614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        mPC = pc;
1624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        // write epilog code
1634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        BX(AL, LR);
1644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint ARMAssembler::generate(const char* name)
1684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    // fixup all the branches
1704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    size_t count = mBranchTargets.size();
1714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    while (count--) {
1724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        const branch_target_t& bt = mBranchTargets[count];
1734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        uint32_t* target_pc = mLabels.valueFor(bt.label);
1744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        LOG_ALWAYS_FATAL_IF(!target_pc,
1754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                "error resolving branch targets, target_pc is null");
1764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int32_t offset = int32_t(target_pc - (bt.pc+2));
1774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        *bt.pc |= offset & 0xFFFFFF;
1784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    mAssembly->resize( int(pc()-base())*4 );
1814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    // the instruction cache is flushed by CodeCache
1834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const int64_t duration = ggl_system_time() - mDuration;
1844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const char * const format = "generated %s (%d ins) at [%p:%p] in %lld ns\n";
185fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block    ALOGI(format, name, int(pc()-base()), base(), pc(), duration);
1864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if defined(WITH_LIB_HARDWARE)
1884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (__builtin_expect(mQemuTracing, 0)) {
1894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int err = qemu_add_mapping(int(base()), name);
1904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        mQemuTracing = (err >= 0);
1914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
1934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
1954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    property_get("debug.pf.disasm", value, "0");
1964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (atoi(value) != 0) {
1974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        printf(format, name, int(pc()-base()), base(), pc(), duration);
1984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        disassemble(name);
1994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
2004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return NO_ERROR;
2024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectuint32_t* ARMAssembler::pcForLabel(const char* label)
2054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
2064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return mLabels.valueFor(label);
2074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// ----------------------------------------------------------------------------
2104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
2124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark -
2134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark Data Processing...
2144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
2154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::dataProcessing(int opcode, int cc,
2174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int s, int Rd, int Rn, uint32_t Op2)
2184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
2194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (opcode<<21) | (s<<20) | (Rn<<16) | (Rd<<12) | Op2;
2204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
2234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark -
2244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark Multiply...
2254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
2264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// multiply...
2284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::MLA(int cc, int s,
2294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int Rd, int Rm, int Rs, int Rn) {
2304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (Rd == Rm) { int t = Rm; Rm=Rs; Rs=t; }
2314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    LOG_FATAL_IF(Rd==Rm, "MLA(r%u,r%u,r%u,r%u)", Rd,Rm,Rs,Rn);
2324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ =    (cc<<28) | (1<<21) | (s<<20) |
2334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                (Rd<<16) | (Rn<<12) | (Rs<<8) | 0x90 | Rm;
2344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::MUL(int cc, int s,
2364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int Rd, int Rm, int Rs) {
2374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    if (Rd == Rm) { int t = Rm; Rm=Rs; Rs=t; }
2384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    LOG_FATAL_IF(Rd==Rm, "MUL(r%u,r%u,r%u)", Rd,Rm,Rs);
2394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (s<<20) | (Rd<<16) | (Rs<<8) | 0x90 | Rm;
2404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::UMULL(int cc, int s,
2424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int RdLo, int RdHi, int Rm, int Rs) {
2434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi,
2444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                        "UMULL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs);
2454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ =    (cc<<28) | (1<<23) | (s<<20) |
2464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm;
2474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::UMUAL(int cc, int s,
2494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int RdLo, int RdHi, int Rm, int Rs) {
2504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi,
2514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                        "UMUAL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs);
2524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ =    (cc<<28) | (1<<23) | (1<<21) | (s<<20) |
2534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm;
2544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SMULL(int cc, int s,
2564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int RdLo, int RdHi, int Rm, int Rs) {
2574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi,
2584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                        "SMULL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs);
2594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ =    (cc<<28) | (1<<23) | (1<<22) | (s<<20) |
2604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm;
2614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SMUAL(int cc, int s,
2634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int RdLo, int RdHi, int Rm, int Rs) {
2644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi,
2654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                        "SMUAL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs);
2664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ =    (cc<<28) | (1<<23) | (1<<22) | (1<<21) | (s<<20) |
2674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm;
2684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
2714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark -
2724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark Branches...
2734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
2744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// branches...
2764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::B(int cc, uint32_t* pc)
2774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
2784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int32_t offset = int32_t(pc - (mPC+2));
2794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (0xA<<24) | (offset & 0xFFFFFF);
2804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::BL(int cc, uint32_t* pc)
2834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
2844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    int32_t offset = int32_t(pc - (mPC+2));
2854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (0xB<<24) | (offset & 0xFFFFFF);
2864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::BX(int cc, int Rn)
2894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
2904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x12FFF10 | Rn;
2914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
2924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
2944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark -
2954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark Data Transfer...
2964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
2974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
2984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// data transfert...
2994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::LDR(int cc, int Rd, int Rn, uint32_t offset) {
3004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (1<<26) | (1<<20) | (Rn<<16) | (Rd<<12) | offset;
3014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::LDRB(int cc, int Rd, int Rn, uint32_t offset) {
3034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (1<<26) | (1<<22) | (1<<20) | (Rn<<16) | (Rd<<12) | offset;
3044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::STR(int cc, int Rd, int Rn, uint32_t offset) {
3064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (1<<26) | (Rn<<16) | (Rd<<12) | offset;
3074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::STRB(int cc, int Rd, int Rn, uint32_t offset) {
3094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (1<<26) | (1<<22) | (Rn<<16) | (Rd<<12) | offset;
3104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::LDRH(int cc, int Rd, int Rn, uint32_t offset) {
3134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (1<<20) | (Rn<<16) | (Rd<<12) | 0xB0 | offset;
3144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::LDRSB(int cc, int Rd, int Rn, uint32_t offset) {
3164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (1<<20) | (Rn<<16) | (Rd<<12) | 0xD0 | offset;
3174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::LDRSH(int cc, int Rd, int Rn, uint32_t offset) {
3194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (1<<20) | (Rn<<16) | (Rd<<12) | 0xF0 | offset;
3204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::STRH(int cc, int Rd, int Rn, uint32_t offset) {
3224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (Rn<<16) | (Rd<<12) | 0xB0 | offset;
3234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
3264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark -
3274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark Block Data Transfer...
3284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
3294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// block data transfer...
3314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::LDM(int cc, int dir,
3324f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int Rn, int W, uint32_t reg_list)
3334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{   //                    ED FD EA FA      IB IA DB DA
3344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const uint8_t P[8] = { 1, 0, 1, 0,      1, 0, 1, 0 };
3354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const uint8_t U[8] = { 1, 1, 0, 0,      1, 1, 0, 0 };
3364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (4<<25) | (uint32_t(P[dir])<<24) |
3374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            (uint32_t(U[dir])<<23) | (1<<20) | (W<<21) | (Rn<<16) | reg_list;
3384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3394f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3404f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::STM(int cc, int dir,
3414f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        int Rn, int W, uint32_t reg_list)
342a7e96642a9f91620b69716cc3198c6ebb4d0553cKan-Ru Chen{   //                    ED FD EA FA      IB IA DB DA
3434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const uint8_t P[8] = { 0, 1, 0, 1,      1, 0, 1, 0 };
3444f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    const uint8_t U[8] = { 0, 0, 1, 1,      1, 1, 0, 0 };
3454f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (4<<25) | (uint32_t(P[dir])<<24) |
3464f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            (uint32_t(U[dir])<<23) | (0<<20) | (W<<21) | (Rn<<16) | reg_list;
3474f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3484f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3494f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
3504f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark -
3514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark Special...
3524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
3534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// special...
3554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SWP(int cc, int Rn, int Rd, int Rm) {
3564f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (2<<23) | (Rn<<16) | (Rd << 12) | 0x90 | Rm;
3574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SWPB(int cc, int Rn, int Rd, int Rm) {
3594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (2<<23) | (1<<22) | (Rn<<16) | (Rd << 12) | 0x90 | Rm;
3604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SWI(int cc, uint32_t comment) {
3624f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | (0xF<<24) | comment;
3634f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3654f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#if 0
3664f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark -
3674f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#pragma mark DSP instructions...
3684f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#endif
3694f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project// DSP instructions...
3714f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::PLD(int Rn, uint32_t offset) {
3724f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    LOG_ALWAYS_FATAL_IF(!((offset&(1<<24)) && !(offset&(1<<21))),
3734f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                        "PLD only P=1, W=0");
3744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = 0xF550F000 | (Rn<<16) | offset;
3754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::CLZ(int cc, int Rd, int Rm)
3784f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
3794f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x16F0F10| (Rd<<12) | Rm;
3804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3824f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::QADD(int cc,  int Rd, int Rm, int Rn)
3834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
3844f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x1000050 | (Rn<<16) | (Rd<<12) | Rm;
3854f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3864f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3874f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::QDADD(int cc,  int Rd, int Rm, int Rn)
3884f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
3894f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x1400050 | (Rn<<16) | (Rd<<12) | Rm;
3904f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3914f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3924f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::QSUB(int cc,  int Rd, int Rm, int Rn)
3934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
3944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x1200050 | (Rn<<16) | (Rd<<12) | Rm;
3954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
3964f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
3974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::QDSUB(int cc,  int Rd, int Rm, int Rn)
3984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
3994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x1600050 | (Rn<<16) | (Rd<<12) | Rm;
4004f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
4014f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4024f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SMUL(int cc, int xy,
4034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                int Rd, int Rm, int Rs)
4044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
4054f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x1600080 | (Rd<<16) | (Rs<<8) | (xy<<4) | Rm;
4064f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
4074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4084f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SMULW(int cc, int y,
4094f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                int Rd, int Rm, int Rs)
4104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
4114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x12000A0 | (Rd<<16) | (Rs<<8) | (y<<4) | Rm;
4124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
4134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SMLA(int cc, int xy,
4154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                int Rd, int Rm, int Rs, int Rn)
4164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
4174f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x1000080 | (Rd<<16) | (Rn<<12) | (Rs<<8) | (xy<<4) | Rm;
4184f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
4194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SMLAL(int cc, int xy,
4214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                int RdHi, int RdLo, int Rs, int Rm)
4224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
4234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x1400080 | (RdHi<<16) | (RdLo<<12) | (Rs<<8) | (xy<<4) | Rm;
4244f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
4254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
4264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid ARMAssembler::SMLAW(int cc, int y,
4274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                int Rd, int Rm, int Rs, int Rn)
4284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
4294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    *mPC++ = (cc<<28) | 0x1200080 | (Rd<<16) | (Rn<<12) | (Rs<<8) | (y<<4) | Rm;
4304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
4314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
43296dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewell#if 0
43396dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewell#pragma mark -
43496dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewell#pragma mark Byte/half word extract and extend (ARMv6+ only)...
43596dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewell#endif
43696dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewell
43796dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewellvoid ARMAssembler::UXTB16(int cc, int Rd, int Rm, int rotate)
43896dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewell{
43996dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewell    *mPC++ = (cc<<28) | 0x6CF0070 | (Rd<<12) | ((rotate >> 3) << 10) | Rm;
44096dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewell}
4414dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell#if 0
4424dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell#pragma mark -
4434dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell#pragma mark Bit manipulation (ARMv7+ only)...
4444dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell#endif
4454dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell
4464dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell// Bit manipulation (ARMv7+ only)...
4474dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewellvoid ARMAssembler::UBFX(int cc, int Rd, int Rn, int lsb, int width)
4484dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell{
4494dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell    *mPC++ = (cc<<28) | 0x7E00000 | ((width-1)<<16) | (Rd<<12) | (lsb<<7) | 0x50 | Rn;
4504dc1fa8e8d1f14868ab8bba93a8cbb87f847c4e3Martyn Capewell}
45196dbb4fc58fe2dcf4390e073dbb42cc77ef2f0b5Martyn Capewell
4522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
4532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
4542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Addressing modes...
4552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
4562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindint ARMAssembler::buildImmediate(
4582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        uint32_t immediate, uint32_t& rot, uint32_t& imm)
4592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
4602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    rot = 0;
4612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    imm = immediate;
4622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (imm > 0x7F) { // skip the easy cases
4632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        while (!(imm&3)  || (imm&0xFC000000)) {
4642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            uint32_t newval;
4652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            newval = imm >> 2;
4662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            newval |= (imm&3) << 30;
4672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            imm = newval;
4682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            rot += 2;
4692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (rot == 32) {
4702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                rot = 0;
4712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                break;
4722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
4732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
4742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
4752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    rot = (16 - (rot>>1)) & 0xF;
4762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (imm>=0x100)
4782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        return -EINVAL;
4792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (((imm>>(rot<<1)) | (imm<<(32-(rot<<1)))) != immediate)
4812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        return -1;
4822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return 0;
4842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
4852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// shifters...
4872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindbool ARMAssembler::isValidImmediate(uint32_t immediate)
4892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
4902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    uint32_t rot, imm;
4912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return buildImmediate(immediate, rot, imm) == 0;
4922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
4932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::imm(uint32_t immediate)
4952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
4962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    uint32_t rot, imm;
4972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    int err = buildImmediate(immediate, rot, imm);
4982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(err==-EINVAL,
5002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "immediate %08x cannot be encoded",
5012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immediate);
5022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(err,
5042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "immediate (%08x) encoding bogus!",
5052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immediate);
5062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return (1<<25) | (rot<<8) | imm;
5082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::reg_imm(int Rm, int type, uint32_t shift)
5112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return ((shift&0x1F)<<7) | ((type&0x3)<<5) | (Rm&0xF);
5132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::reg_rrx(int Rm)
5162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return (ROR<<5) | (Rm&0xF);
5182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::reg_reg(int Rm, int type, int Rs)
5212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return ((Rs&0xF)<<8) | ((type&0x3)<<5) | (1<<4) | (Rm&0xF);
5232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// addressing modes...
5262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// LDR(B)/STR(B)/PLD (immediate and Rm can be negative, which indicate U=0)
5272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::immed12_pre(int32_t immed12, int W)
5282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800,
5302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "LDR(B)/STR(B)/PLD immediate too big (%08x)",
5312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immed12);
5322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return (1<<24) | (((uint32_t(immed12)>>31)^1)<<23) |
5332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            ((W&1)<<21) | (abs(immed12)&0x7FF);
5342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::immed12_post(int32_t immed12)
5372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800,
5392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "LDR(B)/STR(B)/PLD immediate too big (%08x)",
5402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immed12);
5412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return (((uint32_t(immed12)>>31)^1)<<23) | (abs(immed12)&0x7FF);
5432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::reg_scale_pre(int Rm, int type,
5462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        uint32_t shift, int W)
5472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return  (1<<25) | (1<<24) |
5492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) |
5502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            reg_imm(abs(Rm), type, shift);
5512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::reg_scale_post(int Rm, int type, uint32_t shift)
5542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return (1<<25) | (((uint32_t(Rm)>>31)^1)<<23) | reg_imm(abs(Rm), type, shift);
5562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// LDRH/LDRSB/LDRSH/STRH (immediate and Rm can be negative, which indicate U=0)
5592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::immed8_pre(int32_t immed8, int W)
5602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    uint32_t offset = abs(immed8);
5622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100,
5642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)",
5652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immed8);
5662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return  (1<<24) | (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) |
5682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            ((W&1)<<21) | (((offset&0xF0)<<4)|(offset&0xF));
5692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::immed8_post(int32_t immed8)
5722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    uint32_t offset = abs(immed8);
5742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100,
5762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)",
5772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immed8);
5782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) |
5802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            (((offset&0xF0)<<4) | (offset&0xF));
5812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::reg_pre(int Rm, int W)
5842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | (abs(Rm)&0xF);
5862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ARMAssembler::reg_post(int Rm)
5892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
5902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return (((uint32_t(Rm)>>31)^1)<<23) | (abs(Rm)&0xF);
5912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
5922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5934f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}; // namespace android
5944f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
595