1%def field(helper=""): 2 /* 3 * General field read / write (iget-* iput-* sget-* sput-*). 4 */ 5 .extern $helper 6 REFRESH_INST ${opnum} # fix rINST to include opcode 7 movq rPC, OUT_ARG0 # arg0: Instruction* inst 8 movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data 9 leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf 10 movq rSELF, OUT_ARG3 # arg3: Thread* self 11 call SYMBOL($helper) 12 testb %al, %al 13 jz MterpPossibleException 14 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 15 16%def op_check_cast(): 17/* 18 * Check to see if a cast from one class to another is allowed. 19 */ 20 /* check-cast vAA, class@BBBB */ 21 EXPORT_PC 22 movzwq 2(rPC), OUT_ARG0 # OUT_ARG0 <- BBBB 23 leaq VREG_ADDRESS(rINSTq), OUT_ARG1 24 movq OFF_FP_METHOD(rFP), OUT_ARG2 25 movq rSELF, OUT_ARG3 26 call SYMBOL(MterpCheckCast) # (index, &obj, method, self) 27 testb %al, %al 28 jnz MterpPossibleException 29 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 30 31%def op_iget(is_object="0", helper="MterpIGetU32"): 32% field(helper=helper) 33 34%def op_iget_boolean(): 35% op_iget(helper="MterpIGetU8") 36 37%def op_iget_boolean_quick(): 38% op_iget_quick(load="movsbl") 39 40%def op_iget_byte(): 41% op_iget(helper="MterpIGetI8") 42 43%def op_iget_byte_quick(): 44% op_iget_quick(load="movsbl") 45 46%def op_iget_char(): 47% op_iget(helper="MterpIGetU16") 48 49%def op_iget_char_quick(): 50% op_iget_quick(load="movzwl") 51 52%def op_iget_object(): 53% op_iget(is_object="1", helper="MterpIGetObj") 54 55%def op_iget_object_quick(): 56 /* For: iget-object-quick */ 57 /* op vA, vB, offset@CCCC */ 58 .extern artIGetObjectFromMterp 59 movzbq rINSTbl, %rcx # rcx <- BA 60 sarl $$4, %ecx # ecx <- B 61 GET_VREG OUT_32_ARG0, %rcx # vB (object we're operating on) 62 movzwl 2(rPC), OUT_32_ARG1 # eax <- field byte offset 63 EXPORT_PC 64 callq SYMBOL(artIGetObjectFromMterp) # (obj, offset) 65 movq rSELF, %rcx 66 cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx) 67 jnz MterpException # bail out 68 andb $$0xf, rINSTbl # rINST <- A 69 SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value 70 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 71 72%def op_iget_quick(load="movl", wide="0"): 73 /* For: iget-quick, iget-boolean-quick, iget-byte-quick, iget-char-quick, iget-short-quick, iget-wide-quick */ 74 /* op vA, vB, offset@CCCC */ 75 movl rINST, %ecx # rcx <- BA 76 sarl $$4, %ecx # ecx <- B 77 GET_VREG %ecx, %rcx # vB (object we're operating on) 78 movzwq 2(rPC), %rax # eax <- field byte offset 79 testl %ecx, %ecx # is object null? 80 je common_errNullObject 81 andb $$0xf,rINSTbl # rINST <- A 82 .if $wide 83 movq (%rcx,%rax,1), %rax 84 SET_WIDE_VREG %rax, rINSTq # fp[A] <- value 85 .else 86 ${load} (%rcx,%rax,1), %eax 87 SET_VREG %eax, rINSTq # fp[A] <- value 88 .endif 89 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 90 91%def op_iget_short(): 92% op_iget(helper="MterpIGetI16") 93 94%def op_iget_short_quick(): 95% op_iget_quick(load="movswl") 96 97%def op_iget_wide(): 98% op_iget(helper="MterpIGetU64") 99 100%def op_iget_wide_quick(): 101% op_iget_quick(load="movswl", wide="1") 102 103%def op_instance_of(): 104/* 105 * Check to see if an object reference is an instance of a class. 106 * 107 * Most common situation is a non-null object, being compared against 108 * an already-resolved class. 109 */ 110 /* instance-of vA, vB, class@CCCC */ 111 EXPORT_PC 112 movzwl 2(rPC), OUT_32_ARG0 # OUT_32_ARG0 <- CCCC 113 movl rINST, %eax # eax <- BA 114 sarl $$4, %eax # eax <- B 115 leaq VREG_ADDRESS(%rax), OUT_ARG1 # Get object address 116 movq OFF_FP_METHOD(rFP), OUT_ARG2 117 movq rSELF, OUT_ARG3 118 call SYMBOL(MterpInstanceOf) # (index, &obj, method, self) 119 movsbl %al, %eax 120 movq rSELF, %rcx 121 cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx) 122 jnz MterpException 123 andb $$0xf, rINSTbl # rINSTbl <- A 124 SET_VREG %eax, rINSTq 125 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 126 127%def op_iput(is_object="0", helper="MterpIPutU32"): 128% field(helper=helper) 129 130%def op_iput_boolean(): 131% op_iput(helper="MterpIPutU8") 132 133%def op_iput_boolean_quick(): 134% op_iput_quick(reg="rINSTbl", store="movb") 135 136%def op_iput_byte(): 137% op_iput(helper="MterpIPutI8") 138 139%def op_iput_byte_quick(): 140% op_iput_quick(reg="rINSTbl", store="movb") 141 142%def op_iput_char(): 143% op_iput(helper="MterpIPutU16") 144 145%def op_iput_char_quick(): 146% op_iput_quick(reg="rINSTw", store="movw") 147 148%def op_iput_object(): 149% op_iput(is_object="1", helper="MterpIPutObj") 150 151%def op_iput_object_quick(): 152 EXPORT_PC 153 leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0 154 movq rPC, OUT_ARG1 155 REFRESH_INST ${opnum} 156 movl rINST, OUT_32_ARG2 157 call SYMBOL(MterpIputObjectQuick) 158 testb %al, %al 159 jz MterpException 160 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 161 162%def op_iput_quick(reg="rINST", store="movl"): 163 /* For: iput-quick, iput-object-quick */ 164 /* op vA, vB, offset@CCCC */ 165 movzbq rINSTbl, %rcx # rcx <- BA 166 sarl $$4, %ecx # ecx <- B 167 GET_VREG %ecx, %rcx # vB (object we're operating on) 168 testl %ecx, %ecx # is object null? 169 je common_errNullObject 170 andb $$0xf, rINSTbl # rINST <- A 171 GET_VREG rINST, rINSTq # rINST <- v[A] 172 movzwq 2(rPC), %rax # rax <- field byte offset 173 ${store} ${reg}, (%rcx,%rax,1) 174 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 175 176%def op_iput_short(): 177% op_iput(helper="MterpIPutI16") 178 179%def op_iput_short_quick(): 180% op_iput_quick(reg="rINSTw", store="movw") 181 182%def op_iput_wide(): 183% op_iput(helper="MterpIPutU64") 184 185%def op_iput_wide_quick(): 186 /* iput-wide-quick vA, vB, offset@CCCC */ 187 movzbq rINSTbl, %rcx # rcx<- BA 188 sarl $$4, %ecx # ecx<- B 189 GET_VREG %ecx, %rcx # vB (object we're operating on) 190 testl %ecx, %ecx # is object null? 191 je common_errNullObject 192 movzwq 2(rPC), %rax # rax<- field byte offset 193 leaq (%rcx,%rax,1), %rcx # ecx<- Address of 64-bit target 194 andb $$0xf, rINSTbl # rINST<- A 195 GET_WIDE_VREG %rax, rINSTq # rax<- fp[A]/fp[A+1] 196 movq %rax, (%rcx) # obj.field<- r0/r1 197 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 198 199%def op_new_instance(): 200/* 201 * Create a new instance of a class. 202 */ 203 /* new-instance vAA, class@BBBB */ 204 EXPORT_PC 205 leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0 206 movq rSELF, OUT_ARG1 207 REFRESH_INST ${opnum} 208 movq rINSTq, OUT_ARG2 209 call SYMBOL(MterpNewInstance) 210 testb %al, %al # 0 means an exception is thrown 211 jz MterpPossibleException 212 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 213 214%def op_sget(is_object="0", helper="MterpSGetU32"): 215% field(helper=helper) 216 217%def op_sget_boolean(): 218% op_sget(helper="MterpSGetU8") 219 220%def op_sget_byte(): 221% op_sget(helper="MterpSGetI8") 222 223%def op_sget_char(): 224% op_sget(helper="MterpSGetU16") 225 226%def op_sget_object(): 227% op_sget(is_object="1", helper="MterpSGetObj") 228 229%def op_sget_short(): 230% op_sget(helper="MterpSGetI16") 231 232%def op_sget_wide(): 233% op_sget(helper="MterpSGetU64") 234 235%def op_sput(is_object="0", helper="MterpSPutU32"): 236% field(helper=helper) 237 238%def op_sput_boolean(): 239% op_sput(helper="MterpSPutU8") 240 241%def op_sput_byte(): 242% op_sput(helper="MterpSPutI8") 243 244%def op_sput_char(): 245% op_sput(helper="MterpSPutU16") 246 247%def op_sput_object(): 248% op_sput(is_object="1", helper="MterpSPutObj") 249 250%def op_sput_short(): 251% op_sput(helper="MterpSPutI16") 252 253%def op_sput_wide(): 254% op_sput(helper="MterpSPutU64") 255