1200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 2200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Copyright (C) 2016 The Android Open Source Project 3200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * 4200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Licensed under the Apache License, Version 2.0 (the "License"); 5200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * you may not use this file except in compliance with the License. 6200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * You may obtain a copy of the License at 7200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * 8200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * http://www.apache.org/licenses/LICENSE-2.0 9200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * 10200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Unless required by applicable law or agreed to in writing, software 11200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * distributed under the License is distributed on an "AS IS" BASIS, 12200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * See the License for the specific language governing permissions and 14200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * limitations under the License. 15200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 16200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 17200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 18200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung Art assembly interpreter notes: 19200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 20200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung First validate assembly code by implementing ExecuteXXXImpl() style body (doesn't 21200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung handle invoke, allows higher-level code to create frame & shadow frame. 22200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 23200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung Once that's working, support direct entry code & eliminate shadow frame (and 24200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung excess locals allocation. 25200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 26200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung Some (hopefully) temporary ugliness. We'll treat rFP as pointing to the 27200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung base of the vreg array within the shadow frame. Access the other fields, 28200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung dex_pc_, method_ and number_of_vregs_ via negative offsets. For now, we'll continue 29200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung the shadow frame mechanism of double-storing object references - via rFP & 30200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung number_of_vregs_. 31200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 32200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 33200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 34200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#include "asm_support.h" 35200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 36200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#if (__mips==32) && (__mips_isa_rev>=2) 37200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define MIPS32REVGE2 /* mips32r2 and greater */ 38200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#if (__mips==32) && (__mips_isa_rev>=5) 39200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define FPU64 /* 64 bit FPU */ 40200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#if (__mips==32) && (__mips_isa_rev>=6) 41200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define MIPS32REVGE6 /* mips32r6 and greater */ 42200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#endif 43200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#endif 44200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#endif 45200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 46200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* MIPS definitions and declarations 47200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 48200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung reg nick purpose 49200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s0 rPC interpreted program counter, used for fetching instructions 50200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s1 rFP interpreted frame pointer, used for accessing locals and args 51200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s2 rSELF self (Thread) pointer 52200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s3 rIBASE interpreted instruction base pointer, used for computed goto 53200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s4 rINST first 16-bit code unit of current instruction 54200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s6 rREFS base of object references in shadow frame (ideally, we'll get rid of this later). 55200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung*/ 56200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 57200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* single-purpose registers, given names for clarity */ 58200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rPC s0 59200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rFP s1 60200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rSELF s2 61200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rIBASE s3 62200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rINST s4 63200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rOBJ s5 64200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rREFS s6 65200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rTEMP s7 66200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 67200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rARG0 a0 68200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rARG1 a1 69200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rARG2 a2 70200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rARG3 a3 71200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rRESULT0 v0 72200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define rRESULT1 v1 73200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 74200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* GP register definitions */ 75200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define zero $$0 /* always zero */ 76200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define AT $$at /* assembler temp */ 77200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define v0 $$2 /* return value */ 78200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define v1 $$3 79200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define a0 $$4 /* argument registers */ 80200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define a1 $$5 81200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define a2 $$6 82200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define a3 $$7 83200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t0 $$8 /* temp registers (not saved across subroutine calls) */ 84200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t1 $$9 85200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t2 $$10 86200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t3 $$11 87200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t4 $$12 88200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t5 $$13 89200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t6 $$14 90200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t7 $$15 91200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ta0 $$12 /* alias */ 92200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ta1 $$13 93200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ta2 $$14 94200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ta3 $$15 95200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define s0 $$16 /* saved across subroutine calls (callee saved) */ 96200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define s1 $$17 97200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define s2 $$18 98200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define s3 $$19 99200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define s4 $$20 100200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define s5 $$21 101200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define s6 $$22 102200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define s7 $$23 103200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t8 $$24 /* two more temp registers */ 104200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define t9 $$25 105200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define k0 $$26 /* kernel temporary */ 106200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define k1 $$27 107200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define gp $$28 /* global pointer */ 108200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define sp $$29 /* stack pointer */ 109200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define s8 $$30 /* one more callee saved */ 110200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ra $$31 /* return address */ 111200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 112200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* FP register definitions */ 113200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fv0 $$f0 114200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fv0f $$f1 115200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fv1 $$f2 116200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fv1f $$f3 117200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fa0 $$f12 118200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fa0f $$f13 119200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fa1 $$f14 120200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fa1f $$f15 121200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft0 $$f4 122200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft0f $$f5 123200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft1 $$f6 124200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft1f $$f7 125200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft2 $$f8 126200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft2f $$f9 127200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft3 $$f10 128200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft3f $$f11 129200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft4 $$f16 130200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft4f $$f17 131200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft5 $$f18 132200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ft5f $$f19 133200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs0 $$f20 134200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs0f $$f21 135200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs1 $$f22 136200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs1f $$f23 137200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs2 $$f24 138200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs2f $$f25 139200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs3 $$f26 140200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs3f $$f27 141200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs4 $$f28 142200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs4f $$f29 143200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs5 $$f30 144200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fs5f $$f31 145200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 146200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#ifndef MIPS32REVGE6 147200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fcc0 $$fcc0 148200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define fcc1 $$fcc1 149200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#endif 150200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 151200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 152200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs. So, 153200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * to access other shadow frame fields, we need to use a backwards offset. Define those here. 154200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 155200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET) 156200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET) 157200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET) 158200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET) 159200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET) 160200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET) 161200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET) 162200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define OFF_FP_CODE_ITEM OFF_FP(SHADOWFRAME_CODE_ITEM_OFFSET) 163200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET) 164200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 165200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define MTERP_PROFILE_BRANCHES 1 166200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define MTERP_LOGGING 0 167200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 168200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 169200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must 170200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * be done *before* something throws. 171200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * 172200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * It's okay to do this more than once. 173200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * 174200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped 175200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction 176200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * offset into the code_items_[] array. For effiency, we will "export" the 177200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC 178200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * to convert to a dex pc when needed. 179200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 180200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define EXPORT_PC() \ 181200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rPC, OFF_FP_DEX_PC_PTR(rFP) 182200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 183200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define EXPORT_DEX_PC(tmp) \ 184200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung lw tmp, OFF_FP_CODE_ITEM(rFP) \ 185200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rPC, OFF_FP_DEX_PC_PTR(rFP) \ 186200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu tmp, CODEITEM_INSNS_OFFSET \ 187200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung subu tmp, rPC, tmp \ 188200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sra tmp, tmp, 1 \ 189200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw tmp, OFF_FP_DEX_PC(rFP) 190200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 191200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 192200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Fetch the next instruction from rPC into rINST. Does not advance rPC. 193200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 194200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define FETCH_INST() lhu rINST, (rPC) 195200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 196200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 197200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Fetch the next instruction from the specified offset. Advances rPC 198200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * to point to the next instruction. "_count" is in 16-bit code units. 199200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * 200200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * This must come AFTER anything that can throw an exception, or the 201200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * exception catch may miss. (This also implies that it must come after 202200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * EXPORT_PC().) 203200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 204200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define FETCH_ADVANCE_INST(_count) lhu rINST, ((_count)*2)(rPC); \ 205200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu rPC, rPC, ((_count) * 2) 206200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 207200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 208200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * The operation performed here is similar to FETCH_ADVANCE_INST, except the 209200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * src and dest registers are parameterized (not hard-wired to rPC and rINST). 210200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 211200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define PREFETCH_ADVANCE_INST(_dreg, _sreg, _count) \ 212200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung lhu _dreg, ((_count)*2)(_sreg) ; \ 213200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu _sreg, _sreg, (_count)*2 214200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 215200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 216200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Similar to FETCH_ADVANCE_INST, but does not update rPC. Used to load 217200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * rINST ahead of possible exception point. Be sure to manually advance rPC 218200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * later. 219200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 220200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define PREFETCH_INST(_count) lhu rINST, ((_count)*2)(rPC) 221200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 222200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* Advance rPC by some number of code units. */ 223200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ADVANCE(_count) addu rPC, rPC, ((_count) * 2) 224200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 225200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 226200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Fetch the next instruction from an offset specified by rd. Updates 227200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * rPC to point to the next instruction. "rd" must specify the distance 228200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * in bytes, *not* 16-bit code units, and may be a signed value. 229200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 230200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define FETCH_ADVANCE_INST_RB(rd) addu rPC, rPC, rd; \ 231200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung lhu rINST, (rPC) 232200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 233200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 234200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Fetch a half-word code unit from an offset past the current PC. The 235200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * "_count" value is in 16-bit code units. Does not advance rPC. 236200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * 237200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * The "_S" variant works the same but treats the value as signed. 238200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 239200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define FETCH(rd, _count) lhu rd, ((_count) * 2)(rPC) 240200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define FETCH_S(rd, _count) lh rd, ((_count) * 2)(rPC) 241200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 242200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 243200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Fetch one byte from an offset past the current PC. Pass in the same 244200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * "_count" as you would for FETCH, and an additional 0/1 indicating which 245200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * byte of the halfword you want (lo/hi). 246200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 247200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define FETCH_B(rd, _count, _byte) lbu rd, ((_count) * 2 + _byte)(rPC) 248200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 249200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 250200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Put the instruction's opcode field into the specified register. 251200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 252200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GET_INST_OPCODE(rd) and rd, rINST, 0xFF 253200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 254200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 255200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Put the prefetched instruction's opcode field into the specified register. 256200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 257200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GET_PREFETCHED_OPCODE(dreg, sreg) andi dreg, sreg, 255 258200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 259200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 260200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Begin executing the opcode in rd. 261200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 262200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GOTO_OPCODE(rd) sll rd, rd, ${handler_size_bits}; \ 263200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu rd, rIBASE, rd; \ 264200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung jalr zero, rd 265200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 266200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GOTO_OPCODE_BASE(_base, rd) sll rd, rd, ${handler_size_bits}; \ 267200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu rd, _base, rd; \ 268200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung jalr zero, rd 269200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 270200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 271200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Get/set the 32-bit value from a Dalvik register. 272200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 273200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GET_VREG(rd, rix) LOAD_eas2(rd, rFP, rix) 274200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 275200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GET_VREG_F(rd, rix) EAS2(AT, rFP, rix); \ 276200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set noat; l.s rd, (AT); .set at 277200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 278200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define SET_VREG(rd, rix) .set noat; \ 279200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll AT, rix, 2; \ 280200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rFP, AT; \ 281200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rd, 0(t8); \ 282200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rREFS, AT; \ 283200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at; \ 284200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 0(t8) 285200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 286200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define SET_VREG64(rlo, rhi, rix) .set noat; \ 287200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll AT, rix, 2; \ 288200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rFP, AT; \ 289200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rlo, 0(t8); \ 290200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rhi, 4(t8); \ 291200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rREFS, AT; \ 292200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at; \ 293200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 0(t8); \ 294200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 4(t8) 295200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 296200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#ifdef FPU64 297200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define SET_VREG64_F(rlo, rhi, rix) .set noat; \ 298200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll AT, rix, 2; \ 299200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rREFS, AT; \ 300200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 0(t8); \ 301200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 4(t8); \ 302200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rFP, AT; \ 303200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung mfhc1 AT, rlo; \ 304200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw AT, 4(t8); \ 305200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at; \ 306200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s.s rlo, 0(t8) 307200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#else 308200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define SET_VREG64_F(rlo, rhi, rix) .set noat; \ 309200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll AT, rix, 2; \ 310200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rFP, AT; \ 311200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s.s rlo, 0(t8); \ 312200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s.s rhi, 4(t8); \ 313200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rREFS, AT; \ 314200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at; \ 315200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 0(t8); \ 316200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 4(t8) 317200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#endif 318200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 319200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define SET_VREG_OBJECT(rd, rix) .set noat; \ 320200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll AT, rix, 2; \ 321200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rFP, AT; \ 322200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rd, 0(t8); \ 323200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rREFS, AT; \ 324200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at; \ 325200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rd, 0(t8) 326200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 327200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* Combination of the SET_VREG and GOTO_OPCODE functions to save 1 instruction */ 328200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define SET_VREG_GOTO(rd, rix, dst) .set noreorder; \ 329200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll dst, dst, ${handler_size_bits}; \ 330200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu dst, rIBASE, dst; \ 331200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set noat; \ 332200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll AT, rix, 2; \ 333200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rFP, AT; \ 334200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rd, 0(t8); \ 335200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rREFS, AT; \ 336200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at; \ 337200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung jalr zero, dst; \ 338200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 0(t8); \ 339200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set reorder 340200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 341200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* Combination of the SET_VREG64 and GOTO_OPCODE functions to save 1 instruction */ 342200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define SET_VREG64_GOTO(rlo, rhi, rix, dst) .set noreorder; \ 343200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll dst, dst, ${handler_size_bits}; \ 344200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu dst, rIBASE, dst; \ 345200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set noat; \ 346200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll AT, rix, 2; \ 347200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rFP, AT; \ 348200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rlo, 0(t8); \ 349200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rhi, 4(t8); \ 350200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rREFS, AT; \ 351200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at; \ 352200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 0(t8); \ 353200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung jalr zero, dst; \ 354200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 4(t8); \ 355200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set reorder 356200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 357200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define SET_VREG_F(rd, rix) .set noat; \ 358200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll AT, rix, 2; \ 359200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rFP, AT; \ 360200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s.s rd, 0(t8); \ 361200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu t8, rREFS, AT; \ 362200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at; \ 363200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw zero, 0(t8) 364200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 365200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GET_OPA(rd) srl rd, rINST, 8 366200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#ifdef MIPS32REVGE2 367200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GET_OPA4(rd) ext rd, rINST, 8, 4 368200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#else 369200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GET_OPA4(rd) GET_OPA(rd); and rd, 0xf 370200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#endif 371200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define GET_OPB(rd) srl rd, rINST, 12 372200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 373200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 374200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Form an Effective Address rd = rbase + roff<<n; 375200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Uses reg AT 376200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 377200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define EASN(rd, rbase, roff, rshift) .set noat; \ 378200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sll AT, roff, rshift; \ 379200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu rd, rbase, AT; \ 380200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at 381200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 382200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define EAS1(rd, rbase, roff) EASN(rd, rbase, roff, 1) 383200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define EAS2(rd, rbase, roff) EASN(rd, rbase, roff, 2) 384200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define EAS3(rd, rbase, roff) EASN(rd, rbase, roff, 3) 385200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define EAS4(rd, rbase, roff) EASN(rd, rbase, roff, 4) 386200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 387200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 388200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Form an Effective Shift Right rd = rbase + roff>>n; 389200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * Uses reg AT 390200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 391200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define ESRN(rd, rbase, roff, rshift) .set noat; \ 392200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung srl AT, roff, rshift; \ 393200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung addu rd, rbase, AT; \ 394200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at 395200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 396200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD_eas2(rd, rbase, roff) EAS2(AT, rbase, roff); \ 397200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set noat; lw rd, 0(AT); .set at 398200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 399200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STORE_eas2(rd, rbase, roff) EAS2(AT, rbase, roff); \ 400200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set noat; sw rd, 0(AT); .set at 401200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 402200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD_RB_OFF(rd, rbase, off) lw rd, off(rbase) 403200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STORE_RB_OFF(rd, rbase, off) sw rd, off(rbase) 404200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 405200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STORE64_off(rlo, rhi, rbase, off) sw rlo, off(rbase); \ 406200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw rhi, (off+4)(rbase) 407200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD64_off(rlo, rhi, rbase, off) lw rlo, off(rbase); \ 408200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung lw rhi, (off+4)(rbase) 409200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 410200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STORE64(rlo, rhi, rbase) STORE64_off(rlo, rhi, rbase, 0) 411200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD64(rlo, rhi, rbase) LOAD64_off(rlo, rhi, rbase, 0) 412200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 413200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#ifdef FPU64 414200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STORE64_off_F(rlo, rhi, rbase, off) s.s rlo, off(rbase); \ 415200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set noat; \ 416200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung mfhc1 AT, rlo; \ 417200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung sw AT, (off+4)(rbase); \ 418200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at 419200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD64_off_F(rlo, rhi, rbase, off) l.s rlo, off(rbase); \ 420200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set noat; \ 421200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung lw AT, (off+4)(rbase); \ 422200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung mthc1 AT, rlo; \ 423200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung .set at 424200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#else 425200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STORE64_off_F(rlo, rhi, rbase, off) s.s rlo, off(rbase); \ 426200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung s.s rhi, (off+4)(rbase) 427200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD64_off_F(rlo, rhi, rbase, off) l.s rlo, off(rbase); \ 428200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung l.s rhi, (off+4)(rbase) 429200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#endif 430200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 431200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STORE64_F(rlo, rhi, rbase) STORE64_off_F(rlo, rhi, rbase, 0) 432200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD64_F(rlo, rhi, rbase) LOAD64_off_F(rlo, rhi, rbase, 0) 433200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 434200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 435200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD_base_offMirrorArray_length(rd, rbase) LOAD_RB_OFF(rd, rbase, MIRROR_ARRAY_LENGTH_OFFSET) 436200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 437200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_STORE(rd, off) sw rd, off(sp) 438200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_LOAD(rd, off) lw rd, off(sp) 439200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define CREATE_STACK(n) subu sp, sp, n 440200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define DELETE_STACK(n) addu sp, sp, n 441200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 442200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD_ADDR(dest, addr) la dest, addr 443200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define LOAD_IMM(dest, imm) li dest, imm 444200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define MOVE_REG(dest, src) move dest, src 445200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_SIZE 128 446200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 447200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_OFFSET_ARG04 16 448200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_OFFSET_ARG05 20 449200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_OFFSET_ARG06 24 450200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_OFFSET_ARG07 28 451200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_OFFSET_GP 84 452200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 453200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define JAL(n) jal n 454200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define BAL(n) bal n 455200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 456200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung/* 457200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * FP register usage restrictions: 458200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * 1) We don't use the callee save FP registers so we don't have to save them. 459200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung * 2) We don't use the odd FP registers so we can share code with mips32r6. 460200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung */ 461200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_STORE_FULL() CREATE_STACK(STACK_SIZE); \ 462200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(ra, 124); \ 463200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(s8, 120); \ 464200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(s0, 116); \ 465200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(s1, 112); \ 466200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(s2, 108); \ 467200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(s3, 104); \ 468200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(s4, 100); \ 469200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(s5, 96); \ 470200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(s6, 92); \ 471200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_STORE(s7, 88); 472200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung 473200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung#define STACK_LOAD_FULL() STACK_LOAD(gp, STACK_OFFSET_GP); \ 474200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(s7, 88); \ 475200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(s6, 92); \ 476200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(s5, 96); \ 477200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(s4, 100); \ 478200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(s3, 104); \ 479200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(s2, 108); \ 480200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(s1, 112); \ 481200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(s0, 116); \ 482200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(s8, 120); \ 483200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung STACK_LOAD(ra, 124); \ 484200f040af3e4fe9e178cb63c90860d58d90ef665Douglas Leung DELETE_STACK(STACK_SIZE) 485