Home | History | Annotate | Download | only in mips
      1 %def op_aget(load="lw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
      2     /*
      3      * Array get, 32 bits or less.  vAA <- vBB[vCC].
      4      *
      5      * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
      6      * instructions.  We use a pair of FETCH_Bs instead.
      7      *
      8      * for: aget, aget-boolean, aget-byte, aget-char, aget-short
      9      *
     10      * NOTE: assumes data offset for arrays is the same for all non-wide types.
     11      * If this changes, specialize.
     12      */
     13     /* op vAA, vBB, vCC */
     14     FETCH_B(a2, 1, 0)                      #  a2 <- BB
     15     GET_OPA(rOBJ)                          #  rOBJ <- AA
     16     FETCH_B(a3, 1, 1)                      #  a3 <- CC
     17     GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
     18     GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
     19     # null array object?
     20     beqz      a0, common_errNullObject     #  yes, bail
     21     LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- arrayObj->length
     22     EASN(a0, a0, a1, $shift)               #  a0 <- arrayObj + index*width
     23     # a1 >= a3; compare unsigned index
     24     bgeu      a1, a3, common_errArrayIndex #  index >= length, bail
     25     FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
     26     $load a2, $data_offset(a0)             #  a2 <- vBB[vCC]
     27     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
     28     SET_VREG_GOTO(a2, rOBJ, t0)            #  vAA <- a2
     29 
     30 %def op_aget_boolean():
     31 %  op_aget(load="lbu", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
     32 
     33 %def op_aget_byte():
     34 %  op_aget(load="lb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
     35 
     36 %def op_aget_char():
     37 %  op_aget(load="lhu", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
     38 
     39 %def op_aget_object():
     40     /*
     41      * Array object get.  vAA <- vBB[vCC].
     42      *
     43      * for: aget-object
     44      */
     45     /* op vAA, vBB, vCC */
     46     FETCH_B(a2, 1, 0)                      #  a2 <- BB
     47     GET_OPA(rOBJ)                          #  rOBJ <- AA
     48     FETCH_B(a3, 1, 1)                      #  a3 <- CC
     49     EXPORT_PC()
     50     GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
     51     GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
     52     JAL(artAGetObjectFromMterp)            #  v0 <- GetObj(array, index)
     53     lw   a1, THREAD_EXCEPTION_OFFSET(rSELF)
     54     PREFETCH_INST(2)                       #  load rINST
     55     bnez a1, MterpException
     56     ADVANCE(2)                             #  advance rPC
     57     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
     58     SET_VREG_OBJECT_GOTO(v0, rOBJ, t0)     #  vAA <- v0
     59 
     60 %def op_aget_short():
     61 %  op_aget(load="lh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
     62 
     63 %def op_aget_wide():
     64     /*
     65      * Array get, 64 bits.  vAA <- vBB[vCC].
     66      *
     67      * Arrays of long/double are 64-bit aligned.
     68      */
     69     /* aget-wide vAA, vBB, vCC */
     70     FETCH(a0, 1)                           #  a0 <- CCBB
     71     GET_OPA(rOBJ)                          #  rOBJ <- AA
     72     and       a2, a0, 255                  #  a2 <- BB
     73     srl       a3, a0, 8                    #  a3 <- CC
     74     GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
     75     GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
     76     # null array object?
     77     beqz      a0, common_errNullObject     #  yes, bail
     78     LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- arrayObj->length
     79     EAS3(a0, a0, a1)                       #  a0 <- arrayObj + index*width
     80     bgeu      a1, a3, common_errArrayIndex #  index >= length, bail
     81 
     82     FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
     83     LOAD64_off(a2, a3, a0, MIRROR_WIDE_ARRAY_DATA_OFFSET)
     84     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
     85     SET_VREG64_GOTO(a2, a3, rOBJ, t0)      #  vAA/vAA+1 <- a2/a3
     86 
     87 %def op_aput(store="sw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
     88 
     89     /*
     90      * Array put, 32 bits or less.  vBB[vCC] <- vAA.
     91      *
     92      * for: aput, aput-boolean, aput-byte, aput-char, aput-short
     93      *
     94      * NOTE: this assumes data offset for arrays is the same for all non-wide types.
     95      * If this changes, specialize.
     96      */
     97     /* op vAA, vBB, vCC */
     98     FETCH_B(a2, 1, 0)                      #  a2 <- BB
     99     GET_OPA(rOBJ)                          #  rOBJ <- AA
    100     FETCH_B(a3, 1, 1)                      #  a3 <- CC
    101     GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
    102     GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
    103     # null array object?
    104     beqz      a0, common_errNullObject     #  yes, bail
    105     LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- arrayObj->length
    106     EASN(a0, a0, a1, $shift)               #  a0 <- arrayObj + index*width
    107     bgeu      a1, a3, common_errArrayIndex #  index >= length, bail
    108     FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
    109     GET_VREG(a2, rOBJ)                     #  a2 <- vAA
    110     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
    111     GET_OPCODE_TARGET(t0)
    112     $store a2, $data_offset(a0)            #  vBB[vCC] <- a2
    113     JR(t0)                                 #  jump to next instruction
    114 
    115 %def op_aput_boolean():
    116 %  op_aput(store="sb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
    117 
    118 %def op_aput_byte():
    119 %  op_aput(store="sb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
    120 
    121 %def op_aput_char():
    122 %  op_aput(store="sh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
    123 
    124 %def op_aput_object():
    125     /*
    126      * Store an object into an array.  vBB[vCC] <- vAA.
    127      *
    128      */
    129     /* op vAA, vBB, vCC */
    130     EXPORT_PC()
    131     addu   a0, rFP, OFF_FP_SHADOWFRAME
    132     move   a1, rPC
    133     move   a2, rINST
    134     JAL(MterpAputObject)
    135     beqz   v0, MterpPossibleException
    136     FETCH_ADVANCE_INST(2)               # advance rPC, load rINST
    137     GET_INST_OPCODE(t0)                 # extract opcode from rINST
    138     GOTO_OPCODE(t0)                     # jump to next instruction
    139 
    140 %def op_aput_short():
    141 %  op_aput(store="sh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
    142 
    143 %def op_aput_wide():
    144     /*
    145      * Array put, 64 bits.  vBB[vCC] <- vAA.
    146      */
    147     /* aput-wide vAA, vBB, vCC */
    148     FETCH(a0, 1)                           #  a0 <- CCBB
    149     GET_OPA(t0)                            #  t0 <- AA
    150     and       a2, a0, 255                  #  a2 <- BB
    151     srl       a3, a0, 8                    #  a3 <- CC
    152     GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
    153     GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
    154     # null array object?
    155     beqz      a0, common_errNullObject     #  yes, bail
    156     LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- arrayObj->length
    157     EAS3(a0, a0, a1)                       #  a0 <- arrayObj + index*width
    158     EAS2(rOBJ, rFP, t0)                    #  rOBJ <- &fp[AA]
    159     # compare unsigned index, length
    160     bgeu      a1, a3, common_errArrayIndex #  index >= length, bail
    161 
    162     FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
    163     LOAD64(a2, a3, rOBJ)                   #  a2/a3 <- vAA/vAA+1
    164     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
    165     GET_OPCODE_TARGET(t0)
    166     STORE64_off(a2, a3, a0, MIRROR_WIDE_ARRAY_DATA_OFFSET) #  a2/a3 <- vBB[vCC]
    167     JR(t0)                                 #  jump to next instruction
    168 
    169 %def op_array_length():
    170     /*
    171      * Return the length of an array.
    172      */
    173     /* array-length vA, vB */
    174     GET_OPB(a1)                            #  a1 <- B
    175     GET_OPA4(a2)                           #  a2 <- A+
    176     GET_VREG(a0, a1)                       #  a0 <- vB (object ref)
    177     # is object null?
    178     beqz      a0, common_errNullObject     #  yup, fail
    179     FETCH_ADVANCE_INST(1)                  #  advance rPC, load rINST
    180     LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- array length
    181     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
    182     SET_VREG_GOTO(a3, a2, t0)              #  vA <- length
    183 
    184 %def op_fill_array_data():
    185     /* fill-array-data vAA, +BBBBBBBB */
    186     EXPORT_PC()
    187     FETCH(a1, 1)                           #  a1 <- bbbb (lo)
    188     FETCH(a0, 2)                           #  a0 <- BBBB (hi)
    189     GET_OPA(a3)                            #  a3 <- AA
    190     INSERT_HIGH_HALF(a1, a0)               #  a1 <- BBBBbbbb
    191     GET_VREG(a0, a3)                       #  a0 <- vAA (array object)
    192     EAS1(a1, rPC, a1)                      #  a1 <- PC + BBBBbbbb*2 (array data off.)
    193     JAL(MterpFillArrayData)                #  v0 <- Mterp(obj, payload)
    194     beqz      v0,  MterpPossibleException  #  has exception
    195     FETCH_ADVANCE_INST(3)                  #  advance rPC, load rINST
    196     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
    197     GOTO_OPCODE(t0)                        #  jump to next instruction
    198 
    199 %def op_filled_new_array(helper="MterpFilledNewArray"):
    200     /*
    201      * Create a new array with elements filled from registers.
    202      *
    203      * for: filled-new-array, filled-new-array/range
    204      */
    205     /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
    206     /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
    207     .extern $helper
    208     EXPORT_PC()
    209     addu   a0, rFP, OFF_FP_SHADOWFRAME     # a0 <- shadow frame
    210     move   a1, rPC
    211     move   a2, rSELF
    212     JAL($helper)                           #  v0 <- helper(shadow_frame, pc, self)
    213     beqz      v0,  MterpPossibleException  #  has exception
    214     FETCH_ADVANCE_INST(3)                  #  advance rPC, load rINST
    215     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
    216     GOTO_OPCODE(t0)                        #  jump to next instruction
    217 
    218 %def op_filled_new_array_range():
    219 %  op_filled_new_array(helper="MterpFilledNewArrayRange")
    220 
    221 %def op_new_array():
    222     /*
    223      * Allocate an array of objects, specified with the array class
    224      * and a count.
    225      *
    226      * The verifier guarantees that this is an array class, so we don't
    227      * check for it here.
    228      */
    229     /* new-array vA, vB, class@CCCC */
    230     EXPORT_PC()
    231     addu   a0, rFP, OFF_FP_SHADOWFRAME
    232     move   a1, rPC
    233     move   a2, rINST
    234     move   a3, rSELF
    235     JAL(MterpNewArray)
    236     beqz   v0, MterpPossibleException
    237     FETCH_ADVANCE_INST(2)               # advance rPC, load rINST
    238     GET_INST_OPCODE(t0)                 # extract opcode from rINST
    239     GOTO_OPCODE(t0)                     # jump to next instruction
    240