1 /* 2 * TCG Backend Data: load-store optimization only. 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 #ifdef CONFIG_SOFTMMU 24 #define TCG_MAX_QEMU_LDST 640 25 26 typedef struct TCGLabelQemuLdst { 27 int is_ld:1; /* qemu_ld: 1, qemu_st: 0 */ 28 TCGMemOp opc:4; 29 TCGReg addrlo_reg; /* reg index for low word of guest virtual addr */ 30 TCGReg addrhi_reg; /* reg index for high word of guest virtual addr */ 31 TCGReg datalo_reg; /* reg index for low word to be loaded or stored */ 32 TCGReg datahi_reg; /* reg index for high word to be loaded or stored */ 33 int mem_index; /* soft MMU memory index */ 34 uint8_t *raddr; /* gen code addr of the next IR of qemu_ld/st IR */ 35 uint8_t *label_ptr[2]; /* label pointers to be updated */ 36 } TCGLabelQemuLdst; 37 38 typedef struct TCGBackendData { 39 int nb_ldst_labels; 40 TCGLabelQemuLdst ldst_labels[TCG_MAX_QEMU_LDST]; 41 } TCGBackendData; 42 43 44 /* 45 * Initialize TB backend data at the beginning of the TB. 46 */ 47 48 static inline void tcg_out_tb_init(TCGContext *s) 49 { 50 s->be->nb_ldst_labels = 0; 51 } 52 53 /* 54 * Generate TB finalization at the end of block 55 */ 56 57 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l); 58 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l); 59 60 static void tcg_out_tb_finalize(TCGContext *s) 61 { 62 TCGLabelQemuLdst *lb = s->be->ldst_labels; 63 int i, n = s->be->nb_ldst_labels; 64 65 /* qemu_ld/st slow paths */ 66 for (i = 0; i < n; i++) { 67 if (lb[i].is_ld) { 68 tcg_out_qemu_ld_slow_path(s, lb + i); 69 } else { 70 tcg_out_qemu_st_slow_path(s, lb + i); 71 } 72 } 73 } 74 75 /* 76 * Allocate a new TCGLabelQemuLdst entry. 77 */ 78 79 static inline TCGLabelQemuLdst *new_ldst_label(TCGContext *s) 80 { 81 TCGBackendData *be = s->be; 82 int n = be->nb_ldst_labels; 83 84 assert(n < TCG_MAX_QEMU_LDST); 85 be->nb_ldst_labels = n + 1; 86 return &be->ldst_labels[n]; 87 } 88 #else 89 #include "tcg-be-null.h" 90 #endif /* CONFIG_SOFTMMU */ 91