1 /* ---------------------- xmix_vm.h : 2 * This file contains internal declarations used in the implementation 3 * of the mix_vm_t type. 4 * ------------------------------------------------------------------ 5 * Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 24 #ifndef XMIX_VM_H 25 #define XMIX_VM_H 26 27 #include <string.h> 28 29 #include "mix_symbol_table.h" 30 #include "mix_device.h" 31 #include "mix_src_file.h" 32 #include "mix_predicate_list.h" 33 #include "mix_vm.h" 34 35 /* The mix_vm_t type */ 36 enum { 37 IREG_NO_ = 6, 38 BD_NO_ = 21, 39 MEM_CELLS_NO_ = MIX_VM_CELL_NO, 40 MEM_CELLS_MAX_ = MIX_VM_CELL_NO - 1 41 }; 42 43 struct mix_vm_t 44 { 45 mix_word_t reg[IREG_NO_+3]; 46 mix_word_t cell[MEM_CELLS_NO_]; 47 gboolean overflow; 48 mix_cmpflag_t cmpflag; 49 mix_short_t loc_count; 50 mix_vm_status_t status; 51 mix_vm_error_t last_error; 52 mix_device_t * devices[BD_NO_]; 53 gint max_backtrace_amount; /* the limit of backtraces */ 54 mix_address_t start_addr; /* start address of loaded file */ 55 GTree *line_table; /* source line no -> address */ 56 GTree *address_table; /* adress -> source line no */ 57 gint8 bp[MEM_CELLS_NO_/8]; /* each bit signals a break point */ 58 mix_vm_clock_t *clock; /* the vm clock */ 59 mix_symbol_table_t *symbol_table; 60 mix_src_file_t *src_file; /* source of last loaded code file */ 61 mix_device_factory_t factory; /* the factory for new devices */ 62 mix_predicate_list_t *pred_list; /* predicates for conditional bps */ 63 GQueue *address_list; /* list of executed addresses */ 64 }; 65 66 /* Macros for accessing/modifying the above structure. 67 * Warning: the arguments of these macros must not have side-effects. 68 */ 69 #define IOK_(idx) ( (idx) > 0 && (idx) < IREG_NO_+1 ) 70 #define MEMOK_(addr) ( mix_short_is_positive(addr) && (addr) < MEM_CELLS_NO_ ) 71 #define REGOK_(r) ( (r) >= 0 && (r) < IREG_NO_ + 3 ) 72 73 enum { A_ = 0, X_, J_, I1_, I2_, I3_, I4_, I5_, I6_ }; 74 75 #define get_reg_(vm, r) ((vm)->reg[r]) 76 #define get_rA_(vm) get_reg_(vm, A_) 77 #define get_rX_(vm) get_reg_(vm, X_) 78 #define get_rJ_(vm) get_reg_(vm, J_) 79 #define get_rI_(vm,idx) get_reg_(vm, I1_ + (idx) - 1) 80 #define get_cell_(vm,addr) ( MEMOK_(addr) ? vm->cell[addr] : MIX_WORD_ZERO ) 81 #define get_cell_ptr_(vm,addr) ( MEMOK_(addr) ? (vm->cell) + addr : NULL ) 82 #define get_cmp_(vm) (vm->cmpflag) 83 #define get_over_(vm) (vm->overflow) 84 #define get_loc_(vm) (vm->loc_count) 85 #define get_clock_(vm) (vm->clock) 86 #define get_pred_list_(vm) (vm->pred_list) 87 #define get_address_list_(vm) (vm->address_list) 88 #define get_status_(vm) (vm->status) 89 #define get_last_error_(vm) (vm->last_error) 90 #define set_last_error_(vm,error) ((vm)->last_error = (error)) 91 92 #define set_reg_(vm,r,x) \ 93 do { \ 94 if ( REGOK_(r) ) vm->reg[r] = (x); \ 95 } while (FALSE) 96 97 #define set_rA_(vm,x) set_reg_(vm,A_,x) 98 #define set_rX_(vm,x) set_reg_(vm,X_,x) 99 #define set_rJ_(vm,x) set_reg_(vm,J_,(x)&MIX_SHORT_MAX) 100 #define set_rI_(vm,idx,x) set_reg_(vm,(idx) + I1_ - 1,x) 101 102 #define set_cell_(vm,addr,x) \ 103 do { \ 104 if ( MEMOK_(addr) ) (vm)->cell[addr] = (x); \ 105 } while (FALSE) 106 107 #define set_cmp_(vm,x) (vm)->cmpflag = (x) 108 #define set_over_(vm,x) (vm)->overflow = (x) 109 #define set_loc_(vm,x) (vm)->loc_count = (MEMOK_(x)? (x) : MIX_SHORT_ZERO) 110 111 #define set_status_(vm,s) ((vm)->status = (s)) 112 #define is_halted_(vm) ((vm)->status == MIX_VM_HALT) 113 #define halt_(vm,val) ((vm)->status = (val)? MIX_VM_HALT : MIX_VM_RUNNING) 114 115 #define inc_loc_(vm) \ 116 do { \ 117 if (++(vm->loc_count) == MEM_CELLS_NO_) \ 118 { vm->loc_count--; halt_(vm, TRUE); } \ 119 } while(FALSE) 120 121 #define set_start_(vm,val) ((vm)->start_addr = (val)) 122 #define reset_loc_(vm) set_loc_ (vm, vm->start_addr) 123 #define update_time_(vm,ins) mix_vm_clock_add_lapse (get_clock_(vm), ins) 124 125 /* Breakpoints handling */ 126 #define bp_clear_all_(vm) memset (vm->bp, 0, MEM_CELLS_NO_/8) 127 #define bp_set_(vm,addr) vm->bp[(addr)>>3] |= 1 << ((addr)&7) 128 #define bp_clear_(vm,addr) vm->bp[(addr)>>3] &= ~(1 << ((addr)&7)) 129 #define bp_is_set_(vm,addr) vm->bp[(addr)>>3] & (1 << ((addr)&7)) 130 131 /* Instruction handlers */ 132 typedef gboolean (*ins_handler_t_)(mix_vm_t *,const mix_ins_t *); 133 134 extern ins_handler_t_ ins_handlers_[MIX_BYTE_MAX + 1]; 135 136 137 #endif /* XMIX_VM_H */ 138 139