OSDN Git Service

* public snapshot of sid simulator
[pf3gnuchains/pf3gnuchains3x.git] / sid / component / cgen-cpu / arm7t / arm7f.h
1 // arm7f.h - Main header for the ARM7 CPU family.  -*- C++ -*-
2
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.
6
7 // A "cpu family" is a CGEN notion to put related variants under one roof.
8 // The "f" suffix in "arm7f" is for "family".
9
10 #ifndef ARM7F_H
11 #define ARM7F_H
12
13 #include "cgen-cpu.h"
14 #include "arm-desc.h"
15 #include "arm-defs.h"
16 #include "arm-decode.h"
17 #include "thumb-decode.h"
18
19
20 namespace arm7f {
21
22 using namespace cgen;
23 using namespace arm;
24
25
26 // Put machine generated elements in base class as we want to override
27 // some of its methods.
28 class arm7f_cpu_cgen
29 {
30 // Include cgen generated elements.
31 #include "arm-cpu.h"
32
33 protected:
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;
37
38   inline void cgen_rtx_error (const char* msg) const
39     {
40       cerr << "arm7f-cpu rtx error: " << msg << endl;
41       // throw cpu_exception ();
42     }
43 };
44
45
46 enum eit 
47 {
48   EIT_NONE = 0,
49   EIT_RESET,
50   EIT_DATA_ABORT,
51   EIT_FIQ,
52   EIT_IRQ,
53   EIT_PREFETCH_ABORT,
54   EIT_UNDEFINED_INSN,
55   EIT_SWI_INSN
56 };
57
58
59 class arm7f_cpu: public arm7f_cpu_cgen, public cgen_bi_endian_cpu
60 {
61 public:
62   arm7f_cpu ();
63   ~arm7f_cpu () {}
64
65   // Called by the semantic code to perform a branch.
66   // The result is the new address.
67   inline void
68   branch (PCADDR new_val, PCADDR& npc, sem_status& status)
69     {
70       npc = new_val;
71     }
72
73   // Called by the semantic code at the end of a non-cti insn.
74   inline void
75   done_insn (PCADDR npc, sem_status& status)
76     {
77       this->h_pc_set (npc);
78     }
79
80   // Called by the semantic code at the end of a cti insn.
81   inline void
82   done_cti_insn (PCADDR npc, sem_status& status)
83     {
84       this->h_pc_set (npc);
85     }
86
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);
90
91   void invalid_insn (PCADDR pc);
92   void reset ();
93   bool initialized_p;
94
95 private:
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;
101
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);
110
111   void arm_tbit_set (BI newval);
112   void arm_mbits_set (UINT newval);
113
114   void step_insns (); // dispatches to one of following "workers"
115   void step_arm ();
116   void step_thumb ();
117   void step_arm_pbb ();
118   void step_thumb_pbb ();
119
120   // PBB engine support.
121   void arm_pbb_run ();
122   arm_scache* arm_pbb_begin (PCADDR pc);
123   void thumb_pbb_run ();
124   thumb_scache* thumb_pbb_begin (PCADDR pc);
125
126   void
127   set_pc (host_int_4 v)
128     {
129       this->h_pc_set ((PCADDR) v);
130     }
131
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);
135
136   // processor mode (h-mbits inverted)
137   output_pin nm_pin;
138   arm::ARM_MODE mode ();
139
140   // Exceptions, interrupts, and traps support
141
142   eit pending_eit;
143   void queue_eit (eit new_eit);
144   int eit_priority (eit e);
145   void process_eit (eit new_eit);
146
147   void memory_trap (const cpu_memory_fault&);
148
149   // current state of h-tbit
150   binary_output_pin tbit_pin;
151
152   // exception generating and support pins
153
154   // Specifies asynchronous/synchronous nature of interrupts.
155   // ??? Of little utility at the moment.
156   binary_input_pin isync_pin;
157
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);
165
166   // cpu is reset by driving this pin low
167 #if 0
168   callback_pin<arm7f_cpu> nreset_pin;
169   void do_nreset_pin (host_int_4 value);
170 #endif
171
172   void flush_icache ();
173
174   // Attribute helper functions.
175   // cpsr
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)
180     {
181       host_int_4 value;
182       component::status stat = parse_attribute (s, value);
183
184       // save last cpsr
185       host_int_4 last_cpsr = h_cpsr_get ();
186
187       // this may fail via an exception thrown by cgen_rtx_error()
188       try
189         {
190           if (stat == component::ok)
191             h_cpsr_set (value);
192         }
193       catch (cpu_exception& t)
194         {
195           try { h_cpsr_set (last_cpsr); } catch (...) { }
196           stat = component::bad_value;
197         }
198
199       return stat;
200     }
201
202   // overload state save & restore
203   void stream_state (ostream& o) const;
204   void destream_state (istream& i);
205
206   // Override GETMEMSI, which has odd semantics for misaligned accesses.
207 public:
208   inline
209   SI GETMEMSI (PCADDR pc, ADDR addr)
210   {
211     SI word;
212     unsigned short offset = addr % 4;
213
214     switch (offset)
215       {
216       case 0:
217         return cgen_bi_endian_cpu::GETMEMSI (pc, addr);
218       case 1:
219         word = cgen_bi_endian_cpu::GETMEMSI (pc, addr-1);
220         return (word >> 8) | ((word & 0xFF) << 24); 
221       case 2:
222         word = cgen_bi_endian_cpu::GETMEMSI (pc, addr-2);
223         return ((word & 0xFFFFU) << 16) | ((word & 0xFFFF0000U) >> 16);
224       case 3:
225         word = cgen_bi_endian_cpu::GETMEMSI (pc, addr-3);
226         return (word << 8) | ((word & 0xFF000000) >> 24); 
227       }
228   }
229
230
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);
235
236   // FIXME: To be moved to rtl.
237   inline BI 
238   eval_cond (UINT cond, PCADDR pc)
239     {
240       switch (cond) {
241       case arm::COND_EQ:
242         return this->h_zbit_get ();
243       case arm::COND_NE:
244         return !(this->h_zbit_get ());
245       case arm::COND_CS:
246         return this->h_cbit_get ();
247       case arm::COND_CC:
248         return !(this->h_cbit_get ());
249       case arm::COND_MI:
250         return this->h_nbit_get ();
251       case arm::COND_PL:
252         return !(this->h_nbit_get ());
253       case arm::COND_VS:
254         return this->h_vbit_get ();
255       case arm::COND_VC:
256         return !(this->h_vbit_get ());
257       case arm::COND_HI:
258         return this->h_cbit_get () && !(this->h_zbit_get ());
259       case arm::COND_LS:
260         return !(this->h_cbit_get ()) || this->h_zbit_get ();
261       case arm::COND_GE:
262         return this->h_nbit_get () == this->h_vbit_get ();
263       case arm::COND_LT:
264         return this->h_nbit_get () != this->h_vbit_get ();
265       case arm::COND_GT:
266         return !(this->h_zbit_get ()) && 
267           (this->h_nbit_get () == this->h_vbit_get ());
268       case arm::COND_LE:
269         return this->h_zbit_get() ||
270           (this->h_nbit_get () != this->h_vbit_get ());
271       case arm::COND_AL:
272         return 1;
273       default:
274         this->invalid_insn (pc);
275         return 0; // XXX: notreached?
276       }
277     }
278 }; // arm7_cpu
279 \f
280 // RTL attribute accessors.
281 // ??? Need to allow application specific rtl generation.  Later.
282
283 #define GET_ATTR_R15_OFFSET() (abuf->idesc->attrs.get_r15_offset_attr ())
284
285 } // namespace arm7f
286
287 #endif // ARM7F_H