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