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