codegen: fix bug on riscv when --ptrcomp was used
[ajla.git] / c1-mips.inc
blob8f6e6441018988f02171caf8ceeebfb8d3e5fca3
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_FLAGS                  0
48 #define ARCH_SUPPORTS_TRAPS             OS_SUPPORTS_TRAPS
49 #define ARCH_TRAP_BEFORE                1
50 #define ARCH_PREFERS_SX(size)           0
51 #define ARCH_HAS_BWX                    1
52 #define ARCH_HAS_MUL                    1
53 #define ARCH_HAS_DIV                    1
54 #define ARCH_HAS_ANDN                   0
55 #define ARCH_HAS_SHIFTED_ADD(bits)      (MIPS_R6 && (bits) >= 1 && (bits) <= 4)
56 #define ARCH_HAS_BTX(btx, size, cnst)   0
57 #define ARCH_SHIFT_SIZE                 OP_SIZE_4
58 #define ARCH_HAS_FP_GP_MOV              1
59 #define ARCH_NEEDS_BARRIER              0
61 #define i_size(size)                    OP_SIZE_NATIVE
62 #define i_size_rot(size)                maximum(size, OP_SIZE_4)
63 #define i_size_cmp(size)                OP_SIZE_NATIVE
65 #if __mips < 2
66 #define MIPS_LOAD_DELAY_SLOTS           1
67 #define MIPS_HAS_LS_DOUBLE              0
68 #define MIPS_HAS_SQRT                   0
69 #define MIPS_HAS_TRUNC                  0
70 #else
71 #define MIPS_LOAD_DELAY_SLOTS           0
72 #define MIPS_HAS_LS_DOUBLE              1
73 #define MIPS_HAS_SQRT                   1
74 #define MIPS_HAS_TRUNC                  1
75 #endif
77 #if __mips < 4
78 #define MIPS_R4000_ERRATA               1
79 #define MIPS_FCMP_DELAY_SLOTS           1
80 #define MIPS_HAS_MOVT                   0
81 #else
82 #define MIPS_R4000_ERRATA               0
83 #define MIPS_FCMP_DELAY_SLOTS           0
84 #define MIPS_HAS_MOVT                   1
85 #endif
87 #if __mips < 32
88 #define MIPS_HAS_CLZ                    0
89 #define MIPS_HAS_MUL                    0
90 #else
91 #define MIPS_HAS_CLZ                    1
92 #define MIPS_HAS_MUL                    1
93 #endif
95 #if __mips < 32 || !defined(__mips_isa_rev) || __mips_isa_rev < 2
96 #define MIPS_HAS_ROT                    0
97 #else
98 #define MIPS_HAS_ROT                    1
99 #endif
101 #if __mips < 32 || !defined(__mips_isa_rev) || __mips_isa_rev < 6
102 #define MIPS_R6                         0
103 #else
104 #define MIPS_R6                         1
105 #endif
107 #define R_ZERO          0x00
108 #define R_AT            0x01
109 #define R_V0            0x02
110 #define R_V1            0x03
111 #define R_A0            0x04
112 #define R_A1            0x05
113 #define R_A2            0x06
114 #define R_A3            0x07
115 #define R_T0            0x08
116 #define R_T1            0x09
117 #define R_T2            0x0a
118 #define R_T3            0x0b
119 #define R_T4            0x0c
120 #define R_T5            0x0d
121 #define R_T6            0x0e
122 #define R_T7            0x0f
123 #define R_S0            0x10
124 #define R_S1            0x11
125 #define R_S2            0x12
126 #define R_S3            0x13
127 #define R_S4            0x14
128 #define R_S5            0x15
129 #define R_S6            0x16
130 #define R_S7            0x17
131 #define R_T8            0x18
132 #define R_T9            0x19
133 #define R_K0            0x1a
134 #define R_K1            0x1b
135 #define R_GP            0x1c
136 #define R_SP            0x1d
137 #define R_FP            0x1e
138 #define R_RA            0x1f
140 #define R_F0            0x20
141 #define R_F1            0x21
142 #define R_F2            0x22
143 #define R_F3            0x23
144 #define R_F4            0x24
145 #define R_F5            0x25
146 #define R_F6            0x26
147 #define R_F7            0x27
148 #define R_F8            0x28
149 #define R_F9            0x29
150 #define R_F10           0x2a
151 #define R_F11           0x2b
152 #define R_F12           0x2c
153 #define R_F13           0x2d
154 #define R_F14           0x2e
155 #define R_F15           0x2f
156 #define R_F16           0x30
157 #define R_F17           0x31
158 #define R_F18           0x32
159 #define R_F19           0x33
160 #define R_F20           0x34
161 #define R_F21           0x35
162 #define R_F22           0x36
163 #define R_F23           0x37
164 #define R_F24           0x38
165 #define R_F25           0x39
166 #define R_F26           0x3a
167 #define R_F27           0x3b
168 #define R_F28           0x3c
169 #define R_F29           0x3d
170 #define R_F30           0x3e
171 #define R_F31           0x3f
173 #define R_FRAME         R_S0
174 #define R_UPCALL        R_S1
176 #define R_SCRATCH_1     R_A0
177 #define R_SCRATCH_2     R_A1
178 #define R_SCRATCH_3     R_A2
179 #define R_SCRATCH_4     R_SAVED_2
180 #define R_SCRATCH_NA_1  R_T0
181 #define R_SCRATCH_NA_2  R_T1
182 #define R_SCRATCH_NA_3  R_T2
184 #define R_SAVED_1       R_S2
185 #define R_SAVED_2       R_S3
187 #define R_ARG0          R_A0
188 #define R_ARG1          R_A1
189 #define R_ARG2          R_A2
190 #define R_ARG3          R_A3
192 #define R_RET0          R_V0
193 #define R_RET1          R_V1
195 #define R_OFFSET_IMM    R_T3
196 #define R_CONST_IMM     R_T4
197 #define R_CMP_RESULT    R_T5
199 #define FR_SCRATCH_1    R_F0
200 #define FR_SCRATCH_2    R_F2
201 #define FR_SCRATCH_3    R_F4
202 #define FR_CMP_RESULT   R_F6
204 #define SUPPORTED_FP    0x6
206 #ifdef ARCH_MIPS_O32
207 #define FRAME_SIZE      64
208 #define SAVE_OFFSET     20
209 #else
210 #define FRAME_SIZE      96
211 #define SAVE_OFFSET     0
212 #endif
214 static bool reg_is_fp(unsigned reg)
216         return reg >= 0x20 && reg < 0x40;
219 static const uint8_t regs_saved[] = { R_S4, R_S5, R_S6, R_S7,
220 #ifndef ARCH_MIPS_O32
221         R_GP,
222 #endif
223         R_FP };
224 static const uint8_t regs_volatile[] = { R_A3, R_T6, R_T7, R_T8, R_T9, R_RA };
225 static const uint8_t fp_saved[] = { 0 };
226 #define n_fp_saved 0U
227 static const uint8_t fp_volatile[] = { R_F8, R_F10, R_F12, R_F14, R_F16, R_F18 };
228 #define reg_is_saved(r) (((r) >= R_S0 && (r) <= R_S7) || (r) == R_GP || (r) == R_FP)
230 static bool attr_w gen_load_constant(struct codegen_context *ctx, unsigned reg, uint64_t c)
232         if (OP_SIZE_NATIVE == OP_SIZE_4)
233                 c = (int32_t)c;
234         if ((int64_t)c != (int32_t)c) {
235                 if (MIPS_R6) {
236                         g(gen_load_constant(ctx, reg, (int32_t)c));
237                         if ((int32_t)c < 0) {
238                                 c += 0x100000000ULL;
239                         }
240                         c &= ~0xFFFFFFFFULL;
241                         c >>= 32;
242                         if (c & 0xFFFFULL) {
243                                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_ADD, 0);
244                                 gen_one(reg);
245                                 gen_one(reg);
246                                 gen_one(ARG_IMM);
247                                 gen_eight((uint64_t)(int16_t)c << 32);
248                         }
249                         if ((int16_t)c < 0) {
250                                 c += 0x10000ULL;
251                         }
252                         c &= ~0xFFFFULL;
253                         c >>= 16;
254                         if (c & 0xFFFFULL) {
255                                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_ADD, 0);
256                                 gen_one(reg);
257                                 gen_one(reg);
258                                 gen_one(ARG_IMM);
259                                 gen_eight(c << 48);
260                         }
261                         return true;
262                 }
263                 if (c && !(c & (c - 1))) {
264                         int bit = -1;
265                         uint64_t cc = c;
266                         do {
267                                 cc >>= 1;
268                                 bit++;
269                         } while (cc);
270                         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
271                         gen_one(reg);
272                         gen_one(R_ZERO);
273                         gen_one(ARG_IMM);
274                         gen_eight(1);
276                         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
277                         gen_one(reg);
278                         gen_one(reg);
279                         gen_one(ARG_IMM);
280                         gen_eight(bit);
282                         return true;
283                 }
284                 if (~c && !(~c & (~c - 1))) {
285                         g(gen_load_constant(ctx, reg, ~c));
287                         gen_insn(INSN_ALU1, OP_SIZE_NATIVE, ALU1_NOT, 0);
288                         gen_one(reg);
289                         gen_one(reg);
291                         return true;
292                 }
293                 g(gen_load_constant(ctx, reg, (int32_t)((c & 0xFFFFFFFF00000000ULL) >> 32)));
294                 c &= 0xFFFFFFFFULL;
295                 if (c & 0xFFFF0000ULL) {
296                         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
297                         gen_one(reg);
298                         gen_one(reg);
299                         gen_one(ARG_IMM);
300                         gen_eight(16);
302                         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
303                         gen_one(reg);
304                         gen_one(reg);
305                         gen_one(ARG_IMM);
306                         gen_eight(c >> 16);
308                         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
309                         gen_one(reg);
310                         gen_one(reg);
311                         gen_one(ARG_IMM);
312                         gen_eight(16);
313                 } else {
314                         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
315                         gen_one(reg);
316                         gen_one(reg);
317                         gen_one(ARG_IMM);
318                         gen_eight(32);
319                 }
320                 if (c & 0xFFFFULL) {
321                         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
322                         gen_one(reg);
323                         gen_one(reg);
324                         gen_one(ARG_IMM);
325                         gen_eight(c & 0xFFFFULL);
326                 }
327                 return true;
328         }
329         if (c == (uint16_t)c) {
330                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
331                 gen_one(reg);
332                 gen_one(R_ZERO);
333                 gen_one(ARG_IMM);
334                 gen_eight(c);
335                 return true;
336         }
337         if ((int64_t)c == (int16_t)c) {
338                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_ADD, 0);
339                 gen_one(reg);
340                 gen_one(R_ZERO);
341                 gen_one(ARG_IMM);
342                 gen_eight(c);
343                 return true;
344         }
345         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
346         gen_one(reg);
347         gen_one(ARG_IMM);
348         gen_eight(c & ~0xffffULL);
349         if (c & 0xFFFFULL) {
350                 gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
351                 gen_one(reg);
352                 gen_one(reg);
353                 gen_one(ARG_IMM);
354                 gen_eight(c & 0xFFFFULL);
355         }
356         return true;
359 static bool attr_w gen_address(struct codegen_context *ctx, unsigned base, int64_t imm, unsigned purpose, unsigned size)
361         ctx->base_reg = base;
362         ctx->offset_imm = imm;
363         ctx->offset_reg = false;
364         switch (purpose) {
365                 case IMM_PURPOSE_LDR_OFFSET:
366                 case IMM_PURPOSE_LDR_SX_OFFSET:
367                 case IMM_PURPOSE_STR_OFFSET:
368                 case IMM_PURPOSE_VLDR_VSTR_OFFSET:
369                 case IMM_PURPOSE_MVI_CLI_OFFSET:
370                         if (likely(imm == (int16_t)imm))
371                                 return true;
372                         break;
373                 default:
374                         internal(file_line, "gen_address: invalid purpose %u (imm %"PRIxMAX", size %u)", purpose, (uintmax_t)imm, size);
375         }
376         g(gen_load_constant(ctx, R_OFFSET_IMM, imm));
377         gen_insn(INSN_ALU, OP_SIZE_ADDRESS, ALU_ADD, 0);
378         gen_one(R_OFFSET_IMM);
379         gen_one(R_OFFSET_IMM);
380         gen_one(base);
381         ctx->base_reg = R_OFFSET_IMM;
382         ctx->offset_imm = 0;
383         return true;
386 static bool is_direct_const(int64_t imm, unsigned purpose, unsigned size)
388         if (MIPS_R4000_ERRATA && (purpose == IMM_PURPOSE_ADD || purpose == IMM_PURPOSE_SUB) && size == OP_SIZE_8)
389                 return false;
390         switch (purpose) {
391                 case IMM_PURPOSE_STORE_VALUE:
392                         if (!imm)
393                                 return true;
394                         break;
395                 case IMM_PURPOSE_ADD:
396                 case IMM_PURPOSE_CMP:
397                 case IMM_PURPOSE_CMP_LOGICAL:
398                         if (likely(imm == (int16_t)imm))
399                                 return true;
400                         break;
401                 case IMM_PURPOSE_SUB:
402                         if (likely(imm > -0x8000) && likely(imm <= 0x8000))
403                                 return true;
404                         break;
405                 case IMM_PURPOSE_AND:
406                 case IMM_PURPOSE_OR:
407                 case IMM_PURPOSE_XOR:
408                 case IMM_PURPOSE_TEST:
409                         if (likely((uint64_t)imm == (uint16_t)imm))
410                                 return true;
411                         break;
412                 case IMM_PURPOSE_MUL:
413                         break;
414                 default:
415                         internal(file_line, "is_direct_const: invalid purpose %u (imm %"PRIxMAX", size %u)", purpose, (uintmax_t)imm, size);
416         }
417         return false;
420 static bool attr_w gen_imm(struct codegen_context *ctx, int64_t imm, unsigned purpose, unsigned size)
422         if (is_direct_const(imm, purpose, size)) {
423                 ctx->const_imm = imm;
424                 ctx->const_reg = false;
425         } else {
426                 g(gen_load_constant(ctx, R_CONST_IMM, imm));
427                 ctx->const_reg = true;
428         }
429         return true;
432 static bool attr_w gen_entry(struct codegen_context *ctx)
434         int save_offset;
435         unsigned reg;
437         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_SUB, 0);
438         gen_one(R_SP);
439         gen_one(R_SP);
440         gen_one(ARG_IMM);
441         gen_eight(FRAME_SIZE);
443         save_offset = SAVE_OFFSET;
445         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
446         gen_insn(INSN_MOV, OP_SIZE_4, 0, 0);
447         gen_address_offset();
448         gen_one(R_ARG2);
449         save_offset += 1 << OP_SIZE_NATIVE;
451         for (reg = R_S0; reg <= R_S7; reg++) {
452                 g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
453                 gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
454                 gen_address_offset();
455                 gen_one(reg);
456                 save_offset += 1 << OP_SIZE_NATIVE;
457         }
458 #ifndef ARCH_MIPS_O32
459         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
460         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
461         gen_address_offset();
462         gen_one(R_GP);
463         save_offset += 1 << OP_SIZE_NATIVE;
464 #endif
465         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
466         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
467         gen_address_offset();
468         gen_one(R_FP);
469         save_offset += 1 << OP_SIZE_NATIVE;
471         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
472         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
473         gen_address_offset();
474         gen_one(R_RA);
476         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
477         gen_one(R_FRAME);
478         gen_one(R_ARG0);
480         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
481         gen_one(R_UPCALL);
482         gen_one(R_ARG1);
484         gen_insn(INSN_JMP_INDIRECT, 0, 0, 0);
485         gen_one(R_ARG3);
487         return true;
490 static bool attr_w gen_escape_arg(struct codegen_context *ctx, ip_t ip, uint32_t escape_label)
492         g(gen_load_constant(ctx, R_RET1, (int32_t)ip));
494         gen_insn(INSN_JMP, 0, 0, 0);
495         gen_four(escape_label);
497         return true;
500 static bool attr_w gen_escape(struct codegen_context *ctx)
502         int save_offset;
503         unsigned reg;
505 #if defined(ARCH_MIPS_N32)
506         gen_insn(INSN_ROT, OP_SIZE_NATIVE, ROT_SHL, 0);
507         gen_one(R_RET1);
508         gen_one(R_RET1);
509         gen_one(ARG_IMM);
510         gen_eight(32);
512         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_OR, 0);
513         gen_one(R_RET0);
514         gen_one(R_FRAME);
515         gen_one(R_RET1);
516 #else
517         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
518         gen_one(R_RET0);
519         gen_one(R_FRAME);
520 #endif
522         save_offset = SAVE_OFFSET + (1 << OP_SIZE_NATIVE);
523         for (reg = R_S0; reg <= R_S7; reg++) {
524                 g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_LDR_OFFSET, OP_SIZE_NATIVE));
525                 gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
526                 gen_one(reg);
527                 gen_address_offset();
528                 save_offset += 1 << OP_SIZE_NATIVE;
529         }
530 #ifndef ARCH_MIPS_O32
531         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
532         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
533         gen_one(R_GP);
534         gen_address_offset();
535         save_offset += 1 << OP_SIZE_NATIVE;
536 #endif
537         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_LDR_OFFSET, OP_SIZE_NATIVE));
538         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
539         gen_one(R_FP);
540         gen_address_offset();
541         save_offset += 1 << OP_SIZE_NATIVE;
543         g(gen_address(ctx, R_SP, save_offset, IMM_PURPOSE_LDR_OFFSET, OP_SIZE_NATIVE));
544         gen_insn(INSN_MOV, OP_SIZE_NATIVE, 0, 0);
545         gen_one(R_RA);
546         gen_address_offset();
548         gen_insn(INSN_ALU, OP_SIZE_NATIVE, ALU_ADD, 0);
549         gen_one(R_SP);
550         gen_one(R_SP);
551         gen_one(ARG_IMM);
552         gen_eight(FRAME_SIZE);
554         gen_insn(INSN_RET, 0, 0, 0);
556         return true;
559 static bool attr_w gen_upcall_argument(struct codegen_context attr_unused *ctx, unsigned attr_unused arg)
561         return true;
564 static bool attr_w gen_upcall(struct codegen_context *ctx, unsigned offset, unsigned n_args)
566         g(gen_address(ctx, R_UPCALL, offset, IMM_PURPOSE_LDR_OFFSET, OP_SIZE_ADDRESS));
567         gen_insn(INSN_MOV, OP_SIZE_ADDRESS, 0, 0);
568         gen_one(R_T9);
569         gen_address_offset();
571         gen_insn(INSN_CALL_INDIRECT, OP_SIZE_ADDRESS, 0, 0);
572         gen_one(R_T9);
574         g(gen_upcall_end(ctx, n_args));
576         return true;
579 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);
581 static bool attr_w gen_timestamp_test(struct codegen_context *ctx, uint32_t escape_label)
583         g(gen_address(ctx, R_UPCALL, offsetof(struct cg_upcall_vector_s, ts), IMM_PURPOSE_LDR_OFFSET, OP_SIZE_4));
584         gen_insn(INSN_MOV, OP_SIZE_4, 0, 0);
585         gen_one(R_SCRATCH_1);
586         gen_address_offset();
588         g(gen_address(ctx, R_SP, SAVE_OFFSET, IMM_PURPOSE_STR_OFFSET, OP_SIZE_NATIVE));
589         gen_insn(INSN_MOV, OP_SIZE_4, 0, 0);
590         gen_one(R_SCRATCH_2);
591         gen_address_offset();
593         g(gen_cmp_test_jmp(ctx, INSN_CMP, OP_SIZE_NATIVE, R_SCRATCH_1, R_SCRATCH_2, COND_NE, escape_label));
595         return true;