qemu

Форк
0
/
tcg-pool.c.inc 
162 строки · 5.3 Кб
1
/*
2
 * TCG Backend Data: constant pool.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to deal
6
 * in the Software without restriction, including without limitation the rights
7
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
 * copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
 * THE SOFTWARE.
21
 */
22

23
typedef struct TCGLabelPoolData {
24
    struct TCGLabelPoolData *next;
25
    tcg_insn_unit *label;
26
    intptr_t addend;
27
    int rtype;
28
    unsigned nlong;
29
    tcg_target_ulong data[];
30
} TCGLabelPoolData;
31

32

33
static TCGLabelPoolData *new_pool_alloc(TCGContext *s, int nlong, int rtype,
34
                                        tcg_insn_unit *label, intptr_t addend)
35
{
36
    TCGLabelPoolData *n = tcg_malloc(sizeof(TCGLabelPoolData)
37
                                     + sizeof(tcg_target_ulong) * nlong);
38

39
    n->label = label;
40
    n->addend = addend;
41
    n->rtype = rtype;
42
    n->nlong = nlong;
43
    return n;
44
}
45

46
static void new_pool_insert(TCGContext *s, TCGLabelPoolData *n)
47
{
48
    TCGLabelPoolData *i, **pp;
49
    int nlong = n->nlong;
50

51
    /* Insertion sort on the pool.  */
52
    for (pp = &s->pool_labels; (i = *pp) != NULL; pp = &i->next) {
53
        if (nlong > i->nlong) {
54
            break;
55
        }
56
        if (nlong < i->nlong) {
57
            continue;
58
        }
59
        if (memcmp(n->data, i->data, sizeof(tcg_target_ulong) * nlong) >= 0) {
60
            break;
61
        }
62
    }
63
    n->next = *pp;
64
    *pp = n;
65
}
66

67
/* The "usual" for generic integer code.  */
68
static inline void new_pool_label(TCGContext *s, tcg_target_ulong d, int rtype,
69
                                  tcg_insn_unit *label, intptr_t addend)
70
{
71
    TCGLabelPoolData *n = new_pool_alloc(s, 1, rtype, label, addend);
72
    n->data[0] = d;
73
    new_pool_insert(s, n);
74
}
75

76
/* For v64 or v128, depending on the host.  */
77
static inline void new_pool_l2(TCGContext *s, int rtype, tcg_insn_unit *label,
78
                               intptr_t addend, tcg_target_ulong d0,
79
                               tcg_target_ulong d1)
80
{
81
    TCGLabelPoolData *n = new_pool_alloc(s, 2, rtype, label, addend);
82
    n->data[0] = d0;
83
    n->data[1] = d1;
84
    new_pool_insert(s, n);
85
}
86

87
/* For v128 or v256, depending on the host.  */
88
static inline void new_pool_l4(TCGContext *s, int rtype, tcg_insn_unit *label,
89
                               intptr_t addend, tcg_target_ulong d0,
90
                               tcg_target_ulong d1, tcg_target_ulong d2,
91
                               tcg_target_ulong d3)
92
{
93
    TCGLabelPoolData *n = new_pool_alloc(s, 4, rtype, label, addend);
94
    n->data[0] = d0;
95
    n->data[1] = d1;
96
    n->data[2] = d2;
97
    n->data[3] = d3;
98
    new_pool_insert(s, n);
99
}
100

101
/* For v256, for 32-bit host.  */
102
static inline void new_pool_l8(TCGContext *s, int rtype, tcg_insn_unit *label,
103
                               intptr_t addend, tcg_target_ulong d0,
104
                               tcg_target_ulong d1, tcg_target_ulong d2,
105
                               tcg_target_ulong d3, tcg_target_ulong d4,
106
                               tcg_target_ulong d5, tcg_target_ulong d6,
107
                               tcg_target_ulong d7)
108
{
109
    TCGLabelPoolData *n = new_pool_alloc(s, 8, rtype, label, addend);
110
    n->data[0] = d0;
111
    n->data[1] = d1;
112
    n->data[2] = d2;
113
    n->data[3] = d3;
114
    n->data[4] = d4;
115
    n->data[5] = d5;
116
    n->data[6] = d6;
117
    n->data[7] = d7;
118
    new_pool_insert(s, n);
119
}
120

121
/* To be provided by cpu/tcg-target.c.inc.  */
122
static void tcg_out_nop_fill(tcg_insn_unit *p, int count);
123

124
static int tcg_out_pool_finalize(TCGContext *s)
125
{
126
    TCGLabelPoolData *p = s->pool_labels;
127
    TCGLabelPoolData *l = NULL;
128
    void *a;
129

130
    if (p == NULL) {
131
        return 0;
132
    }
133

134
    /* ??? Round up to qemu_icache_linesize, but then do not round
135
       again when allocating the next TranslationBlock structure.  */
136
    a = (void *)ROUND_UP((uintptr_t)s->code_ptr,
137
                         sizeof(tcg_target_ulong) * p->nlong);
138
    tcg_out_nop_fill(s->code_ptr, (tcg_insn_unit *)a - s->code_ptr);
139
    s->data_gen_ptr = a;
140

141
    for (; p != NULL; p = p->next) {
142
        size_t size = sizeof(tcg_target_ulong) * p->nlong;
143
        uintptr_t value;
144

145
        if (!l || l->nlong != p->nlong || memcmp(l->data, p->data, size)) {
146
            if (unlikely(a > s->code_gen_highwater)) {
147
                return -1;
148
            }
149
            memcpy(a, p->data, size);
150
            a += size;
151
            l = p;
152
        }
153

154
        value = (uintptr_t)tcg_splitwx_to_rx(a) - size;
155
        if (!patch_reloc(p->label, p->rtype, value, p->addend)) {
156
            return -2;
157
        }
158
    }
159

160
    s->code_ptr = a;
161
    return 0;
162
}
163

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.