codegen: improve constant loading; don't load constants from the code
[ajla.git] / cg-flcch.inc
blob05af38b555be8be08cfd209f8a143174e2e53d97
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 static bool attr_w clear_flag_cache(struct codegen_context *ctx)
21         memset(ctx->flag_cache, 0, function_n_variables(ctx->fn) * sizeof(int8_t));
22         return true;
25 /*#define clear_flag_cache(ctx) \
26         (debug("clearing flag cache @ %d", __LINE__), memset((ctx)->flag_cache, 0, function_n_variables(ctx->fn) * sizeof(int8_t)), true)*/
28 static inline void flag_set(struct codegen_context *ctx, frame_t slot, bool val)
30         if (val && !must_be_flat_chicken && da(ctx->fn,function)->local_variables_flags[slot].must_be_flat) {
31                 internal(file_line, "flag_set: %s: setting slot %lu as not flat", da(ctx->fn,function)->function_name, (unsigned long)slot);
32         }
33         ctx->flag_cache[slot] = !val ? -1 : 1;
36 static inline void flag_set_unknown(struct codegen_context *ctx, frame_t slot)
38         ctx->flag_cache[slot] = 0;
41 static inline bool flag_must_be_flat(struct codegen_context *ctx, frame_t slot)
43         if (!must_be_flat_chicken && da(ctx->fn,function)->local_variables_flags[slot].must_be_flat) {
44                 if (ctx->flag_cache[slot] == 1)
45                         internal(file_line, "flag_must_be_flat: %s: must_be_flat slot %lu is not flat", da(ctx->fn,function)->function_name, (unsigned long)slot);
46                 return true;
47         }
48         return false;
51 static inline bool flag_is_clear(struct codegen_context *ctx, frame_t slot)
53         if (!flag_cache_chicken && ctx->flag_cache[slot] == -1)
54                 return true;
55         if (flag_must_be_flat(ctx, slot))
56                 return true;
57         return false;
60 static inline bool flag_is_set(struct codegen_context *ctx, frame_t slot)
62         if (!flag_cache_chicken && ctx->flag_cache[slot] == 1)
63                 return true;
64         return false;
67 static bool attr_w gen_test_1_cached(struct codegen_context *ctx, frame_t slot_1, uint32_t label)
69         if (flag_is_clear(ctx, slot_1))
70                 return true;
71         return gen_test_1(ctx, R_FRAME, slot_1, 0, label, false, TEST);
74 static bool attr_w gen_test_2_cached(struct codegen_context *ctx, frame_t slot_1, frame_t slot_2, uint32_t label)
76         if (flag_is_clear(ctx, slot_1))
77                 return gen_test_1_cached(ctx, slot_2, label);
78         if (flag_is_clear(ctx, slot_2))
79                 return gen_test_1_cached(ctx, slot_1, label);
80         return gen_test_2(ctx, slot_1, slot_2, label);
83 static bool attr_w gen_test_1_jz_cached(struct codegen_context *ctx, frame_t slot_1, uint32_t label)
85         const struct type *type = get_type_of_local(ctx, slot_1);
86         if (!TYPE_IS_FLAT(type) && !da(ctx->fn,function)->local_variables_flags[slot_1].may_be_borrowed)
87                 return true;
88         if (flag_is_set(ctx, slot_1))
89                 return true;
90         return gen_test_1(ctx, R_FRAME, slot_1, 0, label, true, TEST);