1606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes/* libs/pixelflinger/codeflinger/MIPS64Assembler.cpp 2606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** 3606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** Copyright 2015, The Android Open Source Project 4606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** 5606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** Licensed under the Apache License, Version 2.0 (the "License"); 6606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** you may not use this file except in compliance with the License. 7606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** You may obtain a copy of the License at 8606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** 9606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** http://www.apache.org/licenses/LICENSE-2.0 10606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** 11606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** Unless required by applicable law or agreed to in writing, software 12606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** distributed under the License is distributed on an "AS IS" BASIS, 13606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** See the License for the specific language governing permissions and 15606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** limitations under the License. 16606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes*/ 17606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 18606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 19606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes/* MIPS64 assembler and ARM->MIPS64 assembly translator 20606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** 21606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** The approach is utilize MIPSAssembler generator, using inherited MIPS64Assembler 22606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** that overrides just the specific MIPS64r6 instructions. 23606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** For now ArmToMips64Assembler is copied over from ArmToMipsAssembler class, 24606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** changing some MIPS64r6 related stuff. 25606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** 26606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes*/ 27606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 28606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#define LOG_TAG "MIPS64Assembler" 29606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 30606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#include <stdio.h> 31606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#include <stdlib.h> 32606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 3366ce3e08c5632a20ea66bde6dd76397041edf034Mark Salyzyn#include <cutils/properties.h> 3430f991f251940be3ed11566fb71139852286f68aMark Salyzyn#include <log/log.h> 35606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#include <private/pixelflinger/ggl_context.h> 36606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 37606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#include "MIPS64Assembler.h" 38606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#include "CodeCache.h" 39606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#include "mips64_disassem.h" 40606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 41606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#define NOT_IMPLEMENTED() LOG_ALWAYS_FATAL("Arm instruction %s not yet implemented\n", __func__) 42606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 43606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// ---------------------------------------------------------------------------- 44606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 45606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesnamespace android { 46606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 47606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// ---------------------------------------------------------------------------- 48606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 49606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 50606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark ArmToMips64Assembler... 51606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 52606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 53606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesArmToMips64Assembler::ArmToMips64Assembler(const sp<Assembly>& assembly, 54606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes char *abuf, int linesz, int instr_count) 55606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : ARMAssemblerInterface(), 56606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmDisassemblyBuffer(abuf), 57606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmLineLength(linesz), 58606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmInstrCount(instr_count), 59606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mInum(0), 60606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mAssembly(assembly) 61606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 62606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips = new MIPS64Assembler(assembly, this); 63606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC = (uint32_t **) malloc(ARM_MAX_INSTUCTIONS * sizeof(uint32_t *)); 64606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes init_conditional_labels(); 65606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 66606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 67606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesArmToMips64Assembler::ArmToMips64Assembler(void* assembly) 68606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : ARMAssemblerInterface(), 69606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmDisassemblyBuffer(NULL), 70606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mInum(0), 71606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mAssembly(NULL) 72606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 73606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips = new MIPS64Assembler(assembly, this); 74606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC = (uint32_t **) malloc(ARM_MAX_INSTUCTIONS * sizeof(uint32_t *)); 75606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes init_conditional_labels(); 76606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 77606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 78606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesArmToMips64Assembler::~ArmToMips64Assembler() 79606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 80606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes delete mMips; 81606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes free((void *) mArmPC); 82606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 83606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 84606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t* ArmToMips64Assembler::pc() const 85606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 86606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return mMips->pc(); 87606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 88606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 89606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t* ArmToMips64Assembler::base() const 90606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 91606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return mMips->base(); 92606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 93606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 94606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::reset() 95606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 96606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.labelnum = 0; 97606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mInum = 0; 98606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->reset(); 99606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 100606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 101606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesint ArmToMips64Assembler::getCodegenArch() 102606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 103606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return CODEGEN_ARCH_MIPS64; 104606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 105606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 106606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::comment(const char* string) 107606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 108606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->comment(string); 109606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 110606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 111606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::label(const char* theLabel) 112606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 113606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->label(theLabel); 114606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 115606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 116606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::disassemble(const char* name) 117606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 118606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->disassemble(name); 119606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 120606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 121606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::init_conditional_labels() 122606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 123606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int i; 124606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes for (i=0;i<99; ++i) { 125606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes sprintf(cond.label[i], "cond_%d", i); 126606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 127606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 128606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 129606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 130606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 131606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 132606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 133606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark Prolog/Epilog & Generate... 134606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 135606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 136606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::prolog() 137606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 138606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); // save starting PC for this instr 139606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 140606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(R_sp, R_sp, -(5 * 8)); 141606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SD(R_s0, R_sp, 0); 142606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SD(R_s1, R_sp, 8); 143606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SD(R_s2, R_sp, 16); 144606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SD(R_s3, R_sp, 24); 145606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SD(R_s4, R_sp, 32); 146606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MOVE(R_v0, R_a0); // move context * passed in a0 to v0 (arm r0) 147606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 148606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 149606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::epilog(uint32_t touched) 150606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 151606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); // save starting PC for this instr 152606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 153606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LD(R_s0, R_sp, 0); 154606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LD(R_s1, R_sp, 8); 155606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LD(R_s2, R_sp, 16); 156606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LD(R_s3, R_sp, 24); 157606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LD(R_s4, R_sp, 32); 158606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(R_sp, R_sp, (5 * 8)); 159606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->JR(R_ra); 160606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 161606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 162606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 163606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesint ArmToMips64Assembler::generate(const char* name) 164606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 165606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return mMips->generate(name); 166606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 167606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 168606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::fix_branches() 169606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 170606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->fix_branches(); 171606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 172606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 173606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t* ArmToMips64Assembler::pcForLabel(const char* label) 174606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 175606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return mMips->pcForLabel(label); 176606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 177606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 178606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::set_condition(int mode, int R1, int R2) { 179606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (mode == 2) { 180606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = SBIT_COND; 181606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 182606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = CMP_COND; 183606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 184606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = R1; 185606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r2 = R2; 186606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 187606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 188606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes//---------------------------------------------------------- 189606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 190606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 191606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 192606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark Addressing modes & shifters... 193606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 194606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 195606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 196606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// do not need this for MIPS, but it is in the Interface (virtual) 197606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesint ArmToMips64Assembler::buildImmediate( 198606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes uint32_t immediate, uint32_t& rot, uint32_t& imm) 199606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 200606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // for MIPS, any 32-bit immediate is OK 201606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes rot = 0; 202606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes imm = immediate; 203606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return 0; 204606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 205606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 206606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// shifters... 207606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 208606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesbool ArmToMips64Assembler::isValidImmediate(uint32_t immediate) 209606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 210606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // for MIPS, any 32-bit immediate is OK 211606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return true; 212606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 213606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 214606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::imm(uint32_t immediate) 215606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 216606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = immediate; 217606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_IMM; 218606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 219606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 220606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::reg_imm(int Rm, int type, uint32_t shift) 221606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 222606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.reg = Rm; 223606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.stype = type; 224606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = shift; 225606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_REG_IMM; 226606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 227606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 228606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::reg_rrx(int Rm) 229606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 230606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // reg_rrx mode is not used in the GLLAssember code at this time 231606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_UNSUPPORTED; 232606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 233606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 234606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::reg_reg(int Rm, int type, int Rs) 235606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 236606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // reg_reg mode is not used in the GLLAssember code at this time 237606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_UNSUPPORTED; 238606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 239606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 240606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 241606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// addressing modes... 242606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// LDR(B)/STR(B)/PLD (immediate and Rm can be negative, which indicate U=0) 243606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::immed12_pre(int32_t immed12, int W) 244606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 245606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, 246606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "LDR(B)/STR(B)/PLD immediate too big (%08x)", 247606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes immed12); 248606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = immed12; 249606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.writeback = W; 250606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_IMM_12_PRE; 251606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 252606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 253606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::immed12_post(int32_t immed12) 254606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 255606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, 256606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "LDR(B)/STR(B)/PLD immediate too big (%08x)", 257606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes immed12); 258606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 259606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = immed12; 260606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_IMM_12_POST; 261606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 262606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 263606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::reg_scale_pre(int Rm, int type, 264606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes uint32_t shift, int W) 265606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 266606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL_IF(W | type | shift, "reg_scale_pre adv modes not yet implemented"); 267606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 268606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.reg = Rm; 269606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // amode.stype = type; // more advanced modes not used in GGLAssembler yet 270606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // amode.value = shift; 271606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // amode.writeback = W; 272606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_REG_SCALE_PRE; 273606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 274606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 275606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::reg_scale_post(int Rm, int type, uint32_t shift) 276606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 277606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("adr mode reg_scale_post not yet implemented\n"); 278606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_UNSUPPORTED; 279606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 280606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 281606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// LDRH/LDRSB/LDRSH/STRH (immediate and Rm can be negative, which indicate U=0) 282606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::immed8_pre(int32_t immed8, int W) 283606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 284606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("adr mode immed8_pre not yet implemented\n"); 285606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 286606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, 287606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", 288606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes immed8); 289606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_IMM_8_PRE; 290606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 291606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 292606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::immed8_post(int32_t immed8) 293606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 294606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, 295606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", 296606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes immed8); 297606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = immed8; 298606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_IMM_8_POST; 299606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 300606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 301606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::reg_pre(int Rm, int W) 302606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 303606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL_IF(W, "reg_pre writeback not yet implemented"); 304606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.reg = Rm; 305606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_REG_PRE; 306606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 307606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 308606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesuint32_t ArmToMips64Assembler::reg_post(int Rm) 309606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 310606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("adr mode reg_post not yet implemented\n"); 311606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return AMODE_UNSUPPORTED; 312606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 313606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 314606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 315606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 316606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// ---------------------------------------------------------------------------- 317606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 318606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 319606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 320606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark Data Processing... 321606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 322606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 323606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 324606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesstatic const char * const dpOpNames[] = { 325606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "AND", "EOR", "SUB", "RSB", "ADD", "ADC", "SBC", "RSC", 326606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "TST", "TEQ", "CMP", "CMN", "ORR", "MOV", "BIC", "MVN" 327606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes}; 328606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 329606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// check if the operand registers from a previous CMP or S-bit instruction 330606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// would be overwritten by this instruction. If so, move the value to a 331606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// safe register. 332606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// Note that we cannot tell at _this_ instruction time if a future (conditional) 333606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// instruction will _also_ use this value (a defect of the simple 1-pass, one- 334606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// instruction-at-a-time translation). Therefore we must be conservative and 335606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// save the value before it is overwritten. This costs an extra MOVE instr. 336606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 337606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::protectConditionalOperands(int Rd) 338606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 339606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (Rd == cond.r1) { 340606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MOVE(R_cmp, cond.r1); 341606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = R_cmp; 342606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 343606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (cond.type == CMP_COND && Rd == cond.r2) { 344606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MOVE(R_cmp2, cond.r2); 345606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r2 = R_cmp2; 346606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 347606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 348606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 349606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 350606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// interprets the addressing mode, and generates the common code 351606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// used by the majority of data-processing ops. Many MIPS instructions 352606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// have a register-based form and a different immediate form. See 353606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// opAND below for an example. (this could be inlined) 354606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// 355606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// this works with the imm(), reg_imm() methods above, which are directly 356606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// called by the GLLAssembler. 357606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// note: _signed parameter defaults to false (un-signed) 358606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// note: tmpReg parameter defaults to 1, MIPS register AT 359606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesint ArmToMips64Assembler::dataProcAdrModes(int op, int& source, bool _signed, int tmpReg) 360606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 361606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (op < AMODE_REG) { 362606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes source = op; 363606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return SRC_REG; 364606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if (op == AMODE_IMM) { 365606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if ((!_signed && amode.value > 0xffff) 366606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes || (_signed && ((int)amode.value < -32768 || (int)amode.value > 32767) )) { 367606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LUI(tmpReg, (amode.value >> 16)); 368606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.value & 0x0000ffff) { 369606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(tmpReg, tmpReg, (amode.value & 0x0000ffff)); 370606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 371606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes source = tmpReg; 372606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return SRC_REG; 373606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 374606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes source = amode.value; 375606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return SRC_IMM; 376606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 377606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if (op == AMODE_REG_IMM) { 378606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (amode.stype) { 379606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LSL: mMips->SLL(tmpReg, amode.reg, amode.value); break; 380606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LSR: mMips->SRL(tmpReg, amode.reg, amode.value); break; 381606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case ASR: mMips->SRA(tmpReg, amode.reg, amode.value); break; 382606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case ROR: mMips->ROTR(tmpReg, amode.reg, amode.value); break; 383606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 384606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes source = tmpReg; 385606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return SRC_REG; 386606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { // adr mode RRX is not used in GGL Assembler at this time 387606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // we are screwed, this should be exception, assert-fail or something 388606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("adr mode reg_rrx not yet implemented\n"); 389606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return SRC_ERROR; 390606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 391606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 392606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 393606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 394606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::dataProcessing(int opcode, int cc, 395606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int s, int Rd, int Rn, uint32_t Op2) 396606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 397606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int src; // src is modified by dataProcAdrModes() - passed as int& 398606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 399606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (cc != AL) { 400606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes protectConditionalOperands(Rd); 401606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // the branch tests register(s) set by prev CMP or instr with 'S' bit set 402606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // inverse the condition to jump past this conditional instruction 403606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ArmToMips64Assembler::B(cc^1, cond.label[++cond.labelnum]); 404606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 405606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); // save starting PC for this instr 406606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 407606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 408606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (opcode) { 409606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opAND: 410606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src) == SRC_REG) { 411606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->AND(Rd, Rn, src); 412606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { // adr mode was SRC_IMM 413606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ANDI(Rd, Rn, src); 414606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 415606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 416606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 417606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opADD: 418606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // set "signed" to true for adr modes 419606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src, true) == SRC_REG) { 420606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ADDU(Rd, Rn, src); 421606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { // adr mode was SRC_IMM 422606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ADDIU(Rd, Rn, src); 423606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 424606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 425606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 426606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opSUB: 427606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // set "signed" to true for adr modes 428606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src, true) == SRC_REG) { 429606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SUBU(Rd, Rn, src); 430606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { // adr mode was SRC_IMM 431606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SUBIU(Rd, Rn, src); 432606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 433606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 434606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 435606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opADD64: 436606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // set "signed" to true for adr modes 437606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src, true) == SRC_REG) { 438606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDU(Rd, Rn, src); 439606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { // adr mode was SRC_IMM 440606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rd, Rn, src); 441606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 442606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 443606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 444606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opSUB64: 445606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // set "signed" to true for adr modes 446606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src, true) == SRC_REG) { 447606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DSUBU(Rd, Rn, src); 448606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { // adr mode was SRC_IMM 449606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DSUBIU(Rd, Rn, src); 450606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 451606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 452606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 453606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opEOR: 454606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src) == SRC_REG) { 455606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->XOR(Rd, Rn, src); 456606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { // adr mode was SRC_IMM 457606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->XORI(Rd, Rn, src); 458606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 459606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 460606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 461606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opORR: 462606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src) == SRC_REG) { 463606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->OR(Rd, Rn, src); 464606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { // adr mode was SRC_IMM 465606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(Rd, Rn, src); 466606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 467606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 468606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 469606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opBIC: 470606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src) == SRC_IMM) { 471606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // if we are 16-bit imnmediate, load to AT reg 472606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(R_at, 0, src); 473606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes src = R_at; 474606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 475606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOT(R_at, src); 476606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->AND(Rd, Rn, R_at); 477606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 478606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 479606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opRSB: 480606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src) == SRC_IMM) { 481606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // if we are 16-bit imnmediate, load to AT reg 482606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(R_at, 0, src); 483606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes src = R_at; 484606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 485606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SUBU(Rd, src, Rn); // subu with the parameters reversed 486606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 487606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 488606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opMOV: 489606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (Op2 < AMODE_REG) { // op2 is reg # in this case 490606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MOVE(Rd, Op2); 491606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if (Op2 == AMODE_IMM) { 492606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.value > 0xffff) { 493606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LUI(Rd, (amode.value >> 16)); 494606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.value & 0x0000ffff) { 495606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(Rd, Rd, (amode.value & 0x0000ffff)); 496606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 497606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 498606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(Rd, 0, amode.value); 499606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 500606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if (Op2 == AMODE_REG_IMM) { 501606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (amode.stype) { 502606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LSL: mMips->SLL(Rd, amode.reg, amode.value); break; 503606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LSR: mMips->SRL(Rd, amode.reg, amode.value); break; 504606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case ASR: mMips->SRA(Rd, amode.reg, amode.value); break; 505606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case ROR: mMips->ROTR(Rd, amode.reg, amode.value); break; 506606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 507606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 508606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes else { 509606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // adr mode RRX is not used in GGL Assembler at this time 510606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->UNIMPL(); 511606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 512606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 513606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 514606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opMVN: // this is a 1's complement: NOT 515606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (Op2 < AMODE_REG) { // op2 is reg # in this case 516606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOR(Rd, Op2, 0); // NOT is NOR with 0 517606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 518606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if (Op2 == AMODE_IMM) { 519606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.value > 0xffff) { 520606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LUI(Rd, (amode.value >> 16)); 521606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.value & 0x0000ffff) { 522606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(Rd, Rd, (amode.value & 0x0000ffff)); 523606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 524606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 525606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(Rd, 0, amode.value); 526606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 527606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if (Op2 == AMODE_REG_IMM) { 528606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (amode.stype) { 529606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LSL: mMips->SLL(Rd, amode.reg, amode.value); break; 530606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LSR: mMips->SRL(Rd, amode.reg, amode.value); break; 531606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case ASR: mMips->SRA(Rd, amode.reg, amode.value); break; 532606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case ROR: mMips->ROTR(Rd, amode.reg, amode.value); break; 533606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 534606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 535606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes else { 536606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // adr mode RRX is not used in GGL Assembler at this time 537606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->UNIMPL(); 538606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 539606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOR(Rd, Rd, 0); // NOT is NOR with 0 540606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 541606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 542606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opCMP: 543606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // Either operand of a CMP instr could get overwritten by a subsequent 544606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // conditional instruction, which is ok, _UNLESS_ there is a _second_ 545606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // conditional instruction. Under MIPS, this requires doing the comparison 546606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // again (SLT), and the original operands must be available. (and this 547606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // pattern of multiple conditional instructions from same CMP _is_ used 548606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // in GGL-Assembler) 549606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // 550606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // For now, if a conditional instr overwrites the operands, we will 551606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // move them to dedicated temp regs. This is ugly, and inefficient, 552606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // and should be optimized. 553606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // 554606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // WARNING: making an _Assumption_ that CMP operand regs will NOT be 555606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // trashed by intervening NON-conditional instructions. In the general 556606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // case this is legal, but it is NOT currently done in GGL-Assembler. 557606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 558606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = CMP_COND; 559606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = Rn; 560606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (dataProcAdrModes(Op2, src, false, R_cmp2) == SRC_REG) { 561606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r2 = src; 562606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { // adr mode was SRC_IMM 563606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(R_cmp2, R_zero, src); 564606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r2 = R_cmp2; 565606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 566606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 567606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 568606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 569606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 570606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opTST: 571606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opTEQ: 572606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opCMN: 573606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opADC: 574606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opSBC: 575606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case opRSC: 576606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->UNIMPL(); // currently unused in GGL Assembler code 577606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 578606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 579606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 580606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (cc != AL) { 581606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->label(cond.label[cond.labelnum]); 582606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 583606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (s && opcode != opCMP) { 584606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = SBIT_COND; 585606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = Rd; 586606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 587606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 588606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 589606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 590606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 591606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 592606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 593606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark Multiply... 594606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 595606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 596606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// multiply, accumulate 597606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::MLA(int cc, int s, 598606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int Rd, int Rm, int Rs, int Rn) { 599606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 600606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes //ALOGW("MLA"); 601606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); // save starting PC for this instr 602606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 603606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MUL(R_at, Rm, Rs); 604606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ADDU(Rd, R_at, Rn); 605606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (s) { 606606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = SBIT_COND; 607606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = Rd; 608606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 609606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 610606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 611606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::MUL(int cc, int s, 612606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int Rd, int Rm, int Rs) { 613606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 614606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MUL(Rd, Rm, Rs); 615606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (s) { 616606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = SBIT_COND; 617606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = Rd; 618606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 619606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 620606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 621606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::UMULL(int cc, int s, 622606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int RdLo, int RdHi, int Rm, int Rs) { 623606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 624606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MUH(RdHi, Rm, Rs); 625606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MUL(RdLo, Rm, Rs); 626606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 627606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (s) { 628606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = SBIT_COND; 629606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = RdHi; // BUG... 630606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("Condition on UMULL must be on 64-bit result\n"); 631606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 632606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 633606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 634606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::UMUAL(int cc, int s, 635606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int RdLo, int RdHi, int Rm, int Rs) { 636606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi, 637606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "UMUAL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs); 638606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | (1<<23) | (1<<21) | (s<<20) | 639606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm; 640606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 641606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 642606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 643606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (s) { 644606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = SBIT_COND; 645606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = RdHi; // BUG... 646606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("Condition on UMULL must be on 64-bit result\n"); 647606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 648606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 649606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 650606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SMULL(int cc, int s, 651606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int RdLo, int RdHi, int Rm, int Rs) { 652606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi, 653606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "SMULL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs); 654606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | (1<<23) | (1<<22) | (s<<20) | 655606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm; 656606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 657606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 658606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 659606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (s) { 660606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = SBIT_COND; 661606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = RdHi; // BUG... 662606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("Condition on SMULL must be on 64-bit result\n"); 663606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 664606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 665606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SMUAL(int cc, int s, 666606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int RdLo, int RdHi, int Rm, int Rs) { 667606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi, 668606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "SMUAL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs); 669606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | (1<<23) | (1<<22) | (1<<21) | (s<<20) | 670606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm; 671606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 672606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 673606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 674606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (s) { 675606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.type = SBIT_COND; 676606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes cond.r1 = RdHi; // BUG... 677606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("Condition on SMUAL must be on 64-bit result\n"); 678606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 679606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 680606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 681606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 682606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 683606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 684606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 685606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark Branches... 686606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 687606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 688606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// branches... 689606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 690606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::B(int cc, const char* label) 691606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 692606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 693606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (cond.type == SBIT_COND) { cond.r2 = R_zero; } 694606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 695606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch(cc) { 696606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case EQ: mMips->BEQ(cond.r1, cond.r2, label); break; 697606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case NE: mMips->BNE(cond.r1, cond.r2, label); break; 698606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case HS: mMips->BGEU(cond.r1, cond.r2, label); break; 699606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LO: mMips->BLTU(cond.r1, cond.r2, label); break; 700606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case MI: mMips->BLT(cond.r1, cond.r2, label); break; 701606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case PL: mMips->BGE(cond.r1, cond.r2, label); break; 702606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 703606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case HI: mMips->BGTU(cond.r1, cond.r2, label); break; 704606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LS: mMips->BLEU(cond.r1, cond.r2, label); break; 705606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case GE: mMips->BGE(cond.r1, cond.r2, label); break; 706606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LT: mMips->BLT(cond.r1, cond.r2, label); break; 707606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case GT: mMips->BGT(cond.r1, cond.r2, label); break; 708606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case LE: mMips->BLE(cond.r1, cond.r2, label); break; 709606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AL: mMips->B(label); break; 710606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case NV: /* B Never - no instruction */ break; 711606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 712606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case VS: 713606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case VC: 714606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes default: 715606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("Unsupported cc: %02x\n", cc); 716606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 717606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 718606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 719606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 720606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::BL(int cc, const char* label) 721606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 722606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("branch-and-link not supported yet\n"); 723606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 724606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 725606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 726606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// no use for Branches with integer PC, but they're in the Interface class .... 727606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::B(int cc, uint32_t* to_pc) 728606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 729606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("branch to absolute PC not supported, use Label\n"); 730606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 731606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 732606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 733606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::BL(int cc, uint32_t* to_pc) 734606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 735606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("branch to absolute PC not supported, use Label\n"); 736606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 737606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 738606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 739606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::BX(int cc, int Rn) 740606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 741606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL("branch to absolute PC not supported, use Label\n"); 742606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 743606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 744606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 745606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 746606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 747606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 748606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 749606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark Data Transfer... 750606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 751606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 752606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// data transfer... 753606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::LDR(int cc, int Rd, int Rn, uint32_t offset) 754606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 755606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 756606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // work-around for ARM default address mode of immed12_pre(0) 757606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (offset > AMODE_UNSUPPORTED) offset = 0; 758606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (offset) { 759606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case 0: 760606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = 0; 761606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.writeback = 0; 762606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // fall thru to next case .... 763606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_PRE: 764606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (Rn == ARMAssemblerInterface::SP) { 765606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes Rn = R_sp; // convert LDR via Arm SP to LW via Mips SP 766606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 767606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LW(Rd, Rn, amode.value); 768606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.writeback) { // OPTIONAL writeback on pre-index mode 769606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 770606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 771606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 772606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_POST: 773606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (Rn == ARMAssemblerInterface::SP) { 774606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes Rn = R_sp; // convert STR thru Arm SP to STR thru Mips SP 775606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 776606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LW(Rd, Rn, 0); 777606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 778606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 779606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_REG_SCALE_PRE: 780606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // we only support simple base + index, no advanced modes for this one yet 781606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDU(R_at, Rn, amode.reg); 782606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LW(Rd, R_at, 0); 783606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 784606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 785606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 786606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 787606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::LDRB(int cc, int Rd, int Rn, uint32_t offset) 788606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 789606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 790606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // work-around for ARM default address mode of immed12_pre(0) 791606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (offset > AMODE_UNSUPPORTED) offset = 0; 792606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (offset) { 793606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case 0: 794606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = 0; 795606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.writeback = 0; 796606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // fall thru to next case .... 797606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_PRE: 798606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LBU(Rd, Rn, amode.value); 799606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.writeback) { // OPTIONAL writeback on pre-index mode 800606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 801606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 802606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 803606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_POST: 804606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LBU(Rd, Rn, 0); 805606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 806606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 807606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_REG_SCALE_PRE: 808606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // we only support simple base + index, no advanced modes for this one yet 809606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDU(R_at, Rn, amode.reg); 810606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LBU(Rd, R_at, 0); 811606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 812606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 813606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 814606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 815606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 816606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::STR(int cc, int Rd, int Rn, uint32_t offset) 817606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 818606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 819606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // work-around for ARM default address mode of immed12_pre(0) 820606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (offset > AMODE_UNSUPPORTED) offset = 0; 821606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (offset) { 822606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case 0: 823606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = 0; 824606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.writeback = 0; 825606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // fall thru to next case .... 826606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_PRE: 827606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (Rn == ARMAssemblerInterface::SP) { 828606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes Rn = R_sp; // convert STR thru Arm SP to SW thru Mips SP 829606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 830606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.writeback) { // OPTIONAL writeback on pre-index mode 831606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // If we will writeback, then update the index reg, then store. 832606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // This correctly handles stack-push case. 833606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 834606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SW(Rd, Rn, 0); 835606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 836606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // No writeback so store offset by value 837606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SW(Rd, Rn, amode.value); 838606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 839606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 840606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_POST: 841606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SW(Rd, Rn, 0); 842606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); // post index always writes back 843606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 844606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_REG_SCALE_PRE: 845606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // we only support simple base + index, no advanced modes for this one yet 846606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDU(R_at, Rn, amode.reg); 847606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SW(Rd, R_at, 0); 848606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 849606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 850606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 851606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 852606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::STRB(int cc, int Rd, int Rn, uint32_t offset) 853606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 854606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 855606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // work-around for ARM default address mode of immed12_pre(0) 856606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (offset > AMODE_UNSUPPORTED) offset = 0; 857606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (offset) { 858606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case 0: 859606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = 0; 860606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.writeback = 0; 861606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // fall thru to next case .... 862606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_PRE: 863606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SB(Rd, Rn, amode.value); 864606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.writeback) { // OPTIONAL writeback on pre-index mode 865606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 866606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 867606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 868606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_POST: 869606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SB(Rd, Rn, 0); 870606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 871606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 872606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_REG_SCALE_PRE: 873606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // we only support simple base + index, no advanced modes for this one yet 874606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDU(R_at, Rn, amode.reg); 875606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SB(Rd, R_at, 0); 876606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 877606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 878606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 879606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 880606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::LDRH(int cc, int Rd, int Rn, uint32_t offset) 881606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 882606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 883606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // work-around for ARM default address mode of immed8_pre(0) 884606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (offset > AMODE_UNSUPPORTED) offset = 0; 885606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (offset) { 886606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case 0: 887606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = 0; 888606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // fall thru to next case .... 889606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_8_PRE: // no support yet for writeback 890606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LHU(Rd, Rn, amode.value); 891606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 892606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_8_POST: 893606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LHU(Rd, Rn, 0); 894606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 895606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 896606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_REG_PRE: 897606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // we only support simple base +/- index 898606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.reg >= 0) { 899606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDU(R_at, Rn, amode.reg); 900606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 901606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DSUBU(R_at, Rn, abs(amode.reg)); 902606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 903606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LHU(Rd, R_at, 0); 904606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 905606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 906606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 907606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 908606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::LDRSB(int cc, int Rd, int Rn, uint32_t offset) 909606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 910606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 911606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 912606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 913606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 914606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 915606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::LDRSH(int cc, int Rd, int Rn, uint32_t offset) 916606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 917606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 918606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 919606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 920606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 921606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 922606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::STRH(int cc, int Rd, int Rn, uint32_t offset) 923606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 924606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 925606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // work-around for ARM default address mode of immed8_pre(0) 926606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (offset > AMODE_UNSUPPORTED) offset = 0; 927606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (offset) { 928606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case 0: 929606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = 0; 930606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // fall thru to next case .... 931606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_8_PRE: // no support yet for writeback 932606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SH(Rd, Rn, amode.value); 933606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 934606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_8_POST: 935606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SH(Rd, Rn, 0); 936606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 937606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 938606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_REG_PRE: 939606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // we only support simple base +/- index 940606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.reg >= 0) { 941606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDU(R_at, Rn, amode.reg); 942606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 943606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DSUBU(R_at, Rn, abs(amode.reg)); 944606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 945606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SH(Rd, R_at, 0); 946606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 947606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 948606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 949606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 950606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 951606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 952606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 953606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 954606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark Block Data Transfer... 955606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 956606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 957606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// block data transfer... 958606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::LDM(int cc, int dir, 959606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int Rn, int W, uint32_t reg_list) 960606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ // ED FD EA FA IB IA DB DA 961606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // const uint8_t P[8] = { 1, 0, 1, 0, 1, 0, 1, 0 }; 962606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // const uint8_t U[8] = { 1, 1, 0, 0, 1, 1, 0, 0 }; 963606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | (4<<25) | (uint32_t(P[dir])<<24) | 964606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // (uint32_t(U[dir])<<23) | (1<<20) | (W<<21) | (Rn<<16) | reg_list; 965606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 966606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 967606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 968606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 969606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 970606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::STM(int cc, int dir, 971606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int Rn, int W, uint32_t reg_list) 972606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ // FA EA FD ED IB IA DB DA 973606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // const uint8_t P[8] = { 0, 1, 0, 1, 1, 0, 1, 0 }; 974606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // const uint8_t U[8] = { 0, 0, 1, 1, 1, 1, 0, 0 }; 975606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | (4<<25) | (uint32_t(P[dir])<<24) | 976606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // (uint32_t(U[dir])<<23) | (0<<20) | (W<<21) | (Rn<<16) | reg_list; 977606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 978606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 979606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 980606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 981606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 982606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 983606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 984606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 985606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 986606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark Special... 987606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 988606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 989606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// special... 990606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SWP(int cc, int Rn, int Rd, int Rm) { 991606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | (2<<23) | (Rn<<16) | (Rd << 12) | 0x90 | Rm; 992606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 993606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 994606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 995606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 996606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 997606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SWPB(int cc, int Rn, int Rd, int Rm) { 998606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | (2<<23) | (1<<22) | (Rn<<16) | (Rd << 12) | 0x90 | Rm; 999606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1000606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1001606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1002606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1003606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1004606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SWI(int cc, uint32_t comment) { 1005606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | (0xF<<24) | comment; 1006606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1007606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1008606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1009606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1010606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1011606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1012606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 1013606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 1014606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark DSP instructions... 1015606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 1016606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1017606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// DSP instructions... 1018606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::PLD(int Rn, uint32_t offset) { 1019606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL_IF(!((offset&(1<<24)) && !(offset&(1<<21))), 1020606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "PLD only P=1, W=0"); 1021606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = 0xF550F000 | (Rn<<16) | offset; 1022606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1023606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1024606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1025606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1026606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1027606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::CLZ(int cc, int Rd, int Rm) 1028606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1029606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1030606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->CLZ(Rd, Rm); 1031606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1032606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1033606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::QADD(int cc, int Rd, int Rm, int Rn) 1034606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1035606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | 0x1000050 | (Rn<<16) | (Rd<<12) | Rm; 1036606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1037606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1038606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1039606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1040606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1041606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::QDADD(int cc, int Rd, int Rm, int Rn) 1042606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1043606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | 0x1400050 | (Rn<<16) | (Rd<<12) | Rm; 1044606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1045606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1046606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1047606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1048606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1049606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::QSUB(int cc, int Rd, int Rm, int Rn) 1050606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1051606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | 0x1200050 | (Rn<<16) | (Rd<<12) | Rm; 1052606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1053606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1054606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1055606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1056606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1057606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::QDSUB(int cc, int Rd, int Rm, int Rn) 1058606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1059606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | 0x1600050 | (Rn<<16) | (Rd<<12) | Rm; 1060606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1061606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1062606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1063606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1064606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1065606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// 16 x 16 signed multiply (like SMLAxx without the accumulate) 1066606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SMUL(int cc, int xy, 1067606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int Rd, int Rm, int Rs) 1068606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1069606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1070606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1071606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // the 16 bits may be in the top or bottom half of 32-bit source reg, 1072606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // as defined by the codes BB, BT, TB, TT (compressed param xy) 1073606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // where x corresponds to Rm and y to Rs 1074606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1075606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // select half-reg for Rm 1076606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (xy & xyTB) { 1077606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // use top 16-bits 1078606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SRA(R_at, Rm, 16); 1079606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 1080606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // use bottom 16, but sign-extend to 32 1081606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SEH(R_at, Rm); 1082606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1083606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // select half-reg for Rs 1084606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (xy & xyBT) { 1085606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // use top 16-bits 1086606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SRA(R_at2, Rs, 16); 1087606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 1088606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // use bottom 16, but sign-extend to 32 1089606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SEH(R_at2, Rs); 1090606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1091606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MUL(Rd, R_at, R_at2); 1092606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1093606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1094606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// signed 32b x 16b multiple, save top 32-bits of 48-bit result 1095606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SMULW(int cc, int y, 1096606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int Rd, int Rm, int Rs) 1097606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1098606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1099606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1100606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // the selector yT or yB refers to reg Rs 1101606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (y & yT) { 1102606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // zero the bottom 16-bits, with 2 shifts, it can affect result 1103606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SRL(R_at, Rs, 16); 1104606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SLL(R_at, R_at, 16); 1105606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1106606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 1107606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // move low 16-bit half, to high half 1108606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SLL(R_at, Rs, 16); 1109606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1110606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MUH(Rd, Rm, R_at); 1111606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1112606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1113606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// 16 x 16 signed multiply, accumulate: Rd = Rm{16} * Rs{16} + Rn 1114606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SMLA(int cc, int xy, 1115606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int Rd, int Rm, int Rs, int Rn) 1116606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1117606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1118606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1119606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // the 16 bits may be in the top or bottom half of 32-bit source reg, 1120606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // as defined by the codes BB, BT, TB, TT (compressed param xy) 1121606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // where x corresponds to Rm and y to Rs 1122606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1123606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // select half-reg for Rm 1124606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (xy & xyTB) { 1125606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // use top 16-bits 1126606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SRA(R_at, Rm, 16); 1127606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 1128606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // use bottom 16, but sign-extend to 32 1129606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SEH(R_at, Rm); 1130606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1131606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // select half-reg for Rs 1132606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (xy & xyBT) { 1133606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // use top 16-bits 1134606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SRA(R_at2, Rs, 16); 1135606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 1136606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // use bottom 16, but sign-extend to 32 1137606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SEH(R_at2, Rs); 1138606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1139606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1140606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->MUL(R_at, R_at, R_at2); 1141606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ADDU(Rd, R_at, Rn); 1142606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1143606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1144606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SMLAL(int cc, int xy, 1145606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int RdHi, int RdLo, int Rs, int Rm) 1146606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1147606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | 0x1400080 | (RdHi<<16) | (RdLo<<12) | (Rs<<8) | (xy<<4) | Rm; 1148606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1149606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1150606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1151606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1152606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1153606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::SMLAW(int cc, int y, 1154606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int Rd, int Rm, int Rs, int Rn) 1155606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1156606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // *mPC++ = (cc<<28) | 0x1200080 | (Rd<<16) | (Rn<<12) | (Rs<<8) | (y<<4) | Rm; 1157606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1158606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1159606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1160606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1161606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1162606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// used by ARMv6 version of GGLAssembler::filter32 1163606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::UXTB16(int cc, int Rd, int Rm, int rotate) 1164606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1165606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1166606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1167606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes //Rd[31:16] := ZeroExtend((Rm ROR (8 * sh))[23:16]), 1168606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes //Rd[15:0] := ZeroExtend((Rm ROR (8 * sh))[7:0]). sh 0-3. 1169606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1170606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ROTR(R_at2, Rm, rotate * 8); 1171606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LUI(R_at, 0xFF); 1172606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->ORI(R_at, R_at, 0xFF); 1173606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->AND(Rd, R_at2, R_at); 1174606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1175606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1176606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::UBFX(int cc, int Rd, int Rn, int lsb, int width) 1177606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1178606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes /* Placeholder for UBFX */ 1179606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1180606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1181606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->NOP2(); 1182606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes NOT_IMPLEMENTED(); 1183606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1184606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1185606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// ---------------------------------------------------------------------------- 1186606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// Address Processing... 1187606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// ---------------------------------------------------------------------------- 1188606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1189606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::ADDR_ADD(int cc, 1190606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int s, int Rd, int Rn, uint32_t Op2) 1191606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1192606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// if(cc != AL){ NOT_IMPLEMENTED(); return;} //Not required 1193606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// if(s != 0) { NOT_IMPLEMENTED(); return;} //Not required 1194606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes dataProcessing(opADD64, cc, s, Rd, Rn, Op2); 1195606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1196606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1197606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::ADDR_SUB(int cc, 1198606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int s, int Rd, int Rn, uint32_t Op2) 1199606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1200606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// if(cc != AL){ NOT_IMPLEMENTED(); return;} //Not required 1201606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes// if(s != 0) { NOT_IMPLEMENTED(); return;} //Not required 1202606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes dataProcessing(opSUB64, cc, s, Rd, Rn, Op2); 1203606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1204606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1205606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::ADDR_LDR(int cc, int Rd, int Rn, uint32_t offset) { 1206606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1207606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // work-around for ARM default address mode of immed12_pre(0) 1208606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (offset > AMODE_UNSUPPORTED) offset = 0; 1209606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (offset) { 1210606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case 0: 1211606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = 0; 1212606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.writeback = 0; 1213606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // fall thru to next case .... 1214606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_PRE: 1215606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (Rn == ARMAssemblerInterface::SP) { 1216606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes Rn = R_sp; // convert LDR via Arm SP to LW via Mips SP 1217606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1218606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LD(Rd, Rn, amode.value); 1219606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.writeback) { // OPTIONAL writeback on pre-index mode 1220606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 1221606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1222606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 1223606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_POST: 1224606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (Rn == ARMAssemblerInterface::SP) { 1225606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes Rn = R_sp; // convert STR thru Arm SP to STR thru Mips SP 1226606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1227606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LD(Rd, Rn, 0); 1228606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 1229606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 1230606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_REG_SCALE_PRE: 1231606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // we only support simple base + index, no advanced modes for this one yet 1232606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDU(R_at, Rn, amode.reg); 1233606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->LD(Rd, R_at, 0); 1234606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 1235606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1236606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1237606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1238606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid ArmToMips64Assembler::ADDR_STR(int cc, int Rd, int Rn, uint32_t offset) { 1239606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mArmPC[mInum++] = pc(); 1240606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // work-around for ARM default address mode of immed12_pre(0) 1241606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (offset > AMODE_UNSUPPORTED) offset = 0; 1242606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes switch (offset) { 1243606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case 0: 1244606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.value = 0; 1245606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes amode.writeback = 0; 1246606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // fall thru to next case .... 1247606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_PRE: 1248606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (Rn == ARMAssemblerInterface::SP) { 1249606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes Rn = R_sp; // convert STR thru Arm SP to SW thru Mips SP 1250606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1251606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (amode.writeback) { // OPTIONAL writeback on pre-index mode 1252606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // If we will writeback, then update the index reg, then store. 1253606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // This correctly handles stack-push case. 1254606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); 1255606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SD(Rd, Rn, 0); 1256606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 1257606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // No writeback so store offset by value 1258606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SD(Rd, Rn, amode.value); 1259606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1260606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 1261606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_IMM_12_POST: 1262606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SD(Rd, Rn, 0); 1263606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDIU(Rn, Rn, amode.value); // post index always writes back 1264606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 1265606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes case AMODE_REG_SCALE_PRE: 1266606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // we only support simple base + index, no advanced modes for this one yet 1267606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->DADDU(R_at, Rn, amode.reg); 1268606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mMips->SD(Rd, R_at, 0); 1269606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes break; 1270606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1271606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1272606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1273606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if 0 1274606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark - 1275606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#pragma mark MIPS Assembler... 1276606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 1277606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1278606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1279606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes//************************************************************************** 1280606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes//************************************************************************** 1281606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes//************************************************************************** 1282606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1283606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1284606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes/* MIPS64 assembler 1285606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** this is a subset of mips64r6, targeted specifically at ARM instruction 1286606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** replacement in the pixelflinger/codeflinger code. 1287606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** 1288606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** This class is extended from MIPSAssembler class and overrides only 1289606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** MIPS64r6 specific stuff. 1290606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes*/ 1291606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1292606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesMIPS64Assembler::MIPS64Assembler(const sp<Assembly>& assembly, ArmToMips64Assembler *parent) 1293606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : mParent(parent), 1294606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes MIPSAssembler::MIPSAssembler(assembly, NULL) 1295606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1296606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1297606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1298606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesMIPS64Assembler::MIPS64Assembler(void* assembly, ArmToMips64Assembler *parent) 1299606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : mParent(parent), 1300e0c9f2bc5a6ab19fa6e457a30a0f1231e09b0afbLjubomir Papuga MIPSAssembler::MIPSAssembler(assembly) 1301606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1302606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1303606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1304606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesMIPS64Assembler::~MIPS64Assembler() 1305606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1306606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1307606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1308606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::reset() 1309606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1310606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (mAssembly != NULL) { 1311606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mBase = mPC = (uint32_t *)mAssembly->base(); 1312606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 1313606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mPC = mBase = base(); 1314606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1315606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mBranchTargets.clear(); 1316606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mLabels.clear(); 1317606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mLabelsInverseMapping.clear(); 1318606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mComments.clear(); 1319606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1320606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1321606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1322606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::disassemble(const char* name) 1323606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1324606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes char di_buf[140]; 1325606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1326606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes bool arm_disasm_fmt = (mParent->mArmDisassemblyBuffer == NULL) ? false : true; 1327606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1328606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes typedef char dstr[40]; 1329606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes dstr *lines = (dstr *)mParent->mArmDisassemblyBuffer; 1330606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1331606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (mParent->mArmDisassemblyBuffer != NULL) { 1332606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes for (int i=0; i<mParent->mArmInstrCount; ++i) { 1333606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes string_detab(lines[i]); 1334606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1335606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1336606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1337606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // iArm is an index to Arm instructions 1...n for this assembly sequence 1338606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // mArmPC[iArm] holds the value of the Mips-PC for the first MIPS 1339606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // instruction corresponding to that Arm instruction number 1340606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1341606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int iArm = 0; 1342606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes size_t count = pc()-base(); 1343606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes uint32_t* mipsPC = base(); 1344606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1345606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes while (count--) { 1346606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ssize_t label = mLabelsInverseMapping.indexOfKey(mipsPC); 1347606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (label >= 0) { 1348606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ALOGW("%s:\n", mLabelsInverseMapping.valueAt(label)); 1349606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1350606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ssize_t comment = mComments.indexOfKey(mipsPC); 1351606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (comment >= 0) { 1352606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ALOGW("; %s\n", mComments.valueAt(comment)); 1353606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1354606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ::mips_disassem(mipsPC, di_buf, arm_disasm_fmt); 1355606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes string_detab(di_buf); 1356606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes string_pad(di_buf, 30); 1357606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ALOGW("%08lx: %08x %s", uintptr_t(mipsPC), uint32_t(*mipsPC), di_buf); 1358606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes mipsPC++; 1359606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1360606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1361606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1362606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::fix_branches() 1363606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1364606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes // fixup all the branches 1365606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes size_t count = mBranchTargets.size(); 1366606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes while (count--) { 1367606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes const branch_target_t& bt = mBranchTargets[count]; 1368606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes uint32_t* target_pc = mLabels.valueFor(bt.label); 1369606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes LOG_ALWAYS_FATAL_IF(!target_pc, 1370606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "error resolving branch targets, target_pc is null"); 1371606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int32_t offset = int32_t(target_pc - (bt.pc+1)); 1372606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *bt.pc |= offset & 0x00FFFF; 1373606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 1374606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1375606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1376606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::DADDU(int Rd, int Rs, int Rt) 1377606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1378606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (spec_op<<OP_SHF) | (daddu_fn<<FUNC_SHF) 1379606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes | (Rs<<RS_SHF) | (Rt<<RT_SHF) | (Rd<<RD_SHF); 1380606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1381606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1382606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::DADDIU(int Rt, int Rs, int16_t imm) 1383606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1384606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (daddiu_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | (imm & MSK_16); 1385606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1386606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1387606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::DSUBU(int Rd, int Rs, int Rt) 1388606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1389606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (spec_op<<OP_SHF) | (dsubu_fn<<FUNC_SHF) | 1390606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes (Rs<<RS_SHF) | (Rt<<RT_SHF) | (Rd<<RD_SHF) ; 1391606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1392606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1393606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::DSUBIU(int Rt, int Rs, int16_t imm) // really addiu(d, s, -j) 1394606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1395606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (daddiu_op<<OP_SHF) | (Rt<<RT_SHF) | (Rs<<RS_SHF) | ((-imm) & MSK_16); 1396606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1397606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1398606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::MUL(int Rd, int Rs, int Rt) 1399606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1400606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (spec_op<<OP_SHF) | (mul_fn<<RE_SHF) | (sop30_fn<<FUNC_SHF) | 1401606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes (Rs<<RS_SHF) | (Rt<<RT_SHF) | (Rd<<RD_SHF) ; 1402606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1403606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1404606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::MUH(int Rd, int Rs, int Rt) 1405606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1406606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (spec_op<<OP_SHF) | (muh_fn<<RE_SHF) | (sop30_fn<<FUNC_SHF) | 1407606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes (Rs<<RS_SHF) | (Rt<<RT_SHF) | (Rd<<RD_SHF) ; 1408606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1409606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1410606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::CLO(int Rd, int Rs) 1411606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1412606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (spec_op<<OP_SHF) | (17<<FUNC_SHF) | 1413606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes (Rd<<RD_SHF) | (Rs<<RS_SHF) | (1<<RE_SHF); 1414606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1415606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1416606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::CLZ(int Rd, int Rs) 1417606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1418606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (spec_op<<OP_SHF) | (16<<FUNC_SHF) | 1419606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes (Rd<<RD_SHF) | (Rs<<RS_SHF) | (1<<RE_SHF); 1420606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1421606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1422606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::LD(int Rt, int Rbase, int16_t offset) 1423606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1424606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (ld_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16); 1425606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1426606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1427606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::SD(int Rt, int Rbase, int16_t offset) 1428606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1429606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (sd_op<<OP_SHF) | (Rbase<<RS_SHF) | (Rt<<RT_SHF) | (offset & MSK_16); 1430606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1431606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1432606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::LUI(int Rt, int16_t offset) 1433606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1434606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (aui_op<<OP_SHF) | (Rt<<RT_SHF) | (offset & MSK_16); 1435606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1436606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1437606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1438606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesvoid MIPS64Assembler::JR(int Rs) 1439606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes{ 1440606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *mPC++ = (spec_op<<OP_SHF) | (Rs<<RS_SHF) | (jalr_fn << FUNC_SHF); 1441606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes MIPS64Assembler::NOP(); 1442606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 1443606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 1444606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes}; // namespace android: 1445