2393 lines
82 KiB
Plaintext
2393 lines
82 KiB
Plaintext
#------------------------------------------------------------------------------------
|
|
# Sleigh specification file for DALVIK VM
|
|
#------------------------------------------------------------------------------------
|
|
|
|
define endian=little;
|
|
|
|
define alignment=1;
|
|
|
|
@define CPOOL_METHOD "0:4"
|
|
@define CPOOL_FIELD "1:4"
|
|
@define CPOOL_STATIC_FIELD "2:4"
|
|
@define CPOOL_STATIC_METHOD "3:4"
|
|
@define CPOOL_STRING "4:4"
|
|
@define CPOOL_CLASSREF "5:4"
|
|
@define CPOOL_ARRAYLENGTH "6:4"
|
|
@define CPOOL_SUPER "7:4"
|
|
@define CPOOL_INSTANCEOF "8:4"
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
define space ram type=ram_space size=4 default;
|
|
|
|
#define space object type=ram_space size=4; # object instances
|
|
|
|
#define space method type=ram_space size=4; # method references
|
|
|
|
#define space field type=ram_space size=4; # field references
|
|
|
|
define space register type=register_space size=4;
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
define register offset=0x0 size=4 [ sp fp resultreg ];
|
|
define register offset=0x8 size=8 [ resultregw ];
|
|
|
|
define register offset=0x100 size=4 # Special input registers
|
|
[
|
|
iv0 iv1 iv2 iv3 iv4 iv5 iv6 iv7
|
|
iv8 iv9 iv10 iv11 iv12 iv13 iv14 iv15
|
|
];
|
|
|
|
define register offset=0x104 size=8 # Wide input registers ODD
|
|
[
|
|
ivw1 ivw3 ivw5 ivw7 ivw9 ivw11 ivw13
|
|
];
|
|
|
|
define register offset=0x100 size=8 # Wide input registers EVEN
|
|
[
|
|
ivw0 ivw2 ivw4 ivw6 ivw8 ivw10 ivw12 ivw14
|
|
];
|
|
|
|
define register offset=0x1000 size=4
|
|
[
|
|
v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15
|
|
v16 v17 v18 v19 v20 v21 v22 v23 v24 v25 v26 v27 v28 v29 v30 v31
|
|
v32 v33 v34 v35 v36 v37 v38 v39 v40 v41 v42 v43 v44 v45 v46 v47
|
|
v48 v49 v50 v51 v52 v53 v54 v55 v56 v57 v58 v59 v60 v61 v62 v63
|
|
v64 v65 v66 v67 v68 v69 v70 v71 v72 v73 v74 v75 v76 v77 v78 v79
|
|
v80 v81 v82 v83 v84 v85 v86 v87 v88 v89 v90 v91 v92 v93 v94 v95
|
|
v96 v97 v98 v99 v100 v101 v102 v103 v104 v105 v106 v107 v108 v109 v110 v111
|
|
v112 v113 v114 v115 v116 v117 v118 v119 v120 v121 v122 v123 v124 v125 v126 v127
|
|
v128 v129 v130 v131 v132 v133 v134 v135 v136 v137 v138 v139 v140 v141 v142 v143
|
|
v144 v145 v146 v147 v148 v149 v150 v151 v152 v153 v154 v155 v156 v157 v158 v159
|
|
v160 v161 v162 v163 v164 v165 v166 v167 v168 v169 v170 v171 v172 v173 v174 v175
|
|
v176 v177 v178 v179 v180 v181 v182 v183 v184 v185 v186 v187 v188 v189 v190 v191
|
|
v192 v193 v194 v195 v196 v197 v198 v199 v200 v201 v202 v203 v204 v205 v206 v207
|
|
v208 v209 v210 v211 v212 v213 v214 v215 v216 v217 v218 v219 v220 v221 v222 v223
|
|
v224 v225 v226 v227 v228 v229 v230 v231 v232 v233 v234 v235 v236 v237 v238 v239
|
|
v240 v241 v242 v243 v244 v245 v246 v247 v248 v249 v250 v251 v252 v253 v254 v255
|
|
];
|
|
|
|
define register offset=0x1004 size=8 # ODD NUMBER WIDE REGISTERS
|
|
[
|
|
vw1 vw3 vw5 vw7 vw9 vw11 vw13 vw15
|
|
vw17 vw19 vw21 vw23 vw25 vw27 vw29 vw31
|
|
vw33 vw35 vw37 vw39 vw41 vw43 vw45 vw47
|
|
vw49 vw51 vw53 vw55 vw57 vw59 vw61 vw63
|
|
vw65 vw67 vw69 vw71 vw73 vw75 vw77 vw79
|
|
vw81 vw83 vw85 vw87 vw89 vw91 vw93 vw95
|
|
vw97 vw99 vw101 vw103 vw105 vw107 vw109 vw111
|
|
vw113 vw115 vw117 vw119 vw121 vw123 vw125 vw127
|
|
vw129 vw131 vw133 vw135 vw137 vw139 vw141 vw143
|
|
vw145 vw147 vw149 vw151 vw153 vw155 vw157 vw159
|
|
vw161 vw163 vw165 vw167 vw169 vw171 vw173 vw175
|
|
vw177 vw179 vw181 vw183 vw185 vw187 vw189 vw191
|
|
vw193 vw195 vw197 vw199 vw201 vw203 vw205 vw207
|
|
vw209 vw211 vw213 vw215 vw217 vw219 vw221 vw223
|
|
vw225 vw227 vw229 vw231 vw233 vw235 vw237 vw239
|
|
vw241 vw243 vw245 vw247 vw249 vw251 vw253
|
|
];
|
|
|
|
define register offset=0x1000 size=8 # EVEN NUMBER WIDE REGISTERS
|
|
[
|
|
vw0 vw2 vw4 vw6 vw8 vw10 vw12 vw14
|
|
vw16 vw18 vw20 vw22 vw24 vw26 vw28 vw30
|
|
vw32 vw34 vw36 vw38 vw40 vw42 vw44 vw46
|
|
vw48 vw50 vw52 vw54 vw56 vw58 vw60 vw62
|
|
vw64 vw66 vw68 vw70 vw72 vw74 vw76 vw78
|
|
vw80 vw82 vw84 vw86 vw88 vw90 vw92 vw94
|
|
vw96 vw98 vw100 vw102 vw104 vw106 vw108 vw110
|
|
vw112 vw114 vw116 vw118 vw120 vw122 vw124 vw126
|
|
vw128 vw130 vw132 vw134 vw136 vw138 vw140 vw142
|
|
vw144 vw146 vw148 vw150 vw152 vw154 vw156 vw158
|
|
vw160 vw162 vw164 vw166 vw168 vw170 vw172 vw174
|
|
vw176 vw178 vw180 vw182 vw184 vw186 vw188 vw190
|
|
vw192 vw194 vw196 vw198 vw200 vw202 vw204 vw206
|
|
vw208 vw210 vw212 vw214 vw216 vw218 vw220 vw222
|
|
vw224 vw226 vw228 vw230 vw232 vw234 vw236 vw238
|
|
vw240 vw242 vw244 vw246 vw248 vw250 vw252 vw254
|
|
];
|
|
|
|
# TODO:
|
|
# 1) test accessing register space past v255. e.g. v12345.
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
define token instruction_byte ( 8 )
|
|
inst0 = ( 0, 7 )
|
|
;
|
|
|
|
define token instruction_byte_w_padding ( 16 )
|
|
inst1 = ( 0, 7 )
|
|
inst1_padding = ( 0, 15 )
|
|
;
|
|
|
|
define token instruction_operands_4_4 ( 8 )
|
|
A_BITS_0_3 = (0,3)
|
|
B_BITS_0_3 = (0,3)
|
|
A_BITS_4_7 = (4,7)
|
|
B_BITS_4_7 = (4,7)
|
|
B_BITS_4_7_S = (4,7) signed
|
|
;
|
|
|
|
define token instruction_operands_8 ( 8 )
|
|
A_BITS_0_7 = (0,7)
|
|
A_BITS_0_7_S = (0,7) signed
|
|
B_BITS_0_7 = (0,7)
|
|
B_BITS_0_7_S = (0,7) signed
|
|
C_BITS_0_7 = (0,7)
|
|
C_BITS_0_7_S = (0,7) signed
|
|
;
|
|
|
|
define token instruction_operands_16 ( 16 )
|
|
A_BITS_0_15 = (0,15)
|
|
A_BITS_0_15_S = (0,15) signed
|
|
B_BITS_0_15 = (0,15)
|
|
B_BITS_0_15_S = (0,15) signed
|
|
C_BITS_0_15 = (0,15)
|
|
C_BITS_0_15_S = (0,15) signed
|
|
;
|
|
|
|
define token instruction_operands_32 ( 32 )
|
|
A_BITS_0_31 = (0,31)
|
|
A_BITS_0_31_S = (0,31) signed
|
|
B_BITS_0_31 = (0,31)
|
|
B_BITS_0_31_S = (0,31) signed
|
|
C_BITS_0_31 = (0,31)
|
|
C_BITS_0_31_S = (0,31) signed
|
|
;
|
|
|
|
define token invoke_operands ( 40 )
|
|
N_PARAMS = ( 4, 7)
|
|
PARAM_G = ( 0, 3)
|
|
METHOD_INDEX = ( 8,23)
|
|
VTABLE_OFFSET = ( 8,23)
|
|
INLINE = ( 8,23)
|
|
PARAM_D = (28,31)
|
|
PARAM_C = (24,27)
|
|
PARAM_F = (36,39)
|
|
PARAM_E = (32,35)
|
|
;
|
|
|
|
define token array_operands ( 40 )
|
|
N_ELEMENTS = ( 4, 7)
|
|
ELEMENT_G = ( 0, 3)
|
|
TYPE_INDEX = ( 8,23)
|
|
ELEMENT_D = (28,31)
|
|
ELEMENT_C = (24,27)
|
|
ELEMENT_F = (36,39)
|
|
ELEMENT_E = (32,35)
|
|
;
|
|
|
|
define token CONST16 ( 16 ) # one 16 constant
|
|
constant16 = ( 0,15 )
|
|
constant16s = ( 0,15 ) signed
|
|
;
|
|
|
|
define token CONST32 ( 32 ) # one 32 constant
|
|
constant32 = ( 0,31 )
|
|
constant32s = ( 0,31 ) signed
|
|
;
|
|
|
|
define token CONST64 ( 64 ) # one 64 constant
|
|
constant64 = ( 0,63 )
|
|
;
|
|
|
|
# add "8" to skip over "fp" and "sp" !!
|
|
|
|
registerA4: reg is A_BITS_0_3 [ reg = (A_BITS_0_3 * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
registerA8: reg is A_BITS_0_7 [ reg = (A_BITS_0_7 * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
registerA16: reg is A_BITS_0_15 [ reg = (A_BITS_0_15 * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
|
|
registerA4w: reg is A_BITS_0_3 [ reg = (A_BITS_0_3 * 4) + 0x1000; ] { export *[register]:8 reg; }
|
|
registerA8w: reg is A_BITS_0_7 [ reg = (A_BITS_0_7 * 4) + 0x1000; ] { export *[register]:8 reg; }
|
|
registerA16w: reg is A_BITS_0_15 [ reg = (A_BITS_0_15 * 4) + 0x1000; ] { export *[register]:8 reg; }
|
|
|
|
registerB4: reg is B_BITS_4_7 [ reg = (B_BITS_4_7 * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
registerB8: reg is B_BITS_0_7 [ reg = (B_BITS_0_7 * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
registerB16: reg is B_BITS_0_15 [ reg = (B_BITS_0_15 * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
|
|
registerB4w: reg is B_BITS_4_7 [ reg = (B_BITS_4_7 * 4) + 0x1000; ] { export *[register]:8 reg; }
|
|
registerB8w: reg is B_BITS_0_7 [ reg = (B_BITS_0_7 * 4) + 0x1000; ] { export *[register]:8 reg; }
|
|
registerB16w: reg is B_BITS_0_15 [ reg = (B_BITS_0_15 * 4) + 0x1000; ] { export *[register]:8 reg; }
|
|
|
|
registerC8: reg is C_BITS_0_7 [ reg = (C_BITS_0_7 * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
registerC16: reg is C_BITS_0_15 [ reg = (C_BITS_0_15 * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
registerC32: reg is C_BITS_0_31 [ reg = (C_BITS_0_31 * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
|
|
|
|
registerC8w: reg is C_BITS_0_7 [ reg = (C_BITS_0_7 * 4) + 0x1000; ] { export *[register]:8 reg; }
|
|
registerC16w: reg is C_BITS_0_15 [ reg = (C_BITS_0_15 * 4) + 0x1000; ] { export *[register]:8 reg; }
|
|
registerC32w: reg is C_BITS_0_31 [ reg = (C_BITS_0_31 * 4) + 0x1000; ] { export *[register]:8 reg; }
|
|
|
|
regParamC: reg is PARAM_C [ reg = (PARAM_C * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
regParamD: reg is PARAM_D [ reg = (PARAM_D * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
regParamE: reg is PARAM_E [ reg = (PARAM_E * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
regParamF: reg is PARAM_F [ reg = (PARAM_F * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
regParamG: reg is PARAM_G [ reg = (PARAM_G * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
|
|
regElemC: reg is ELEMENT_C [ reg = (ELEMENT_C * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
regElemD: reg is ELEMENT_D [ reg = (ELEMENT_D * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
regElemE: reg is ELEMENT_E [ reg = (ELEMENT_E * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
regElemF: reg is ELEMENT_F [ reg = (ELEMENT_F * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
regElemG: reg is ELEMENT_G [ reg = (ELEMENT_G * 4) + 0x1000; ] { export *[register]:4 reg; }
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
rel16: reloc is A_BITS_0_15_S [ reloc = inst_start + ( A_BITS_0_15_S * 2 ); ] { export *[ram]:32 reloc; }
|
|
|
|
goto8: reloc is A_BITS_0_7_S [ reloc = inst_start + ( A_BITS_0_7_S * 2 ); ] { export *[ram]:8 reloc; }
|
|
goto16: reloc is A_BITS_0_15_S [ reloc = inst_start + ( A_BITS_0_15_S * 2 ); ] { export *[ram]:16 reloc; }
|
|
goto32: reloc is A_BITS_0_31_S [ reloc = inst_start + ( A_BITS_0_31_S ); ] { export *[ram]:32 reloc; }
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Special op which injects correct p-code for invoke*_range instructions
|
|
# It takes two arguments: 1) is the number of parameters for the method 2) is the starting register
|
|
define pcodeop moveRangeToIV;
|
|
|
|
define pcodeop monitorEnter;
|
|
define pcodeop monitorExit;
|
|
|
|
define pcodeop checkCast;
|
|
|
|
define pcodeop throwException;
|
|
|
|
define pcodeop getStaticFieldVolatile;
|
|
define pcodeop setStaticFieldVolatile;
|
|
|
|
define pcodeop getInstanceFieldQuick;
|
|
define pcodeop getInstanceFieldVolatile;
|
|
define pcodeop setInstanceFieldQuick;
|
|
define pcodeop setInstanceFieldVolatile;
|
|
|
|
define pcodeop filledNewArray;
|
|
define pcodeop filledNewArrayRange;
|
|
|
|
define pcodeop invokeSuperQuick;
|
|
define pcodeop invokeSuperQuickRange;
|
|
define pcodeop invokeVirtualQuick;
|
|
define pcodeop invokeVirtualQuickRange;
|
|
|
|
define pcodeop switchAssist;
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Waste cycles.
|
|
|
|
:nop is inst0=0x00
|
|
{
|
|
#no pCode
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Move the contents of one non-object register to another.
|
|
#
|
|
# A: destination register (4 bits)
|
|
# B: source register (4 bits)
|
|
|
|
:move registerA4,registerB4 is inst0=0x01 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerB4;
|
|
}
|
|
|
|
# Move the contents of one non-object register to another.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: source register (16 bits)
|
|
|
|
:move_from_16 registerA8,registerB16 is inst0=0x02 ; registerA8 ; registerB16
|
|
{
|
|
registerA8 = registerB16;
|
|
}
|
|
|
|
# Move the contents of one non-object register to another.
|
|
#
|
|
# A: destination register (16 bits)
|
|
# B: source register (16 bits)
|
|
|
|
:move_16 registerA16,registerB16 is inst1=0x03 & inst1_padding ; registerA16 ; registerB16
|
|
{
|
|
registerA16 = registerB16;
|
|
}
|
|
|
|
# Move the contents of one register-pair to another.
|
|
#
|
|
# A: destination register pair (4 bits)
|
|
# B: source register pair (4 bits)
|
|
|
|
:move_wide registerA4w,registerB4w is inst0=0x04 ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerB4w;
|
|
}
|
|
|
|
# Move the contents of one register-pair to another.
|
|
#
|
|
# A: destination register pair (8 bits)
|
|
# B: source register pair (16 bits)
|
|
|
|
:move_wide_from_16 registerA8w,registerB16w is inst0=0x05 ; registerA8w ; registerB16w
|
|
{
|
|
registerA8w = registerB16w;
|
|
}
|
|
|
|
# Move the contents of one register-pair to another.
|
|
#
|
|
# A: destination register pair (16 bits)
|
|
# B: source register pair (16 bits)
|
|
|
|
:move_wide_16 registerA16w,registerB16w is inst0=0x06 ; registerA16w ; registerB16w
|
|
{
|
|
registerA16w = registerB16w;
|
|
}
|
|
|
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
|
#
|
|
# Move the contents of one object-bearing register to another.
|
|
#
|
|
# A: destination register (4 bits)
|
|
# B: source register (4 bits)
|
|
|
|
:move_object registerA4,registerB4 is inst0=0x07 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerB4;
|
|
}
|
|
|
|
# Move the contents of one object-bearing register to another.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: source register (16 bits)
|
|
|
|
:move_object_from_16 registerA8,registerB16 is inst0=0x08 ; registerA8 ; registerB16
|
|
{
|
|
registerA8 = registerB16;
|
|
}
|
|
|
|
# Move the contents of one object-bearing register to another.
|
|
#
|
|
# A: destination register (16 bits)
|
|
# B: source register (16 bits)
|
|
|
|
:move_object_16 registerA16,registerB16 is inst1=0x09 & inst1_padding ; registerA16 ; registerB16
|
|
{
|
|
registerA16 = registerB16;
|
|
}
|
|
|
|
# Move the single-word non-object result of the most recent invoke-kind
|
|
# into the indicated register. This must be done as the instruction
|
|
# immediately after an invoke-kind whose (single-word, non-object)
|
|
# result is not to be ignored; anywhere else is invalid.
|
|
#
|
|
# A: destination register (8 bits)
|
|
|
|
:move_result registerA8 is inst0=0x0a ; registerA8
|
|
{
|
|
registerA8 = resultreg;
|
|
}
|
|
|
|
# Move the double-word result of the most recent invoke-kind into
|
|
# the indicated register pair. This must be done as the instruction
|
|
# immediately after an invoke-kind whose (double-word) result is
|
|
# not to be ignored; anywhere else is invalid.
|
|
#
|
|
# A: destination register pair (8 bits)
|
|
|
|
:move_result_wide registerA8w is inst0=0x0b ; registerA8w
|
|
{
|
|
registerA8w = resultregw;
|
|
}
|
|
|
|
# Move the object result of the most recent invoke-kind into
|
|
# the indicated register. This must be done as the instruction
|
|
# immediately after an invoke-kind or filled-new-array whose
|
|
# (object) result is not to be ignored; anywhere else is invalid.
|
|
#
|
|
# A: destination register (8 bits)
|
|
|
|
:move_result_object registerA8 is inst0=0x0c ; registerA8
|
|
{
|
|
registerA8 = resultreg;
|
|
}
|
|
|
|
# Save a just-caught exception into the given register. This must
|
|
# be the first instruction of any exception handler whose caught
|
|
# exception is not to be ignored, and this instruction must only
|
|
# ever occur as the first instruction of an exception handler;
|
|
# anywhere else is invalid.
|
|
#
|
|
# A: destination register (8 bits)
|
|
|
|
:move_exception registerA8 is inst0=0x0d ; registerA8
|
|
{
|
|
#TODO pCode
|
|
# this requires state!?
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Return from a void method.
|
|
|
|
:return_void is inst1=0x0e & inst1_padding
|
|
{
|
|
return [sp];
|
|
}
|
|
|
|
# Return from a single-width (32-bit) non-object value-returning method.
|
|
#
|
|
# A: return value register (8 bits)
|
|
|
|
:return registerA8 is inst0=0x0f ; registerA8
|
|
{
|
|
resultreg = registerA8;
|
|
return [sp];
|
|
}
|
|
|
|
# Return from a double-width (64-bit) value-returning method.
|
|
#
|
|
# A: return value register-pair (8 bits)
|
|
|
|
:return_wide registerA8w is inst0=0x10 ; registerA8w
|
|
{
|
|
resultregw = registerA8w;
|
|
return [sp];
|
|
}
|
|
|
|
# Return from an object-returning method.
|
|
#
|
|
# A: return value register (8 bits)
|
|
|
|
:return_object registerA8 is inst0=0x11 ; registerA8
|
|
{
|
|
resultreg = registerA8;
|
|
return [sp];
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Move the given literal value (sign-extended to 32 bits) into the specified register.
|
|
#
|
|
# A: destination register (4 bits)
|
|
# B: signed int (4 bits)
|
|
|
|
:const_4 registerA4,B_BITS_4_7_S is inst0=0x12 ; registerA4 & B_BITS_4_7_S
|
|
{
|
|
registerA4 = sext( B_BITS_4_7_S:4) ;
|
|
}
|
|
|
|
# Move the given literal value (sign-extended to 32 bits) into the specified register.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: signed int (16 bits)
|
|
|
|
:const_16 registerA8,B_BITS_0_15_S is inst0=0x13 ; registerA8 ; B_BITS_0_15_S
|
|
{
|
|
registerA8 = sext( B_BITS_0_15_S:4 );
|
|
}
|
|
|
|
# Move the given literal value into the specified register.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: arbitrary 32-bit constant
|
|
|
|
:"const" registerA8,constant32 is inst0=0x14 ; registerA8 ; constant32
|
|
{
|
|
registerA8 = constant32;
|
|
}
|
|
|
|
# Move the given literal value (right-zero-extended to 32 bits) into the specified register.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: signed int (16 bits)
|
|
|
|
:const_high_16 registerA8,B_BITS_0_15 is inst0=0x15 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
registerA8 = B_BITS_0_15:4 << 16;
|
|
}
|
|
|
|
# Move the given literal value (sign-extended to 64 bits) into the specified register-pair.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: signed int (16 bits)
|
|
|
|
:const_wide_16 registerA8w,constant16s is inst0=0x16 ; registerA8w ; constant16s
|
|
{
|
|
registerA8w = sext( constant16s:2 );
|
|
}
|
|
|
|
# Move the given literal value (sign-extended to 64 bits) into the specified register-pair.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: signed int (32 bits)
|
|
|
|
:const_wide_32 registerA8w,constant32s is inst0=0x17 ; registerA8w ; constant32s
|
|
{
|
|
registerA8w = sext( constant32s:4 );
|
|
}
|
|
|
|
# Move the given literal value into the specified register-pair.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: arbitrary double-width (64-bit) constant
|
|
|
|
:const_wide registerA8w,constant64 is inst0=0x18 ; registerA8w ; constant64
|
|
{
|
|
registerA8w = constant64;
|
|
}
|
|
|
|
# Move the given literal value (right-zero-extended to 64 bits) into the specified register-pair.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: signed int (16 bits)
|
|
|
|
:const_wide_high_16 registerA8w,B_BITS_0_15_S is inst0=0x19 ; registerA8w ; B_BITS_0_15_S
|
|
{
|
|
registerA8w = B_BITS_0_15_S << 48;
|
|
}
|
|
|
|
# Move a reference to the string specified by the given index into the specified register.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: string index
|
|
|
|
:const_string registerA8,B_BITS_0_15 is inst0=0x1a ; registerA8 ; B_BITS_0_15
|
|
{
|
|
registerA8 = cpool(0:4, B_BITS_0_15:4, $(CPOOL_STRING));
|
|
}
|
|
|
|
# Move a reference to the string specified by the given index into the specified register.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: string index
|
|
|
|
:const_string_jumbo registerA8,B_BITS_0_31 is inst0=0x1b ; registerA8 ; B_BITS_0_31
|
|
{
|
|
registerA8 = cpool(0:4, B_BITS_0_31:4, $(CPOOL_STRING));
|
|
}
|
|
|
|
# Move a reference to the class specified by the given index into the
|
|
# specified register. In the case where the indicated type is primitive,
|
|
# this will store a reference to the primitive type's degenerate class.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: type index
|
|
|
|
:const_class registerA8,B_BITS_0_15 is inst0=0x1c ; registerA8 ; B_BITS_0_15
|
|
{
|
|
registerA8 = cpool( 0:4, B_BITS_0_15:4, $(CPOOL_CLASSREF));
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Acquire the monitor for the indicated object.
|
|
#
|
|
# A: reference-bearing register (8 bits)
|
|
|
|
:monitor_enter registerA8 is inst0=0x1d ; registerA8
|
|
{
|
|
monitorEnter( registerA8 );
|
|
}
|
|
|
|
# Release the monitor for the indicated object.
|
|
#
|
|
# A: reference-bearing register (8 bits)
|
|
|
|
:monitor_exit registerA8 is inst0=0x1e ; registerA8
|
|
{
|
|
monitorExit( registerA8 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Throw a ClassCastException if the reference in the given register
|
|
# cannot be cast to the indicated type.
|
|
#
|
|
# A: reference-bearing register (8 bits)
|
|
# B: type index (16 bits)
|
|
|
|
:check_cast registerA8,B_BITS_0_15 is inst0=0x1f ; registerA8 ; B_BITS_0_15
|
|
{
|
|
checkCast( registerA8, cpool( 0:4, B_BITS_0_15:4, $(CPOOL_CLASSREF)) );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Store in the given destination register 1 if the indicated reference
|
|
# is an instance of the given type, or 0 if not.
|
|
#
|
|
# A: destination register (4 bits)
|
|
# B: reference-bearing register (4 bits)
|
|
# C: type index (16 bits)
|
|
|
|
:instance_of registerA4,registerB4,C_BITS_0_15 is inst0=0x20 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
res:1 = cpool( registerB4, C_BITS_0_15:4, $(CPOOL_INSTANCEOF) );
|
|
registerA4 = zext( res );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Store in the given destination register the length of the indicated array, in entries
|
|
#
|
|
# A: destination register (4 bits)
|
|
# B: array reference-bearing register (4 bits)
|
|
|
|
:array_length registerA4,registerB4 is inst0=0x21 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = cpool( registerB4, 0:4, $(CPOOL_ARRAYLENGTH) );
|
|
}
|
|
|
|
# Construct a new instance of the indicated type, storing a reference
|
|
# to it in the destination. The type must refer to a non-array class.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: type index
|
|
|
|
:new_instance registerA8,B_BITS_0_15 is inst0=0x22 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
registerA8 = newobject( cpool( 0:4, B_BITS_0_15:4, $(CPOOL_CLASSREF)) );
|
|
}
|
|
|
|
# Construct a new array of the indicated type and size. The type must be an array type.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: size register
|
|
# C: type index
|
|
|
|
:new_array registerA4,registerB4,C_BITS_0_15 is inst0=0x23 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
registerA4 = newobject( cpool( 0:4, C_BITS_0_15:4, $(CPOOL_CLASSREF)), registerB4 );
|
|
}
|
|
|
|
# Construct an array of the given type and size, filling it with the supplied
|
|
# contents. The type must be an array type. The array's contents must be
|
|
# single-word (that is, no arrays of long or double, but reference types are
|
|
# acceptable). The constructed instance is stored as a "result" in the same
|
|
# way that the method invocation instructions store their results, so the
|
|
# constructed instance must be moved to a register with an immediately
|
|
# subsequent move-result-object instruction (if it is to be used).
|
|
#
|
|
# A: array size and argument word count (4 bits)
|
|
# B: type index (16 bits)
|
|
# C..G: argument registers (4 bits each)
|
|
|
|
:filled_new_array TYPE_INDEX is inst0=0x24 ; N_ELEMENTS = 0 & TYPE_INDEX & regElemC & regElemD & regElemE & regElemF & regElemG
|
|
{
|
|
#TODO pCode
|
|
filledNewArray( TYPE_INDEX:4 );
|
|
}
|
|
:filled_new_array TYPE_INDEX,regElemC is inst0=0x24 ; N_ELEMENTS = 1 & TYPE_INDEX & regElemC & regElemD & regElemE & regElemF & regElemG
|
|
{
|
|
#TODO pCode
|
|
filledNewArray( TYPE_INDEX:4, regElemC );
|
|
}
|
|
:filled_new_array TYPE_INDEX,regElemC,regElemD is inst0=0x24 ; N_ELEMENTS = 2 & TYPE_INDEX & regElemC & regElemD & regElemE & regElemF & regElemG
|
|
{
|
|
#TODO pCode
|
|
filledNewArray( TYPE_INDEX:4, regElemC, regElemD );
|
|
}
|
|
:filled_new_array TYPE_INDEX,regElemC,regElemD,regElemE is inst0=0x24 ; N_ELEMENTS = 3 & TYPE_INDEX & regElemC & regElemD & regElemE & regElemF & regElemG
|
|
{
|
|
#TODO pCode
|
|
filledNewArray( TYPE_INDEX:4, regElemC, regElemD, regElemE );
|
|
}
|
|
:filled_new_array TYPE_INDEX,regElemC,regElemD,regElemE,regElemF is inst0=0x24 ; N_ELEMENTS = 4 & TYPE_INDEX & regElemC & regElemD & regElemE & regElemF & regElemG
|
|
{
|
|
#TODO pCode
|
|
filledNewArray( TYPE_INDEX:4, regElemC, regElemD, regElemE, regElemF );
|
|
}
|
|
:filled_new_array TYPE_INDEX,regElemC,regElemD,regElemE,regElemF,regElemG is inst0=0x24 ; N_ELEMENTS = 5 & TYPE_INDEX & regElemC & regElemD & regElemE & regElemF & regElemG
|
|
{
|
|
#TODO pCode
|
|
filledNewArray( TYPE_INDEX:4, regElemC, regElemD, regElemE, regElemF, regElemG );
|
|
}
|
|
|
|
# Construct an array of the given type and size, filling it with
|
|
# the supplied contents. Clarifications and restrictions are the
|
|
# same as filled-new-array, described above.
|
|
#
|
|
# A: array size and argument word count (8 bits)
|
|
# B: type index (16 bits)
|
|
# C: first argument register (16 bits)
|
|
# N = A + C - 1
|
|
|
|
:filled_new_array_range A_BITS_0_7,B_BITS_0_15,registerC16 is inst0=0x25 ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
#TODO pCode
|
|
filledNewArrayRange( A_BITS_0_7:4, B_BITS_0_15:4, registerC16 );
|
|
}
|
|
|
|
# Fill the given array with the indicated data. The reference must
|
|
# be to an array of primitives, and the data table must match it in type
|
|
# and must contain no more elements than will fit in the array. That is,
|
|
# the array may be larger than the table, and if so, only the initial
|
|
# elements of the array are set, leaving the remainder alone.
|
|
#
|
|
# A: array reference (8 bits)
|
|
# B: signed "branch" offset to table data pseudo-instruction (32 bits)
|
|
|
|
:fill_array_data registerA8,B_BITS_0_31_S is inst0=0x26 ; registerA8 ; B_BITS_0_31_S
|
|
{
|
|
#TODO pCode
|
|
# fillArrayData
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Throw the indicated exception.
|
|
#
|
|
# A: exception-bearing register (8 bits)
|
|
|
|
:throw registerA8 is inst0=0x27 ; registerA8
|
|
{
|
|
throwException( registerA8 );
|
|
return [registerA8];#TODO is the best way to return??
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Unconditionally jump to the indicated instruction.
|
|
#
|
|
# A: signed branch offset (8 bits)
|
|
|
|
:goto goto8 is inst0=0x28 ; goto8
|
|
{
|
|
goto goto8;
|
|
}
|
|
|
|
# Unconditionally jump to the indicated instruction.
|
|
#
|
|
# A: signed branch offset (16 bits)
|
|
|
|
:goto_16 goto16 is inst1=0x29 & inst1_padding ; goto16
|
|
{
|
|
goto goto16;
|
|
}
|
|
|
|
# Unconditionally jump to the indicated instruction.
|
|
#
|
|
# A: signed branch offset (32 bits)
|
|
|
|
:goto_32 goto32 is inst1=0x2a & inst1_padding ; goto32
|
|
{
|
|
goto goto32;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Jump to a new instruction based on the value in the given register,
|
|
# using a table of offsets corresponding to each value in a particular
|
|
# integral range, or fall through to the next instruction if there is no match.
|
|
#
|
|
# A: register to test
|
|
# B: signed "branch" offset to table data pseudo-instruction (32 bits)
|
|
#
|
|
# NOTE: Offset (B) and destinations must be multiplied by 2.
|
|
|
|
# TODO use disassembly action??
|
|
|
|
:packed_switch registerA8,B_BITS_0_31_S is inst0=0x2b ; registerA8 ; B_BITS_0_31_S
|
|
{
|
|
distance:4 = B_BITS_0_31_S * 2;
|
|
# ident:2 = *[ram] ( inst_start + distance );
|
|
# if (ident != 0x0100) goto inst_next;
|
|
size2:2 = *[ram] ( inst_start + distance + 2 );
|
|
sze:4 = zext( size2 );
|
|
first_key:4 = *[ram] ( inst_start + distance + 2 + 2 );
|
|
|
|
if ( registerA8 < first_key ) goto inst_next;
|
|
if ( registerA8 >= ( first_key + sze ) ) goto inst_next;
|
|
|
|
targets:4 = ( inst_start + distance + 2 + 2 + 4 );
|
|
delta:4 = ( registerA8 ) - ( first_key ); # which index into target
|
|
value:4 = *[ram] ( targets + ( delta * 4 ) );
|
|
address:4 = ( inst_start + ( value * 2 ) );
|
|
|
|
goto [ address ];
|
|
}
|
|
|
|
# Jump to a new instruction based on the value in the given register,
|
|
# using an ordered table of value-offset pairs, or fall through to the
|
|
# next instruction if there is no match.
|
|
#
|
|
# A: register to test
|
|
# B: signed "branch" offset to table data pseudo-instruction (32 bits)
|
|
#
|
|
# NOTE: Offset (B) and destinations must be multiplied by 2.
|
|
|
|
:sparse_switch registerA8,B_BITS_0_31_S is inst0=0x2c ; registerA8 ; B_BITS_0_31_S
|
|
{
|
|
distance:4 = B_BITS_0_31_S * 2;
|
|
temp:4 = inst_start;
|
|
size2:2 = *[ram] ( temp + 2 + distance);
|
|
sze:4 = zext( size2 );
|
|
defaultPos:4 = inst_next;
|
|
|
|
|
|
address:4 = switchAssist( registerA8, sze, defaultPos, temp, distance );
|
|
goto [ address ];
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Perform the indicated floating point or long comparison,
|
|
# setting a to 0 if b == c, 1 if b > c, or -1 if b < c.
|
|
# The "bias" listed for the floating point operations indicates
|
|
# how NaN comparisons are treated: "gt bias" instructions return 1 for
|
|
# NaN comparisons, and "lt bias" instructions return -1.
|
|
#
|
|
# For example, to check to see if floating point x < y it is advisable
|
|
# to use cmpg-float; a result of -1 indicates that the test was true,
|
|
# and the other values indicate it was false either due to a valid
|
|
# comparison or because one of the values was NaN.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: first source register or pair
|
|
# C: second source register or pair
|
|
|
|
:cmpl_float registerA8,registerB8,registerC8 is inst0=0x2d ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = zext( registerC8 f<= registerB8) + zext( registerC8 f< registerB8) - 1;
|
|
}
|
|
|
|
:cmpg_float registerA8,registerB8,registerC8 is inst0=0x2e ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = zext( registerC8 f<= registerB8) + zext( registerC8 f< registerB8) - 1;
|
|
}
|
|
|
|
:cmpl_double registerA8,registerB8w,registerC8w is inst0=0x2f ; registerA8 ; registerB8w ; registerC8w
|
|
{
|
|
registerA8 = zext( registerC8w f<= registerB8w) + zext( registerC8w f< registerB8w) - 1;
|
|
}
|
|
|
|
:cmpg_double registerA8,registerB8w,registerC8w is inst0=0x30 ; registerA8 ; registerB8w ; registerC8w
|
|
{
|
|
registerA8 = zext( registerC8w f<= registerB8w) + zext( registerC8w f< registerB8w) - 1;
|
|
}
|
|
|
|
:cmp_long registerA8,registerB8w,registerC8w is inst0=0x31 ; registerA8 ; registerB8w ; registerC8w
|
|
{
|
|
registerA8 = zext( registerC8w s<= registerB8w ) + zext( registerC8w s< registerB8w ) - 1;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Branch to the given destination if the given two registers' values compare as specified.
|
|
#
|
|
# A: first register to test (4 bits)
|
|
# B: second register to test (4 bits)
|
|
# C: signed branch offset (16 bits)
|
|
|
|
:if_eq registerA4,registerB4,rel16 is inst0=0x32 ; registerA4 & registerB4 ; rel16
|
|
{
|
|
if ( registerA4 == registerB4 ) goto rel16;
|
|
}
|
|
|
|
:if_ne registerA4,registerB4,rel16 is inst0=0x33 ; registerA4 & registerB4 ; rel16
|
|
{
|
|
if ( registerA4 != registerB4 ) goto rel16;
|
|
}
|
|
|
|
:if_lt registerA4,registerB4,rel16 is inst0=0x34 ; registerA4 & registerB4 ; rel16
|
|
{
|
|
if ( registerA4 s< registerB4 ) goto rel16;
|
|
}
|
|
|
|
:if_ge registerA4,registerB4,rel16 is inst0=0x35 ; registerA4 & registerB4 ; rel16
|
|
{
|
|
if ( registerA4 s>= registerB4 ) goto rel16;
|
|
}
|
|
|
|
:if_gt registerA4,registerB4,rel16 is inst0=0x36 ; registerA4 & registerB4 ; rel16
|
|
{
|
|
if ( registerA4 s> registerB4 ) goto rel16;
|
|
}
|
|
|
|
:if_le registerA4,registerB4,rel16 is inst0=0x37 ; registerA4 & registerB4 ; rel16
|
|
{
|
|
if ( registerA4 s<= registerB4 ) goto rel16;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Branch to the given destination if the given register's value compares with 0 as specified.
|
|
#
|
|
# A: register to test (8 bits)
|
|
# B: signed branch offset (16 bits)
|
|
|
|
:if_eqz registerA8,rel16 is inst0=0x38 ; registerA8 ; rel16
|
|
{
|
|
if ( registerA8 == 0 ) goto rel16;
|
|
}
|
|
|
|
:if_nez registerA8,rel16 is inst0=0x39 ; registerA8 ; rel16
|
|
{
|
|
if ( registerA8 != 0 ) goto rel16;
|
|
}
|
|
|
|
:if_ltz registerA8,rel16 is inst0=0x3a ; registerA8 ; rel16
|
|
{
|
|
if ( registerA8 s< 0 ) goto rel16;
|
|
}
|
|
|
|
:if_gez registerA8,rel16 is inst0=0x3b ; registerA8 ; rel16
|
|
{
|
|
if ( registerA8 s>= 0 ) goto rel16;
|
|
}
|
|
|
|
:if_gtz registerA8,rel16 is inst0=0x3c ; registerA8 ; rel16
|
|
{
|
|
if ( registerA8 s> 0 ) goto rel16;
|
|
}
|
|
|
|
:if_lez registerA8,rel16 is inst0=0x3d ; registerA8 ; rel16
|
|
{
|
|
if ( registerA8 s<= 0 ) goto rel16;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# 0x3e unused
|
|
# 0x3f unused
|
|
# 0x40 unused
|
|
# 0x41 unused
|
|
# 0x42 unused
|
|
# 0x43 unused
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Perform the identified array operation at the identified index
|
|
# of the given array, loading or storing into the value register.
|
|
#
|
|
# A: value register or pair; may be source or dest (8 bits)
|
|
# B: array register (8 bits)
|
|
# C: index register (8 bits)
|
|
|
|
:aget registerA8,registerB8,registerC8 is inst0=0x44 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = *( registerB8 + registerC8*4 );
|
|
}
|
|
|
|
:aget_wide registerA8w,registerB8,registerC8 is inst0=0x45 ; registerA8w ; registerB8 ; registerC8
|
|
{
|
|
registerA8w = *( registerB8 + registerC8*8 );
|
|
}
|
|
|
|
:aget_object registerA8,registerB8,registerC8 is inst0=0x46 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = *( registerB8 + registerC8*4 );
|
|
}
|
|
|
|
:aget_boolean registerA8,registerB8,registerC8 is inst0=0x47 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = zext( *:1 ( registerB8 + registerC8 ));
|
|
}
|
|
|
|
:aget_byte registerA8,registerB8,registerC8 is inst0=0x48 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = sext( *:1 (registerB8 + registerC8) );
|
|
}
|
|
|
|
:aget_char registerA8,registerB8,registerC8 is inst0=0x49 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = zext( *:2 (registerB8 + registerC8*2 ) );
|
|
}
|
|
|
|
:aget_short registerA8,registerB8,registerC8 is inst0=0x4a ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = sext( *:2 (registerB8 + registerC8 * 2 ) );
|
|
}
|
|
|
|
:aput registerA8,registerB8,registerC8 is inst0=0x4b ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
*( registerB8 + registerC8 * 4 ) = registerA8;
|
|
}
|
|
|
|
:aput_wide registerA8w,registerB8,registerC8 is inst0=0x4c ; registerA8w ; registerB8 ; registerC8
|
|
{
|
|
*( registerB8 + registerC8 * 8 ) = registerA8w;
|
|
}
|
|
|
|
:aput_object registerA8,registerB8,registerC8 is inst0=0x4d ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
*( registerB8 + registerC8 * 4 ) = registerA8;
|
|
}
|
|
|
|
:aput_boolean registerA8,registerB8,registerC8 is inst0=0x4e ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
*( registerB8 + registerC8 ) = registerA8:1;
|
|
}
|
|
|
|
:aput_byte registerA8,registerB8,registerC8 is inst0=0x4f ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
*( registerB8 + registerC8 ) = registerA8:1;
|
|
}
|
|
|
|
:aput_char registerA8,registerB8,registerC8 is inst0=0x50 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
*( registerB8 + registerC8*2 ) = registerA8:2;
|
|
}
|
|
|
|
:aput_short registerA8,registerB8,registerC8 is inst0=0x51 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
*( registerB8 + registerC8*2 ) = registerA8:2;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Perform the identified object instance field operation with the
|
|
# identified field, loading or storing into the value register.
|
|
#
|
|
# A: value register or pair; may be source or dest (4 bits)
|
|
# B: object register (4 bits)
|
|
# C: instance field reference index (16 bits)
|
|
|
|
:iget registerA4,[registerB4:C_BITS_0_15] is inst0=0x52 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool( registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
registerA4 = *ptr;
|
|
}
|
|
|
|
:iget_wide registerA4w,[registerB4:C_BITS_0_15] is inst0=0x53 ; registerA4w & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool( registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
registerA4w = *ptr;
|
|
}
|
|
|
|
:iget_object registerA4,[registerB4:C_BITS_0_15] is inst0=0x54 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool( registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
registerA4 = *ptr;
|
|
}
|
|
|
|
:iget_boolean registerA4,[registerB4:C_BITS_0_15] is inst0=0x55 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool( registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
registerA4 = zext( *:1 ptr );
|
|
}
|
|
|
|
:iget_byte registerA4,[registerB4:C_BITS_0_15] is inst0=0x56 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool( registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
registerA4 = sext( *:1 ptr );
|
|
}
|
|
|
|
:iget_char registerA4,[registerB4:C_BITS_0_15] is inst0=0x57 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool( registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
registerA4 = zext( *:2 ptr );
|
|
}
|
|
|
|
:iget_short registerA4,[registerB4:C_BITS_0_15] is inst0=0x58 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool( registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
registerA4 = sext( *:2 ptr );
|
|
}
|
|
|
|
:iput registerA4,[registerB4:C_BITS_0_15] is inst0=0x59 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
*ptr = registerA4;
|
|
}
|
|
|
|
:iput_wide registerA4w,[registerB4:C_BITS_0_15] is inst0=0x5a ; registerA4w & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
*ptr = registerA4w;
|
|
}
|
|
|
|
:iput_object registerA4,[registerB4:C_BITS_0_15] is inst0=0x5b ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
*ptr = registerA4;
|
|
}
|
|
|
|
:iput_boolean registerA4,[registerB4:C_BITS_0_15] is inst0=0x5c ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
*ptr = registerA4 : 1;
|
|
}
|
|
|
|
:iput_byte registerA4,[registerB4:C_BITS_0_15] is inst0=0x5d ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
*ptr = registerA4 : 1;
|
|
}
|
|
|
|
:iput_char registerA4,[registerB4:C_BITS_0_15] is inst0=0x5e ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
*ptr = registerA4 : 2;
|
|
}
|
|
|
|
:iput_short registerA4,[registerB4:C_BITS_0_15] is inst0=0x5f ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(registerB4, C_BITS_0_15:4, $(CPOOL_FIELD));
|
|
*ptr = registerA4 : 2;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Perform the identified object static field operation with the identified
|
|
# static field, loading or storing into the value register.
|
|
#
|
|
# A: value register or pair; may be source or dest (8 bits)
|
|
# B: static field reference index (16 bits)
|
|
|
|
:sget registerA8,B_BITS_0_15 is inst0=0x60 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
registerA8 = *ptr;
|
|
}
|
|
:sget_wide registerA8w,B_BITS_0_15 is inst0=0x61 ; registerA8w ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
registerA8w = *ptr;
|
|
}
|
|
:sget_object registerA8,B_BITS_0_15 is inst0=0x62 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
registerA8 = *ptr;
|
|
}
|
|
:sget_boolean registerA8,B_BITS_0_15 is inst0=0x63 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
registerA8 = zext(*:1 ptr);
|
|
}
|
|
:sget_byte registerA8,B_BITS_0_15 is inst0=0x64 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
registerA8 = sext(*:1 ptr);
|
|
}
|
|
:sget_char registerA8,B_BITS_0_15 is inst0=0x65 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
registerA8 = zext(*:2 ptr);
|
|
}
|
|
:sget_short registerA8,B_BITS_0_15 is inst0=0x66 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
registerA8 = sext(*:2 ptr);
|
|
}
|
|
|
|
:sput registerA8,B_BITS_0_15 is inst0=0x67 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
*ptr = registerA8;
|
|
}
|
|
:sput_wide registerA8w,B_BITS_0_15 is inst0=0x68 ; registerA8w ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
*ptr = registerA8w;
|
|
}
|
|
:sput_object registerA8,B_BITS_0_15 is inst0=0x69 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
*ptr = registerA8;
|
|
}
|
|
:sput_boolean registerA8,B_BITS_0_15 is inst0=0x6a ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
*ptr = registerA8:1;
|
|
}
|
|
:sput_byte registerA8,B_BITS_0_15 is inst0=0x6b ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
*ptr = registerA8:1;
|
|
}
|
|
:sput_char registerA8,B_BITS_0_15 is inst0=0x6c ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
*ptr = registerA8:2;
|
|
}
|
|
:sput_short registerA8,B_BITS_0_15 is inst0=0x6d ; registerA8 ; B_BITS_0_15
|
|
{
|
|
ptr:4 = cpool(0:4,B_BITS_0_15:4,$(CPOOL_STATIC_FIELD));
|
|
*ptr = registerA8:2;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Call the indicated method. The result (if any) may be stored with
|
|
# an appropriate move-result* variant as the immediately subsequent
|
|
# instruction.
|
|
#
|
|
# A: argument word count (4 bits)
|
|
# B: method reference index (16 bits)
|
|
# C..G: argument registers (4 bits each)
|
|
|
|
# invoke-virtual is used to invoke a normal virtual method
|
|
# (a method that is not private, static, or final, and is also not a constructor).
|
|
|
|
:invoke_virtual METHOD_INDEX is inst0=0x6e ; N_PARAMS=0 & METHOD_INDEX
|
|
{
|
|
destination:4 = cpool( 0:4, METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_virtual METHOD_INDEX,regParamC is inst0=0x6e ; N_PARAMS=1 & METHOD_INDEX & regParamC
|
|
{
|
|
iv0 = regParamC;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_virtual METHOD_INDEX,regParamC,regParamD is inst0=0x6e ; N_PARAMS=2 & METHOD_INDEX & regParamC & regParamD
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_virtual METHOD_INDEX,regParamC,regParamD,regParamE is inst0=0x6e ; N_PARAMS=3 & METHOD_INDEX & regParamC & regParamD & regParamE
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_virtual METHOD_INDEX,regParamC,regParamD,regParamE,regParamF is inst0=0x6e ; N_PARAMS=4 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_virtual METHOD_INDEX,regParamC,regParamD,regParamE,regParamF,regParamG is inst0=0x6e ; N_PARAMS=5 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF & regParamG
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
iv4 = regParamG;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
|
|
# invoke-super is used to invoke the closest superclass's virtual
|
|
# method (as opposed to the one with the same method_id in the
|
|
# calling class). The same method restrictions hold as for invoke-virtual.
|
|
|
|
:invoke_super METHOD_INDEX is inst0=0x6f ; N_PARAMS=0 & METHOD_INDEX
|
|
{
|
|
destination:4 = cpool( cpool( 0:4, 0:4, $(CPOOL_SUPER)), METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_super METHOD_INDEX,regParamC is inst0=0x6f ; N_PARAMS=1 & METHOD_INDEX & regParamC
|
|
{
|
|
iv0 = regParamC;
|
|
destination:4 = cpool( cpool( 0:4, 0:4, $(CPOOL_SUPER)), METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_super METHOD_INDEX,regParamC,regParamD is inst0=0x6f ; N_PARAMS=2 & METHOD_INDEX & regParamC & regParamD
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
destination:4 = cpool( cpool( 0:4, 0:4, $(CPOOL_SUPER)), METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_super METHOD_INDEX,regParamC,regParamD,regParamE is inst0=0x6f ; N_PARAMS=3 & METHOD_INDEX & regParamC & regParamD & regParamE
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
destination:4 = cpool( cpool( 0:4, 0:4, $(CPOOL_SUPER)), METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_super METHOD_INDEX,regParamC,regParamD,regParamE,regParamF is inst0=0x6f ; N_PARAMS=4 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
destination:4 = cpool( cpool( 0:4, 0:4, $(CPOOL_SUPER)), METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_super METHOD_INDEX,regParamC,regParamD,regParamE,regParamF,regParamG is inst0=0x6f ; N_PARAMS=5 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF & regParamG
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
iv4 = regParamG;
|
|
destination:4 = cpool( cpool( 0:4, 0:4, $(CPOOL_SUPER)), METHOD_INDEX:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
|
|
# invoke-direct is used to invoke a non-static direct
|
|
# method (that is, an instance method that is by its
|
|
# nature non-overridable, namely either a private instance
|
|
# method or a constructor).
|
|
|
|
:invoke_direct METHOD_INDEX is inst0=0x70 ; N_PARAMS=0 & METHOD_INDEX
|
|
{
|
|
destination:4 = cpool( 0:4, METHOD_INDEX, $(CPOOL_METHOD));
|
|
call [destination];
|
|
}
|
|
:invoke_direct METHOD_INDEX,regParamC is inst0=0x70 ; N_PARAMS=1 & METHOD_INDEX & regParamC
|
|
{
|
|
iv0 = regParamC;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_direct METHOD_INDEX,regParamC,regParamD, is inst0=0x70 ; N_PARAMS=2 & METHOD_INDEX & regParamC & regParamD
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_direct METHOD_INDEX,regParamC,regParamD,regParamE is inst0=0x70 ; N_PARAMS=3 & METHOD_INDEX & regParamC & regParamD & regParamE
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_direct METHOD_INDEX,regParamC,regParamD,regParamE,regParamF is inst0=0x70 ; N_PARAMS=4 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_direct METHOD_INDEX,regParamC,regParamD,regParamE,regParamF,regParamG is inst0=0x70 ; N_PARAMS=5 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF & regParamG
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
iv4 = regParamG;
|
|
destination:4 = cpool( regParamC, METHOD_INDEX, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
|
|
# invoke-static is used to invoke a static method
|
|
# (which is always considered a direct method).
|
|
|
|
:invoke_static METHOD_INDEX is inst0=0x71 ; N_PARAMS=0 & METHOD_INDEX
|
|
{
|
|
destination:4 = cpool( 0:4, METHOD_INDEX, $(CPOOL_STATIC_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_static METHOD_INDEX,regParamC is inst0=0x71 ; N_PARAMS=1 & METHOD_INDEX & regParamC
|
|
{
|
|
iv0 = regParamC;
|
|
destination:4 = cpool( 0:4, METHOD_INDEX, $(CPOOL_STATIC_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_static METHOD_INDEX,regParamC,regParamD is inst0=0x71 ; N_PARAMS=2 & METHOD_INDEX & regParamC & regParamD
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
destination:4 = cpool( 0:4, METHOD_INDEX, $(CPOOL_STATIC_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_static METHOD_INDEX,regParamC,regParamD,regParamE is inst0=0x71 ; N_PARAMS=3 & METHOD_INDEX & regParamC & regParamD & regParamE
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
destination:4 = cpool( 0:4, METHOD_INDEX, $(CPOOL_STATIC_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_static METHOD_INDEX,regParamC,regParamD,regParamE,regParamF is inst0=0x71 ; N_PARAMS=4 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
destination:4 = cpool( 0:4, METHOD_INDEX, $(CPOOL_STATIC_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_static METHOD_INDEX,regParamC,regParamD,regParamE,regParamF,regParamG is inst0=0x71 ; N_PARAMS=5 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF & regParamG
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
iv4 = regParamG;
|
|
destination:4 = cpool( 0:4, METHOD_INDEX, $(CPOOL_STATIC_METHOD));
|
|
call [ destination ];
|
|
}
|
|
|
|
# invoke-interface is used to invoke an interface
|
|
# method, that is, on an object whose concrete
|
|
# class isn't known, using a method_id that refers
|
|
# to an interface.
|
|
|
|
:invoke_interface METHOD_INDEX is inst0=0x72 ; N_PARAMS=0 & METHOD_INDEX
|
|
{
|
|
destination:4 = cpool( 0:4, METHOD_INDEX,$(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_interface METHOD_INDEX,regParamC is inst0=0x72 ; N_PARAMS=1 & METHOD_INDEX & regParamC
|
|
{
|
|
iv0 = regParamC;
|
|
destination:4 = cpool(regParamC,METHOD_INDEX,$(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_interface METHOD_INDEX,regParamC,regParamD is inst0=0x72 ; N_PARAMS=2 & METHOD_INDEX & regParamC & regParamD
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
destination:4 = cpool(regParamC,METHOD_INDEX,$(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_interface METHOD_INDEX,regParamC,regParamD,regParamE is inst0=0x72 ; N_PARAMS=3 & METHOD_INDEX & regParamC & regParamD & regParamE
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
destination:4 = cpool(regParamC,METHOD_INDEX,$(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_interface METHOD_INDEX,regParamC,regParamD,regParamE,regParamF is inst0=0x72 ; N_PARAMS=4 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
destination:4 = cpool(regParamC,METHOD_INDEX,$(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_interface METHOD_INDEX,regParamC,regParamD,regParamE,regParamF,regParamG is inst0=0x72 ; N_PARAMS=5 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF & regParamG
|
|
{
|
|
iv0 = regParamC;
|
|
iv1 = regParamD;
|
|
iv2 = regParamE;
|
|
iv3 = regParamF;
|
|
iv4 = regParamG;
|
|
destination:4 = cpool(regParamC,METHOD_INDEX,$(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# 0x73 unused
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Call the indicated method.
|
|
# See first invoke-kind description above for details, caveats, and suggestions.
|
|
#
|
|
# A: argument word count (8 bits)
|
|
# B: method reference index (16 bits)
|
|
# C: first argument register (16 bits)
|
|
# N = A + C - 1
|
|
|
|
:invoke_virtual_range B_BITS_0_15,A_BITS_0_7,registerC16 is inst0=0x74 ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
moveRangeToIV( A_BITS_0_7:4, registerC16 );
|
|
destination:4 = cpool(registerC16, B_BITS_0_15:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_super_range B_BITS_0_15,A_BITS_0_7,registerC16 is inst0=0x75 ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
moveRangeToIV( A_BITS_0_7:4, registerC16 );
|
|
destination:4 = cpool( cpool( 0:4, 0:4, $(CPOOL_SUPER)), B_BITS_0_15:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_direct_range B_BITS_0_15,A_BITS_0_7,registerC16 is inst0=0x76 ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
moveRangeToIV( A_BITS_0_7:4, registerC16 );
|
|
destination:4 = cpool(registerC16, B_BITS_0_15:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_static_range B_BITS_0_15,A_BITS_0_7,registerC16 is inst0=0x77 ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
moveRangeToIV( A_BITS_0_7:4, registerC16 );
|
|
destination:4 = cpool(0:4, B_BITS_0_15:4, $(CPOOL_STATIC_METHOD));
|
|
call [ destination ];
|
|
}
|
|
:invoke_interface_range B_BITS_0_15,A_BITS_0_7,registerC16 is inst0=0x78 ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
moveRangeToIV( A_BITS_0_7:4, registerC16 );
|
|
destination:4 = cpool(registerC16, B_BITS_0_15:4, $(CPOOL_METHOD));
|
|
call [ destination ];
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# 0x79 unused
|
|
# 0x7a unused
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Perform the identified unary operation on the source register,
|
|
# storing the result in the destination register.
|
|
#
|
|
# A: destination register or pair (4 bits)
|
|
# B: source register or pair (4 bits)
|
|
|
|
:neg_int registerA4,registerB4 is inst0=0x7b ; registerA4 & registerB4
|
|
{
|
|
registerA4 = -registerB4;
|
|
}
|
|
|
|
:not_int registerA4,registerB4 is inst0=0x7c ; registerA4 & registerB4
|
|
{
|
|
registerA4 = ~registerB4;
|
|
}
|
|
|
|
:neg_long registerA4w,registerB4w is inst0=0x7d ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = -registerB4w;
|
|
}
|
|
|
|
:not_long registerA4w,registerB4w is inst0=0x7e ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = ~registerB4w;
|
|
}
|
|
|
|
:neg_float registerA4,registerB4 is inst0=0x7f ; registerA4 & registerB4
|
|
{
|
|
registerA4 = f-registerB4;
|
|
}
|
|
|
|
:neg_double registerA4,registerB4 is inst0=0x80 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = f-registerB4;
|
|
}
|
|
|
|
:int_to_long registerA4w,registerB4 is inst0=0x81 ; registerA4w & registerB4
|
|
{
|
|
registerA4w = sext(registerB4);
|
|
}
|
|
|
|
:int_to_float registerA4,registerB4 is inst0=0x82 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = int2float(registerB4);
|
|
}
|
|
|
|
:int_to_double registerA4w,registerB4 is inst0=0x83 ; registerA4w & registerB4
|
|
{
|
|
registerA4w = int2float(registerB4);
|
|
}
|
|
|
|
:long_to_int registerA4,registerB4w is inst0=0x84 ; registerA4 & registerB4w
|
|
{
|
|
registerA4 = registerB4w:4;
|
|
}
|
|
:long_to_float registerA4,registerB4w is inst0=0x85 ; registerA4 & registerB4w
|
|
{
|
|
registerA4 = int2float(registerB4w);
|
|
}
|
|
|
|
:long_to_double registerA4w,registerB4w is inst0=0x86 ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = int2float(registerB4w);
|
|
}
|
|
|
|
:float_to_int registerA4,registerB4 is inst0=0x87 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = trunc(registerB4);
|
|
}
|
|
|
|
:float_to_long registerA4w,registerB4 is inst0=0x88 ; registerA4w & registerB4
|
|
{
|
|
registerA4w = trunc(registerB4);
|
|
}
|
|
|
|
:float_to_double registerA4w,registerB4 is inst0=0x89 ; registerA4w & registerB4
|
|
{
|
|
registerA4w = float2float(registerB4);
|
|
}
|
|
|
|
:double_to_int registerA4,registerB4w is inst0=0x8a ; registerA4 & registerB4w
|
|
{
|
|
registerA4 = trunc(registerB4w);
|
|
}
|
|
|
|
:double_to_long registerA4w,registerB4w is inst0=0x8b ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = trunc(registerB4w);
|
|
}
|
|
|
|
:double_to_float registerA4,registerB4w is inst0=0x8c ; registerA4 & registerB4w
|
|
{
|
|
registerA4 = float2float(registerB4w);
|
|
}
|
|
|
|
:int_to_byte registerA4,registerB4 is inst0=0x8d ; registerA4 & registerB4
|
|
{
|
|
registerA4 = sext(registerB4:1);
|
|
}
|
|
|
|
:int_to_char registerA4,registerB4 is inst0=0x8e ; registerA4 & registerB4
|
|
{
|
|
registerA4 = zext(registerB4:2);
|
|
}
|
|
|
|
:int_to_short registerA4,registerB4 is inst0=0x8f ; registerA4 & registerB4
|
|
{
|
|
registerA4 = sext(registerB4:2);
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Perform the identified binary operation on the two source registers,
|
|
# storing the result in the destination register.
|
|
#
|
|
# A: destination register or pair (8 bits)
|
|
# B: first source register or pair (8 bits)
|
|
# C: second source register or pair (8 bits)
|
|
|
|
:add_int registerA8,registerB8,registerC8 is inst0=0x90 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 + registerC8;
|
|
}
|
|
:sub_int registerA8,registerB8,registerC8 is inst0=0x91 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 - registerC8;
|
|
}
|
|
:mul_int registerA8,registerB8,registerC8 is inst0=0x92 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 * registerC8;
|
|
}
|
|
:div_int registerA8,registerB8,registerC8 is inst0=0x93 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 s/ registerC8;
|
|
}
|
|
:rem_int registerA8,registerB8,registerC8 is inst0=0x94 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 s% registerC8;
|
|
}
|
|
:and_int registerA8,registerB8,registerC8 is inst0=0x95 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 & registerC8;
|
|
}
|
|
:or_int registerA8,registerB8,registerC8 is inst0=0x96 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 | registerC8;
|
|
}
|
|
:xor_int registerA8,registerB8,registerC8 is inst0=0x97 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 ^ registerC8;
|
|
}
|
|
:shl_int registerA8,registerB8,registerC8 is inst0=0x98 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 << registerC8;
|
|
}
|
|
:shr_int registerA8,registerB8,registerC8 is inst0=0x99 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 s>> registerC8;
|
|
}
|
|
:ushr_int registerA8,registerB8,registerC8 is inst0=0x9a ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 >> registerC8;
|
|
}
|
|
:add_long registerA8w,registerB8w,registerC8w is inst0=0x9b ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w + registerC8w;
|
|
}
|
|
:sub_long registerA8w,registerB8w,registerC8w is inst0=0x9c ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w - registerC8w;
|
|
}
|
|
:mul_long registerA8w,registerB8w,registerC8w is inst0=0x9d ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w * registerC8w;
|
|
}
|
|
:div_long registerA8w,registerB8w,registerC8w is inst0=0x9e ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w s/ registerC8w;
|
|
}
|
|
:rem_long registerA8w,registerB8w,registerC8w is inst0=0x9f ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w s% registerC8w;
|
|
}
|
|
:and_long registerA8w,registerB8w,registerC8w is inst0=0xa0 ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w & registerC8w;
|
|
}
|
|
:or_long registerA8w,registerB8w,registerC8w is inst0=0xa1 ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w | registerC8w;
|
|
}
|
|
:xor_long registerA8w,registerB8w,registerC8w is inst0=0xa2 ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w ^ registerC8w;
|
|
}
|
|
:shl_long registerA8w,registerB8w,registerC8 is inst0=0xa3 ; registerA8w ; registerB8w ; registerC8
|
|
{
|
|
registerA8w = registerB8w << registerC8;
|
|
}
|
|
:shr_long registerA8w,registerB8w,registerC8 is inst0=0xa4 ; registerA8w ; registerB8w ; registerC8
|
|
{
|
|
registerA8w = registerB8w s>> registerC8;
|
|
}
|
|
:ushr_long registerA8w,registerB8w,registerC8 is inst0=0xa5 ; registerA8w ; registerB8w ; registerC8
|
|
{
|
|
registerA8w = registerB8w >> registerC8;
|
|
}
|
|
:add_float registerA8,registerB8,registerC8 is inst0=0xa6 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 f+ registerC8;
|
|
}
|
|
:sub_float registerA8,registerB8,registerC8 is inst0=0xa7 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 f- registerC8;
|
|
}
|
|
:mul_float registerA8,registerB8,registerC8 is inst0=0xa8 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 f* registerC8;
|
|
}
|
|
:div_float registerA8,registerB8,registerC8 is inst0=0xa9 ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 f/ registerC8;
|
|
}
|
|
:rem_float registerA8,registerB8,registerC8 is inst0=0xaa ; registerA8 ; registerB8 ; registerC8
|
|
{
|
|
registerA8 = registerB8 s% registerC8;#TODO how to tell floating point??
|
|
}
|
|
:add_double registerA8w,registerB8w,registerC8w is inst0=0xab ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w f+ registerC8w;
|
|
}
|
|
:sub_double registerA8w,registerB8w,registerC8w is inst0=0xac ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w f- registerC8w;
|
|
}
|
|
:mul_double registerA8w,registerB8w,registerC8w is inst0=0xad ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w f* registerC8w;
|
|
}
|
|
:div_double registerA8w,registerB8w,registerC8w is inst0=0xae ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w f/ registerC8w;
|
|
}
|
|
:rem_double registerA8w,registerB8w,registerC8w is inst0=0xaf ; registerA8w ; registerB8w ; registerC8w
|
|
{
|
|
registerA8w = registerB8w s% registerC8w;#TODO how to tell floating point??
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Perform the identified binary operation on the two source registers,
|
|
# storing the result in the first source register.
|
|
#
|
|
# A: destination and first source register or pair (4 bits)
|
|
# B: second source register or pair (4 bits)
|
|
|
|
:add_int_2addr registerA4,registerB4 is inst0=0xb0 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 + registerB4;
|
|
}
|
|
:sub_int_2addr registerA4,registerB4 is inst0=0xb1 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 - registerB4;
|
|
}
|
|
:mul_int_2addr registerA4,registerB4 is inst0=0xb2 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 * registerB4;
|
|
}
|
|
:div_int_2addr registerA4,registerB4 is inst0=0xb3 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 s/ registerB4;
|
|
}
|
|
:rem_int_2addr registerA4,registerB4 is inst0=0xb4 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 s% registerB4;
|
|
}
|
|
:and_int_2addr registerA4,registerB4 is inst0=0xb5 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 & registerB4;
|
|
}
|
|
:or_int_2addr registerA4,registerB4 is inst0=0xb6 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 | registerB4;
|
|
}
|
|
:xor_int_2addr registerA4,registerB4 is inst0=0xb7 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 ^ registerB4;
|
|
}
|
|
:shl_int_2addr registerA4,registerB4 is inst0=0xb8 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 << registerB4;
|
|
}
|
|
:shr_int_2addr registerA4,registerB4 is inst0=0xb9 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 s>> registerB4;
|
|
}
|
|
:ushr_int_2addr registerA4,registerB4 is inst0=0xba ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 >> registerB4;
|
|
}
|
|
:add_long_2addr registerA4w,registerB4w is inst0=0xbb ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w + registerB4w;
|
|
}
|
|
:sub_long_2addr registerA4w,registerB4w is inst0=0xbc ; registerA4w & registerB4w
|
|
{
|
|
registerA4w= registerA4w - registerB4w;
|
|
}
|
|
:mul_long_2addr registerA4w,registerB4w is inst0=0xbd ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w * registerB4w;
|
|
}
|
|
:div_long_2addr registerA4w,registerB4w is inst0=0xbe ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w s/ registerB4w;
|
|
}
|
|
:rem_long_2addr registerA4w,registerB4w is inst0=0xbf ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w s% registerB4w;
|
|
}
|
|
:and_long_2addr registerA4w,registerB4w is inst0=0xc0 ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w & registerB4w;
|
|
}
|
|
:or_long_2addr registerA4w,registerB4w is inst0=0xc1 ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w | registerB4w;
|
|
}
|
|
:xor_long_2addr registerA4w,registerB4w is inst0=0xc2 ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w ^ registerB4w;
|
|
}
|
|
:shl_long_2addr registerA4w,registerB4 is inst0=0xc3 ; registerA4w & registerB4
|
|
{
|
|
registerA4w = registerA4w << registerB4;
|
|
}
|
|
:shr_long_2addr registerA4w,registerB4 is inst0=0xc4 ; registerA4w & registerB4
|
|
{
|
|
registerA4w = registerA4w s>> registerB4;
|
|
}
|
|
:ushr_long_2addr registerA4w,registerB4 is inst0=0xc5 ; registerA4w & registerB4
|
|
{
|
|
registerA4w = registerA4w >> registerB4;
|
|
}
|
|
:add_float_2addr registerA4,registerB4 is inst0=0xc6 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 f+ registerB4;
|
|
}
|
|
:sub_float_2addr registerA4,registerB4 is inst0=0xc7 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 f- registerB4;
|
|
}
|
|
:mul_float_2addr registerA4,registerB4 is inst0=0xc8 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 f* registerB4;
|
|
}
|
|
:div_float_2addr registerA4,registerB4 is inst0=0xc9 ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 f/ registerB4;
|
|
}
|
|
:rem_float_2addr registerA4,registerB4 is inst0=0xca ; registerA4 & registerB4
|
|
{
|
|
registerA4 = registerA4 s% registerB4;
|
|
}
|
|
:add_double_2addr registerA4w,registerB4w is inst0=0xcb ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w f+ registerB4w;
|
|
}
|
|
:sub_double_2addr registerA4w,registerB4w is inst0=0xcc ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w f- registerB4w;
|
|
}
|
|
:mul_double_2addr registerA4w,registerB4w is inst0=0xcd ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w f* registerB4w;
|
|
}
|
|
:div_double_2addr registerA4w,registerB4w is inst0=0xce ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w f/ registerB4w;
|
|
}
|
|
:rem_double_2addr registerA4w,registerB4w is inst0=0xcf ; registerA4w & registerB4w
|
|
{
|
|
registerA4w = registerA4w s% registerB4w;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Perform the indicated binary op on the indicated register (first argument)
|
|
# and literal value (second argument), storing the result in the destination
|
|
# register.
|
|
#
|
|
# A: destination register (4 bits)
|
|
# B: source register (4 bits)
|
|
# C: signed int constant (16 bits)
|
|
|
|
:add_int_lit16 registerA4,registerB4,C_BITS_0_15_S is inst0=0xd0 ; registerA4 & registerB4 ; C_BITS_0_15_S
|
|
{
|
|
registerA4 = registerB4 + C_BITS_0_15_S;
|
|
}
|
|
:rsub_int registerA4,registerB4,C_BITS_0_15_S is inst0=0xd1 ; registerA4 & registerB4 ; C_BITS_0_15_S
|
|
{
|
|
registerA4 = C_BITS_0_15_S - registerB4; # Twos-complement reverse subtraction.
|
|
}
|
|
:mul_int_lit16 registerA4,registerB4,C_BITS_0_15_S is inst0=0xd2 ; registerA4 & registerB4 ; C_BITS_0_15_S
|
|
{
|
|
registerA4 = registerB4 * C_BITS_0_15_S;
|
|
}
|
|
:div_int_lit16 registerA4,registerB4,C_BITS_0_15_S is inst0=0xd3 ; registerA4 & registerB4 ; C_BITS_0_15_S
|
|
{
|
|
registerA4 = registerB4 s/ C_BITS_0_15_S;
|
|
}
|
|
:rem_int_lit16 registerA4,registerB4,C_BITS_0_15_S is inst0=0xd4 ; registerA4 & registerB4 ; C_BITS_0_15_S
|
|
{
|
|
registerA4 = registerB4 s% C_BITS_0_15_S;
|
|
}
|
|
:and_int_lit16 registerA4,registerB4,C_BITS_0_15_S is inst0=0xd5 ; registerA4 & registerB4 ; C_BITS_0_15_S
|
|
{
|
|
registerA4 = registerB4 & C_BITS_0_15_S;
|
|
}
|
|
:or_int_lit16 registerA4,registerB4,C_BITS_0_15_S is inst0=0xd6 ; registerA4 & registerB4 ; C_BITS_0_15_S
|
|
{
|
|
registerA4 = registerB4 | C_BITS_0_15_S;
|
|
}
|
|
:xor_int_lit16 registerA4,registerB4,C_BITS_0_15_S is inst0=0xd7 ; registerA4 & registerB4 ; C_BITS_0_15_S
|
|
{
|
|
registerA4 = registerB4 ^ C_BITS_0_15_S;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# Perform the indicated binary op on the indicated register (first argument)
|
|
# and literal value (second argument), storing the result in the destination
|
|
# register.
|
|
#
|
|
# A: destination register (8 bits)
|
|
# B: source register (8 bits)
|
|
# C: signed int constant (8 bits)
|
|
|
|
:add_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xd8 ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 + C_BITS_0_7_S;
|
|
}
|
|
:rsub_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xd9 ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = C_BITS_0_7_S - registerB8; # Twos-complement reverse subtraction.
|
|
}
|
|
:mul_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xda ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 * C_BITS_0_7_S;
|
|
}
|
|
:div_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xdb ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 s/ C_BITS_0_7_S;
|
|
}
|
|
:rem_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xdc ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 s% C_BITS_0_7_S;
|
|
}
|
|
:and_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xdd ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 & C_BITS_0_7_S;
|
|
}
|
|
:or_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xde ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 | C_BITS_0_7_S;
|
|
}
|
|
:xor_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xdf ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 ^ C_BITS_0_7_S;
|
|
}
|
|
:shl_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xe0 ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 << C_BITS_0_7_S;
|
|
}
|
|
:shr_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xe1 ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 s>> C_BITS_0_7_S;
|
|
}
|
|
:ushr_int_lit8 registerA8,registerB8,C_BITS_0_7_S is inst0=0xe2 ; registerA8 ; registerB8 ; C_BITS_0_7_S
|
|
{
|
|
registerA8 = registerB8 >> C_BITS_0_7_S; #TODO should this value be signed???
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iget_volatile registerA4,[registerB4:C_BITS_0_15] is inst0=0xe3 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
registerA4 = getInstanceFieldVolatile( registerB4, C_BITS_0_15:16 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iput_volatile registerA4,[registerB4:C_BITS_0_15] is inst0=0xe4 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
setInstanceFieldVolatile( registerB4, C_BITS_0_15:16, registerA4 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:sget_volatile registerA8,B_BITS_0_15 is inst0=0xe5 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
registerA8 = getStaticFieldVolatile( B_BITS_0_15:16 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:sput_volatile registerA8,B_BITS_0_15 is inst0=0xe6 ; registerA8 ; B_BITS_0_15
|
|
{
|
|
setStaticFieldVolatile( B_BITS_0_15:16, registerA8 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iget_object_volatile registerA4,[registerB4:C_BITS_0_15] is inst0=0xe7 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
registerA4 = getInstanceFieldVolatile( registerB4, C_BITS_0_15:16 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iget_wide_volatile registerA4w,[registerB4:C_BITS_0_15] is inst0=0xe8 ; registerA4w & registerB4 ; C_BITS_0_15
|
|
{
|
|
registerA4w = getInstanceFieldVolatile( registerB4, C_BITS_0_15:16 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iput_wide_volatile registerA4w,[registerB4:C_BITS_0_15] is inst0=0xe9 ; registerA4w & registerB4 ; C_BITS_0_15
|
|
{
|
|
setInstanceFieldVolatile( registerB4, C_BITS_0_15:16, registerA4w );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:sget_wide_volatile registerA8w,B_BITS_0_15 is inst0=0xea ; registerA8w ; B_BITS_0_15
|
|
{
|
|
registerA8w = getStaticFieldVolatile( B_BITS_0_15:16 );
|
|
}
|
|
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:sput_wide_volatile registerA8w,B_BITS_0_15 is inst0=0xeb ; registerA8w ; B_BITS_0_15
|
|
{
|
|
setStaticFieldVolatile( B_BITS_0_15:16, registerA8w );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iput_byte_quick registerA4,[registerB4:C_BITS_0_15] is inst0=0xec ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
setInstanceFieldQuick( registerB4, C_BITS_0_15:16, registerA4 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:throw_verification_error registerA8,registerB16 is inst0=0xed ; registerA8 ; registerB16
|
|
{
|
|
registerA8 = registerB16;
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:execute_inline INLINE,{} is inst0=0xee ; N_PARAMS=0 & INLINE
|
|
{
|
|
destination:4 = *[ram] ( ( 4 * INLINE:4 ) + 0xe0000000 );
|
|
call [ destination ];
|
|
}
|
|
:execute_inline INLINE,{regParamC} is inst0=0xee ; N_PARAMS=1 & INLINE & regParamC
|
|
{
|
|
destination:4 = *[ram] ( ( 4 * INLINE:4 ) + 0xe0000000 );
|
|
call [ destination ];
|
|
}
|
|
:execute_inline INLINE,{regParamC,regParamD} is inst0=0xee ; N_PARAMS=2 & INLINE & regParamC & regParamD
|
|
{
|
|
destination:4 = *[ram] ( ( 4 * INLINE:4 ) + 0xe0000000 );
|
|
call [ destination ];
|
|
}
|
|
:execute_inline INLINE,{regParamC,regParamD,regParamE} is inst0=0xee ; N_PARAMS=3 & INLINE & regParamC & regParamD & regParamE
|
|
{
|
|
destination:4 = *[ram] ( ( 4 * INLINE:4 ) + 0xe0000000 );
|
|
call [ destination ];
|
|
}
|
|
:execute_inline INLINE,{regParamC,regParamD,regParamE,regParamF} is inst0=0xee ; N_PARAMS=4 & INLINE & regParamC & regParamD & regParamE & regParamF
|
|
{
|
|
destination:4 = *[ram] ( ( 4 * INLINE:4 ) + 0xe0000000 );
|
|
call [ destination ];
|
|
}
|
|
:execute_inline INLINE,{regParamC,regParamD,regParamE,regParamF,regParamG} is inst0=0xee ; N_PARAMS=5 & INLINE & regParamC & regParamD & regParamE & regParamF & regParamG
|
|
{
|
|
destination:4 = *[ram] ( ( 4 * INLINE:4 ) + 0xe0000000 );
|
|
call [ destination ];
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:execute_inline_range "inline@"^B_BITS_0_15,A_BITS_0_7,registerC16 is inst0=0xef ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
destination:4 = *[ram] ( ( 4 * B_BITS_0_15:4 ) + 0xe0000000 );
|
|
call [ destination ];
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# THIS ODEX INSTRUCTION WAS VALID UNTIL API version 13 (OS Version 3.2.x)
|
|
|
|
# :invoke_direct_empty METHOD_INDEX is inst0=0xf0 ; N_PARAMS=0 & METHOD_INDEX
|
|
# {
|
|
# destination:4 = *[ram] ( ( 4 * METHOD_INDEX:4 ) + 0xe0000000 );
|
|
# call [ destination ];
|
|
# }
|
|
# :invoke_direct_empty METHOD_INDEX,regParamC is inst0=0xf0 ; N_PARAMS=1 & METHOD_INDEX & regParamC
|
|
# {
|
|
# destination:4 = *[ram] ( ( 4 * METHOD_INDEX:4 ) + 0xe0000000 );
|
|
# call [ destination ];
|
|
# }
|
|
# :invoke_direct_empty METHOD_INDEX,regParamC,regParamD is inst0=0xf0 ; N_PARAMS=2 & METHOD_INDEX & regParamC & regParamD
|
|
# {
|
|
# destination:4 = *[ram] ( ( 4 * METHOD_INDEX:4 ) + 0xe0000000 );
|
|
# call [ destination ];
|
|
# }
|
|
# :invoke_direct_empty METHOD_INDEX,regParamC,regParamD,regParamE is inst0=0xf0 ; N_PARAMS=3 & METHOD_INDEX & regParamC & regParamD & regParamE
|
|
# {
|
|
# destination:4 = *[ram] ( ( 4 * METHOD_INDEX:4 ) + 0xe0000000 );
|
|
# call [ destination ];
|
|
# }
|
|
# :invoke_direct_empty METHOD_INDEX,regParamC,regParamD,regParamE,regParamF is inst0=0xf0 ; N_PARAMS=4 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF
|
|
# {
|
|
# destination:4 = *[ram] ( ( 4 * METHOD_INDEX:4 ) + 0xe0000000 );
|
|
# call [ destination ];
|
|
# }
|
|
# :invoke_direct_empty METHOD_INDEX,regParamC,regParamD,regParamE,regParamF,regParamG is inst0=0xf0 ; N_PARAMS=5 & METHOD_INDEX & regParamC & regParamD & regParamE & regParamF & regParamG
|
|
# {
|
|
# destination:4 = *[ram] ( ( 4 * METHOD_INDEX:4 ) + 0xe0000000 );
|
|
# call [ destination ];
|
|
# }
|
|
|
|
|
|
# THIS ODEX INSTRUCTION WAS ADDED IN API version 14 (OS VERSIOn 4.0.x ICS)
|
|
|
|
:invoke_object_init_range B_BITS_0_15,A_BITS_0_7,registerC16 is inst0=0xf0 ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
destination:4 = *[ram] ( ( 4 * B_BITS_0_15:4 ) + 0xe0000000 );
|
|
call [ destination ];
|
|
}
|
|
|
|
# 0xf0 iget-byte-quick TODO All ART Versions
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:return_void_barrier is inst1=0xf1 & inst1_padding
|
|
{
|
|
return [sp];#TODO
|
|
}
|
|
|
|
# 0xf1 iget-char-quick TODO
|
|
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iget_quick "field@"^C_BITS_0_15,registerA4,registerB4 is inst0=0xf2 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
registerA4 = getInstanceFieldQuick( registerB4, C_BITS_0_15:16 );
|
|
}
|
|
|
|
# 0xf2 iget-short-quick TODO
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iget_wide_quick "field@"^C_BITS_0_15,registerA4w,registerB4 is inst0=0xf3 ; registerA4w & registerB4 ; C_BITS_0_15
|
|
{
|
|
registerA4w = getInstanceFieldQuick( registerB4, C_BITS_0_15:16 );
|
|
}
|
|
|
|
# 0xf3 invoke-lambda TODO
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iget_object_quick "field@"^C_BITS_0_15,registerA4,registerB4 is inst0=0xf4 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
registerA4 = getInstanceFieldQuick( registerB4, C_BITS_0_15:16 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iput_quick "field@"^C_BITS_0_15,registerA4,registerB4 is inst0=0xf5 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
setInstanceFieldQuick( registerB4, C_BITS_0_15:16, registerA4 );
|
|
}
|
|
|
|
# 0xf5 capture-variable TODO
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iput_wide_quick "field@"^C_BITS_0_15,registerA4w,registerB4 is inst0=0xf6 ; registerA4w & registerB4 ; C_BITS_0_15
|
|
{
|
|
setInstanceFieldQuick( registerB4, C_BITS_0_15:16, registerA4w );
|
|
}
|
|
|
|
# 0xf6 create-lambda TODO
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iput_object_quick "field@"^C_BITS_0_15,registerA4,registerB4 is inst0=0xf7 ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
setInstanceFieldQuick( registerB4, C_BITS_0_15:16, registerA4 );
|
|
}
|
|
|
|
# 0xf7 liberate-variable TODO
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:invoke_virtual_quick "vtable@"^VTABLE_OFFSET is inst0=0xf8 ; N_PARAMS=0 & VTABLE_OFFSET
|
|
{
|
|
invokeVirtualQuick( VTABLE_OFFSET:4 );
|
|
}
|
|
:invoke_virtual_quick "vtable@"^VTABLE_OFFSET,regParamC is inst0=0xf8 ; N_PARAMS=1 & VTABLE_OFFSET & regParamC
|
|
{
|
|
invokeVirtualQuick( VTABLE_OFFSET:4, regParamC );
|
|
}
|
|
:invoke_virtual_quick "vtable@"^VTABLE_OFFSET,regParamC,regParamD is inst0=0xf8 ; N_PARAMS=2 & VTABLE_OFFSET & regParamC & regParamD
|
|
{
|
|
invokeVirtualQuick( VTABLE_OFFSET:4, regParamC, regParamD );
|
|
}
|
|
:invoke_virtual_quick "vtable@"^VTABLE_OFFSET,regParamC,regParamD,regParamE is inst0=0xf8 ; N_PARAMS=3 & VTABLE_OFFSET & regParamC & regParamD & regParamE
|
|
{
|
|
invokeVirtualQuick( VTABLE_OFFSET:4, regParamC, regParamD, regParamE );
|
|
}
|
|
:invoke_virtual_quick "vtable@"^VTABLE_OFFSET,regParamC,regParamD,regParamE,regParamF is inst0=0xf8 ; N_PARAMS=4 & VTABLE_OFFSET & regParamC & regParamD & regParamE & regParamF
|
|
{
|
|
invokeVirtualQuick( VTABLE_OFFSET:4, regParamC, regParamD, regParamE, regParamF );
|
|
}
|
|
:invoke_virtual_quick "vtable@"^VTABLE_OFFSET,regParamC,regParamD,regParamE,regParamF,regParamG is inst0=0xf8 ; N_PARAMS=5 & VTABLE_OFFSET & regParamC & regParamD & regParamE & regParamF & regParamG
|
|
{
|
|
invokeVirtualQuick( VTABLE_OFFSET:4, regParamC, regParamD, regParamE, regParamF, regParamG );
|
|
|
|
}
|
|
|
|
# 0xf8 box-lambda TODO
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:invoke_virtual_quick_range "vtable@"^B_BITS_0_15,A_BITS_0_7,registerC16 is inst0=0xf9 ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
invokeVirtualQuickRange( B_BITS_0_15:4, A_BITS_0_7:4, registerC16 );
|
|
}
|
|
|
|
# 0xf9 unbox-lambda TODO
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:invoke_super_quick "vtable@"^VTABLE_OFFSET is inst0=0xfa ; N_PARAMS=0 & VTABLE_OFFSET
|
|
{
|
|
invokeSuperQuick( VTABLE_OFFSET:4 );
|
|
}
|
|
:invoke_super_quick "vtable@"^VTABLE_OFFSET,regParamC is inst0=0xfa ; N_PARAMS=1 & VTABLE_OFFSET & regParamC
|
|
{
|
|
invokeSuperQuick( VTABLE_OFFSET:4, regParamC );
|
|
}
|
|
:invoke_super_quick "vtable@"^VTABLE_OFFSET,regParamC,regParamD is inst0=0xfa ; N_PARAMS=2 & VTABLE_OFFSET & regParamC & regParamD
|
|
{
|
|
invokeSuperQuick( VTABLE_OFFSET:4, regParamC, regParamD );
|
|
}
|
|
:invoke_super_quick "vtable@"^VTABLE_OFFSET,regParamC,regParamD,regParamE is inst0=0xfa ; N_PARAMS=3 & VTABLE_OFFSET & regParamC & regParamD & regParamE
|
|
{
|
|
invokeSuperQuick( VTABLE_OFFSET:4, regParamC, regParamD, regParamE );
|
|
}
|
|
:invoke_super_quick "vtable@"^VTABLE_OFFSET,regParamC,regParamD,regParamE,regParamF is inst0=0xfa ; N_PARAMS=4 & VTABLE_OFFSET & regParamC & regParamD & regParamE & regParamF
|
|
{
|
|
invokeSuperQuick( VTABLE_OFFSET:4, regParamC, regParamD, regParamE, regParamF );
|
|
}
|
|
:invoke_super_quick "vtable@"^VTABLE_OFFSET,regParamC,regParamD,regParamE,regParamF,regParamG is inst0=0xfa ; N_PARAMS=5 & VTABLE_OFFSET & regParamC & regParamD & regParamE & regParamF & regParamG
|
|
{
|
|
invokeSuperQuick( VTABLE_OFFSET:4, regParamC, regParamD, regParamE, regParamF, regParamG );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:invoke_super_quick_range "vtable@"^B_BITS_0_15,A_BITS_0_7,registerC16 is inst0=0xfb ; A_BITS_0_7 ; B_BITS_0_15 ; registerC16
|
|
{
|
|
invokeSuperQuickRange( B_BITS_0_15:4, A_BITS_0_7:4, registerC16 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:iput_object_volatile registerA4,registerB4,C_BITS_0_15 is inst0=0xfc ; registerA4 & registerB4 ; C_BITS_0_15
|
|
{
|
|
setInstanceFieldVolatile( registerB4, C_BITS_0_15:16, registerA4 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:sget_object_volatile registerA8,B_BITS_0_15 is inst0=0xfd ; registerA8 ; B_BITS_0_15
|
|
{
|
|
registerA8 = getStaticFieldVolatile( B_BITS_0_15:16 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
:sput_object_volatile registerA8,B_BITS_0_15 is inst0=0xfe ; registerA8 ; B_BITS_0_15
|
|
{
|
|
setStaticFieldVolatile( B_BITS_0_15:16, registerA8 );
|
|
}
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|
|
|
|
# 0xff ?
|
|
|
|
#------------------------------------------------------------------------------------
|
|
#------------------------------------------------------------------------------------
|