1 // arm7f.h - Main header for the ARM7 CPU family. -*- C++ -*-
3 // Copyright (C) 1999, 2000 Red Hat.
4 // Portions Copyright (C) 2004 Sirius Satellite Radio Inc.
5 // This file is part of SID and is licensed under the GPL.
6 // See the file COPYING.SID for conditions for redistribution.
8 // A "cpu family" is a CGEN notion to put related variants under one roof.
9 // The "f" suffix in "arm7f" is for "family".
16 // #include "arm-defs.h"
17 #include "arm-decode.h"
18 #include "thumb-decode.h"
27 // Put machine generated elements in base class as we want to override
28 // some of its methods.
31 // Include cgen generated elements.
35 // These are called from within inline functions in arm-cpu.h
36 virtual void arm_tbit_set (BI newval) = 0;
37 virtual void arm_mbits_set (UINT newval) = 0;
39 inline void cgen_rtx_error (const char* msg) const
41 cerr << "arm7f-cpu rtx error: " << msg << endl;
42 // throw cpu_exception ();
60 class arm7f_cpu: public arm7f_cpu_cgen, public cgen_bi_endian_cpu
64 ~arm7f_cpu () throw() {}
66 // Called by the semantic code to perform a branch.
67 // The result is the new address.
69 branch (PCADDR new_val, PCADDR& npc, sem_status& status)
74 // Called by the semantic code at the end of a non-cti insn.
76 done_insn (PCADDR npc, sem_status& status)
81 // Called by the semantic code at the end of a cti insn.
83 done_cti_insn (PCADDR npc, sem_status& status)
88 // Called by the semantic code to perform the swi insn.
89 SI arm_swi (PCADDR pc, UINT trap);
90 SI thumb_swi (PCADDR pc, UINT trap);
92 void invalid_insn (PCADDR pc);
97 // pbb engine [also includes scache engine]
98 typedef pbb_engine<arm7f_cpu, arm_scache> arm_engine_t;
99 typedef pbb_engine<arm7f_cpu, thumb_scache> thumb_engine_t;
100 arm_engine_t arm_engine;
101 thumb_engine_t thumb_engine;
103 // ??? no need for one copy per cpu of some of this
104 // Install a pbb or scache engine.
105 void set_pbb_engine ();
106 void set_scache_engine ();
107 // Update the engine according to current_engine_type.
108 void update_engine ();
109 // Extra support is needed to handle the engine-type attribute.
110 component::status set_engine_type (const string& s);
112 void arm_tbit_set (BI newval);
113 void arm_mbits_set (UINT newval);
115 void step_insns (); // dispatches to one of following "workers"
118 void step_arm_pbb ();
119 void step_thumb_pbb ();
121 // PBB engine support.
123 arm_scache* arm_pbb_begin (PCADDR pc);
124 void thumb_pbb_run ();
125 thumb_scache* thumb_pbb_begin (PCADDR pc);
128 set_pc (host_int_4 v)
130 this->h_pc_set ((PCADDR) v);
136 return this->h_pc_get ();
139 // debug support routines
140 string dbg_get_reg (host_int_4 n);
141 component::status dbg_set_reg (host_int_4 n, const string& s);
143 // processor mode (h-mbits inverted)
145 arm::ARM_MODE mode ();
147 // Exceptions, interrupts, and traps support
150 void queue_eit (eit new_eit);
151 int eit_priority (eit e);
152 void process_eit (eit new_eit);
154 void memory_trap (const cpu_memory_fault&);
156 // current state of h-tbit
157 binary_output_pin tbit_pin;
159 // exception generating and support pins
161 // Specifies asynchronous/synchronous nature of interrupts.
162 // ??? Of little utility at the moment.
163 binary_input_pin isync_pin;
165 // FIQ/IRQ are generated by driving these pins (low).
166 // It is synchronous if ISYNC is high, asynchronous if ISYNC is low.
167 // If asynchronous, a cycle delay for synchronization is incurred.
171 // cpu is reset by driving this pin low
173 callback_pin<arm7f_cpu> nreset_pin;
174 void do_nreset_pin (host_int_4 value);
177 void flush_icache ();
179 // Attribute helper functions.
181 string get_h_cpsr_for_attr () { return make_attribute (h_cpsr_get ()); }
182 string get_h_cpsr2_for_attr ();
183 component::status set_h_cpsr2_for_attr (const string& s) { return component::bad_value; }
184 component::status set_h_cpsr_for_attr (const string& s)
187 component::status stat = parse_attribute (s, value);
190 host_int_4 last_cpsr = h_cpsr_get ();
192 // this may fail via an exception thrown by cgen_rtx_error()
195 if (stat == component::ok)
198 catch (cpu_exception& t)
200 try { h_cpsr_set (last_cpsr); } catch (...) { }
201 stat = component::bad_value;
207 // overload state save & restore
208 void stream_state (ostream& o) const;
209 void destream_state (istream& i);
211 // Override GETMEMSI, which has odd semantics for misaligned accesses.
214 SI GETMEMSI (PCADDR pc, ADDR addr)
217 unsigned short offset = addr % 4;
222 return cgen_bi_endian_cpu::GETMEMSI (pc, addr);
224 word = cgen_bi_endian_cpu::GETMEMSI (pc, addr-1);
225 return (word >> 8) | ((word & 0xFF) << 24);
227 word = cgen_bi_endian_cpu::GETMEMSI (pc, addr-2);
228 return ((word & 0xFFFFU) << 16) | ((word & 0xFFFF0000U) >> 16);
230 word = cgen_bi_endian_cpu::GETMEMSI (pc, addr-3);
231 return (word << 8) | ((word & 0xFF000000) >> 24);
236 SI compute_operand2_immshift (SI rm, int type, int shift);
237 SI compute_operand2_regshift (SI rm, int type, SI shift);
238 BI compute_carry_out_immshift (SI rm, int type, int shift, BI cbit);
239 BI compute_carry_out_regshift (SI rm, int type, SI shift, BI cbit);
241 // FIXME: To be moved to rtl.
243 eval_cond (UINT cond, PCADDR pc)
247 return this->h_zbit_get ();
249 return !(this->h_zbit_get ());
251 return this->h_cbit_get ();
253 return !(this->h_cbit_get ());
255 return this->h_nbit_get ();
257 return !(this->h_nbit_get ());
259 return this->h_vbit_get ();
261 return !(this->h_vbit_get ());
263 return this->h_cbit_get () && !(this->h_zbit_get ());
265 return !(this->h_cbit_get ()) || this->h_zbit_get ();
267 return this->h_nbit_get () == this->h_vbit_get ();
269 return this->h_nbit_get () != this->h_vbit_get ();
271 return !(this->h_zbit_get ()) &&
272 (this->h_nbit_get () == this->h_vbit_get ());
274 return this->h_zbit_get() ||
275 (this->h_nbit_get () != this->h_vbit_get ());
279 this->invalid_insn (pc);
280 return 0; // XXX: notreached?
285 // RTL attribute accessors.
286 // ??? Need to allow application specific rtl generation. Later.
288 #define GET_ATTR_R15_OFFSET() (abuf->idesc->attrs.get_r15_offset_attr ())