OSDN Git Service

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