@@ -300,7 +300,7 @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
300
300
301
301
for (j = 0 ; j < TARGET_INSN_START_WORDS ; ++ j ) {
302
302
if (i == 0 ) {
303
- prev = (j == 0 ? tb_pc (tb ) : 0 );
303
+ prev = (! TARGET_TB_PCREL && j == 0 ? tb_pc (tb ) : 0 );
304
304
} else {
305
305
prev = tcg_ctx -> gen_insn_data [i - 1 ][j ];
306
306
}
@@ -328,7 +328,7 @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
328
328
static int cpu_restore_state_from_tb (CPUState * cpu , TranslationBlock * tb ,
329
329
uintptr_t searched_pc , bool reset_icount )
330
330
{
331
- target_ulong data [TARGET_INSN_START_WORDS ] = { tb_pc ( tb ) } ;
331
+ target_ulong data [TARGET_INSN_START_WORDS ];
332
332
uintptr_t host_pc = (uintptr_t )tb -> tc .ptr ;
333
333
CPUArchState * env = cpu -> env_ptr ;
334
334
const uint8_t * p = tb -> tc .ptr + tb -> tc .size ;
@@ -344,6 +344,11 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
344
344
return -1 ;
345
345
}
346
346
347
+ memset (data , 0 , sizeof (data ));
348
+ if (!TARGET_TB_PCREL ) {
349
+ data [0 ] = tb_pc (tb );
350
+ }
351
+
347
352
/* Reconstruct the stored insn data while looking for the point at
348
353
which the end of the insn exceeds the searched_pc. */
349
354
for (i = 0 ; i < num_insns ; ++ i ) {
@@ -886,13 +891,13 @@ static bool tb_cmp(const void *ap, const void *bp)
886
891
const TranslationBlock * a = ap ;
887
892
const TranslationBlock * b = bp ;
888
893
889
- return tb_pc (a ) == tb_pc (b ) &&
890
- a -> cs_base == b -> cs_base &&
891
- a -> flags == b -> flags &&
892
- (tb_cflags (a ) & ~CF_INVALID ) == (tb_cflags (b ) & ~CF_INVALID ) &&
893
- a -> trace_vcpu_dstate == b -> trace_vcpu_dstate &&
894
- a -> page_addr [0 ] == b -> page_addr [0 ] &&
895
- a -> page_addr [1 ] == b -> page_addr [1 ];
894
+ return (( TARGET_TB_PCREL || tb_pc (a ) == tb_pc (b ) ) &&
895
+ a -> cs_base == b -> cs_base &&
896
+ a -> flags == b -> flags &&
897
+ (tb_cflags (a ) & ~CF_INVALID ) == (tb_cflags (b ) & ~CF_INVALID ) &&
898
+ a -> trace_vcpu_dstate == b -> trace_vcpu_dstate &&
899
+ a -> page_addr [0 ] == b -> page_addr [0 ] &&
900
+ a -> page_addr [1 ] == b -> page_addr [1 ]) ;
896
901
}
897
902
898
903
void tb_htable_init (void )
@@ -1149,14 +1154,35 @@ static inline void tb_jmp_unlink(TranslationBlock *dest)
1149
1154
qemu_spin_unlock (& dest -> jmp_lock );
1150
1155
}
1151
1156
1157
+ static void tb_jmp_cache_inval_tb (TranslationBlock * tb )
1158
+ {
1159
+ CPUState * cpu ;
1160
+
1161
+ if (TARGET_TB_PCREL ) {
1162
+ /* A TB may be at any virtual address */
1163
+ CPU_FOREACH (cpu ) {
1164
+ tcg_flush_jmp_cache (cpu );
1165
+ }
1166
+ } else {
1167
+ uint32_t h = tb_jmp_cache_hash_func (tb_pc (tb ));
1168
+
1169
+ CPU_FOREACH (cpu ) {
1170
+ CPUJumpCache * jc = cpu -> tb_jmp_cache ;
1171
+
1172
+ if (qatomic_read (& jc -> array [h ].tb ) == tb ) {
1173
+ qatomic_set (& jc -> array [h ].tb , NULL );
1174
+ }
1175
+ }
1176
+ }
1177
+ }
1178
+
1152
1179
/*
1153
1180
* In user-mode, call with mmap_lock held.
1154
1181
* In !user-mode, if @rm_from_page_list is set, call with the TB's pages'
1155
1182
* locks held.
1156
1183
*/
1157
1184
static void do_tb_phys_invalidate (TranslationBlock * tb , bool rm_from_page_list )
1158
1185
{
1159
- CPUState * cpu ;
1160
1186
PageDesc * p ;
1161
1187
uint32_t h ;
1162
1188
tb_page_addr_t phys_pc ;
@@ -1171,8 +1197,8 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
1171
1197
1172
1198
/* remove the TB from the hash list */
1173
1199
phys_pc = tb -> page_addr [0 ];
1174
- h = tb_hash_func (phys_pc , tb_pc (tb ), tb -> flags , orig_cflags ,
1175
- tb -> trace_vcpu_dstate );
1200
+ h = tb_hash_func (phys_pc , ( TARGET_TB_PCREL ? 0 : tb_pc (tb )) ,
1201
+ tb -> flags , orig_cflags , tb -> trace_vcpu_dstate );
1176
1202
if (!qht_remove (& tb_ctx .htable , tb , h )) {
1177
1203
return ;
1178
1204
}
@@ -1188,13 +1214,7 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
1188
1214
}
1189
1215
1190
1216
/* remove the TB from the hash list */
1191
- h = tb_jmp_cache_hash_func (tb -> pc );
1192
- CPU_FOREACH (cpu ) {
1193
- CPUJumpCache * jc = cpu -> tb_jmp_cache ;
1194
- if (qatomic_read (& jc -> array [h ].tb ) == tb ) {
1195
- qatomic_set (& jc -> array [h ].tb , NULL );
1196
- }
1197
- }
1217
+ tb_jmp_cache_inval_tb (tb );
1198
1218
1199
1219
/* suppress this TB from the two jump lists */
1200
1220
tb_remove_from_jmp_list (tb , 0 );
@@ -1303,8 +1323,8 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
1303
1323
}
1304
1324
1305
1325
/* add in the hash table */
1306
- h = tb_hash_func (phys_pc , tb_pc ( tb ), tb -> flags , tb -> cflags ,
1307
- tb -> trace_vcpu_dstate );
1326
+ h = tb_hash_func (phys_pc , ( TARGET_TB_PCREL ? 0 : tb_pc ( tb )) ,
1327
+ tb -> flags , tb -> cflags , tb -> trace_vcpu_dstate );
1308
1328
qht_insert (& tb_ctx .htable , tb , h , & existing_tb );
1309
1329
1310
1330
/* remove TB from the page(s) if we couldn't insert it */
@@ -1375,7 +1395,9 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
1375
1395
1376
1396
gen_code_buf = tcg_ctx -> code_gen_ptr ;
1377
1397
tb -> tc .ptr = tcg_splitwx_to_rx (gen_code_buf );
1398
+ #if !TARGET_TB_PCREL
1378
1399
tb -> pc = pc ;
1400
+ #endif
1379
1401
tb -> cs_base = cs_base ;
1380
1402
tb -> flags = flags ;
1381
1403
tb -> cflags = cflags ;
0 commit comments