s390: use signed tag comparisons, so that we could use
[ajla.git] / c1-mips.inc
blob22c9b0d71246b740bab17cc7e7f13dc2adee000c
1 /*
2  * Copyright (C) 2024 Mikulas Patocka
3  *
4  * This file is part of Ajla.
5  *
6  * Ajla is free software: you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation, either version 3 of the License, or (at your option) any later
9  * version.
10  *
11  * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * Ajla. If not, see <https://www.gnu.org/licenses/>.
17  */
19 #ifdef ARCH_MIPS_O32
20 #define OP_SIZE_NATIVE  OP_SIZE_4
21 #else
22 #define OP_SIZE_NATIVE  OP_SIZE_8
23 #endif
25 #ifdef ARCH_MIPS32
26 #define OP_SIZE_ADDRESS OP_SIZE_4
27 #else
28 #define OP_SIZE_ADDRESS OP_SIZE_8
29 #endif
31 #define JMP_LIMIT       JMP_EXTRA_LONG
33 #define UNALIGNED_TRAP                  (!MIPS_R6)
35 #define ALU_WRITES_FLAGS(alu, im)       0
36 #define ALU1_WRITES_FLAGS(alu)          0
37 #define ROT_WRITES_FLAGS(alu, size, im) 0
38 #define COND_IS_LOGICAL(cond)           0
40 #define ARCH_PARTIAL_ALU(size)          0
41 #define ARCH_IS_3ADDRESS(alu, f)        1
42 #define ARCH_IS_3ADDRESS_IMM(alu, f)    1
43 #define ARCH_IS_3ADDRESS_ROT(alu, size) 1
44 #define ARCH_IS_3ADDRESS_ROT_IMM(alu)   1
45 #define ARCH_IS_2ADDRESS(alu)           1
46 #define ARCH_IS_3ADDRESS_FP             1
47 #define ARCH_HAS_JMP_2REGS(cond)        ((cond) == COND_E || (cond) == COND_NE || MIPS_R6)
48 #define ARCH_HAS_FLAGS                  0
49 #define ARCH_SUPPORTS_TRAPS             OS_SUPPORTS_TRAPS
50 #define ARCH_TRAP_BEFORE                1
51 #define ARCH_PREFERS_SX(size)           0
52 #define ARCH_HAS_BWX                    1
53 #define ARCH_HAS_MUL                    1
54 #define ARCH_HAS_DIV                    1
55 #define ARCH_HAS_ANDN                   0
56 #define ARCH_HAS_SHIFTED_ADD(bits)      (MIPS_R6 && (bits) >= 1 && (bits) <= 4)
57 #define ARCH_HAS_BTX(btx, size, cnst)   0
58 #define ARCH_SHIFT_SIZE                 OP_SIZE_4
59 #define ARCH_HAS_FP_GP_MOV              1
60 #define ARCH_NEEDS_BARRIER              0
62 #define i_size(size)                    OP_SIZE_NATIVE
63 #define i_size_rot(size)                maximum(size, OP_SIZE_4)
64 #define i_size_cmp(size)                OP_SIZE_NATIVE
66 #if __mips < 2
67 #define MIPS_LOAD_DELAY_SLOTS           1
68 #define MIPS_HAS_LS_DOUBLE              0
69 #define MIPS_HAS_SQRT                   0
70 #define MIPS_HAS_TRUNC                  0
71 #else
72 #define MIPS_LOAD_DELAY_SLOTS           0
73 #define MIPS_HAS_LS_DOUBLE              1
74 #define MIPS_HAS_SQRT                   1
75 #define MIPS_HAS_TRUNC                  1
76 #endif
78 #if __mips < 4
79 #define MIPS_R4000_ERRATA               1
80 #define MIPS_FCMP_DELAY_SLOTS           1
81 #define MIPS_HAS_MOVT                   0
82 #else
83 #define MIPS_R4000_ERRATA               0
84 #define MIPS_FCMP_DELAY_SLOTS           0
85 #define MIPS_HAS_MOVT                   1
86 #endif
88 #if __mips < 32
89 #define MIPS_HAS_CLZ                    0
90 #define MIPS_HAS_MUL                    0
91 #else
92 #define MIPS_HAS_CLZ                    1
93 #define MIPS_HAS_MUL                    1
94 #endif
96 #if __mips < 32 || !defined(__mips_isa_rev) || __mips_isa_rev < 2
97 #define MIPS_HAS_ROT                    0
98 #else
99 #define MIPS_HAS_ROT                    1
100 #endif
102 #if __mips < 32 || !defined(__mips_isa_rev) || __mips_isa_rev < 6
103 #define MIPS_R6                         0
104 #else
105 #define MIPS_R6                         1
106 #endif
108 #define R_ZERO          0x00
109 #define R_AT            0x01
110 #define R_V0            0x02
111 #define R_V1            0x03
112 #define R_A0            0x04
113 #define R_A1            0x05
114 #define R_A2            0x06
115 #define R_A3            0x07
116 #define R_T0            0x08
117 #define R_T1            0x09
118 #define R_T2            0x0a
119 #define R_T3            0x0b
120 #define R_T4            0x0c
121 #define R_T5            0x0d
122 #define R_T6            0x0e
123 #define R_T7            0x0f
124 #define R_S0            0x10
125 #define R_S1            0x11
126 #define R_S2            0x12
127 #define R_S3            0x13
128 #define R_S4            0x14
129 #define R_S5            0x15
130 #define R_S6            0x16
131 #define R_S7            0x17
132 #define R_T8            0x18
133 #define R_T9            0x19
134 #define R_K0            0x1a
135 #define R_K1            0x1b
136 #define R_GP            0x1c
137 #define R_SP            0x1d
138 #define R_FP            0x1e
139 #define R_RA            0x1f
141 #define R_F0            0x20
142 #define R_F1            0x21
143 #define R_F2            0x22
144 #define R_F3            0x23
145 #define R_F4            0x24
146 #define R_F5            0x25
147 #define R_F6            0x26
148 #define R_F7            0x27
149 #define R_F8            0x28
150 #define R_F9            0x29
151 #define R_F10           0x2a
152 #define R_F11           0x2b
153 #define R_F12           0x2c
154 #define R_F13           0x2d
155 #define R_F14           0x2e
156 #define R_F15           0x2f
157 #define R_F16           0x30
158 #define R_F17           0x31
159 #define R_F18           0x32
160 #define R_F19           0x33
161 #define R_F20           0x34
162 #define R_F21           0x35
163 #define R_F22           0x36
164 #define R_F23           0x37
165 #define R_F24           0x38
166 #define R_F25           0x39
167 #define R_F26           0x3a
168 #define R_F27           0x3b
169 #define R_F28           0x3c
170 #define R_F29           0x3d
171 #define R_F30           0x3e
172 #define R_F31           0x3f
174 #define R_FRAME         R_S0
175 #define R_UPCALL        R_S1
177 #define R_SCRATCH_1     R_A0
178 #define R_SCRATCH_2     R_A1
179 #define R_SCRATCH_3     R_A2
180 #define R_SCRATCH_4     R_SAVED_2
181 #define R_SCRATCH_NA_1  R_T0
182 #define R_SCRATCH_NA_2  R_T1
183 #define R_SCRATCH_NA_3  R_T2
185 #define R_SAVED_1       R_S2
186 #define R_SAVED_2       R_S3
188 #define R_ARG0          R_A0
189 #define R_ARG1          R_A1
190 #define R_ARG2          R_A2
191 #define R_ARG3          R_A3
193 #define R_RET0          R_V0
194 #define R_RET1          R_V1
196 #define R_OFFSET_IMM    R_T3
197 #define R_CONST_IMM     R_T4
198 #define R_CMP_RESULT    R_T5
200 #define FR_SCRATCH_1    R_F0
201 #define FR_SCRATCH_2    R_F2
202 #define FR_SCRATCH_3    R_F4
203 #define FR_CMP_RESULT   R_F6
205 #define SUPPORTED_FP    0x6
207 #ifdef ARCH_MIPS_O32
208 #define FRAME_SIZE      64
209 #define SAVE_OFFSET     20
210 #else
211 #define FRAME_SIZE      96
212 #define SAVE_OFFSET     0
213 #endif
215 static bool reg_is_fp(unsigned reg)
217         return reg >= 0x20 && reg < 0x40;
220 static const uint8_t regs_saved[] = { R_S4, R_S5, R_S6, R_S7,
221 #ifndef ARCH_MIPS_O32
222         R_GP,
223 #endif
224         R_FP };
225 static const uint8_t regs_volatile[] = { R_A3, R_T6, R_T7, R_T8, R_T9 };
226 static const uint8_t fp_saved[] = { 0 };
227 #define n_fp_saved 0U
228 static const uint8_t fp_volatile[] = { R_F8, R_F10, R_F12, R_F14, R_F16, R_F18 };
229 #define reg_is_saved(r) (((r) >= R_S0 && (r) <= R_S7) || (r) == R_GP || (r) == R_FP)
231 static bool attr_w gen_load_constant(struct codegen_context *ctx, unsigned reg, uint64_t c)
233         if (OP_SIZE_NATIVE == OP_SIZE_4)
234                 c = (int32_t)c;
235         if ((int64_t)c != (int32_t)c) {
236                 if (MIPS_R6) {
237                         g(gen_load_constant(ctx, reg, (int32_t)c));
238                         if ((int32_t)c < 0) {
239                                 c += 0x100000000ULL;
240                         }
241                         c &= ~0xFFFFFFFFULL;
242                         c >>= 32;
243                         if (c & 0xFFFFULL) {
244                                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_ADD, 0);
245                                 gen_one(reg);
246                                 gen_one(reg);
247                                 gen_one(ARG_IMM);
248                                 gen_eight((uint64_t)(int16_t)c << 32);
249                         }
250                         if ((int16_t)c < 0) {
251                                 c += 0x10000ULL;
252                         }
253                         c &= ~0xFFFFULL;
254                         c >>= 16;
255                         if (c & 0xFFFFULL) {
256                                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_ADD, 0);
257                                 gen_one(reg);
258                                 gen_one(reg);
259                                 gen_one(ARG_IMM);
260                                 gen_eight(c << 48);
261                         }
262                         return true;
263                 }
264                 if (c && !(c & (c - 1))) {
265                         int bit = -1;
266                         uint64_t cc = c;
267                         do {
268                                 cc >>= 1;
269                                 bit++;
270                         } while (cc);
271                         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
272                         gen_one(reg);
273                         gen_one(R_ZERO);
274                         gen_one(ARG_IMM);
275                         gen_eight(1);
277                         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
278                         gen_one(reg);
279                         gen_one(reg);
280                         gen_one(ARG_IMM);
281                         gen_eight(bit);
283                         return true;
284                 }
285                 if (~c && !(~c & (~c - 1))) {
286                         g(gen_load_constant(ctx, reg, ~c));
288                         gen_insn(INSN_ALU1, OP_SIZE_NATIVE, ALU1_NOT, 0);
289                         gen_one(reg);
290                         gen_one(reg);
292                         return true;
293                 }
294                 g(gen_load_constant(ctx, reg, (int32_t)((c & 0xFFFFFFFF00000000ULL) >> 32)));
295                 c &= 0xFFFFFFFFULL;
296                 if (c & 0xFFFF0000ULL) {
297                         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
298                         gen_one(reg);
299                         gen_one(reg);
300                         gen_one(ARG_IMM);
301                         gen_eight(16);
303                         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
304                         gen_one(reg);
305                         gen_one(reg);
306                         gen_one(ARG_IMM);
307                         gen_eight(c >> 16);
309                         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
310                         gen_one(reg);
311                         gen_one(reg);
312                         gen_one(ARG_IMM);
313                         gen_eight(16);
314                 } else {
315                         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
316                         gen_one(reg);
317                         gen_one(reg);
318                         gen_one(ARG_IMM);
319                         gen_eight(32);
320                 }
321                 if (c & 0xFFFFULL) {
322                         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
323                         gen_one(reg);
324                         gen_one(reg);
325                         gen_one(ARG_IMM);
326                         gen_eight(c & 0xFFFFULL);
327                 }
328                 return true;
329         }
330         if (c == (uint16_t)c) {
331                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
332                 gen_one(reg);
333                 gen_one(R_ZERO);
334                 gen_one(ARG_IMM);
335                 gen_eight(c);
336                 return true;
337         }
338         if ((int64_t)c == (int16_t)c) {
339                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_ADD, 0);
340                 gen_one(reg);
341                 gen_one(R_ZERO);
342                 gen_one(ARG_IMM);
343                 gen_eight(c);
344                 return true;
345         }
346         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
347         gen_one(reg);
348         gen_one(ARG_IMM);
349         gen_eight(c & ~0xffffULL);
350         if (c & 0xFFFFULL) {
351                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
352                 gen_one(reg);
353                 gen_one(reg);
354                 gen_one(ARG_IMM);
355                 gen_eight(c & 0xFFFFULL);
356         }
357         return true;
360 static bool attr_w gen_address(struct codegen_context *ctx, unsigned base, int64_t imm, unsigned purpose, unsigned size)
362         ctx->base_reg = base;
363         ctx->offset_imm = imm;
364         ctx->offset_reg = false;
365         switch (purpose) {
366                 case IMM_PURPOSE_LDR_OFFSET:
367                 case IMM_PURPOSE_LDR_SX_OFFSET:
368                 case IMM_PURPOSE_STR_OFFSET:
369                 case IMM_PURPOSE_VLDR_VSTR_OFFSET:
370                 case IMM_PURPOSE_MVI_CLI_OFFSET:
371                         if (likely(imm == (int16_t)imm))
372                                 return true;
373                         break;
374                 default:
375                         internal(file_line, "gen_address: invalid purpose %u (imm %"PRIxMAX", size %u)", purpose, (uintmax_t)imm, size);
376         }
377         g(gen_load_constant(ctx, R_OFFSET_IMM, imm));
378         gen_insn(INSN_ALU, OP_SIZE_ADDRESS, ALU_ADD, 0);
379         gen_one(R_OFFSET_IMM);
380         gen_one(R_OFFSET_IMM);
381         gen_one(base);
382         ctx->base_reg = R_OFFSET_IMM;
383         ctx->offset_imm = 0;
384         return true;
387 static bool is_direct_const(int64_t imm, unsigned purpose, unsigned size)
389         if (MIPS_R4000_ERRATA && (purpose == IMM_PURPOSE_ADD || purpose == IMM_PURPOSE_SUB) && size == OP_SIZE_8)
390                 return false;
391         switch (purpose) {
392                 case IMM_PURPOSE_STORE_VALUE:
393                         if (!imm)
394                                 return true;
395                         break;
396                 case IMM_PURPOSE_ADD:
397                 case IMM_PURPOSE_CMP:
398                 case IMM_PURPOSE_CMP_LOGICAL:
399                         if (likely(imm == (int16_t)imm))
400                                 return true;
401                         break;
402                 case IMM_PURPOSE_SUB:
403                         if (likely(imm > -0x8000) && likely(imm <= 0x8000))
404                                 return true;
405                         break;
406                 case IMM_PURPOSE_AND:
407                 case IMM_PURPOSE_OR:
408                 case IMM_PURPOSE_XOR:
409                 case IMM_PURPOSE_TEST:
410                         if (likely((uint64_t)imm == (uint16_t)imm))
411                                 return true;
412                         break;
413                 case IMM_PURPOSE_MUL:
414                         break;
415                 default:
416                         internal(file_line, "is_direct_const: invalid purpose %u (imm %"PRIxMAX", size %u)", purpose, (uintmax_t)imm, size);
417         }
418         return false;
421 static bool attr_w gen_imm(struct codegen_context *ctx, int64_t imm, unsigned purpose, unsigned size)
423         if (is_direct_const(imm, purpose, size)) {
424                 ctx->const_imm = imm;
425                 ctx->const_reg = false;
426         } else {
427                 g(gen_load_constant(ctx, R_CONST_IMM, imm));
428                 ctx->const_reg = true;
429         }
430         return true;
433 static bool attr_w gen_entry(struct codegen_context *ctx)
435         int save_offset;
436         unsigned reg;
438         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_SUB, 0);
439         gen_one(R_SP);
440         gen_one(R_SP);
441         gen_one(ARG_IMM);
442         gen_eight(FRAME_SIZE);
444         save_offset = SAVE_OFFSET;
446         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
447         gen_insn(INSN_MOV, OP_SIZE_4, 0, 0);
448         gen_address_offset();
449         gen_one(R_ARG2);
450         save_offset += 1 << OP_SIZE_NATIVE;
452         for (reg = R_S0; reg <= R_S7; reg++) {
453                 g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
454                 gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
455                 gen_address_offset();
456                 gen_one(reg);
457                 save_offset += 1 << OP_SIZE_NATIVE;
458         }
459 #ifndef ARCH_MIPS_O32
460         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
461         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
462         gen_address_offset();
463         gen_one(R_GP);
464         save_offset += 1 << OP_SIZE_NATIVE;
465 #endif
466         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
467         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
468         gen_address_offset();
469         gen_one(R_FP);
470         save_offset += 1 << OP_SIZE_NATIVE;
472         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
473         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
474         gen_address_offset();
475         gen_one(R_RA);
477         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
478         gen_one(R_FRAME);
479         gen_one(R_ARG0);
481         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
482         gen_one(R_UPCALL);
483         gen_one(R_ARG1);
485         gen_insn(INSN_JMP_INDIRECT, 0, 0, 0);
486         gen_one(R_ARG3);
488         return true;
491 static bool attr_w gen_escape_arg(struct codegen_context *ctx, ip_t ip, uint32_t escape_label)
493         g(gen_load_constant(ctx, R_RET1, (int32_t)ip));
495         gen_insn(INSN_JMP, 0, 0, 0);
496         gen_four(escape_label);
498         return true;
501 static bool attr_w gen_escape(struct codegen_context *ctx)
503         int save_offset;
504         unsigned reg;
506 #if defined(ARCH_MIPS_N32)
507         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
508         gen_one(R_RET1);
509         gen_one(R_RET1);
510         gen_one(ARG_IMM);
511         gen_eight(32);
513         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
514         gen_one(R_RET0);
515         gen_one(R_FRAME);
516         gen_one(R_RET1);
517 #else
518         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
519         gen_one(R_RET0);
520         gen_one(R_FRAME);
521 #endif
523         save_offset = SAVE_OFFSET + (1 << OP_SIZE_NATIVE);
524         for (reg = R_S0; reg <= R_S7; reg++) {
525                 g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_LDR_OFFSET, OP_SIZE_NATIVE));
526                 gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
527                 gen_one(reg);
528                 gen_address_offset();
529                 save_offset += 1 << OP_SIZE_NATIVE;
530         }
531 #ifndef ARCH_MIPS_O32
532         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
533         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
534         gen_one(R_GP);
535         gen_address_offset();
536         save_offset += 1 << OP_SIZE_NATIVE;
537 #endif
538         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_LDR_OFFSET, OP_SIZE_NATIVE));
539         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
540         gen_one(R_FP);
541         gen_address_offset();
542         save_offset += 1 << OP_SIZE_NATIVE;
544         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_LDR_OFFSET, OP_SIZE_NATIVE));
545         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
546         gen_one(R_RA);
547         gen_address_offset();
549         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_ADD, 0);
550         gen_one(R_SP);
551         gen_one(R_SP);
552         gen_one(ARG_IMM);
553         gen_eight(FRAME_SIZE);
555         gen_insn(INSN_RET, 0, 0, 0);
557         return true;
560 static bool attr_w gen_upcall_argument(struct codegen_context attr_unused *ctx, unsigned attr_unused arg)
562         return true;
565 static bool attr_w gen_upcall(struct codegen_context *ctx, unsigned offset, unsigned n_args)
567         g(gen_address(ctx, R_UPCALL, offset, IMM_PURPOSE_LDR_OFFSET, OP_SIZE_ADDRESS));
568         gen_insn(INSN_MOV, OP_SIZE_ADDRESS, 0, 0);
569         gen_one(R_T9);
570         gen_address_offset();
572         gen_insn(INSN_CALL_INDIRECT, OP_SIZE_ADDRESS, 0, 0);
573         gen_one(R_T9);
575         g(gen_upcall_end(ctx, n_args));
577         return true;
580 static bool attr_w gen_cmp_test_jmp(struct codegen_context *ctx, unsigned insn, unsigned op_size, unsigned reg1, unsigned reg2, unsigned cond, uint32_t label);
582 static bool attr_w gen_timestamp_test(struct codegen_context *ctx, uint32_t escape_label)
584         g(gen_address(ctx, R_UPCALL, offsetof(struct cg_upcall_vector_s, ts), IMM_PURPOSE_LDR_OFFSET, OP_SIZE_4));
585         gen_insn(INSN_MOV, OP_SIZE_4, 0, 0);
586         gen_one(R_SCRATCH_1);
587         gen_address_offset();
589         g(gen_address(ctx, R_SP, SAVE_OFFSET, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
590         gen_insn(INSN_MOV, OP_SIZE_4, 0, 0);
591         gen_one(R_SCRATCH_2);
592         gen_address_offset();
594         g(gen_cmp_test_jmp(ctx, INSN_CMP, OP_SIZE_NATIVE, R_SCRATCH_1, R_SCRATCH_2, COND_NE, escape_label));
596         return true;