88089061756452a54824ef96b1ff6f7dfd74f47d
[external/binutils.git] / sim / mips / m16e.igen
1 // -*- C -*-
2
3 // Simulator definition for the MIPS16e instructions.
4 // Copyright (C) 2005 Free Software Foundation, Inc.
5 // Contributed by Nigel Stephens (nigel@mips.com) and 
6 //                David Ung (davidu@mips.com) of MIPS Technologies.
7 //
8 // This file is part of GDB, the GNU debugger.
9 // 
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2, or (at your option)
13 // any later version.
14 // 
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 // 
20 // You should have received a copy of the GNU General Public License along
21 // with this program; if not, write to the Free Software Foundation, Inc.,
22 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24
25 11101,3.RX,100,10001:RR:16::SEB
26 "seb r<TRX>"
27 *mips16e:
28 {
29   TRACE_ALU_INPUT1 (GPR[TRX]);
30   GPR[TRX] = EXTEND8 (GPR[TRX]);
31   TRACE_ALU_RESULT (GPR[TRX]);
32 }
33
34
35 11101,3.RX,101,10001:RR:16::SEH
36 "seh r<TRX>"
37 *mips16e:
38 {
39   TRACE_ALU_INPUT1 (GPR[TRX]);
40   GPR[TRX] = EXTEND16 (GPR[TRX]);
41   TRACE_ALU_RESULT (GPR[TRX]);
42 }
43
44 11101,3.RX,110,10001:RR:16::SEW
45 "sew r<TRX>"
46 *mips16e:
47 {
48   check_u64 (SD_, instruction_0);
49   TRACE_ALU_INPUT1 (GPR[TRX]);
50   GPR[TRX] = EXTEND32 (GPR[TRX]);
51   TRACE_ALU_RESULT (GPR[TRX]);
52 }
53
54 11101,3.RX,000,10001:RR:16::ZEB
55 "zeb r<TRX>"
56 *mips16e:
57 {
58   TRACE_ALU_INPUT1 (GPR[TRX]);
59   GPR[TRX] =  (unsigned_word)(unsigned8)(GPR[TRX]);
60   TRACE_ALU_RESULT (GPR[TRX]);
61 }
62
63 11101,3.RX,001,10001:RR:16::ZEH
64 "zeh r<TRX>"
65 *mips16e:
66 {
67   TRACE_ALU_INPUT1 (GPR[TRX]);
68   GPR[TRX] = (unsigned_word)(unsigned16)(GPR[TRX]);
69   TRACE_ALU_RESULT (GPR[TRX]);
70 }
71
72 11101,3.RX,010,10001:RR:16::ZEW
73 "zew r<TRX>"
74 *mips16e:
75 {
76   check_u64 (SD_, instruction_0);
77   TRACE_ALU_INPUT1 (GPR[TRX]);
78   GPR[TRX] = (unsigned_word)(unsigned32)(GPR[TRX]);
79   TRACE_ALU_RESULT (GPR[TRX]);
80 }
81
82
83 11101,3.RX,100,00000:RR:16::JRC
84 "jrc r<TRX>"
85 *mips16e:
86 {
87   NIA = GPR[TRX];
88 }
89
90
91 11101,000,101,00000:RR:16::JRCRA
92 "jrc ra"
93 *mips16e:
94 {
95   NIA = RA;
96 }
97
98
99 11101,3.RX,110,00000:RR:16::JALRC
100 "jalrc r<TRX>"
101 *mips16e:
102 {
103   RA = NIA;
104   NIA = GPR[TRX];
105 }
106
107
108 // format routines for save/restore
109 :%s::::RAS:int ras
110 *mips16e
111 {
112   static char buf[10];
113   buf[0] = '\0';
114   if (ras & 4)
115     strcat (buf,"ra,");
116   if (ras & 2)
117     strcat (buf,"s0,");
118   if (ras & 1)
119     strcat (buf,"s1,");
120   return (buf);
121 }
122
123 :%s::::XSREGS:int xsregs
124 *mips16e
125 {
126   if (xsregs > 6)
127     return "s2,s3,s4,s5,s6,s7,s8,";
128   if (xsregs > 5)
129     return "s2,s3,s4,s5,s6,s7,";
130   if (xsregs > 4)
131     return "s2,s3,s4,s5,s6,";
132   if (xsregs > 3)
133     return "s2,s3,s4,s5,";
134   if (xsregs > 2)
135     return "s2,s3,s4,";
136   if (xsregs > 1)
137     return "s2,s3,";
138   if (xsregs > 0)
139     return "s2,";
140   return "";
141 }
142
143 :%s::::AREGS:int aregs
144 *mips16e
145 {
146   // Fixme: how is the arg/static distinction made by the assembler?
147   static const char * const aregstr[16] = {
148     "",
149     "A3,",
150     "A2,A3,",
151     "A1,A2,A3,",
152     "A0,A1,A2,A3,",
153     "a0,",
154     "a0,A3,",
155     "a0,A2,A3,",
156     "a0,A1,A2,A3,",
157     "a0,a1,",
158     "a0,a1,A3,",
159     "a0,a1,A2,A3,",
160     "a0,a1,a2,",
161     "a0,a1,a2,A3,",
162     "?,"
163   };
164   return aregstr[aregs];
165 }
166
167 :compute:::int:SFRAME:FS:((FS == 0) ? 128 \: (FS << 3))
168 :compute:::int:BFRAME:FSHI,FSLO:(((FSHI << 4) | FSLO) << 3)
169
170 :function:::void:do_save:int xsregs, int aregs, int ras0s1, int framesize
171 {
172   unsigned_word temp;    
173   int args, astatic;
174
175   temp = GPR[29];
176
177   /* writes are in the same order as the hardware description... */
178   switch (aregs) {
179   case 0: case 1: case 2: case 3: case 11:
180     args = 0;
181     break;
182   case 4: case 5: case 6: case 7:
183     args = 1;
184     break;
185   case 8: case 9: case 10:
186     args = 2;
187     break;
188   case 12: case 13:
189     args = 3;
190     break;
191   case 14:
192     args = 4;
193     break;
194   default:
195     sim_engine_abort (SD, CPU, CIA, "save: aregs=%d causes unpredictable results\n", aregs);
196   }
197   if (args > 0) {
198     do_store (SD_, AccessLength_WORD, temp, 0, GPR[4]); 
199     if (args > 1) {
200       do_store (SD_,AccessLength_WORD, temp, 4 , GPR[5]); 
201       if (args > 2) {
202         do_store (SD_,AccessLength_WORD, temp, 8 , GPR[6]); 
203         if (args > 3) {
204           do_store (SD_,AccessLength_WORD, temp, 12, GPR[7]);
205         }
206       }
207     }
208   }
209
210   if (ras0s1 & 4)
211     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[31]); 
212
213   switch (xsregs) {
214   case 7:
215     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[30]); 
216   case 6:
217     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[23]); 
218   case 5:
219     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[22]); 
220   case 4:
221     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[21]); 
222   case 3:
223     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[20]); 
224   case 2:
225     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[19]); 
226   case 1:
227     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[18]); 
228   }
229
230   if (ras0s1 & 1)
231     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[17]); 
232   if (ras0s1 & 2)
233     do_store (SD_,AccessLength_WORD, temp -= 4, 0, GPR[16]); 
234
235   switch (aregs) {
236   case 0: case 4: case 8: case 12: case 14:
237     astatic = 0;
238     break;
239   case 1: case 5: case 9: case 13:
240     astatic = 1;
241     break;
242   case 2: case 6: case 10:
243     astatic = 2;
244     break;
245   case 3: case 7:
246     astatic = 3;
247     break;
248   case 11:
249     astatic = 4;
250     break;
251   default:
252     sim_engine_abort (SD, CPU, CIA, "save: aregs=%d causes unpredictable results\n", aregs);
253   }
254   if (astatic > 0) {
255     do_store (SD_, AccessLength_WORD, temp -= 4, 0, GPR[7]);
256     if (astatic > 1) {
257       do_store (SD_, AccessLength_WORD, temp -= 4, 0, GPR[6]);
258       if (astatic > 2) {
259         do_store (SD_, AccessLength_WORD, temp -= 4, 0, GPR[5]);
260         if (astatic > 3) {
261           do_store (SD_, AccessLength_WORD, temp -= 4, 0, GPR[4]);
262         }
263       }
264     }
265   }
266
267   GPR[29] -= framesize;
268 }
269
270 01100,100,1,3.RAS,4.FS:I8:16::SAVE
271 "save %s<RAS>,<SFRAME>"
272 *mips16e
273 {
274   do_save (SD_, 0, 0, RAS, SFRAME);
275 }
276
277
278 11110,3.XSREGS,4.FSHI,4.AREGS + 01100,100,1,3.RAS,4.FSLO:EXT-I8:16::SAVE
279 "save %s<RAS>%s<XSREGS>%s<AREGS><BFRAME>"
280 *mips16e
281 {
282   do_save (SD_, XSREGS, AREGS, RAS, BFRAME);
283 }
284
285
286 :function:::void:do_restore:int xsregs, int aregs, int ras0s1, int framesize
287 *mips16e
288 {
289   unsigned_word temp, temp2;    
290   int astatic;
291
292   temp = GPR[29] + framesize;
293   temp2 = temp;
294
295   /* reads are in the same order as the hardware description... */
296
297   if (ras0s1 & 4)
298     GPR[31] = EXTEND32 (do_load(SD_, AccessLength_WORD, temp -= 4, 0));
299
300   switch (xsregs) {
301   case 7:
302     GPR[30] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 
303   case 6:
304     GPR[23] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 
305   case 5:
306     GPR[22] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 
307   case 4:
308     GPR[21] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 
309   case 3:
310     GPR[20] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 
311   case 2:
312     GPR[19] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 
313   case 1:
314     GPR[18] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 
315   }
316
317   if (ras0s1 & 1)
318     GPR[17] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 
319   if (ras0s1 & 2)
320     GPR[16] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0)); 
321
322   switch (aregs) {
323   case 0: case 4: case 8: case 12: case 14:
324     astatic = 0;
325     break;
326   case 1: case 5: case 9: case 13:
327     astatic = 1;
328     break;
329   case 2: case 6: case 10:
330     astatic = 2;
331     break;
332   case 3: case 7:
333     astatic = 3;
334     break;
335   case 11:
336     astatic = 4;
337     break;
338   default:
339     sim_engine_abort (SD, CPU, CIA, "save: aregs=%d causes unpredictable results\n", aregs);
340   }
341   if (astatic > 0) {
342     GPR[7] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0));
343     if (astatic > 1) {
344       GPR[6] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0));
345       if (astatic > 2) {
346         GPR[5] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0));
347         if (astatic > 3) {
348           GPR[4] = EXTEND32 (do_load (SD_,AccessLength_WORD, temp -= 4, 0));
349         }
350       }
351     }
352   }
353
354   GPR[29] = temp2;
355 }
356
357 01100,100,0,3.RAS,4.FS:I8:16::RESTORE
358 "restore %s<RAS>,<SFRAME>"
359 *mips16e
360
361   do_restore (SD_,0,0,RAS,SFRAME);
362 }
363
364 11110,3.XSREGS,4.FSHI,4.AREGS + 01100,100,0,3.RAS,4.FSLO:EXT-I8:16::RESTORE
365 "restore %s<RAS>%s<XSREGS>%s<AREGS><BFRAME>"
366 *mips16e
367 {
368   do_restore (SD_,XSREGS,AREGS,RAS,BFRAME);
369 }