b3e1caea85cbdbb206ea4b9b60f3d41f5caab33b
[pcsx_rearmed.git] / deps / lightning / lib / jit_size.c
1 /*
2  * Copyright (C) 2013-2022  Free Software Foundation, Inc.
3  *
4  * This file is part of GNU lightning.
5  *
6  * GNU lightning is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * GNU lightning is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14  * License for more details.
15  *
16  * Authors:
17  *      Paulo Cesar Pereira de Andrade
18  */
19
20 #include <lightning.h>
21 #include <lightning/jit_private.h>
22 #if GET_JIT_SIZE
23 #  include <stdio.h>
24 #endif
25
26 /*
27  * Initialization
28  */
29 static jit_int16_t      _szs[jit_code_last_code] = {
30 #if GET_JIT_SIZE
31 #  define JIT_INSTR_MAX         512
32 #else
33 #  if defined(__i386__) || defined(__x86_64__)
34 #    include "jit_x86-sz.c"
35 #  elif defined(__mips__)
36 #    include "jit_mips-sz.c"
37 #  elif defined(__arm__)
38 #    include "jit_arm-sz.c"
39 #  elif defined(__powerpc__)
40 #    include "jit_ppc-sz.c"
41 #  elif defined(__sparc__)
42 #    include "jit_sparc-sz.c"
43 #  elif defined(__ia64__)
44 #    include "jit_ia64-sz.c"
45 #  elif defined(__hppa__)
46 #    include "jit_hppa-sz.c"
47 #  elif defined(__aarch64__)
48 #    include "jit_aarch64-sz.c"
49 #  elif defined(__s390__) || defined(__s390x__)
50 #    include "jit_s390-sz.c"
51 #  elif defined(__alpha__)
52 #    include "jit_alpha-sz.c"
53 #  elif defined(__riscv)
54 #    include "jit_riscv-sz.c"
55 #  elif defined(__loongarch__)
56 #    include "jit_loongarch-sz.c"
57 #  endif
58 #endif
59 };
60
61 /*
62  * Implementation
63  */
64 void
65 jit_init_size(void)
66 {
67 #if DEBUG
68 #  if !GET_JIT_SIZE
69     jit_word_t          offset;
70
71     for (offset = 0; offset < jit_size(_szs); offset++)
72         if (_szs[offset] != 0)
73             return;
74     /* Ensure data was collected */
75     abort();
76 #  endif
77 #endif
78 }
79
80 #if GET_JIT_SIZE
81 void
82 _jit_size_prepare(jit_state_t *_jit)
83 {
84     _jitc->cptr = _jit->code.ptr;
85     _jitc->size = _jit->pc.w;
86 }
87
88 void
89 _jit_size_collect(jit_state_t *_jit, jit_node_t *node)
90 {
91     jit_word_t          length;
92
93     if (_jitc->cptr == _jit->code.ptr) {
94         length = _jit->pc.w - _jitc->size;
95         if (_szs[node->code] < length)
96             _szs[node->code] = length;
97     }
98 }
99
100 #else
101 jit_word_t
102 _jit_get_size(jit_state_t *_jit)
103 {
104     jit_word_t           size;
105     jit_node_t          *node;
106 #  if __riscv && __WORDSIZE == 64
107     jit_word_t           extra = 0;
108 #  endif
109
110     for (size = JIT_INSTR_MAX, node = _jitc->head; node; node = node->next) {
111 #  if __riscv && __WORDSIZE == 64
112         /* Get estimative of extra memory for constants at end of code. */
113         switch (node->code) {
114             case jit_code_movi:
115             case jit_code_movi_f:
116             case jit_code_movi_d:
117             case jit_code_jmpi:
118             case jit_code_calli:
119                 extra += sizeof(jit_word_t);
120             default:
121                 break;
122         }
123 #  endif
124         size += _szs[node->code];
125     }
126 #  if __riscv && __WORDSIZE == 64
127     /* Heuristically only 20% of constants are unique. */
128     size += extra / 5;
129 #  endif
130
131     return size;
132 }
133 #endif
134
135 jit_word_t
136 jit_get_max_instr(void)
137 {
138     return (JIT_INSTR_MAX >= 144 ? JIT_INSTR_MAX : 144);
139 }
140
141 void
142 jit_finish_size(void)
143 {
144 #if GET_JIT_SIZE
145     FILE                *fp;
146     jit_word_t           offset;
147
148     /* Define a single path */
149     fp = fopen(JIT_SIZE_PATH, "a");
150     assert(fp);
151     for (offset = 0; offset < jit_size(_szs); offset++)
152         fprintf(fp, "%d %d\n", offset, _szs[offset]);
153     fclose(fp);
154 #endif
155 }