Home | History | Annotate | Download | only in mips64
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <machine/regdef.h>
     18 
     19 /* TODO: add the missing file and use its FP register definitions. */
     20 /* #include <machine/fpregdef.h> */
     21 /* FP register definitions */
     22 #define f0  $$f0
     23 #define f1  $$f1
     24 #define f2  $$f2
     25 #define f3  $$f3
     26 #define f12 $$f12
     27 #define f13 $$f13
     28 
     29 /*
     30  * It looks like the GNU assembler currently does not support the blec and bgtc
     31  * idioms, which should translate into bgec and bltc respectively with swapped
     32  * left and right register operands.
     33  * TODO: remove these macros when the assembler is fixed.
     34  */
     35 .macro blec lreg, rreg, target
     36     bgec    \rreg, \lreg, \target
     37 .endm
     38 .macro bgtc lreg, rreg, target
     39     bltc    \rreg, \lreg, \target
     40 .endm
     41 
     42 /*
     43 Mterp and MIPS64 notes:
     44 
     45 The following registers have fixed assignments:
     46 
     47   reg nick      purpose
     48   s0  rPC       interpreted program counter, used for fetching instructions
     49   s1  rFP       interpreted frame pointer, used for accessing locals and args
     50   s2  rSELF     self (Thread) pointer
     51   s3  rINST     first 16-bit code unit of current instruction
     52   s4  rIBASE    interpreted instruction base pointer, used for computed goto
     53   s5  rREFS     base of object references in shadow frame  (ideally, we'll get rid of this later).
     54 */
     55 
     56 /* During bringup, we'll use the shadow frame model instead of rFP */
     57 /* single-purpose registers, given names for clarity */
     58 #define rPC     s0
     59 #define rFP     s1
     60 #define rSELF   s2
     61 #define rINST   s3
     62 #define rIBASE  s4
     63 #define rREFS   s5
     64 
     65 /*
     66  * This is a #include, not a %include, because we want the C pre-processor
     67  * to expand the macros into assembler assignment statements.
     68  */
     69 #include "asm_support.h"
     70 
     71 /*
     72  * Instead of holding a pointer to the shadow frame, we keep rFP at the base of the vregs.  So,
     73  * to access other shadow frame fields, we need to use a backwards offset.  Define those here.
     74  */
     75 #define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET)
     76 #define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET)
     77 #define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET)
     78 #define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET)
     79 #define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET)
     80 #define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET)
     81 #define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET)
     82 #define OFF_FP_CODE_ITEM OFF_FP(SHADOWFRAME_CODE_ITEM_OFFSET)
     83 #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET)
     84 
     85 #define MTERP_PROFILE_BRANCHES 1
     86 #define MTERP_LOGGING 0
     87 
     88 /*
     89  * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects.  Must
     90  * be done *before* something throws.
     91  *
     92  * It's okay to do this more than once.
     93  *
     94  * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped
     95  * dex byte codes.  However, the rest of the runtime expects dex pc to be an instruction
     96  * offset into the code_items_[] array.  For effiency, we will "export" the
     97  * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC
     98  * to convert to a dex pc when needed.
     99  */
    100 .macro EXPORT_PC
    101     sd      rPC, OFF_FP_DEX_PC_PTR(rFP)
    102 .endm
    103 
    104 /*
    105  * Refresh handler table.
    106  */
    107 .macro REFRESH_IBASE
    108     ld      rIBASE, THREAD_CURRENT_IBASE_OFFSET(rSELF)
    109 .endm
    110 
    111 /*
    112  * Fetch the next instruction from rPC into rINST.  Does not advance rPC.
    113  */
    114 .macro FETCH_INST
    115     lhu     rINST, 0(rPC)
    116 .endm
    117 
    118 /* Advance rPC by some number of code units. */
    119 .macro ADVANCE count
    120     daddu   rPC, rPC, (\count) * 2
    121 .endm
    122 
    123 /*
    124  * Fetch the next instruction from the specified offset.  Advances rPC
    125  * to point to the next instruction.
    126  *
    127  * This must come AFTER anything that can throw an exception, or the
    128  * exception catch may miss.  (This also implies that it must come after
    129  * EXPORT_PC.)
    130  */
    131 .macro FETCH_ADVANCE_INST count
    132     ADVANCE \count
    133     FETCH_INST
    134 .endm
    135 
    136 /*
    137  * Similar to FETCH_ADVANCE_INST, but does not update rPC.  Used to load
    138  * rINST ahead of possible exception point.  Be sure to manually advance rPC
    139  * later.
    140  */
    141 .macro PREFETCH_INST count
    142     lhu     rINST, ((\count) * 2)(rPC)
    143 .endm
    144 
    145 /*
    146  * Put the instruction's opcode field into the specified register.
    147  */
    148 .macro GET_INST_OPCODE reg
    149     and     \reg, rINST, 255
    150 .endm
    151 
    152 /*
    153  * Begin executing the opcode in _reg.
    154  */
    155 .macro GOTO_OPCODE reg
    156     .set noat
    157     sll     AT, \reg, 7
    158     daddu   AT, rIBASE, AT
    159     jic     AT, 0
    160     .set at
    161 .endm
    162 
    163 /*
    164  * Get/set the 32-bit value from a Dalvik register.
    165  * Note, GET_VREG does sign extension to 64 bits while
    166  * GET_VREG_U does zero extension to 64 bits.
    167  * One is useful for arithmetic while the other is
    168  * useful for storing the result value as 64-bit.
    169  */
    170 .macro GET_VREG reg, vreg
    171     .set noat
    172     dlsa    AT, \vreg, rFP, 2
    173     lw      \reg, 0(AT)
    174     .set at
    175 .endm
    176 .macro GET_VREG_U reg, vreg
    177     .set noat
    178     dlsa    AT, \vreg, rFP, 2
    179     lwu     \reg, 0(AT)
    180     .set at
    181 .endm
    182 .macro GET_VREG_FLOAT reg, vreg
    183     .set noat
    184     dlsa    AT, \vreg, rFP, 2
    185     lwc1    \reg, 0(AT)
    186     .set at
    187 .endm
    188 .macro SET_VREG reg, vreg
    189     .set noat
    190     dlsa    AT, \vreg, rFP, 2
    191     sw      \reg, 0(AT)
    192     dlsa    AT, \vreg, rREFS, 2
    193     sw      zero, 0(AT)
    194     .set at
    195 .endm
    196 .macro SET_VREG_OBJECT reg, vreg
    197     .set noat
    198     dlsa    AT, \vreg, rFP, 2
    199     sw      \reg, 0(AT)
    200     dlsa    AT, \vreg, rREFS, 2
    201     sw      \reg, 0(AT)
    202     .set at
    203 .endm
    204 .macro SET_VREG_FLOAT reg, vreg
    205     .set noat
    206     dlsa    AT, \vreg, rFP, 2
    207     swc1    \reg, 0(AT)
    208     dlsa    AT, \vreg, rREFS, 2
    209     sw      zero, 0(AT)
    210     .set at
    211 .endm
    212 
    213 /*
    214  * Get/set the 64-bit value from a Dalvik register.
    215  * Avoid unaligned memory accesses.
    216  * Note, SET_VREG_WIDE clobbers the register containing the value being stored.
    217  * Note, SET_VREG_DOUBLE clobbers the register containing the Dalvik register number.
    218  */
    219 .macro GET_VREG_WIDE reg, vreg
    220     .set noat
    221     dlsa    AT, \vreg, rFP, 2
    222     lw      \reg, 0(AT)
    223     lw      AT, 4(AT)
    224     dinsu   \reg, AT, 32, 32
    225     .set at
    226 .endm
    227 .macro GET_VREG_DOUBLE reg, vreg
    228     .set noat
    229     dlsa    AT, \vreg, rFP, 2
    230     lwc1    \reg, 0(AT)
    231     lw      AT, 4(AT)
    232     mthc1   AT, \reg
    233     .set at
    234 .endm
    235 .macro SET_VREG_WIDE reg, vreg
    236     .set noat
    237     dlsa    AT, \vreg, rFP, 2
    238     sw      \reg, 0(AT)
    239     drotr32 \reg, \reg, 0
    240     sw      \reg, 4(AT)
    241     dlsa    AT, \vreg, rREFS, 2
    242     sw      zero, 0(AT)
    243     sw      zero, 4(AT)
    244     .set at
    245 .endm
    246 .macro SET_VREG_DOUBLE reg, vreg
    247     .set noat
    248     dlsa    AT, \vreg, rREFS, 2
    249     sw      zero, 0(AT)
    250     sw      zero, 4(AT)
    251     dlsa    AT, \vreg, rFP, 2
    252     swc1    \reg, 0(AT)
    253     mfhc1   \vreg, \reg
    254     sw      \vreg, 4(AT)
    255     .set at
    256 .endm
    257 
    258 /*
    259  * On-stack offsets for spilling/unspilling callee-saved registers
    260  * and the frame size.
    261  */
    262 #define STACK_OFFSET_RA 0
    263 #define STACK_OFFSET_GP 8
    264 #define STACK_OFFSET_S0 16
    265 #define STACK_OFFSET_S1 24
    266 #define STACK_OFFSET_S2 32
    267 #define STACK_OFFSET_S3 40
    268 #define STACK_OFFSET_S4 48
    269 #define STACK_OFFSET_S5 56
    270 #define STACK_SIZE      64
    271 
    272 /* Constants for float/double_to_int/long conversions */
    273 #define INT_MIN             0x80000000
    274 #define INT_MIN_AS_FLOAT    0xCF000000
    275 #define INT_MIN_AS_DOUBLE   0xC1E0000000000000
    276 #define LONG_MIN            0x8000000000000000
    277 #define LONG_MIN_AS_FLOAT   0xDF000000
    278 #define LONG_MIN_AS_DOUBLE  0xC3E0000000000000
    279