1 // sidcpuutil.h - Elements common to CPU models. -*- C++ -*-
3 // Copyright (C) 1999, 2000 Red Hat.
4 // This file is part of SID and is licensed under the GPL.
5 // See the file COPYING.SID for conditions for redistribution.
10 #include <sidattrutil.h>
11 #include <sidpinutil.h>
12 #include <sidbusutil.h>
13 #include <sidcomputil.h>
14 #include <sidmiscutil.h>
15 #include <sidwatchutil.h>
19 // kinds of endianness
28 std::ostream& operator << (std::ostream& o, const endian& e)
33 case endian_unknown: o << "unknown"; break;
34 case endian_big: o << "big"; break;
35 case endian_little: o << "little"; break;
42 std::istream& operator >> (std::istream& i, endian& e)
46 if (s == "unknown" || s == "0") { e = endian_unknown; }
47 else if (s == "big" || s == "1") { e = endian_big; }
48 else if (s == "little" || s == "2") { e = endian_little; }
49 else { i.setstate(std::ios::badbit); e = endian_unknown; }
53 // ------------------------------------------------------------------------
55 class cpu_exception {};
57 class cpu_memory_fault: public cpu_exception
61 sid::host_int_4 address;
62 sid::bus::status status;
63 const char* operation;
65 cpu_memory_fault (sid::host_int_4 p, sid::host_int_4 a, sid::bus::status s, const char* o):
66 pc(p), address(a), status(s), operation(o)
71 // ------------------------------------------------------------------------
74 // Values travelling through the trap-type pin.
75 // Additional "arguments" are sent through the trap-code pin.
77 cpu_trap_software = 1, // trap instruction hit
78 cpu_trap_breakpoint = 2, // breakpoint instruction hit
79 cpu_trap_syscall = 3, // system call instruction hit
80 cpu_trap_invalid_insn = 4, // invalid instruction hit
81 cpu_trap_memory_fault = 5, // memory fault encountered
82 cpu_trap_overflow = 6, // arithmetic overflow
83 cpu_trap_stepped = 7, // single-step completed
87 // Possible trap disposition codes
88 enum cpu_trap_disposition
90 cpu_trap_unhandled = 0, // dispatch to hardware fault handling
91 cpu_trap_handled = 1, // supervisor handled faulting instruction
92 cpu_trap_reissue = 2, // rerun faulting instruction
93 cpu_trap_skip = 3, // skip faulting instruction
97 // ------------------------------------------------------------------------
100 class basic_cpu: public virtual sid::component,
101 protected fixed_pin_map_component,
102 protected fixed_accessor_map_component,
103 protected fixed_attribute_map_component,
104 protected no_relation_component,
105 protected fixed_bus_map_component
108 // recursion protection
110 recursion_limited step_limit;
112 // triggerpoint support
114 friend class self_watcher<basic_cpu>;
115 self_watcher<basic_cpu> triggerpoint_manager;
116 // Virtual pin interfaces between self_watcher and fixed_pin_map_component
117 sid::component::status pin_factory (const std::string& name)
119 return this->triggerpoint_manager.create_virtual_pin (name);
121 void pin_junkyard (const std::string& name)
123 return this->triggerpoint_manager.destroy_virtual_pin (name);
125 // Helper functions for target view support
126 template <class PinType>
127 void add_watchable_pin (const std::string& name, PinType* pin)
129 this->add_pin (name, pin);
130 this->add_attribute (name, pin, "pin");
131 this->triggerpoint_manager.add_watchable_attribute (name);
132 this->categorize (name, "watchable");
135 template <class ValueType>
136 void add_watchable_register (const std::string& name, ValueType* value)
138 this->add_attribute (name, value, "register");
139 this->triggerpoint_manager.add_watchable_attribute (name);
140 this->categorize (name, "watchable");
143 template <class Class, typename Getter, typename Setter>
144 void add_watchable_register (const std::string& name,
149 this->add_attribute_virtual (name, receiver, getter, setter, "register");
150 this->triggerpoint_manager.add_watchable_attribute (name);
151 this->categorize (name, "watchable");
154 template <class Class, typename Getter, typename Setter, typename Parameter>
155 void add_watchable_register (const std::string& name,
161 this->add_attribute_virtual_parameterized (name, param, receiver,
162 getter, setter, "register");
163 this->triggerpoint_manager.add_watchable_attribute (name);
164 this->categorize (name, "watchable");
167 template <class ValueType>
168 void add_watchable_ro_register (const std::string& name, ValueType* value)
170 this->add_attribute_ro (name, value, "register");
171 this->triggerpoint_manager.add_watchable_attribute (name);
172 this->categorize (name, "watchable");
175 // step/yield control pins
177 callback_pin<basic_cpu> step_pin;
178 callback_pin<basic_cpu> yield_pin;
180 sid::host_int_4 step_insn_count;
181 sid::host_int_8 total_insn_count;
182 sid::host_int_4 current_step_insn_count;
183 output_pin step_cycles_pin;
185 bool trace_extract_p;
187 bool enable_step_trap_p;
189 void step_pin_handler (sid::host_int_4)
191 recursion_record limit (& this->step_limit);
192 if (! limit.ok()) return;
194 this->current_step_insn_count = 0;
195 this->yield_p = false;
197 // Enter insn loop. Poll continue_after_insn_p after each instruction
198 sid::host_int_8 prev_insn_count = this->total_insn_count;
200 sid::host_int_8 num_insns = this->total_insn_count - prev_insn_count;
203 const sid::host_int_4 min_num_cycles = 1;
204 const sid::host_int_4 max_num_cycles = 0x7FFFFFFF;
205 sid::host_int_4 num_cycles =
206 num_insns <= min_num_cycles ? min_num_cycles :
207 num_insns >= max_num_cycles ? max_num_cycles :
209 this->stepped (num_cycles);
213 this->yield_p = true;
214 // A subsequent continue_after_insns_p should return false.
216 void yield_pin_handler (sid::host_int_4)
222 virtual void step_insns () = 0;
223 void stepped (sid::host_int_4 n)
225 this->step_cycles_pin.drive (n);
227 bool stop_after_insns_p (sid::host_int_4 num)
229 this->current_step_insn_count += num;
231 (this->current_step_insn_count >= this->step_insn_count))
233 // Batch updates to total_insn_count to avoid long-long
234 // arithmetic overhead in the inner insn-stepping loops.
235 this->total_insn_count += this->current_step_insn_count;
236 this->current_step_insn_count = 0;
246 // Reset the processor model to power-up state.
248 callback_pin<basic_cpu> reset_pin;
249 virtual void reset () = 0;
250 void reset_pin_handler(sid::host_int_4 v) { this->reset (); this->stepped(1); }
252 // Flush internal abstract icache (if any)
254 callback_pin<basic_cpu> flush_icache_pin;
255 virtual void flush_icache () = 0;
256 void flush_icache_pin_handler(sid::host_int_4 v) { this->flush_icache(); }
258 // Set the initial PC after reset
260 callback_pin<basic_cpu> pc_set_pin;
261 virtual void set_pc(sid::host_int_4) = 0;
262 void pc_set_pin_handler(sid::host_int_4 v) { this->set_pc (v); }
264 // Set the initial endianness after reset
266 callback_pin<basic_cpu> endian_set_pin;
267 virtual void set_endian(sid::host_int_4) = 0;
268 void endian_set_pin_handler(sid::host_int_4 v) { this->set_endian (v); }
270 // Signal trap type code and argument
272 output_pin trap_type_pin;
273 output_pin trap_code_pin;
274 input_pin trap_disposition_pin;
276 cpu_trap_disposition signal_trap (cpu_trap_type p, sid::host_int_4 param = 0)
278 // Prepare disposition pin in case we get no signal back
279 this->trap_disposition_pin.driven (sid::host_int_4(cpu_trap_unhandled));
280 this->trap_code_pin.drive (param);
281 this->trap_type_pin.drive (sid::host_int_4(p));
282 return static_cast<cpu_trap_disposition>(trap_disposition_pin.sense ());
286 // state save/restore: Override these in derived classes, but
287 // include a call up to this base implementation.
289 virtual void stream_state(std::ostream& o) const
293 << " " << this->step_insn_count
294 << " " << this->enable_step_trap_p
295 << " " << this->total_insn_count
296 << " " << this->trace_extract_p
297 << " " << this->trace_result_p
299 << " " << this->step_cycles_pin
300 << " " << this->trap_type_pin
301 << " " << this->trap_code_pin;
304 virtual void destream_state(std::istream& i)
308 if (key != "basic-cpu")
310 i.setstate (std::ios::badbit);
313 i >> this->step_insn_count
314 >> this->enable_step_trap_p
315 >> this->total_insn_count
316 >> this->trace_extract_p
317 >> this->trace_result_p
319 >> this->step_cycles_pin
320 >> this->trap_type_pin
321 >> this->trap_code_pin;
326 friend std::ostream& operator << (std::ostream& o, const basic_cpu& c);
327 friend std::istream& operator >> (std::istream& i, basic_cpu& c);
328 std::string save_state() { return make_attribute(*this); }
329 sid::component::status restore_state(const std::string& s)
330 { return parse_attribute(s, *this); }
333 // ------------------------------------------------------------------------
334 // debugger access functions
336 passthrough_bus debugger_bus;
337 virtual std::string dbg_get_reg (sid::host_int_4 n) = 0;
338 virtual sid::component::status dbg_set_reg (sid::host_int_4 n, const std::string& s) = 0;
341 template <typename PC>
342 void create_gdb_register_attrs (sid::host_int_4 count,
343 const std::string& expedited_regno_list,
346 this->triggerpoint_manager.add_watchable_value ("gdb-register-pc", pc);
347 this->add_attribute_ro_value ("gdb-num-registers", count, "debugger");
348 this->add_attribute_ro_value ("gdb-exp-registers", expedited_regno_list, "debugger");
349 for (sid::host_int_4 i=0; i<count; i++)
351 std::string name = std::string ("gdb-register-") + make_numeric_attribute (i);
352 attribute_coder_base* coder =
353 new attribute_coder_virtual_parameterized<basic_cpu,sid::host_int_4>
354 (this, & basic_cpu::dbg_get_reg, & basic_cpu::dbg_set_reg, i);
355 this->add_attribute_coder (name, coder, "debugger");
360 // ------------------------------------------------------------------------
361 // memory access functions
368 template <typename BigOrLittleInt>
369 BigOrLittleInt read_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) const;
370 template <typename BigOrLittleInt>
371 BigOrLittleInt write_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) const;
372 template <typename BigOrLittleInt>
373 BigOrLittleInt read_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) const;
374 template <typename BigOrLittleInt>
375 BigOrLittleInt write_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) const;
377 // ------------------------------------------------------------------------
381 step_limit ("instruction stepping", 1),
382 triggerpoint_manager (this),
383 step_pin (this, & basic_cpu::step_pin_handler),
384 yield_pin (this, & basic_cpu::yield_pin_handler),
385 reset_pin (this, & basic_cpu::reset_pin_handler),
386 flush_icache_pin (this, & basic_cpu::flush_icache_pin_handler),
387 pc_set_pin (this, & basic_cpu::pc_set_pin_handler),
388 endian_set_pin (this, & basic_cpu::endian_set_pin_handler),
389 debugger_bus (& this->data_bus)
393 add_accessor ("data-memory", & this->data_bus);
395 add_accessor ("insn-memory", & this->insn_bus);
396 add_bus ("debugger-bus", & this->debugger_bus);
399 add_pin ("step!", & this->step_pin);
400 add_watchable_pin ("step-cycles", & this->step_cycles_pin);
401 add_pin ("flush-icache", & this->flush_icache_pin);
402 add_pin ("reset!", & this->reset_pin);
403 add_pin ("yield", & this->yield_pin);
404 add_pin ("start-pc-set!", & this->pc_set_pin);
405 add_pin ("endian-set!", & this->endian_set_pin);
406 add_watchable_pin ("trap", & this->trap_type_pin); // output side
407 add_watchable_pin ("trap-code", & this->trap_code_pin);
408 add_pin ("trap", & this->trap_disposition_pin); // input side
411 this->step_insn_count = 1;
412 add_attribute ("step-insn-count", & this->step_insn_count, "setting");
413 this->enable_step_trap_p = false;
414 add_attribute ("enable-step-trap?", & this->enable_step_trap_p, "setting");
415 this->total_insn_count = 0;
416 add_watchable_register ("insn-count", & this->total_insn_count);
417 add_attribute_virtual ("state-snapshot", this,
418 & basic_cpu::save_state,
419 & basic_cpu::restore_state);
420 add_attribute ("trace-extract?", & trace_extract_p, "setting");
421 add_attribute ("trace-result?", & trace_result_p, "setting");
428 inline std::ostream& operator << (std::ostream& o, const basic_cpu& c) {
432 inline std::istream& operator >> (std::istream& i, basic_cpu& c) {
433 c.destream_state (i);
437 template <typename BigOrLittleInt>
438 BigOrLittleInt basic_cpu::read_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) const
440 BigOrLittleInt value;
442 this->insn_bus ? this->insn_bus->read (address, value) : sid::bus::unmapped;
443 if (s == sid::bus::ok)
446 throw cpu_memory_fault (pc, address, s, "insn read");
449 template <typename BigOrLittleInt>
450 BigOrLittleInt basic_cpu::write_insn_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) const
453 this->insn_bus ? this->insn_bus->write (address, value) : sid::bus::unmapped;
454 if (s == sid::bus::ok)
457 throw cpu_memory_fault (pc, address, s, "insn write");
460 template <typename BigOrLittleInt>
461 BigOrLittleInt basic_cpu::read_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt) const
463 BigOrLittleInt value;
465 this->data_bus ? this->data_bus->read (address, value) : sid::bus::unmapped;
466 if (s == sid::bus::ok)
469 throw cpu_memory_fault (pc, address, s, "data read");
472 template <typename BigOrLittleInt>
473 BigOrLittleInt basic_cpu::write_data_memory (sid::host_int_4 pc, sid::host_int_4 address, BigOrLittleInt value) const
476 this->data_bus ? this->data_bus->write (address, value) : sid::bus::unmapped;
477 if (s == sid::bus::ok)
480 throw cpu_memory_fault (pc, address, s, "data write");
485 // ------------------------------------------------------------------------
486 // Derived classes for memory access functions of various endianness
488 class basic_big_endian_cpu: public basic_cpu
490 void set_endian(sid::host_int_4) {}
494 basic_big_endian_cpu ()
496 add_attribute_ro_value ("endian", endian_big, "register");
498 ~basic_big_endian_cpu () {}
500 sid::host_int_1 read_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const
502 return this->read_insn_memory (pc, address, sid::big_int_1());
505 sid::host_int_2 read_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const
507 return this->read_insn_memory (pc, address, sid::big_int_2());
510 sid::host_int_4 read_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const
512 return this->read_insn_memory (pc, address, sid::big_int_4());
515 sid::host_int_8 read_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const
517 return this->read_insn_memory (pc, address, sid::big_int_8());
520 void write_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const
522 this->write_insn_memory (pc, address, sid::big_int_1(value));
525 void write_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const
527 this->write_insn_memory (pc, address, sid::big_int_2(value));
530 void write_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const
532 this->write_insn_memory (pc, address, sid::big_int_4(value));
535 void write_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const
537 this->write_insn_memory (pc, address, sid::big_int_8(value));
540 sid::host_int_1 read_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const
542 return this->read_data_memory (pc, address, sid::big_int_1());
545 sid::host_int_2 read_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const
547 return this->read_data_memory (pc, address, sid::big_int_2());
550 sid::host_int_4 read_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const
552 return this->read_data_memory (pc, address, sid::big_int_4());
555 sid::host_int_8 read_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const
557 return this->read_data_memory (pc, address, sid::big_int_8());
560 void write_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const
562 this->write_data_memory (pc, address, sid::big_int_1(value));
565 void write_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const
567 this->write_data_memory (pc, address, sid::big_int_2(value));
570 void write_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const
572 this->write_data_memory (pc, address, sid::big_int_4(value));
575 void write_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const
577 this->write_data_memory (pc, address, sid::big_int_8(value));
582 // ----------------------------------------------------------------------------
584 class basic_little_endian_cpu: public basic_cpu
586 void set_endian(sid::host_int_4) {}
589 basic_little_endian_cpu ()
591 add_attribute_ro_value ("endian", endian_little, "register");
593 ~basic_little_endian_cpu () {}
595 sid::host_int_1 read_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const
597 return this->read_insn_memory (pc, address, sid::little_int_1());
600 sid::host_int_2 read_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const
602 return this->read_insn_memory (pc, address, sid::little_int_2());
605 sid::host_int_4 read_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const
607 return this->read_insn_memory (pc, address, sid::little_int_4());
610 sid::host_int_8 read_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const
612 return this->read_insn_memory (pc, address, sid::little_int_8());
615 void write_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const
617 this->write_insn_memory (pc, address, sid::little_int_1(value));
620 void write_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const
622 this->write_insn_memory (pc, address, sid::little_int_2(value));
625 void write_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const
627 this->write_insn_memory (pc, address, sid::little_int_4(value));
630 void write_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const
632 this->write_insn_memory (pc, address, sid::little_int_8(value));
635 sid::host_int_1 read_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const
637 return this->read_data_memory (pc, address, sid::little_int_1());
640 sid::host_int_2 read_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const
642 return this->read_data_memory (pc, address, sid::little_int_2());
645 sid::host_int_4 read_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const
647 return this->read_data_memory (pc, address, sid::little_int_4());
650 sid::host_int_8 read_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const
652 return this->read_data_memory (pc, address, sid::little_int_8());
655 void write_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const
657 this->write_data_memory (pc, address, sid::little_int_1(value));
660 void write_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const
662 this->write_data_memory (pc, address, sid::little_int_2(value));
665 void write_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const
667 this->write_data_memory (pc, address, sid::little_int_4(value));
670 void write_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const
672 this->write_data_memory (pc, address, sid::little_int_8(value));
677 // ----------------------------------------------------------------------------
680 class basic_bi_endian_cpu: public basic_cpu
682 endian _current_endianness;
684 endian current_endianness() const { return this->_current_endianness; }
687 basic_bi_endian_cpu ()
689 this->_current_endianness = endian_big;
690 add_attribute ("endian", & this->_current_endianness, "register");
692 ~basic_bi_endian_cpu () {}
694 void set_endian(sid::host_int_4 v)
699 this->_current_endianness = endian_big;
702 this->_current_endianness = endian_little;
705 // XXX: warning message?
710 void stream_state(std::ostream& o) const
712 basic_cpu::stream_state(o);
713 o << " " << this->_current_endianness;
716 void destream_state(std::istream& i)
718 basic_cpu::destream_state(i);
719 i >> this->_current_endianness;
723 sid::host_int_1 read_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const
725 if (this->_current_endianness == endian_little)
726 return this->read_insn_memory (pc, address, sid::little_int_1());
727 else // endian_big or endian_unknown
728 return this->read_insn_memory (pc, address, sid::big_int_1());
731 sid::host_int_2 read_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const
733 if (this->_current_endianness == endian_little)
734 return this->read_insn_memory (pc, address, sid::little_int_2());
735 else // endian_big or endian_unknown
736 return this->read_insn_memory (pc, address, sid::big_int_2());
739 sid::host_int_4 read_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const
741 if (this->_current_endianness == endian_little)
742 return this->read_insn_memory (pc, address, sid::little_int_4());
743 else // endian_big or endian_unknown
744 return this->read_insn_memory (pc, address, sid::big_int_4());
747 sid::host_int_8 read_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const
749 if (this->_current_endianness == endian_little)
750 return this->read_insn_memory (pc, address, sid::little_int_8());
751 else // endian_big or endian_unknown
752 return this->read_insn_memory (pc, address, sid::big_int_8());
755 void write_insn_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const
757 if (this->_current_endianness == endian_little)
758 this->write_insn_memory (pc, address, sid::little_int_1(value));
759 else // endian_big or endian_unknown
760 this->write_insn_memory (pc, address, sid::big_int_1(value));
763 void write_insn_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const
765 if (this->_current_endianness == endian_little)
766 this->write_insn_memory (pc, address, sid::little_int_2(value));
767 else // endian_big or endian_unknown
768 this->write_insn_memory (pc, address, sid::big_int_2(value));
771 void write_insn_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const
773 if (this->_current_endianness == endian_little)
774 this->write_insn_memory (pc, address, sid::little_int_4(value));
775 else // endian_big or endian_unknown
776 this->write_insn_memory (pc, address, sid::big_int_4(value));
779 void write_insn_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const
781 if (this->_current_endianness == endian_little)
782 this->write_insn_memory (pc, address, sid::little_int_8(value));
783 else // endian_big or endian_unknown
784 this->write_insn_memory (pc, address, sid::big_int_8(value));
787 sid::host_int_1 read_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address) const
789 if (this->_current_endianness == endian_little)
790 return this->read_data_memory (pc, address, sid::little_int_1());
791 else // endian_big or endian_unknown
792 return this->read_data_memory (pc, address, sid::big_int_1());
795 sid::host_int_2 read_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address) const
797 if (this->_current_endianness == endian_little)
798 return this->read_data_memory (pc, address, sid::little_int_2());
799 else // endian_big or endian_unknown
800 return this->read_data_memory (pc, address, sid::big_int_2());
803 sid::host_int_4 read_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address) const
805 if (this->_current_endianness == endian_little)
806 return this->read_data_memory (pc, address, sid::little_int_4());
807 else // endian_big or endian_unknown
808 return this->read_data_memory (pc, address, sid::big_int_4());
811 sid::host_int_8 read_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address) const
813 if (this->_current_endianness == endian_little)
814 return this->read_data_memory (pc, address, sid::little_int_8());
815 else // endian_big or endian_unknown
816 return this->read_data_memory (pc, address, sid::big_int_8());
819 void write_data_memory_1 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_1 value) const
821 if (this->_current_endianness == endian_little)
822 this->write_data_memory (pc, address, sid::little_int_1(value));
823 else // endian_big or endian_unknown
824 this->write_data_memory (pc, address, sid::big_int_1(value));
827 void write_data_memory_2 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_2 value) const
829 if (this->_current_endianness == endian_little)
830 this->write_data_memory (pc, address, sid::little_int_2(value));
831 else // endian_big or endian_unknown
832 this->write_data_memory (pc, address, sid::big_int_2(value));
835 void write_data_memory_4 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_4 value) const
837 if (this->_current_endianness == endian_little)
838 this->write_data_memory (pc, address, sid::little_int_4(value));
839 else // endian_big or endian_unknown
840 this->write_data_memory (pc, address, sid::big_int_4(value));
843 void write_data_memory_8 (sid::host_int_4 pc, sid::host_int_4 address, sid::host_int_8 value) const
845 if (this->_current_endianness == endian_little)
846 this->write_data_memory (pc, address, sid::little_int_8(value));
847 else // endian_big or endian_unknown
848 this->write_data_memory (pc, address, sid::big_int_8(value));
853 } // end namespace sidutil
856 #endif // SIDCPUUTIL_H