12bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind/* libs/pixelflinger/codeflinger/MIPSAssembler.cpp
22bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
32bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** Copyright 2012, The Android Open Source Project
42bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
52bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** Licensed under the Apache License, Version 2.0 (the "License");
62bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** you may not use this file except in compliance with the License.
72bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** You may obtain a copy of the License at
82bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
92bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**     http://www.apache.org/licenses/LICENSE-2.0
102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** Unless required by applicable law or agreed to in writing, software
122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** distributed under the License is distributed on an "AS IS" BASIS,
132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** See the License for the specific language governing permissions and
152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** limitations under the License.
162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind*/
172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind/* MIPS assembler and ARM->MIPS assembly translator
202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** The approach is to leave the GGLAssembler and associated files largely
222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** un-changed, still utilizing all Arm instruction generation. Via the
232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** ArmToMipsAssembler (subclassed from ArmAssemblerInterface) each Arm
242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** instruction is translated to one or more Mips instructions as necessary. This
252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** is clearly less efficient than a direct implementation within the
262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** GGLAssembler, but is far cleaner, more maintainable, and has yielded very
272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** significant performance gains on Mips compared to the generic pixel pipeline.
282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** GGLAssembler changes
312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** - The register allocator has been modified to re-map Arm registers 0-15 to mips
332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** registers 2-17. Mips register 0 cannot be used as general-purpose register,
342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** and register 1 has traditional uses as a short-term temporary.
352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** - Added some early bailouts for OUT_OF_REGISTERS in texturing.cpp and
372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** GGLAssembler.cpp, since this is not fatal, and can be retried at lower
382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** optimization level.
392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** ARMAssembler and ARMAssemblerInterface changes
422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** Refactored ARM address-mode static functions (imm(), reg_imm(), imm12_pre(), etc.)
442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** to virtual, so they can be overridden in MIPSAssembler. The implementation of these
452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** functions on ARM is moved from ARMAssemblerInterface.cpp to ARMAssembler.cpp, and
462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** is unchanged from the original. (This required duplicating 2 of these as static
472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** functions in ARMAssemblerInterface.cpp so they could be used as static initializers).
482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind*/
492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#define LOG_TAG "MIPSAssembler"
522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#include <stdio.h>
542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#include <stdlib.h>
552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#include <cutils/log.h>
562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#include <cutils/properties.h>
572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if defined(WITH_LIB_HARDWARE)
592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#include <hardware_legacy/qemu_tracing.h>
602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#include <private/pixelflinger/ggl_context.h>
632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#include "codeflinger/MIPSAssembler.h"
652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#include "codeflinger/CodeCache.h"
662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#include "codeflinger/mips_disassem.h"
672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// Choose MIPS arch variant following gcc flags
692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if defined(__mips__) && __mips==32 && __mips_isa_rev>=2
702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#define mips32r2 1
712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#else
722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#define mips32r2 0
732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#define NOT_IMPLEMENTED()  LOG_ALWAYS_FATAL("Arm instruction %s not yet implemented\n", __func__)
772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// ----------------------------------------------------------------------------
812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindnamespace android {
832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// ----------------------------------------------------------------------------
852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark ArmToMipsAssembler...
882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul LindArmToMipsAssembler::ArmToMipsAssembler(const sp<Assembly>& assembly,
912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                                       char *abuf, int linesz, int instr_count)
922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    :   ARMAssemblerInterface(),
932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mArmDisassemblyBuffer(abuf),
942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mArmLineLength(linesz),
952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mArmInstrCount(instr_count),
962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mInum(0),
972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mAssembly(assembly)
982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips = new MIPSAssembler(assembly, this);
1002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC = (uint32_t **) malloc(ARM_MAX_INSTUCTIONS * sizeof(uint32_t *));
1012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    init_conditional_labels();
1022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul LindArmToMipsAssembler::~ArmToMipsAssembler()
1052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    delete mMips;
1072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    free((void *) mArmPC);
1082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t* ArmToMipsAssembler::pc() const
1112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return mMips->pc();
1132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t* ArmToMipsAssembler::base() const
1162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return mMips->base();
1182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::reset()
1212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    cond.labelnum = 0;
1232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mInum = 0;
1242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->reset();
1252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindint ArmToMipsAssembler::getCodegenArch()
1282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return CODEGEN_ARCH_MIPS;
1302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::comment(const char* string)
1332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->comment(string);
1352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::label(const char* theLabel)
1382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->label(theLabel);
1402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::disassemble(const char* name)
1432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->disassemble(name);
1452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::init_conditional_labels()
1482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    int i;
1502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    for (i=0;i<99; ++i) {
1512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        sprintf(cond.label[i], "cond_%d", i);
1522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
1532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
1582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
1592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Prolog/Epilog & Generate...
1602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
1612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::prolog()
1632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();  // save starting PC for this instr
1652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->ADDIU(R_sp, R_sp, -(5 * 4));
1672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->SW(R_s0, R_sp, 0);
1682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->SW(R_s1, R_sp, 4);
1692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->SW(R_s2, R_sp, 8);
1702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->SW(R_s3, R_sp, 12);
1712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->SW(R_s4, R_sp, 16);
1722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MOVE(R_v0, R_a0);    // move context * passed in a0 to v0 (arm r0)
1732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::epilog(uint32_t touched)
1762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();  // save starting PC for this instr
1782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->LW(R_s0, R_sp, 0);
1802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->LW(R_s1, R_sp, 4);
1812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->LW(R_s2, R_sp, 8);
1822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->LW(R_s3, R_sp, 12);
1832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->LW(R_s4, R_sp, 16);
1842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->ADDIU(R_sp, R_sp, (5 * 4));
1852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->JR(R_ra);
1862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindint ArmToMipsAssembler::generate(const char* name)
1902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return mMips->generate(name);
1922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t* ArmToMipsAssembler::pcForLabel(const char* label)
1952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
1962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return mMips->pcForLabel(label);
1972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
1982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind//----------------------------------------------------------
2022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
2042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
2052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Addressing modes & shifters...
2062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
2072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// do not need this for MIPS, but it is in the Interface (virtual)
2102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindint ArmToMipsAssembler::buildImmediate(
2112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        uint32_t immediate, uint32_t& rot, uint32_t& imm)
2122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // for MIPS, any 32-bit immediate is OK
2142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    rot = 0;
2152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    imm = immediate;
2162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return 0;
2172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// shifters...
2202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindbool ArmToMipsAssembler::isValidImmediate(uint32_t immediate)
2222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // for MIPS, any 32-bit immediate is OK
2242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return true;
2252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::imm(uint32_t immediate)
2282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // ALOGW("immediate value %08x at pc %08x\n", immediate, (int)pc());
2302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.value = immediate;
2312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_IMM;
2322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::reg_imm(int Rm, int type, uint32_t shift)
2352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.reg = Rm;
2372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.stype = type;
2382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.value = shift;
2392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_REG_IMM;
2402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::reg_rrx(int Rm)
2432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // reg_rrx mode is not used in the GLLAssember code at this time
2452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_UNSUPPORTED;
2462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::reg_reg(int Rm, int type, int Rs)
2492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // reg_reg mode is not used in the GLLAssember code at this time
2512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_UNSUPPORTED;
2522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// addressing modes...
2562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// LDR(B)/STR(B)/PLD (immediate and Rm can be negative, which indicate U=0)
2572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::immed12_pre(int32_t immed12, int W)
2582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800,
2602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "LDR(B)/STR(B)/PLD immediate too big (%08x)",
2612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immed12);
2622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.value = immed12;
2632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.writeback = W;
2642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_IMM_12_PRE;
2652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::immed12_post(int32_t immed12)
2682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800,
2702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "LDR(B)/STR(B)/PLD immediate too big (%08x)",
2712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immed12);
2722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.value = immed12;
2742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_IMM_12_POST;
2752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::reg_scale_pre(int Rm, int type,
2782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        uint32_t shift, int W)
2792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(W | type | shift, "reg_scale_pre adv modes not yet implemented");
2812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.reg = Rm;
2832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // amode.stype = type;      // more advanced modes not used in GGLAssembler yet
2842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // amode.value = shift;
2852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // amode.writeback = W;
2862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_REG_SCALE_PRE;
2872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::reg_scale_post(int Rm, int type, uint32_t shift)
2902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL("adr mode reg_scale_post not yet implemented\n");
2922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_UNSUPPORTED;
2932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
2942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
2952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// LDRH/LDRSB/LDRSH/STRH (immediate and Rm can be negative, which indicate U=0)
2962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::immed8_pre(int32_t immed8, int W)
2972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
2982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // uint32_t offset = abs(immed8);
2992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL("adr mode immed8_pre not yet implemented\n");
3012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100,
3032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)",
3042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immed8);
3052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_IMM_8_PRE;
3062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
3072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::immed8_post(int32_t immed8)
3092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
3102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // uint32_t offset = abs(immed8);
3112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100,
3132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)",
3142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        immed8);
3152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.value = immed8;
3162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_IMM_8_POST;
3172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
3182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::reg_pre(int Rm, int W)
3202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
3212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(W, "reg_pre writeback not yet implemented");
3222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    amode.reg = Rm;
3232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_REG_PRE;
3242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
3252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t ArmToMipsAssembler::reg_post(int Rm)
3272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
3282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL("adr mode reg_post not yet implemented\n");
3292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return AMODE_UNSUPPORTED;
3302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
3312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// ----------------------------------------------------------------------------
3352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
3372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
3382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Data Processing...
3392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
3402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindstatic const char * const dpOpNames[] = {
3432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    "AND", "EOR", "SUB", "RSB", "ADD", "ADC", "SBC", "RSC",
3442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    "TST", "TEQ", "CMP", "CMN", "ORR", "MOV", "BIC", "MVN"
3452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind};
3462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// check if the operand registers from a previous CMP or S-bit instruction
3482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// would be overwritten by this instruction. If so, move the value to a
3492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// safe register.
3502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// Note that we cannot tell at _this_ instruction time if a future (conditional)
3512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// instruction will _also_ use this value (a defect of the simple 1-pass, one-
3522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// instruction-at-a-time translation). Therefore we must be conservative and
3532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// save the value before it is overwritten. This costs an extra MOVE instr.
3542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::protectConditionalOperands(int Rd)
3562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
3572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (Rd == cond.r1) {
3582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->MOVE(R_cmp, cond.r1);
3592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r1 = R_cmp;
3602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
3612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (cond.type == CMP_COND && Rd == cond.r2) {
3622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->MOVE(R_cmp2, cond.r2);
3632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r2 = R_cmp2;
3642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
3652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
3662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
3682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// interprets the addressing mode, and generates the common code
3692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// used by the majority of data-processing ops. Many MIPS instructions
3702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// have a register-based form and a different immediate form. See
3712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// opAND below for an example. (this could be inlined)
3722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind//
3732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// this works with the imm(), reg_imm() methods above, which are directly
3742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// called by the GLLAssembler.
3752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// note: _signed parameter defaults to false (un-signed)
3762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// note: tmpReg parameter defaults to 1, MIPS register AT
3772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindint ArmToMipsAssembler::dataProcAdrModes(int op, int& source, bool _signed, int tmpReg)
3782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
3792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (op < AMODE_REG) {
3802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        source = op;
3812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        return SRC_REG;
3822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    } else if (op == AMODE_IMM) {
3832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if ((!_signed && amode.value > 0xffff)
3842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                || (_signed && ((int)amode.value < -32768 || (int)amode.value > 32767) )) {
3852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LUI(tmpReg, (amode.value >> 16));
3862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (amode.value & 0x0000ffff) {
3872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->ORI(tmpReg, tmpReg, (amode.value & 0x0000ffff));
3882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
3892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            source = tmpReg;
3902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            return SRC_REG;
3912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {
3922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            source = amode.value;
3932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            return SRC_IMM;
3942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
3952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    } else if (op == AMODE_REG_IMM) {
3962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        switch (amode.stype) {
3972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case LSL: mMips->SLL(tmpReg, amode.reg, amode.value); break;
3982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case LSR: mMips->SRL(tmpReg, amode.reg, amode.value); break;
3992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case ASR: mMips->SRA(tmpReg, amode.reg, amode.value); break;
4002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case ROR: if (mips32r2) {
4012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                          mMips->ROTR(tmpReg, amode.reg, amode.value);
4022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                      } else {
4032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                          mMips->RORIsyn(tmpReg, amode.reg, amode.value);
4042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                      }
4052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                      break;
4062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
4072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        source = tmpReg;
4082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        return SRC_REG;
4092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    } else {  // adr mode RRX is not used in GGL Assembler at this time
4102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // we are screwed, this should be exception, assert-fail or something
4112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        LOG_ALWAYS_FATAL("adr mode reg_rrx not yet implemented\n");
4122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        return SRC_ERROR;
4132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
4142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
4152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::dataProcessing(int opcode, int cc,
4182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int s, int Rd, int Rn, uint32_t Op2)
4192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
4202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    int src;    // src is modified by dataProcAdrModes() - passed as int&
4212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (cc != AL) {
4242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        protectConditionalOperands(Rd);
4252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // the branch tests register(s) set by prev CMP or instr with 'S' bit set
4262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // inverse the condition to jump past this conditional instruction
4272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        ArmToMipsAssembler::B(cc^1, cond.label[++cond.labelnum]);
4282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    } else {
4292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mArmPC[mInum++] = pc();  // save starting PC for this instr
4302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
4312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    switch (opcode) {
4332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opAND:
4342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (dataProcAdrModes(Op2, src) == SRC_REG) {
4352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->AND(Rd, Rn, src);
4362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {                        // adr mode was SRC_IMM
4372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ANDI(Rd, Rn, src);
4382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
4392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
4402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opADD:
4422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // set "signed" to true for adr modes
4432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (dataProcAdrModes(Op2, src, true) == SRC_REG) {
4442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDU(Rd, Rn, src);
4452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {                        // adr mode was SRC_IMM
4462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDIU(Rd, Rn, src);
4472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
4482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
4492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opSUB:
4512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // set "signed" to true for adr modes
4522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (dataProcAdrModes(Op2, src, true) == SRC_REG) {
4532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SUBU(Rd, Rn, src);
4542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {                        // adr mode was SRC_IMM
4552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SUBIU(Rd, Rn, src);
4562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
4572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
4582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opEOR:
4602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (dataProcAdrModes(Op2, src) == SRC_REG) {
4612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->XOR(Rd, Rn, src);
4622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {                        // adr mode was SRC_IMM
4632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->XORI(Rd, Rn, src);
4642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
4652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
4662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opORR:
4682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (dataProcAdrModes(Op2, src) == SRC_REG) {
4692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->OR(Rd, Rn, src);
4702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {                        // adr mode was SRC_IMM
4712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ORI(Rd, Rn, src);
4722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
4732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
4742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opBIC:
4762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (dataProcAdrModes(Op2, src) == SRC_IMM) {
4772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // if we are 16-bit imnmediate, load to AT reg
4782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ORI(R_at, 0, src);
4792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            src = R_at;
4802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
4812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->NOT(R_at, src);
4822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->AND(Rd, Rn, R_at);
4832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
4842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opRSB:
4862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (dataProcAdrModes(Op2, src) == SRC_IMM) {
4872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // if we are 16-bit imnmediate, load to AT reg
4882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ORI(R_at, 0, src);
4892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            src = R_at;
4902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
4912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->SUBU(Rd, src, Rn);   // subu with the parameters reversed
4922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
4932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
4942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opMOV:
4952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (Op2 < AMODE_REG) {  // op2 is reg # in this case
4962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->MOVE(Rd, Op2);
4972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else if (Op2 == AMODE_IMM) {
4982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (amode.value > 0xffff) {
4992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->LUI(Rd, (amode.value >> 16));
5002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                if (amode.value & 0x0000ffff) {
5012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                    mMips->ORI(Rd, Rd, (amode.value & 0x0000ffff));
5022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                }
5032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind             } else {
5042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->ORI(Rd, 0, amode.value);
5052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
5062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else if (Op2 == AMODE_REG_IMM) {
5072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            switch (amode.stype) {
5082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case LSL: mMips->SLL(Rd, amode.reg, amode.value); break;
5092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case LSR: mMips->SRL(Rd, amode.reg, amode.value); break;
5102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case ASR: mMips->SRA(Rd, amode.reg, amode.value); break;
5112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case ROR: if (mips32r2) {
5122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                          mMips->ROTR(Rd, amode.reg, amode.value);
5132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                      } else {
5142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                          mMips->RORIsyn(Rd, amode.reg, amode.value);
5152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                      }
5162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                      break;
5172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
5182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
5192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        else {
5202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // adr mode RRX is not used in GGL Assembler at this time
5212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->UNIMPL();
5222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
5232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
5242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opMVN:     // this is a 1's complement: NOT
5262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (Op2 < AMODE_REG) {  // op2 is reg # in this case
5272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->NOR(Rd, Op2, 0);     // NOT is NOR with 0
5282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
5292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else if (Op2 == AMODE_IMM) {
5302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (amode.value > 0xffff) {
5312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->LUI(Rd, (amode.value >> 16));
5322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                if (amode.value & 0x0000ffff) {
5332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                    mMips->ORI(Rd, Rd, (amode.value & 0x0000ffff));
5342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                }
5352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind             } else {
5362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->ORI(Rd, 0, amode.value);
5372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind             }
5382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else if (Op2 == AMODE_REG_IMM) {
5392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            switch (amode.stype) {
5402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case LSL: mMips->SLL(Rd, amode.reg, amode.value); break;
5412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case LSR: mMips->SRL(Rd, amode.reg, amode.value); break;
5422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case ASR: mMips->SRA(Rd, amode.reg, amode.value); break;
5432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            case ROR: if (mips32r2) {
5442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                          mMips->ROTR(Rd, amode.reg, amode.value);
5452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                      } else {
5462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                          mMips->RORIsyn(Rd, amode.reg, amode.value);
5472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                      }
5482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                      break;
5492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
5502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
5512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        else {
5522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // adr mode RRX is not used in GGL Assembler at this time
5532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->UNIMPL();
5542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
5552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->NOR(Rd, Rd, 0);     // NOT is NOR with 0
5562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
5572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opCMP:
5592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // Either operand of a CMP instr could get overwritten by a subsequent
5602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // conditional instruction, which is ok, _UNLESS_ there is a _second_
5612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // conditional instruction. Under MIPS, this requires doing the comparison
5622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // again (SLT), and the original operands must be available. (and this
5632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // pattern of multiple conditional instructions from same CMP _is_ used
5642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // in GGL-Assembler)
5652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        //
5662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // For now, if a conditional instr overwrites the operands, we will
5672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // move them to dedicated temp regs. This is ugly, and inefficient,
5682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // and should be optimized.
5692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        //
5702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // WARNING: making an _Assumption_ that CMP operand regs will NOT be
5712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // trashed by intervening NON-conditional instructions. In the general
5722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // case this is legal, but it is NOT currently done in GGL-Assembler.
5732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.type = CMP_COND;
5752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r1 = Rn;
5762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (dataProcAdrModes(Op2, src, false, R_cmp2) == SRC_REG) {
5772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            cond.r2 = src;
5782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {                        // adr mode was SRC_IMM
5792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ORI(R_cmp2, R_zero, src);
5802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            cond.r2 = R_cmp2;
5812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
5822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
5842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opTST:
5872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opTEQ:
5882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opCMN:
5892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opADC:
5902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opSBC:
5912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    case opRSC:
5922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->UNIMPL(); // currently unused in GGL Assembler code
5932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        break;
5942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
5952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
5962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (cc != AL) {
5972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->label(cond.label[cond.labelnum]);
5982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
5992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (s && opcode != opCMP) {
6002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.type = SBIT_COND;
6012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r1 = Rd;
6022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
6032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
6042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
6082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
6092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Multiply...
6102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
6112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// multiply, accumulate
6132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::MLA(int cc, int s,
6142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int Rd, int Rm, int Rs, int Rn) {
6152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();  // save starting PC for this instr
6172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MUL(R_at, Rm, Rs);
6192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->ADDU(Rd, R_at, Rn);
6202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (s) {
6212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.type = SBIT_COND;
6222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r1 = Rd;
6232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
6242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
6252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::MUL(int cc, int s,
6272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int Rd, int Rm, int Rs) {
6282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
6292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MUL(Rd, Rm, Rs);
6302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (s) {
6312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.type = SBIT_COND;
6322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r1 = Rd;
6332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
6342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
6352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::UMULL(int cc, int s,
6372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int RdLo, int RdHi, int Rm, int Rs) {
6382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
6392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MULT(Rm, Rs);
6402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MFHI(RdHi);
6412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MFLO(RdLo);
6422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (s) {
6432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.type = SBIT_COND;
6442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r1 = RdHi;     // BUG...
6452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        LOG_ALWAYS_FATAL("Condition on UMULL must be on 64-bit result\n");
6462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
6472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
6482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::UMUAL(int cc, int s,
6502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int RdLo, int RdHi, int Rm, int Rs) {
6512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi,
6522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "UMUAL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs);
6532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ =    (cc<<28) | (1<<23) | (1<<21) | (s<<20) |
6542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    //             (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm;
6552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
6562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
6572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
6582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (s) {
6592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.type = SBIT_COND;
6602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r1 = RdHi;     // BUG...
6612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        LOG_ALWAYS_FATAL("Condition on UMULL must be on 64-bit result\n");
6622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
6632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
6642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SMULL(int cc, int s,
6662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int RdLo, int RdHi, int Rm, int Rs) {
6672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi,
6682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "SMULL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs);
6692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ =    (cc<<28) | (1<<23) | (1<<22) | (s<<20) |
6702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    //             (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm;
6712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
6722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
6732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
6742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (s) {
6752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.type = SBIT_COND;
6762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r1 = RdHi;     // BUG...
6772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        LOG_ALWAYS_FATAL("Condition on SMULL must be on 64-bit result\n");
6782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
6792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
6802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SMUAL(int cc, int s,
6812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int RdLo, int RdHi, int Rm, int Rs) {
6822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi,
6832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "SMUAL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs);
6842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ =    (cc<<28) | (1<<23) | (1<<22) | (1<<21) | (s<<20) |
6852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    //             (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm;
6862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
6872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
6882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
6892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (s) {
6902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.type = SBIT_COND;
6912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        cond.r1 = RdHi;     // BUG...
6922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        LOG_ALWAYS_FATAL("Condition on SMUAL must be on 64-bit result\n");
6932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
6942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
6952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
6982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
6992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
7002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Branches...
7012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
7022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// branches...
7042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::B(int cc, const char* label)
7062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
7072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
7082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (cond.type == SBIT_COND) { cond.r2 = R_zero; }
7092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    switch(cc) {
7112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case EQ: mMips->BEQ(cond.r1, cond.r2, label); break;
7122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case NE: mMips->BNE(cond.r1, cond.r2, label); break;
7132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case HS: mMips->BGEU(cond.r1, cond.r2, label); break;
7142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case LO: mMips->BLTU(cond.r1, cond.r2, label); break;
7152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case MI: mMips->BLT(cond.r1, cond.r2, label); break;
7162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case PL: mMips->BGE(cond.r1, cond.r2, label); break;
7172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case HI: mMips->BGTU(cond.r1, cond.r2, label); break;
7192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case LS: mMips->BLEU(cond.r1, cond.r2, label); break;
7202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case GE: mMips->BGE(cond.r1, cond.r2, label); break;
7212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case LT: mMips->BLT(cond.r1, cond.r2, label); break;
7222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case GT: mMips->BGT(cond.r1, cond.r2, label); break;
7232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case LE: mMips->BLE(cond.r1, cond.r2, label); break;
7242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AL: mMips->B(label); break;
7252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case NV: /* B Never - no instruction */ break;
7262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case VS:
7282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case VC:
7292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        default:
7302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            LOG_ALWAYS_FATAL("Unsupported cc: %02x\n", cc);
7312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
7322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
7332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
7342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::BL(int cc, const char* label)
7362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
7372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL("branch-and-link not supported yet\n");
7382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
7392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
7402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// no use for Branches with integer PC, but they're in the Interface class ....
7422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::B(int cc, uint32_t* to_pc)
7432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
7442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL("branch to absolute PC not supported, use Label\n");
7452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
7462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
7472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::BL(int cc, uint32_t* to_pc)
7492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
7502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL("branch to absolute PC not supported, use Label\n");
7512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
7522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
7532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::BX(int cc, int Rn)
7552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
7562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL("branch to absolute PC not supported, use Label\n");
7572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
7582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
7592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
7632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
7642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Data Transfer...
7652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
7662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
7672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// data transfer...
7682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::LDR(int cc, int Rd, int Rn, uint32_t offset)
7692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
7702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
7712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // work-around for ARM default address mode of immed12_pre(0)
7722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (offset > AMODE_UNSUPPORTED) offset = 0;
7732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    switch (offset) {
7742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case 0:
7752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.value = 0;
7762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.writeback = 0;
7772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // fall thru to next case ....
7782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_12_PRE:
7792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (Rn == ARMAssemblerInterface::SP) {
7802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                Rn = R_sp;      // convert LDR via Arm SP to LW via Mips SP
7812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
7822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LW(Rd, Rn, amode.value);
7832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (amode.writeback) {      // OPTIONAL writeback on pre-index mode
7842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->ADDIU(Rn, Rn, amode.value);
7852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
7862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
7872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_12_POST:
7882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (Rn == ARMAssemblerInterface::SP) {
7892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                Rn = R_sp;      // convert STR thru Arm SP to STR thru Mips SP
7902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
7912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LW(Rd, Rn, 0);
7922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDIU(Rn, Rn, amode.value);
7932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
7942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_REG_SCALE_PRE:
7952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // we only support simple base + index, no advanced modes for this one yet
7962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDU(R_at, Rn, amode.reg);
7972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LW(Rd, R_at, 0);
7982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
7992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
8002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
8012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
8022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::LDRB(int cc, int Rd, int Rn, uint32_t offset)
8032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
8042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
8052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // work-around for ARM default address mode of immed12_pre(0)
8062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (offset > AMODE_UNSUPPORTED) offset = 0;
8072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    switch (offset) {
8082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case 0:
8092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.value = 0;
8102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.writeback = 0;
8112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // fall thru to next case ....
8122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_12_PRE:
8132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LBU(Rd, Rn, amode.value);
8142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (amode.writeback) {      // OPTIONAL writeback on pre-index mode
8152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->ADDIU(Rn, Rn, amode.value);
8162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
8172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
8182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_12_POST:
8192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LBU(Rd, Rn, 0);
8202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDIU(Rn, Rn, amode.value);
8212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
8222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_REG_SCALE_PRE:
8232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // we only support simple base + index, no advanced modes for this one yet
8242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDU(R_at, Rn, amode.reg);
8252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LBU(Rd, R_at, 0);
8262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
8272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
8282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
8292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
8302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
8312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::STR(int cc, int Rd, int Rn, uint32_t offset)
8322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
8332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
8342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // work-around for ARM default address mode of immed12_pre(0)
8352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (offset > AMODE_UNSUPPORTED) offset = 0;
8362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    switch (offset) {
8372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case 0:
8382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.value = 0;
8392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.writeback = 0;
8402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // fall thru to next case ....
8412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_12_PRE:
8422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (Rn == ARMAssemblerInterface::SP) {
8432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                Rn = R_sp;  // convert STR thru Arm SP to SW thru Mips SP
8442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
8452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (amode.writeback) {      // OPTIONAL writeback on pre-index mode
8462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                // If we will writeback, then update the index reg, then store.
8472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                // This correctly handles stack-push case.
8482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->ADDIU(Rn, Rn, amode.value);
8492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->SW(Rd, Rn, 0);
8502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            } else {
8512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                // No writeback so store offset by value
8522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->SW(Rd, Rn, amode.value);
8532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
8542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
8552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_12_POST:
8562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SW(Rd, Rn, 0);
8572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDIU(Rn, Rn, amode.value);  // post index always writes back
8582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
8592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_REG_SCALE_PRE:
8602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // we only support simple base + index, no advanced modes for this one yet
8612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDU(R_at, Rn, amode.reg);
8622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SW(Rd, R_at, 0);
8632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
8642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
8652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
8662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
8672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::STRB(int cc, int Rd, int Rn, uint32_t offset)
8682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
8692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
8702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // work-around for ARM default address mode of immed12_pre(0)
8712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (offset > AMODE_UNSUPPORTED) offset = 0;
8722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    switch (offset) {
8732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case 0:
8742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.value = 0;
8752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.writeback = 0;
8762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // fall thru to next case ....
8772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_12_PRE:
8782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SB(Rd, Rn, amode.value);
8792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (amode.writeback) {      // OPTIONAL writeback on pre-index mode
8802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->ADDIU(Rn, Rn, amode.value);
8812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
8822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
8832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_12_POST:
8842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SB(Rd, Rn, 0);
8852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDIU(Rn, Rn, amode.value);
8862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
8872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_REG_SCALE_PRE:
8882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // we only support simple base + index, no advanced modes for this one yet
8892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDU(R_at, Rn, amode.reg);
8902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SB(Rd, R_at, 0);
8912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
8922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
8932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
8942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
8952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::LDRH(int cc, int Rd, int Rn, uint32_t offset)
8962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
8972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
8982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // work-around for ARM default address mode of immed8_pre(0)
8992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (offset > AMODE_UNSUPPORTED) offset = 0;
9002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    switch (offset) {
9012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case 0:
9022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.value = 0;
9032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // fall thru to next case ....
9042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_8_PRE:      // no support yet for writeback
9052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LHU(Rd, Rn, amode.value);
9062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
9072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_8_POST:
9082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LHU(Rd, Rn, 0);
9092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDIU(Rn, Rn, amode.value);
9102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
9112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_REG_PRE:
9122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // we only support simple base +/- index
9132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (amode.reg >= 0) {
9142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->ADDU(R_at, Rn, amode.reg);
9152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            } else {
9162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->SUBU(R_at, Rn, abs(amode.reg));
9172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
9182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->LHU(Rd, R_at, 0);
9192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
9202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
9212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
9222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::LDRSB(int cc, int Rd, int Rn, uint32_t offset)
9242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
9252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
9262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
9272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
9282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
9292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::LDRSH(int cc, int Rd, int Rn, uint32_t offset)
9312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
9322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
9332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
9342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
9352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
9362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::STRH(int cc, int Rd, int Rn, uint32_t offset)
9382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
9392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
9402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // work-around for ARM default address mode of immed8_pre(0)
9412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (offset > AMODE_UNSUPPORTED) offset = 0;
9422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    switch (offset) {
9432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case 0:
9442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            amode.value = 0;
9452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // fall thru to next case ....
9462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_8_PRE:      // no support yet for writeback
9472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SH(Rd, Rn, amode.value);
9482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
9492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_IMM_8_POST:
9502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SH(Rd, Rn, 0);
9512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->ADDIU(Rn, Rn, amode.value);
9522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
9532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        case AMODE_REG_PRE:
9542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            // we only support simple base +/- index
9552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            if (amode.reg >= 0) {
9562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->ADDU(R_at, Rn, amode.reg);
9572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            } else {
9582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                mMips->SUBU(R_at, Rn, abs(amode.reg));
9592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            }
9602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SH(Rd, R_at, 0);
9612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            break;
9622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
9632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
9642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
9682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
9692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Block Data Transfer...
9702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
9712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// block data transfer...
9732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::LDM(int cc, int dir,
9742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int Rn, int W, uint32_t reg_list)
9752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{   //                        ED FD EA FA      IB IA DB DA
9762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // const uint8_t P[8] = { 1, 0, 1, 0,      1, 0, 1, 0 };
9772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // const uint8_t U[8] = { 1, 1, 0, 0,      1, 1, 0, 0 };
9782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | (4<<25) | (uint32_t(P[dir])<<24) |
9792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    //         (uint32_t(U[dir])<<23) | (1<<20) | (W<<21) | (Rn<<16) | reg_list;
9802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
9812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
9822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
9832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
9842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::STM(int cc, int dir,
9862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int Rn, int W, uint32_t reg_list)
9872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{   //                        FA EA FD ED      IB IA DB DA
9882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // const uint8_t P[8] = { 0, 1, 0, 1,      1, 0, 1, 0 };
9892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // const uint8_t U[8] = { 0, 0, 1, 1,      1, 1, 0, 0 };
9902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | (4<<25) | (uint32_t(P[dir])<<24) |
9912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    //         (uint32_t(U[dir])<<23) | (0<<20) | (W<<21) | (Rn<<16) | reg_list;
9922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
9932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
9942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
9952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
9962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
9992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
10002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
10012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Special...
10022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
10032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// special...
10052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SWP(int cc, int Rn, int Rd, int Rm) {
10062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | (2<<23) | (Rn<<16) | (Rd << 12) | 0x90 | Rm;
10072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
10092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
10102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
10112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SWPB(int cc, int Rn, int Rd, int Rm) {
10132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | (2<<23) | (1<<22) | (Rn<<16) | (Rd << 12) | 0x90 | Rm;
10142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
10162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
10172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
10182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SWI(int cc, uint32_t comment) {
10202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | (0xF<<24) | comment;
10212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
10232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
10242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
10252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
10282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
10292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark DSP instructions...
10302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
10312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// DSP instructions...
10332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::PLD(int Rn, uint32_t offset) {
10342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    LOG_ALWAYS_FATAL_IF(!((offset&(1<<24)) && !(offset&(1<<21))),
10352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        "PLD only P=1, W=0");
10362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = 0xF550F000 | (Rn<<16) | offset;
10372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
10392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
10402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
10412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::CLZ(int cc, int Rd, int Rm)
10432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
10442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->CLZ(Rd, Rm);
10462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
10472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::QADD(int cc,  int Rd, int Rm, int Rn)
10492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
10502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | 0x1000050 | (Rn<<16) | (Rd<<12) | Rm;
10512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
10532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
10542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
10552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::QDADD(int cc,  int Rd, int Rm, int Rn)
10572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
10582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | 0x1400050 | (Rn<<16) | (Rd<<12) | Rm;
10592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
10612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
10622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
10632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::QSUB(int cc,  int Rd, int Rm, int Rn)
10652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
10662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | 0x1200050 | (Rn<<16) | (Rd<<12) | Rm;
10672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
10692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
10702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
10712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::QDSUB(int cc,  int Rd, int Rm, int Rn)
10732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
10742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | 0x1600050 | (Rn<<16) | (Rd<<12) | Rm;
10752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
10772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
10782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
10792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// 16 x 16 signed multiply (like SMLAxx without the accumulate)
10812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SMUL(int cc, int xy,
10822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                int Rd, int Rm, int Rs)
10832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
10842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
10852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // the 16 bits may be in the top or bottom half of 32-bit source reg,
10872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // as defined by the codes BB, BT, TB, TT (compressed param xy)
10882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // where x corresponds to Rm and y to Rs
10892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
10902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // select half-reg for Rm
10912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (xy & xyTB) {
10922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // use top 16-bits
10932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->SRA(R_at, Rm, 16);
10942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    } else {
10952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // use bottom 16, but sign-extend to 32
10962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (mips32r2) {
10972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SEH(R_at, Rm);
10982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {
10992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SLL(R_at, Rm, 16);
11002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SRA(R_at, R_at, 16);
11012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
11022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
11032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // select half-reg for Rs
11042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (xy & xyBT) {
11052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // use top 16-bits
11062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->SRA(R_at2, Rs, 16);
11072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    } else {
11082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // use bottom 16, but sign-extend to 32
11092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (mips32r2) {
11102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SEH(R_at2, Rs);
11112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {
11122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SLL(R_at2, Rs, 16);
11132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SRA(R_at2, R_at2, 16);
11142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
11152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
11162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MUL(Rd, R_at, R_at2);
11172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
11182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// signed 32b x 16b multiple, save top 32-bits of 48-bit result
11202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SMULW(int cc, int y,
11212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                int Rd, int Rm, int Rs)
11222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
11232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
11242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // the selector yT or yB refers to reg Rs
11262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (y & yT) {
11272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // zero the bottom 16-bits, with 2 shifts, it can affect result
11282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->SRL(R_at, Rs, 16);
11292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->SLL(R_at, R_at, 16);
11302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    } else {
11322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // move low 16-bit half, to high half
11332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->SLL(R_at, Rs, 16);
11342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
11352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MULT(Rm, R_at);
11362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MFHI(Rd);
11372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
11382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// 16 x 16 signed multiply, accumulate: Rd = Rm{16} * Rs{16} + Rn
11402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SMLA(int cc, int xy,
11412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                int Rd, int Rm, int Rs, int Rn)
11422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
11432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
11442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // the 16 bits may be in the top or bottom half of 32-bit source reg,
11462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // as defined by the codes BB, BT, TB, TT (compressed param xy)
11472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // where x corresponds to Rm and y to Rs
11482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // select half-reg for Rm
11502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (xy & xyTB) {
11512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // use top 16-bits
11522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->SRA(R_at, Rm, 16);
11532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    } else {
11542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // use bottom 16, but sign-extend to 32
11552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (mips32r2) {
11562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SEH(R_at, Rm);
11572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {
11582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SLL(R_at, Rm, 16);
11592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SRA(R_at, R_at, 16);
11602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
11612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
11622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // select half-reg for Rs
11632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (xy & xyBT) {
11642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // use top 16-bits
11652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mMips->SRA(R_at2, Rs, 16);
11662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    } else {
11672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // use bottom 16, but sign-extend to 32
11682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (mips32r2) {
11692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SEH(R_at2, Rs);
11702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {
11712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SLL(R_at2, Rs, 16);
11722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            mMips->SRA(R_at2, R_at2, 16);
11732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
11742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
11752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->MUL(R_at, R_at, R_at2);
11772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->ADDU(Rd, R_at, Rn);
11782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
11792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SMLAL(int cc, int xy,
11812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                int RdHi, int RdLo, int Rs, int Rm)
11822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
11832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | 0x1400080 | (RdHi<<16) | (RdLo<<12) | (Rs<<8) | (xy<<4) | Rm;
11842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
11852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
11862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
11872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
11882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::SMLAW(int cc, int y,
11902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                int Rd, int Rm, int Rs, int Rn)
11912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
11922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // *mPC++ = (cc<<28) | 0x1200080 | (Rd<<16) | (Rn<<12) | (Rs<<8) | (y<<4) | Rm;
11932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
11942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->NOP2();
11952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    NOT_IMPLEMENTED();
11962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
11972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
11982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// used by ARMv6 version of GGLAssembler::filter32
11992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::UXTB16(int cc, int Rd, int Rm, int rotate)
12002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
12012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mArmPC[mInum++] = pc();
12022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    //Rd[31:16] := ZeroExtend((Rm ROR (8 * sh))[23:16]),
12042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    //Rd[15:0] := ZeroExtend((Rm ROR (8 * sh))[7:0]). sh 0-3.
12052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->ROTR(Rm, Rm, rotate * 8);
12072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mMips->AND(Rd, Rm, 0x00FF00FF);
12082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
12092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid ArmToMipsAssembler::UBFX(int cc, int Rd, int Rn, int lsb, int width)
12112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
12122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind     /* Placeholder for UBFX */
12132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind     mArmPC[mInum++] = pc();
12142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind     mMips->NOP2();
12162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind     NOT_IMPLEMENTED();
12172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
12182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
12242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
12252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark MIPS Assembler...
12262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
12272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind//**************************************************************************
12302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind//**************************************************************************
12312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind//**************************************************************************
12322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind/* mips assembler
12352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** this is a subset of mips32r2, targeted specifically at ARM instruction
12362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** replacement in the pixelflinger/codeflinger code.
12372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
12382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** To that end, there is no need for floating point, or priviledged
12392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** instructions. This all runs in user space, no float.
12402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
12412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** The syntax makes no attempt to be as complete as the assember, with
12422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** synthetic instructions, and automatic recognition of immedate operands
12432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** (use the immediate form of the instruction), etc.
12442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind**
12452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** We start with mips32r1, and may add r2 and dsp extensions if cpu
12462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** supports. Decision will be made at compile time, based on gcc
12472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** options. (makes sense since android will be built for a a specific
12482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind** device)
12492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind*/
12502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul LindMIPSAssembler::MIPSAssembler(const sp<Assembly>& assembly, ArmToMipsAssembler *parent)
12522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    : mParent(parent),
12532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mAssembly(assembly)
12542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
12552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBase = mPC = (uint32_t *)assembly->base();
12562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mDuration = ggl_system_time();
12572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
12582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul LindMIPSAssembler::~MIPSAssembler()
12602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
12612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
12622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t* MIPSAssembler::pc() const
12652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
12662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return mPC;
12672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
12682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t* MIPSAssembler::base() const
12702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
12712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return mBase;
12722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
12732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::reset()
12752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
12762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBase = mPC = (uint32_t *)mAssembly->base();
12772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBranchTargets.clear();
12782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mLabels.clear();
12792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mLabelsInverseMapping.clear();
12802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mComments.clear();
12812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
12822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// convert tabs to spaces, and remove any newline
12852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// works with strings of limited size (makes a temp copy)
12862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#define TABSTOP 8
12872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::string_detab(char *s)
12882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
12892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    char *os = s;
12902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    char temp[100];
12912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    char *t = temp;
12922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    int len = 99;
12932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    int i = TABSTOP;
12942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
12952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    while (*s && len-- > 0) {
12962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (*s == '\n') { s++; continue; }
12972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (*s == '\t') {
12982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            s++;
12992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            for ( ; i>0; i--) {*t++ = ' '; len--; }
13002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        } else {
13012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            *t++ = *s++;
13022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
13032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (i <= 0) i = TABSTOP;
13042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        i--;
13052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
13062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *t = '\0';
13072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    strcpy(os, temp);
13082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
13092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::string_pad(char *s, int padded_len)
13112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
13122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    int len = strlen(s);
13132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    s += len;
13142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    for (int i = padded_len - len; i > 0; --i) {
13152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        *s++ = ' ';
13162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
13172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *s = '\0';
13182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
13192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// ----------------------------------------------------------------------------
13212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::disassemble(const char* name)
13232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
13242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    char di_buf[140];
13252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (name) {
13272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        ALOGW("%s:\n", name);
13282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
13292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    bool arm_disasm_fmt = (mParent->mArmDisassemblyBuffer == NULL) ? false : true;
13312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    typedef char dstr[40];
13332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    dstr *lines = (dstr *)mParent->mArmDisassemblyBuffer;
13342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (mParent->mArmDisassemblyBuffer != NULL) {
13362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        for (int i=0; i<mParent->mArmInstrCount; ++i) {
13372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            string_detab(lines[i]);
13382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
13392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
13402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // iArm is an index to Arm instructions 1...n for this assembly sequence
13422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // mArmPC[iArm] holds the value of the Mips-PC for the first MIPS
13432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // instruction corresponding to that Arm instruction number
13442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    int iArm = 0;
13462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    size_t count = pc()-base();
13472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    uint32_t* mipsPC = base();
13482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    while (count--) {
13492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        ssize_t label = mLabelsInverseMapping.indexOfKey(mipsPC);
13502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (label >= 0) {
13512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            ALOGW("%s:\n", mLabelsInverseMapping.valueAt(label));
13522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
13532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        ssize_t comment = mComments.indexOfKey(mipsPC);
13542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        if (comment >= 0) {
13552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind            ALOGW("; %s\n", mComments.valueAt(comment));
13562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        }
13572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        // ALOGW("%08x:    %08x    ", int(i), int(i[0]));
13582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        ::mips_disassem(mipsPC, di_buf, arm_disasm_fmt);
13592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        string_detab(di_buf);
13602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        string_pad(di_buf, 30);
13612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        ALOGW("%08x:    %08x    %s", uint32_t(mipsPC), uint32_t(*mipsPC), di_buf);
13622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mipsPC++;
13632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
13642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
13652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::comment(const char* string)
13672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
13682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mComments.add(pc(), string);
13692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
13702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::label(const char* theLabel)
13722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
13732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mLabels.add(theLabel, pc());
13742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mLabelsInverseMapping.add(pc(), theLabel);
13752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
13762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::prolog()
13792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
13802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // empty - done in ArmToMipsAssembler
13812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
13822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::epilog(uint32_t touched)
13842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
13852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // empty - done in ArmToMipsAssembler
13862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
13872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
13882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindint MIPSAssembler::generate(const char* name)
13892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
13902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // fixup all the branches
13912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    size_t count = mBranchTargets.size();
13922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    while (count--) {
13932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        const branch_target_t& bt = mBranchTargets[count];
13942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        uint32_t* target_pc = mLabels.valueFor(bt.label);
13952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        LOG_ALWAYS_FATAL_IF(!target_pc,
13962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                "error resolving branch targets, target_pc is null");
13972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int32_t offset = int32_t(target_pc - (bt.pc+1));
13982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        *bt.pc |= offset & 0x00FFFF;
13992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
14002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mAssembly->resize( int(pc()-base())*4 );
14022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // the instruction & data caches are flushed by CodeCache
14042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    const int64_t duration = ggl_system_time() - mDuration;
14052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    const char * const format = "generated %s (%d ins) at [%p:%p] in %lld ns\n";
14062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    ALOGI(format, name, int(pc()-base()), base(), pc(), duration);
14072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if defined(WITH_LIB_HARDWARE)
14092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (__builtin_expect(mQemuTracing, 0)) {
14102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        int err = qemu_add_mapping(int(base()), name);
14112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        mQemuTracing = (err >= 0);
14122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
14132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
14142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    char value[PROPERTY_VALUE_MAX];
14162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    value[0] = '\0';
14172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    property_get("debug.pf.disasm", value, "0");
14192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    if (atoi(value) != 0) {
14212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind        disassemble(name);
14222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    }
14232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return NO_ERROR;
14252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Linduint32_t* MIPSAssembler::pcForLabel(const char* label)
14282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    return mLabels.valueFor(label);
14302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
14352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
14362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Arithmetic...
14372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
14382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::ADDU(int Rd, int Rs, int Rt)
14402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (addu_fn<<FUNC_SHF)
14422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                    | (Rs<<RS_SHF) | (Rt<<RT_SHF) | (Rd<<RD_SHF);
14432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// MD00086 pdf says this is: ADDIU rt, rs, imm -- they do not use Rd
14462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::ADDIU(int Rt, int Rs, int16_t imm)
14472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (addiu_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | (imm & MSK_16);
14492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SUBU(int Rd, int Rs, int Rt)
14532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (subu_fn<<FUNC_SHF) |
14552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rs<<RS_SHF) | (Rt<<RT_SHF) | (Rd<<RD_SHF) ;
14562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SUBIU(int Rt, int Rs, int16_t imm)   // really addiu(d, s, -j)
14602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (addiu_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | ((-imm) & MSK_16);
14622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::NEGU(int Rd, int Rs)    // really subu(d, zero, s)
14662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::SUBU(Rd, 0, Rs);
14682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MUL(int Rd, int Rs, int Rt)
14712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec2_op<<OP_SHF) | (mul_fn<<FUNC_SHF) |
14732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rs<<RS_SHF) | (Rt<<RT_SHF) | (Rd<<RD_SHF) ;
14742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MULT(int Rs, int Rt)    // dest is hi,lo
14772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (mult_fn<<FUNC_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF);
14792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MULTU(int Rs, int Rt)    // dest is hi,lo
14822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (multu_fn<<FUNC_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF);
14842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MADD(int Rs, int Rt)    // hi,lo = hi,lo + Rs * Rt
14872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec2_op<<OP_SHF) | (madd_fn<<FUNC_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF);
14892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MADDU(int Rs, int Rt)    // hi,lo = hi,lo + Rs * Rt
14922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec2_op<<OP_SHF) | (maddu_fn<<FUNC_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF);
14942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
14952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
14972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MSUB(int Rs, int Rt)    // hi,lo = hi,lo - Rs * Rt
14982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
14992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec2_op<<OP_SHF) | (msub_fn<<FUNC_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF);
15002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MSUBU(int Rs, int Rt)    // hi,lo = hi,lo - Rs * Rt
15032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec2_op<<OP_SHF) | (msubu_fn<<FUNC_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF);
15052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SEB(int Rd, int Rt)    // sign-extend byte (mips32r2)
15092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec3_op<<OP_SHF) | (bshfl_fn<<FUNC_SHF) | (seb_fn << SA_SHF) |
15112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                    (Rt<<RT_SHF) | (Rd<<RD_SHF);
15122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SEH(int Rd, int Rt)    // sign-extend half-word (mips32r2)
15152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec3_op<<OP_SHF) | (bshfl_fn<<FUNC_SHF) | (seh_fn << SA_SHF) |
15172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                    (Rt<<RT_SHF) | (Rd<<RD_SHF);
15182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
15232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
15242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Comparisons...
15252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
15262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SLT(int Rd, int Rs, int Rt)
15282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (slt_fn<<FUNC_SHF) |
15302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
15312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SLTI(int Rt, int Rs, int16_t imm)
15342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (slti_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | (imm & MSK_16);
15362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SLTU(int Rd, int Rs, int Rt)
15402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (sltu_fn<<FUNC_SHF) |
15422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
15432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SLTIU(int Rt, int Rs, int16_t imm)
15462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (sltiu_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | (imm & MSK_16);
15482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
15532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
15542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Logical...
15552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
15562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::AND(int Rd, int Rs, int Rt)
15582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (and_fn<<FUNC_SHF) |
15602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
15612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::ANDI(int Rt, int Rs, uint16_t imm)      // todo: support larger immediate
15642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (andi_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | (imm & MSK_16);
15662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::OR(int Rd, int Rs, int Rt)
15702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (or_fn<<FUNC_SHF) |
15722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
15732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::ORI(int Rt, int Rs, uint16_t imm)
15762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (ori_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | (imm & MSK_16);
15782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::NOR(int Rd, int Rs, int Rt)
15812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (nor_fn<<FUNC_SHF) |
15832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
15842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::NOT(int Rd, int Rs)
15872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NOR(Rd, Rs, 0);  // NOT(d,s) = NOR(d,s,zero)
15892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::XOR(int Rd, int Rs, int Rt)
15922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (xor_fn<<FUNC_SHF) |
15942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
15952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
15962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
15972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::XORI(int Rt, int Rs, uint16_t imm)  // todo: support larger immediate
15982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
15992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (xori_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | (imm & MSK_16);
16002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SLL(int Rd, int Rt, int shft)
16032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (sll_fn<<FUNC_SHF) |
16052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rt<<RT_SHF) | (shft<<RE_SHF);
16062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SLLV(int Rd, int Rt, int Rs)
16092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (sllv_fn<<FUNC_SHF) |
16112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
16122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SRL(int Rd, int Rt, int shft)
16152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (srl_fn<<FUNC_SHF) |
16172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rt<<RT_SHF) | (shft<<RE_SHF);
16182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SRLV(int Rd, int Rt, int Rs)
16212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (srlv_fn<<FUNC_SHF) |
16232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
16242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SRA(int Rd, int Rt, int shft)
16272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (sra_fn<<FUNC_SHF) |
16292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rt<<RT_SHF) | (shft<<RE_SHF);
16302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SRAV(int Rd, int Rt, int Rs)
16332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (srav_fn<<FUNC_SHF) |
16352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
16362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::ROTR(int Rd, int Rt, int shft)      // mips32r2
16392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // note weird encoding (SRL + 1)
16412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (srl_fn<<FUNC_SHF) |
16422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (1<<RS_SHF) | (Rd<<RD_SHF) | (Rt<<RT_SHF) | (shft<<RE_SHF);
16432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::ROTRV(int Rd, int Rt, int Rs)       // mips32r2
16462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // note weird encoding (SRLV + 1)
16482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (srlv_fn<<FUNC_SHF) |
16492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF) | (1<<RE_SHF);
16502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// uses at2 register (mapped to some appropriate mips reg)
16532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::RORsyn(int Rd, int Rt, int Rs)
16542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // synthetic: d = t rotated by s
16562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NEGU(R_at2, Rs);
16572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::SLLV(R_at2, Rt, R_at2);
16582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::SRLV(Rd, Rt, Rs);
16592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::OR(Rd, Rd, R_at2);
16602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// immediate version - uses at2 register (mapped to some appropriate mips reg)
16632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::RORIsyn(int Rd, int Rt, int rot)
16642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // synthetic: d = t rotated by immed rot
16662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // d = s >> rot | s << (32-rot)
16672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::SLL(R_at2, Rt, 32-rot);
16682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::SRL(Rd, Rt, rot);
16692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::OR(Rd, Rd, R_at2);
16702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::CLO(int Rd, int Rs)
16732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // Rt field must have same gpr # as Rd
16752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec2_op<<OP_SHF) | (clo_fn<<FUNC_SHF) |
16762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rd<<RT_SHF);
16772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::CLZ(int Rd, int Rs)
16802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // Rt field must have same gpr # as Rd
16822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec2_op<<OP_SHF) | (clz_fn<<FUNC_SHF) |
16832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rd<<RT_SHF);
16842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::WSBH(int Rd, int Rt)      // mips32r2
16872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
16882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec3_op<<OP_SHF) | (bshfl_fn<<FUNC_SHF) | (wsbh_fn << SA_SHF) |
16892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rt<<RT_SHF) | (Rd<<RD_SHF);
16902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
16912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
16952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
16962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Load/store...
16972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
16982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
16992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::LW(int Rt, int Rbase, int16_t offset)
17002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (lw_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16);
17022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SW(int Rt, int Rbase, int16_t offset)
17052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (sw_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16);
17072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// lb is sign-extended
17102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::LB(int Rt, int Rbase, int16_t offset)
17112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (lb_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16);
17132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::LBU(int Rt, int Rbase, int16_t offset)
17162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (lbu_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16);
17182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SB(int Rt, int Rbase, int16_t offset)
17212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (sb_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16);
17232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// lh is sign-extended
17262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::LH(int Rt, int Rbase, int16_t offset)
17272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (lh_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16);
17292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::LHU(int Rt, int Rbase, int16_t offset)
17322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (lhu_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16);
17342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::SH(int Rt, int Rbase, int16_t offset)
17372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (sh_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16);
17392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::LUI(int Rt, int16_t offset)
17422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (lui_op<<OP_SHF) | (Rt<<RT_SHF) | (offset & MSK_16);
17442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
17492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
17502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Register move...
17512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
17522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MOVE(int Rd, int Rs)
17542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // encoded as "or rd, rs, zero"
17562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (or_fn<<FUNC_SHF) |
17572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (0<<RT_SHF);
17582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MOVN(int Rd, int Rs, int Rt)
17612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (movn_fn<<FUNC_SHF) |
17632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
17642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MOVZ(int Rd, int Rs, int Rt)
17672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (movz_fn<<FUNC_SHF) |
17692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        (Rd<<RD_SHF) | (Rs<<RS_SHF) | (Rt<<RT_SHF);
17702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MFHI(int Rd)
17732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (mfhi_fn<<FUNC_SHF) | (Rd<<RD_SHF);
17752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MFLO(int Rd)
17782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (mflo_fn<<FUNC_SHF) | (Rd<<RD_SHF);
17802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MTHI(int Rs)
17832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (mthi_fn<<FUNC_SHF) | (Rs<<RS_SHF);
17852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::MTLO(int Rs)
17882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
17892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (mtlo_fn<<FUNC_SHF) | (Rs<<RS_SHF);
17902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
17912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
17952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
17962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Branch...
17972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
17982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
17992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// temporarily forcing a NOP into branch-delay slot, just to be safe
18002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// todo: remove NOP, optimze use of delay slots
18012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::B(const char* label)
18022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBranchTargets.add(branch_target_t(label, mPC));
18042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // encoded as BEQ zero, zero, offset
18062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (beq_op<<OP_SHF) | (0<<RT_SHF)
18072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind                        | (0<<RS_SHF) | 0;  // offset filled in later
18082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NOP();
18102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BEQ(int Rs, int Rt, const char* label)
18132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBranchTargets.add(branch_target_t(label, mPC));
18152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (beq_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | 0;
18162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NOP();
18172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BNE(int Rs, int Rt, const char* label)
18202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBranchTargets.add(branch_target_t(label, mPC));
18222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (bne_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | 0;
18232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NOP();
18242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BLEZ(int Rs, const char* label)
18272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBranchTargets.add(branch_target_t(label, mPC));
18292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (blez_op<<OP_SHF) | (0<<RT_SHF) | (Rs<<RS_SHF) | 0;
18302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NOP();
18312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BLTZ(int Rs, const char* label)
18342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBranchTargets.add(branch_target_t(label, mPC));
18362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (regimm_op<<OP_SHF) | (bltz_fn<<RT_SHF) | (Rs<<RS_SHF) | 0;
18372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NOP();
18382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BGTZ(int Rs, const char* label)
18412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBranchTargets.add(branch_target_t(label, mPC));
18432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (bgtz_op<<OP_SHF) | (0<<RT_SHF) | (Rs<<RS_SHF) | 0;
18442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NOP();
18452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BGEZ(int Rs, const char* label)
18492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    mBranchTargets.add(branch_target_t(label, mPC));
18512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (regimm_op<<OP_SHF) | (bgez_fn<<RT_SHF) | (Rs<<RS_SHF) | 0;
18522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NOP();
18532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::JR(int Rs)
18562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (Rs<<RS_SHF) | (jr_fn << FUNC_SHF);
18582bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    MIPSAssembler::NOP();
18592bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18602bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18612bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18622bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
18632bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
18642bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Synthesized Branch...
18652bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
18662bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18672bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// synthetic variants of branches (using slt & friends)
18682bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BEQZ(int Rs, const char* label)
18692bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18702bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BEQ(Rs, R_zero, label);
18712bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18722bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18732bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BNEZ(int Rs, const char* label)
18742bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18752bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BNE(R_at, R_zero, label);
18762bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18772bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18782bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BGE(int Rs, int Rt, const char* label)
18792bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18802bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    SLT(R_at, Rs, Rt);
18812bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BEQ(R_at, R_zero, label);
18822bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18832bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18842bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BGEU(int Rs, int Rt, const char* label)
18852bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18862bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    SLTU(R_at, Rs, Rt);
18872bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BEQ(R_at, R_zero, label);
18882bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18892bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18902bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BGT(int Rs, int Rt, const char* label)
18912bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18922bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    SLT(R_at, Rt, Rs);   // rev
18932bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BNE(R_at, R_zero, label);
18942bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
18952bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
18962bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BGTU(int Rs, int Rt, const char* label)
18972bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
18982bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    SLTU(R_at, Rt, Rs);   // rev
18992bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BNE(R_at, R_zero, label);
19002bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
19012bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19022bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BLE(int Rs, int Rt, const char* label)
19032bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
19042bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    SLT(R_at, Rt, Rs);   // rev
19052bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BEQ(R_at, R_zero, label);
19062bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
19072bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19082bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BLEU(int Rs, int Rt, const char* label)
19092bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
19102bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    SLTU(R_at, Rt, Rs);  // rev
19112bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BEQ(R_at, R_zero, label);
19122bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
19132bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19142bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BLT(int Rs, int Rt, const char* label)
19152bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
19162bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    SLT(R_at, Rs, Rt);
19172bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BNE(R_at, R_zero, label);
19182bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
19192bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19202bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::BLTU(int Rs, int Rt, const char* label)
19212bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
19222bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    SLTU(R_at, Rs, Rt);
19232bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    BNE(R_at, R_zero, label);
19242bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
19252bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19262bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19272bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19282bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19292bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#if 0
19302bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark -
19312bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#pragma mark Misc...
19322bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind#endif
19332bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19342bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::NOP(void)
19352bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
19362bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // encoded as "sll zero, zero, 0", which is all zero
19372bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (sll_fn<<FUNC_SHF);
19382bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
19392bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19402bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// using this as special opcode for not-yet-implemented ARM instruction
19412bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::NOP2(void)
19422bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
19432bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // encoded as "sll zero, zero, 2", still a nop, but a unique code
19442bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (sll_fn<<FUNC_SHF) | (2 << RE_SHF);
19452bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
19462bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19472bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind// using this as special opcode for purposefully NOT implemented ARM instruction
19482bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lindvoid MIPSAssembler::UNIMPL(void)
19492bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind{
19502bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    // encoded as "sll zero, zero, 3", still a nop, but a unique code
19512bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind    *mPC++ = (spec_op<<OP_SHF) | (sll_fn<<FUNC_SHF) | (3 << RE_SHF);
19522bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}
19532bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19542bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19552bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind}; // namespace android:
19562bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
19572bc2b792782b304b15d8c48b54916a9b3fa3a7acPaul Lind
1958