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