]>
Commit | Line | Data |
---|---|---|
5ff7258c RH |
1 | /* |
2 | * Internal declarations for Tiny Code Generator for QEMU | |
3 | * | |
4 | * Copyright (c) 2008 Fabrice Bellard | |
5 | * | |
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | * of this software and associated documentation files (the "Software"), to deal | |
8 | * in the Software without restriction, including without limitation the rights | |
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | * copies of the Software, and to permit persons to whom the Software is | |
11 | * furnished to do so, subject to the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice shall be included in | |
14 | * all copies or substantial portions of the Software. | |
15 | * | |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 | * THE SOFTWARE. | |
23 | */ | |
24 | ||
25 | #ifndef TCG_INTERNAL_H | |
4f31b54b | 26 | #define TCG_INTERNAL_H |
5ff7258c | 27 | |
f9c4bb80 RH |
28 | #ifdef CONFIG_TCG_INTERPRETER |
29 | #include <ffi.h> | |
30 | #endif | |
31 | ||
5ff7258c RH |
32 | #define TCG_HIGHWATER 1024 |
33 | ||
18ff36ab RH |
34 | /* |
35 | * Describe the calling convention of a given argument type. | |
36 | */ | |
37 | typedef enum { | |
38 | TCG_CALL_RET_NORMAL, /* by registers */ | |
313bdea8 | 39 | TCG_CALL_RET_BY_REF, /* for i128, by reference */ |
c6556aa0 | 40 | TCG_CALL_RET_BY_VEC, /* for i128, by vector register */ |
18ff36ab RH |
41 | } TCGCallReturnKind; |
42 | ||
43 | typedef enum { | |
44 | TCG_CALL_ARG_NORMAL, /* by registers (continuing onto stack) */ | |
45 | TCG_CALL_ARG_EVEN, /* like normal, but skipping odd slots */ | |
46 | TCG_CALL_ARG_EXTEND, /* for i32, as a sign/zero-extended i64 */ | |
47 | TCG_CALL_ARG_EXTEND_U, /* ... as a zero-extended i64 */ | |
48 | TCG_CALL_ARG_EXTEND_S, /* ... as a sign-extended i64 */ | |
313bdea8 RH |
49 | TCG_CALL_ARG_BY_REF, /* for i128, by reference, first */ |
50 | TCG_CALL_ARG_BY_REF_N, /* ... by reference, subsequent */ | |
18ff36ab RH |
51 | } TCGCallArgumentKind; |
52 | ||
39004a71 RH |
53 | typedef struct TCGCallArgumentLoc { |
54 | TCGCallArgumentKind kind : 8; | |
55 | unsigned arg_slot : 8; | |
56 | unsigned ref_slot : 8; | |
57 | unsigned arg_idx : 4; | |
58 | unsigned tmp_subindex : 2; | |
59 | } TCGCallArgumentLoc; | |
60 | ||
61 | /* Avoid "unsigned < 0 is always false" Werror, when iarg_regs is empty. */ | |
62 | #define REG_P(L) \ | |
63 | ((int)(L)->arg_slot < (int)ARRAY_SIZE(tcg_target_call_iarg_regs)) | |
64 | ||
3e92aa34 RH |
65 | typedef struct TCGHelperInfo { |
66 | void *func; | |
67 | const char *name; | |
f9c4bb80 RH |
68 | #ifdef CONFIG_TCG_INTERPRETER |
69 | ffi_cif *cif; | |
70 | #endif | |
39004a71 RH |
71 | unsigned typemask : 32; |
72 | unsigned flags : 8; | |
73 | unsigned nr_in : 8; | |
74 | unsigned nr_out : 8; | |
75 | TCGCallReturnKind out_kind : 8; | |
76 | ||
77 | /* Maximum physical arguments are constrained by TCG_TYPE_I128. */ | |
78 | TCGCallArgumentLoc in[MAX_CALL_IARGS * (128 / TCG_TARGET_REG_BITS)]; | |
3e92aa34 RH |
79 | } TCGHelperInfo; |
80 | ||
42eb6dfc | 81 | extern TCGContext tcg_init_ctx; |
5ff7258c | 82 | extern TCGContext **tcg_ctxs; |
0e2d61cf RH |
83 | extern unsigned int tcg_cur_ctxs; |
84 | extern unsigned int tcg_max_ctxs; | |
5ff7258c | 85 | |
43b972b7 | 86 | void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus); |
5ff7258c RH |
87 | bool tcg_region_alloc(TCGContext *s); |
88 | void tcg_region_initial_alloc(TCGContext *s); | |
89 | void tcg_region_prologue_set(TCGContext *s); | |
90 | ||
fa52e660 RH |
91 | static inline void *tcg_call_func(TCGOp *op) |
92 | { | |
93 | return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op)]; | |
94 | } | |
95 | ||
3e92aa34 RH |
96 | static inline const TCGHelperInfo *tcg_call_info(TCGOp *op) |
97 | { | |
98 | return (void *)(uintptr_t)op->args[TCGOP_CALLO(op) + TCGOP_CALLI(op) + 1]; | |
99 | } | |
100 | ||
90163900 RH |
101 | static inline unsigned tcg_call_flags(TCGOp *op) |
102 | { | |
3e92aa34 | 103 | return tcg_call_info(op)->flags; |
90163900 RH |
104 | } |
105 | ||
d56fea79 RH |
106 | #if TCG_TARGET_REG_BITS == 32 |
107 | static inline TCGv_i32 TCGV_LOW(TCGv_i64 t) | |
108 | { | |
aef85402 | 109 | return temp_tcgv_i32(tcgv_i64_temp(t) + HOST_BIG_ENDIAN); |
d56fea79 RH |
110 | } |
111 | static inline TCGv_i32 TCGV_HIGH(TCGv_i64 t) | |
112 | { | |
aef85402 | 113 | return temp_tcgv_i32(tcgv_i64_temp(t) + !HOST_BIG_ENDIAN); |
d56fea79 RH |
114 | } |
115 | #else | |
116 | extern TCGv_i32 TCGV_LOW(TCGv_i64) QEMU_ERROR("32-bit code path is reachable"); | |
117 | extern TCGv_i32 TCGV_HIGH(TCGv_i64) QEMU_ERROR("32-bit code path is reachable"); | |
118 | #endif | |
119 | ||
4771e71c RH |
120 | static inline TCGv_i64 TCGV128_LOW(TCGv_i128 t) |
121 | { | |
122 | /* For 32-bit, offset by 2, which may then have TCGV_{LOW,HIGH} applied. */ | |
123 | int o = HOST_BIG_ENDIAN ? 64 / TCG_TARGET_REG_BITS : 0; | |
124 | return temp_tcgv_i64(tcgv_i128_temp(t) + o); | |
125 | } | |
126 | ||
127 | static inline TCGv_i64 TCGV128_HIGH(TCGv_i128 t) | |
128 | { | |
129 | int o = HOST_BIG_ENDIAN ? 0 : 64 / TCG_TARGET_REG_BITS; | |
130 | return temp_tcgv_i64(tcgv_i128_temp(t) + o); | |
131 | } | |
132 | ||
5ff7258c | 133 | #endif /* TCG_INTERNAL_H */ |