Home | History | Annotate | Line # | Download | only in ppc
vm_n.h revision 1.1.1.1.2.1
      1 /*  This file is part of the program psim.
      2 
      3     Copyright (C) 1994-1997, Andrew Cagney <cagney (at) highland.com.au>
      4 
      5     This program is free software; you can redistribute it and/or modify
      6     it under the terms of the GNU General Public License as published by
      7     the Free Software Foundation; either version 3 of the License, or
      8     (at your option) any later version.
      9 
     10     This program is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13     GNU General Public License for more details.
     14 
     15     You should have received a copy of the GNU General Public License
     16     along with this program; if not, see <http://www.gnu.org/licenses/>.
     17 
     18     */
     19 
     20 
     21 #ifndef N
     22 #error "N must be #defined"
     23 #endif
     24 
     25 /* NOTE: See end of file for #undef */
     26 #define unsigned_N XCONCAT2(unsigned_,N)
     27 #define T2H_N XCONCAT2(T2H_,N)
     28 #define H2T_N XCONCAT2(H2T_,N)
     29 #define vm_data_map_read_N XCONCAT2(vm_data_map_read_,N)
     30 #define vm_data_map_write_N XCONCAT2(vm_data_map_write_,N)
     31 
     32 
     33 INLINE_VM\
     34 (unsigned_N)
     35 vm_data_map_read_N(vm_data_map *map,
     36 		   unsigned_word ea,
     37 		   cpu *processor,
     38 		   unsigned_word cia)
     39 {
     40   if ((ea & (sizeof(unsigned_N)-1)) == 0) {
     41     unsigned ra = vm_real_data_addr(map, ea, 1/*is-read*/, processor, cia);
     42     unsigned_N val;
     43     if (WITH_XOR_ENDIAN)
     44       ra ^= map->translation.xor[sizeof(unsigned_N) - 1];
     45     val = XCONCAT2(core_map_read_,N)(map->read, ra, processor, cia);
     46     if (WITH_MON & MONITOR_LOAD_STORE_UNIT)
     47       mon_read(ea, ra, sizeof(unsigned_N), processor, cia);
     48     TRACE(trace_load_store, ("load cia=0x%lx ea=0x%lx N=%ld val=0x%lx\n",
     49 			     (long)cia, (long)ea, (long)sizeof(unsigned_N), (long)val));
     50     return val;
     51   }
     52   else {
     53     switch (CURRENT_ALIGNMENT) {
     54     case STRICT_ALIGNMENT:
     55       alignment_interrupt(processor, cia, ea);
     56       return 0;
     57     case NONSTRICT_ALIGNMENT:
     58       {
     59 	unsigned_N val;
     60 	if (vm_data_map_read_buffer(map, &val, ea, sizeof(unsigned_N), processor, cia)
     61 	    != sizeof(unsigned_N)) {
     62 	  cpu_error(processor, cia, "misaligned %d byte read to 0x%lx failed",
     63 		    sizeof(unsigned_N), (unsigned long)ea);
     64 	}
     65 	val = T2H_N(val);
     66 	if (WITH_MON & MONITOR_LOAD_STORE_UNIT) {
     67 	  /* YUCK */
     68 	  unsigned ra = vm_real_data_addr(map, ea, 1, processor, cia);
     69 	  mon_read(ea, ra, sizeof(unsigned_N), processor, cia);
     70 	}
     71 	TRACE(trace_load_store, ("load cia=0x%lx ea=0x%lx N=%ld data=0x%lx\n",
     72 				 (long)cia, (long)ea, (long)sizeof(unsigned_N), (long)val));
     73 	return val;
     74       }
     75     default:
     76       error("internal error - vm_data_map_read_N - bad switch");
     77       return 0;
     78     }
     79   }
     80 }
     81 
     82 INLINE_VM\
     83 (void)
     84 vm_data_map_write_N(vm_data_map *map,
     85 		    unsigned_word ea,
     86 		    unsigned_N val,
     87 		    cpu *processor,
     88 		    unsigned_word cia)
     89 {
     90   if ((ea & (sizeof(unsigned_N)-1)) == 0) {
     91     unsigned ra = vm_real_data_addr(map, ea, 0/*is-read?*/, processor, cia);
     92     if (WITH_XOR_ENDIAN)
     93       ra ^= map->translation.xor[sizeof(unsigned_N) - 1];
     94     XCONCAT2(core_map_write_,N)(map->write, ra, val, processor, cia);
     95     if (WITH_MON & MONITOR_LOAD_STORE_UNIT)
     96       mon_write(ea, ra, sizeof(unsigned_N), processor, cia);
     97     TRACE(trace_load_store, ("store cia=0x%lx ea=0x%lx N=%ld val=0x%lx\n",
     98 			     (long)cia, (long)ea, (long)sizeof(unsigned_N), (long)val));
     99   }
    100   else {
    101     switch (CURRENT_ALIGNMENT) {
    102     case STRICT_ALIGNMENT:
    103       alignment_interrupt(processor, cia, ea);
    104       break;
    105     case NONSTRICT_ALIGNMENT:
    106       {
    107 	unsigned_N data = H2T_N(val);
    108 	if (vm_data_map_write_buffer(map, &data, ea, sizeof(unsigned_N), 0, processor, cia)
    109 	    != sizeof(unsigned_N)) {
    110 	  cpu_error(processor, cia, "misaligned %d byte write to 0x%lx failed",
    111 		    sizeof(unsigned_N), (unsigned long)ea);
    112 	}
    113 	if (WITH_MON & MONITOR_LOAD_STORE_UNIT) {
    114 	  /* YUCK */
    115 	  unsigned ra = vm_real_data_addr(map, ea, 1, processor, cia);
    116 	  mon_write(ea, ra, sizeof(unsigned_N), processor, cia);
    117 	}
    118 	TRACE(trace_load_store, ("store cia=0x%lx ea=0x%lx N=%ld val=0x%lx\n",
    119 				 (long)cia, (long)ea, (long)sizeof(unsigned_N), (long)val));
    120       }
    121       break;
    122     default:
    123       error("internal error - vm_data_map_write_N - bad switch");
    124     }
    125   }
    126 }
    127 
    128 /* NOTE: see start of file for #define */
    129 #undef unsigned_N
    130 #undef T2H_N
    131 #undef H2T_N
    132 #undef vm_data_map_read_N
    133 #undef vm_data_map_write_N
    134