1 // arm7f.h - Main header for the ARM7 CPU family. -*- 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.
7 // A "cpu family" is a CGEN notion to put related variants under one roof.
8 // The "f" suffix in "arm7f" is for "family".
16 #include "arm-decode.h"
17 #include "thumb-decode.h"
26 // Put machine generated elements in base class as we want to override
27 // some of its methods.
30 // Include cgen generated elements.
34 // These are called from within inline functions in arm-cpu.h
35 virtual void arm_tbit_set (BI newval) = 0;
36 virtual void arm_mbits_set (UINT newval) = 0;
38 inline void cgen_rtx_error (const char* msg) const
40 cerr << "arm7f-cpu rtx error: " << msg << endl;
41 // throw cpu_exception ();
59 class arm7f_cpu: public arm7f_cpu_cgen, public cgen_bi_endian_cpu
65 // Called by the semantic code to perform a branch.
66 // The result is the new address.
68 branch (PCADDR new_val, PCADDR& npc, sem_status& status)
73 // Called by the semantic code at the end of a non-cti insn.
75 done_insn (PCADDR npc, sem_status& status)
80 // Called by the semantic code at the end of a cti insn.
82 done_cti_insn (PCADDR npc, sem_status& status)
87 // Called by the semantic code to perform the swi insn.
88 SI arm_swi (PCADDR pc, UINT trap);
89 SI thumb_swi (PCADDR pc, UINT trap);
91 void invalid_insn (PCADDR pc);
96 // pbb engine [also includes scache engine]
97 typedef pbb_engine<arm7f_cpu, arm_scache> arm_engine_t;
98 typedef pbb_engine<arm7f_cpu, thumb_scache> thumb_engine_t;
99 arm_engine_t arm_engine;
100 thumb_engine_t thumb_engine;
102 // ??? no need for one copy per cpu of some of this
103 // Install a pbb or scache engine.
104 void set_pbb_engine ();
105 void set_scache_engine ();
106 // Update the engine according to current_engine_type.
107 void update_engine ();
108 // Extra support is needed to handle the engine-type attribute.
109 component::status set_engine_type (const string& s);
111 void arm_tbit_set (BI newval);
112 void arm_mbits_set (UINT newval);
114 void step_insns (); // dispatches to one of following "workers"
117 void step_arm_pbb ();
118 void step_thumb_pbb ();
120 // PBB engine support.
122 arm_scache* arm_pbb_begin (PCADDR pc);
123 void thumb_pbb_run ();
124 thumb_scache* thumb_pbb_begin (PCADDR pc);
127 set_pc (host_int_4 v)
129 this->h_pc_set ((PCADDR) v);
132 // debug support routines
133 string dbg_get_reg (host_int_4 n);
134 component::status dbg_set_reg (host_int_4 n, const string& s);
136 // processor mode (h-mbits inverted)
138 arm::ARM_MODE mode ();
140 // Exceptions, interrupts, and traps support
143 void queue_eit (eit new_eit);
144 int eit_priority (eit e);
145 void process_eit (eit new_eit);
147 void memory_trap (const cpu_memory_fault&);
149 // current state of h-tbit
150 binary_output_pin tbit_pin;
152 // exception generating and support pins
154 // Specifies asynchronous/synchronous nature of interrupts.
155 // ??? Of little utility at the moment.
156 binary_input_pin isync_pin;
158 // FIQ/IRQ are generated by driving these pins (low).
159 // It is synchronous if ISYNC is high, asynchronous if ISYNC is low.
160 // If asynchronous, a cycle delay for synchronization is incurred.
161 callback_pin<arm7f_cpu> nfiq_pin;
162 void do_nfiq_pin (host_int_4 value);
163 callback_pin<arm7f_cpu> nirq_pin;
164 void do_nirq_pin (host_int_4 value);
166 // cpu is reset by driving this pin low
168 callback_pin<arm7f_cpu> nreset_pin;
169 void do_nreset_pin (host_int_4 value);
172 void flush_icache ();
174 // Attribute helper functions.
176 string get_h_cpsr_for_attr () { return make_attribute (h_cpsr_get ()); }
177 string get_h_cpsr2_for_attr ();
178 component::status set_h_cpsr2_for_attr (const string& s) { return component::bad_value; }
179 component::status set_h_cpsr_for_attr (const string& s)
182 component::status stat = parse_attribute (s, value);
185 host_int_4 last_cpsr = h_cpsr_get ();
187 // this may fail via an exception thrown by cgen_rtx_error()
190 if (stat == component::ok)
193 catch (cpu_exception& t)
195 try { h_cpsr_set (last_cpsr); } catch (...) { }
196 stat = component::bad_value;
202 // overload state save & restore
203 void stream_state (ostream& o) const;
204 void destream_state (istream& i);
206 // Override GETMEMSI, which has odd semantics for misaligned accesses.
209 SI GETMEMSI (PCADDR pc, ADDR addr)
212 unsigned short offset = addr % 4;
217 return cgen_bi_endian_cpu::GETMEMSI (pc, addr);
219 word = cgen_bi_endian_cpu::GETMEMSI (pc, addr-1);
220 return (word >> 8) | ((word & 0xFF) << 24);
222 word = cgen_bi_endian_cpu::GETMEMSI (pc, addr-2);
223 return ((word & 0xFFFFU) << 16) | ((word & 0xFFFF0000U) >> 16);
225 word = cgen_bi_endian_cpu::GETMEMSI (pc, addr-3);
226 return (word << 8) | ((word & 0xFF000000) >> 24);
231 SI compute_operand2_immshift (SI rm, int type, int shift);
232 SI compute_operand2_regshift (SI rm, int type, SI shift);
233 BI compute_carry_out_immshift (SI rm, int type, int shift, BI cbit);
234 BI compute_carry_out_regshift (SI rm, int type, SI shift, BI cbit);
236 // FIXME: To be moved to rtl.
238 eval_cond (UINT cond, PCADDR pc)
242 return this->h_zbit_get ();
244 return !(this->h_zbit_get ());
246 return this->h_cbit_get ();
248 return !(this->h_cbit_get ());
250 return this->h_nbit_get ();
252 return !(this->h_nbit_get ());
254 return this->h_vbit_get ();
256 return !(this->h_vbit_get ());
258 return this->h_cbit_get () && !(this->h_zbit_get ());
260 return !(this->h_cbit_get ()) || this->h_zbit_get ();
262 return this->h_nbit_get () == this->h_vbit_get ();
264 return this->h_nbit_get () != this->h_vbit_get ();
266 return !(this->h_zbit_get ()) &&
267 (this->h_nbit_get () == this->h_vbit_get ());
269 return this->h_zbit_get() ||
270 (this->h_nbit_get () != this->h_vbit_get ());
274 this->invalid_insn (pc);
275 return 0; // XXX: notreached?
280 // RTL attribute accessors.
281 // ??? Need to allow application specific rtl generation. Later.
283 #define GET_ATTR_R15_OFFSET() (abuf->idesc->attrs.get_r15_offset_attr ())