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