sim/testsuite/or1k: Add test for 64-bit fpu operations
[external/binutils.git] / sim / mips / mips3264r2.igen
1 // -*- C -*-
2
3 // Simulator definition for the MIPS 32/64 revision 2 instructions.
4 // Copyright (C) 2004-2019 Free Software Foundation, Inc.
5 // Contributed by David Ung, of MIPS Technologies.
6 //
7 // This file is part of the MIPS sim.
8 // 
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 3 of the License, or
12 // (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
22 :function:::void:do_dsbh:int rd, int rt
23 {
24   union { unsigned64 d; unsigned16 h[4]; } u;
25   TRACE_ALU_INPUT1 (GPR[rt]);
26   u.d = GPR[rt];
27   u.h[0] = SWAP_2 (u.h[0]);
28   u.h[1] = SWAP_2 (u.h[1]);
29   u.h[2] = SWAP_2 (u.h[2]);
30   u.h[3] = SWAP_2 (u.h[3]);
31   GPR[rd] = u.d;
32   TRACE_ALU_RESULT1 (GPR[rd]);
33 }
34
35 :function:::void:do_dshd:int rd, int rt
36 {
37   unsigned64 d;
38   TRACE_ALU_INPUT1 (GPR[rt]);
39   d = GPR[rt];
40   GPR[rd] = ((d >> 48)
41              | (d << 48)
42              | ((d & 0x0000ffff00000000ULL) >> 16)
43              | ((d & 0x00000000ffff0000ULL) << 16));
44   TRACE_ALU_RESULT1 (GPR[rd]);
45 }
46
47 :function:::void:do_dext:int rt, int rs, int lsb, int size
48 {
49   TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
50   GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size, lsb);
51   TRACE_ALU_RESULT1 (GPR[rt]);
52 }
53
54 :function:::void:do_dextm:int rt, int rs, int lsb, int size
55 {
56   TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
57   GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size + 32, lsb);
58   TRACE_ALU_RESULT1 (GPR[rt]);
59 }
60
61 :function:::void:do_dextu:int rt, int rs, int lsb, int size
62 {
63   TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
64   GPR[rt] = EXTRACTED64 (GPR[rs], lsb + 32 + size, lsb + 32);
65   TRACE_ALU_RESULT1 (GPR[rt]);
66 }
67
68 :function:::void:do_di:int rt
69 {
70   TRACE_ALU_INPUT0 ();
71   GPR[rt] = EXTEND32 (SR);
72   SR &= ~status_IE;
73   TRACE_ALU_RESULT1 (GPR[rt]);
74 }
75
76 :function:::void:do_dins:int rt, int rs, int lsb, int msb
77 {
78   TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
79   if (lsb <= msb)
80     GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb, lsb);
81   TRACE_ALU_RESULT1 (GPR[rt]);
82 }
83
84 :function:::void:do_dinsm:int rt, int rs, int lsb, int msb
85 {
86   TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
87   if (lsb <= msb + 32)
88     GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb + 32, lsb);
89   TRACE_ALU_RESULT1 (GPR[rt]);
90 }
91
92 :function:::void:do_ei:int rt
93 {
94   TRACE_ALU_INPUT0 ();
95   GPR[rt] = EXTEND32 (SR);
96   SR |= status_IE;
97   TRACE_ALU_RESULT1 (GPR[rt]);
98 }
99
100 :function:::void:do_ext:int rt, int rs, int lsb, int size
101 {
102   TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
103   GPR[rt] = EXTEND32 (EXTRACTED32 (GPR[rs], lsb + size, lsb));
104   TRACE_ALU_RESULT1 (GPR[rt]);
105 }
106
107 :function:::void:do_mfhc1:int rt, int fs
108 {
109   check_fpu (SD_);
110   if (SizeFGR() == 64)
111     GPR[rt] = EXTEND32 (WORD64HI (FGR[fs]));
112   else if ((fs & 0x1) == 0)
113     GPR[rt] = EXTEND32 (FGR[fs + 1]);
114   else
115     {
116       if (STATE_VERBOSE_P(SD))
117         sim_io_eprintf (SD,
118                  "Warning: PC 0x%lx: MFHC1 32-bit use of odd FPR number\n",
119                         (long) CIA);
120       GPR[rt] = EXTEND32 (0xBADF00D);
121     }
122   TRACE_ALU_RESULT (GPR[rt]);
123 }
124
125 :function:::void:do_mthc1:int rt, int fs
126 {
127   check_fpu (SD_);
128   if (SizeFGR() == 64)
129     StoreFPR (fs, fmt_uninterpreted_64, SET64HI (GPR[rt]) | VL4_8 (FGR[fs]));
130   else if ((fs & 0x1) == 0)
131     StoreFPR (fs + 1, fmt_uninterpreted_32, VL4_8 (GPR[rt]));
132   else
133     {
134       if (STATE_VERBOSE_P(SD))
135         sim_io_eprintf (SD,
136                  "Warning: PC 0x%lx: MTHC1 32-bit use of odd FPR number\n",
137                         (long) CIA);
138       StoreFPR (fs, fmt_uninterpreted_32, 0xDEADC0DE);
139     }
140   TRACE_FP_RESULT (GPR[rt]);
141 }
142
143 :function:::void:do_ins:int rt, int rs, int lsb, int msb
144 {
145   TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
146   if (lsb <= msb)
147     GPR[rt] = EXTEND32 (GPR[rt] ^
148                         ((GPR[rt] ^ (GPR[rs] << lsb)) & MASK32 (msb, lsb)));
149   TRACE_ALU_RESULT1 (GPR[rt]);
150 }
151
152 :function:::void:do_dinsu:int rt, int rs, int lsb, int msb
153 {
154   TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
155   if (lsb <= msb)
156     GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << (lsb + 32)))
157       & MASK64 (msb + 32, lsb + 32);
158   TRACE_ALU_RESULT1 (GPR[rt]);
159 }
160
161 :function:::void:do_seb:int rd, int rt
162 {
163   TRACE_ALU_INPUT1 (GPR[rt]);
164   GPR[rd] = EXTEND8 (GPR[rt]);
165   TRACE_ALU_RESULT1 (GPR[rd]);
166 }
167
168 :function:::void:do_seh:int rd, int rt
169 {
170   TRACE_ALU_INPUT1 (GPR[rt]);
171   GPR[rd] = EXTEND16 (GPR[rt]);
172   TRACE_ALU_RESULT1 (GPR[rd]);
173 }
174
175 :function:::void:do_rdhwr:int rt, int rd
176 {
177   // Return 0 for all hardware registers currently
178   GPR[rt] = EXTEND32 (0);
179   TRACE_ALU_RESULT1 (GPR[rt]);
180 }
181
182 :function:::void:do_wsbh:int rd, int rt
183 {
184   union { unsigned32 w; unsigned16 h[2]; } u;
185   TRACE_ALU_INPUT1 (GPR[rt]);
186   u.w = GPR[rt];
187   u.h[0] = SWAP_2 (u.h[0]);
188   u.h[1] = SWAP_2 (u.h[1]);
189   GPR[rd] = EXTEND32 (u.w);
190   TRACE_ALU_RESULT1 (GPR[rd]);
191 }
192
193 011111,5.RS,5.RT,5.SIZE,5.LSB,000011::64::DEXT
194 "dext r<RT>, r<RS>, <LSB>, <SIZE+1>"
195 *mips64r2:
196 {
197   check_u64 (SD_, instruction_0);
198   do_dext (SD_, RT, RS, LSB, SIZE);
199 }
200
201 011111,5.RS,5.RT,5.SIZE,5.LSB,000001::64::DEXTM
202 "dextm r<RT>, r<RS>, <LSB>, <SIZE+33>"
203 *mips64r2:
204 {
205   check_u64 (SD_, instruction_0);
206   do_dextm (SD_, RT, RS, LSB, SIZE);
207 }
208
209 011111,5.RS,5.RT,5.SIZE,5.LSB,000010::64::DEXTU
210 "dextu r<RT>, r<RS>, <LSB+32>, <SIZE+1>"
211 *mips64r2:
212 {
213   check_u64 (SD_, instruction_0);
214   do_dextu (SD_, RT, RS, LSB, SIZE);
215 }
216
217
218 010000,01011,5.RT,01100,00000,0,00,000::32::DI
219 "di":RT == 0
220 "di r<RT>"
221 *mips32r2:
222 *mips64r2:
223 {
224   do_di (SD_, RT);
225 }
226
227
228 011111,5.RS,5.RT,5.MSB,5.LSB,000111::64::DINS
229 "dins r<RT>, r<RS>, <LSB>, <MSB-LSB+1>"
230 *mips64r2:
231 {
232   check_u64 (SD_, instruction_0);
233   do_dins (SD_, RT, RS, LSB, MSB);
234 }
235
236 011111,5.RS,5.RT,5.MSB,5.LSB,000101::64::DINSM
237 "dinsm r<RT>, r<RS>, <LSB>, <MSB+32-LSB+1>"
238 *mips64r2:
239 {
240   check_u64 (SD_, instruction_0);
241   do_dinsm (SD_, RT, RS, LSB, MSB);
242 }
243
244 011111,5.RS,5.RT,5.MSB,5.LSB,000110::64::DINSU
245 "dinsu r<RT>, r<RS>, <LSB+32>, <MSB-LSB+1>"
246 *mips64r2:
247 {
248   check_u64 (SD_, instruction_0);
249   do_dinsu (SD_, RT, RS, LSB, MSB);
250 }
251
252
253 011111,00000,5.RT,5.RD,00010,100100::64::DSBH
254 "dsbh r<RD>, r<RT>"
255 *mips64r2:
256 {
257   check_u64 (SD_, instruction_0);
258   do_dsbh (SD_, RD, RT);
259 }
260
261 011111,00000,5.RT,5.RD,00101,100100::64::DSHD
262 "dshd r<RD>, r<RT>"
263 *mips64r2:
264 {
265   check_u64 (SD_, instruction_0);
266   do_dshd (SD_, RD, RT);
267 }
268
269 010000,01011,5.RT,01100,00000,1,00,000::32::EI
270 "ei":RT == 0
271 "ei r<RT>"
272 *mips32r2:
273 *mips64r2:
274 {
275   do_ei (SD_, RT);
276 }
277
278
279 011111,5.RS,5.RT,5.SIZE,5.LSB,000000::32::EXT
280 "ext r<RT>, r<RS>, <LSB>, <SIZE+1>"
281 *mips32r2:
282 *mips64r2:
283 {
284   do_ext (SD_, RT, RS, LSB, SIZE);
285 }
286
287
288 010001,00011,5.RT,5.FS,00000000000:COP1Sa:32,f::MFHC1
289 "mfhc1 r<RT>, f<FS>"
290 *mips32r2:
291 *mips64r2:
292 {
293   do_mfhc1 (SD_, RT, FS);
294 }
295
296 010001,00111,5.RT,5.FS,00000000000:COP1Sa:32,f::MTHC1
297 "mthc1 r<RT>, f<FS>"
298 *mips32r2:
299 *mips64r2:
300 {
301   do_mthc1 (SD_, RT, FS);
302 }
303
304
305 011111,5.RS,5.RT,5.MSB,5.LSB,000100::32::INS
306 "ins r<RT>, r<RS>, <LSB>, <MSB-LSB+1>"
307 *mips32r2:
308 *mips64r2:
309 {
310   do_ins (SD_, RT, RS, LSB, MSB);
311 }
312
313
314 011111,00000,5.RT,5.RD,10000,100000::32::SEB
315 "seb r<RD>, r<RT>"
316 *mips32r2:
317 *mips64r2:
318 {
319   do_seb (SD_, RD, RT);
320 }
321
322 011111,00000,5.RT,5.RD,11000,100000::32::SEH
323 "seh r<RD>, r<RT>"
324 *mips32r2:
325 *mips64r2:
326 {
327   do_seh (SD_, RD, RT);
328 }
329
330
331 000001,5.BASE,11111,16.OFFSET::32::SYNCI
332 "synci <OFFSET>(r<BASE>)"
333 *mips32r2:
334 *mips64r2:
335 {
336   // sync i-cache - nothing to do currently
337 }
338
339
340 011111,00000,5.RT,5.RD,00000,111011::32::RDHWR
341 "rdhwr r<RT>, r<RD>"
342 *mips32r2:
343 *mips64r2:
344 {
345   do_rdhwr (SD_, RT, RD);
346 }
347
348
349 011111,00000,5.RT,5.RD,00010,100000::32::WSBH
350 "wsbh r<RD>, r<RT>"
351 *mips32r2:
352 *mips64r2:
353 {
354   do_wsbh (SD_, RD, RT);
355 }
356
357
358