3 // Simulator definition for the MIPS 32/64 revision 2 instructions.
4 // Copyright (C) 2004-2016 Free Software Foundation, Inc.
5 // Contributed by David Ung, of MIPS Technologies.
7 // This file is part of the MIPS sim.
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.
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.
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/>.
22 :function:::void:do_dsbh:int rd, int rt
24 union { unsigned64 d; unsigned16 h[4]; } u;
25 TRACE_ALU_INPUT1 (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]);
32 TRACE_ALU_RESULT1 (GPR[rd]);
35 :function:::void:do_dshd:int rd, int rt
38 TRACE_ALU_INPUT1 (GPR[rt]);
42 | ((d & 0x0000ffff00000000ULL) >> 16)
43 | ((d & 0x00000000ffff0000ULL) << 16));
44 TRACE_ALU_RESULT1 (GPR[rd]);
47 :function:::void:do_dext:int rt, int rs, int lsb, int size
49 TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
50 GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size, lsb);
51 TRACE_ALU_RESULT1 (GPR[rt]);
54 :function:::void:do_dextm:int rt, int rs, int lsb, int size
56 TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
57 GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size + 32, lsb);
58 TRACE_ALU_RESULT1 (GPR[rt]);
61 :function:::void:do_dextu:int rt, int rs, int lsb, int size
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]);
68 :function:::void:do_di:int rt
71 GPR[rt] = EXTEND32 (SR);
73 TRACE_ALU_RESULT1 (GPR[rt]);
76 :function:::void:do_dins:int rt, int rs, int lsb, int msb
78 TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
80 GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb, lsb);
81 TRACE_ALU_RESULT1 (GPR[rt]);
84 :function:::void:do_dinsm:int rt, int rs, int lsb, int msb
86 TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
88 GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb + 32, lsb);
89 TRACE_ALU_RESULT1 (GPR[rt]);
92 :function:::void:do_ei:int rt
95 GPR[rt] = EXTEND32 (SR);
97 TRACE_ALU_RESULT1 (GPR[rt]);
100 :function:::void:do_ext:int rt, int rs, int lsb, int size
102 TRACE_ALU_INPUT3 (GPR[rs], lsb, size);
103 GPR[rt] = EXTEND32 (EXTRACTED32 (GPR[rs], lsb + size, lsb));
104 TRACE_ALU_RESULT1 (GPR[rt]);
107 :function:::void:do_mfhc1:int rt, int fs
111 GPR[rt] = EXTEND32 (WORD64HI (FGR[fs]));
112 else if ((fs & 0x1) == 0)
113 GPR[rt] = EXTEND32 (FGR[fs + 1]);
116 if (STATE_VERBOSE_P(SD))
118 "Warning: PC 0x%lx: MFHC1 32-bit use of odd FPR number\n",
120 GPR[rt] = EXTEND32 (0xBADF00D);
122 TRACE_ALU_RESULT (GPR[rt]);
125 :function:::void:do_mthc1:int rt, int fs
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]));
134 if (STATE_VERBOSE_P(SD))
136 "Warning: PC 0x%lx: MTHC1 32-bit use of odd FPR number\n",
138 StoreFPR (fs, fmt_uninterpreted_32, 0xDEADC0DE);
140 TRACE_FP_RESULT (GPR[rt]);
143 :function:::void:do_ins:int rt, int rs, int lsb, int msb
145 TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
147 GPR[rt] = EXTEND32 (GPR[rt] ^
148 ((GPR[rt] ^ (GPR[rs] << lsb)) & MASK32 (msb, lsb)));
149 TRACE_ALU_RESULT1 (GPR[rt]);
152 :function:::void:do_dinsu:int rt, int rs, int lsb, int msb
154 TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb);
156 GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << (lsb + 32)))
157 & MASK64 (msb + 32, lsb + 32);
158 TRACE_ALU_RESULT1 (GPR[rt]);
161 :function:::void:do_seb:int rd, int rt
163 TRACE_ALU_INPUT1 (GPR[rt]);
164 GPR[rd] = EXTEND8 (GPR[rt]);
165 TRACE_ALU_RESULT1 (GPR[rd]);
168 :function:::void:do_seh:int rd, int rt
170 TRACE_ALU_INPUT1 (GPR[rt]);
171 GPR[rd] = EXTEND16 (GPR[rt]);
172 TRACE_ALU_RESULT1 (GPR[rd]);
175 :function:::void:do_rdhwr:int rt, int rd
177 // Return 0 for all hardware registers currently
178 GPR[rt] = EXTEND32 (0);
179 TRACE_ALU_RESULT1 (GPR[rt]);
182 :function:::void:do_wsbh:int rd, int rt
184 union { unsigned32 w; unsigned16 h[2]; } u;
185 TRACE_ALU_INPUT1 (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]);
193 011111,5.RS,5.RT,5.SIZE,5.LSB,000011::64::DEXT
194 "dext r<RT>, r<RS>, <LSB>, <SIZE+1>"
197 check_u64 (SD_, instruction_0);
198 do_dext (SD_, RT, RS, LSB, SIZE);
201 011111,5.RS,5.RT,5.SIZE,5.LSB,000001::64::DEXTM
202 "dextm r<RT>, r<RS>, <LSB>, <SIZE+33>"
205 check_u64 (SD_, instruction_0);
206 do_dextm (SD_, RT, RS, LSB, SIZE);
209 011111,5.RS,5.RT,5.SIZE,5.LSB,000010::64::DEXTU
210 "dextu r<RT>, r<RS>, <LSB+32>, <SIZE+1>"
213 check_u64 (SD_, instruction_0);
214 do_dextu (SD_, RT, RS, LSB, SIZE);
218 010000,01011,5.RT,01100,00000,0,00,000::32::DI
228 011111,5.RS,5.RT,5.MSB,5.LSB,000111::64::DINS
229 "dins r<RT>, r<RS>, <LSB>, <MSB-LSB+1>"
232 check_u64 (SD_, instruction_0);
233 do_dins (SD_, RT, RS, LSB, MSB);
236 011111,5.RS,5.RT,5.MSB,5.LSB,000101::64::DINSM
237 "dinsm r<RT>, r<RS>, <LSB>, <MSB+32-LSB+1>"
240 check_u64 (SD_, instruction_0);
241 do_dinsm (SD_, RT, RS, LSB, MSB);
244 011111,5.RS,5.RT,5.MSB,5.LSB,000110::64::DINSU
245 "dinsu r<RT>, r<RS>, <LSB+32>, <MSB-LSB+1>"
248 check_u64 (SD_, instruction_0);
249 do_dinsu (SD_, RT, RS, LSB, MSB);
253 011111,00000,5.RT,5.RD,00010,100100::64::DSBH
257 check_u64 (SD_, instruction_0);
258 do_dsbh (SD_, RD, RT);
261 011111,00000,5.RT,5.RD,00101,100100::64::DSHD
265 check_u64 (SD_, instruction_0);
266 do_dshd (SD_, RD, RT);
269 010000,01011,5.RT,01100,00000,1,00,000::32::EI
279 011111,5.RS,5.RT,5.SIZE,5.LSB,000000::32::EXT
280 "ext r<RT>, r<RS>, <LSB>, <SIZE+1>"
284 do_ext (SD_, RT, RS, LSB, SIZE);
288 010001,00011,5.RT,5.FS,00000000000:COP1Sa:32,f::MFHC1
293 do_mfhc1 (SD_, RT, FS);
296 010001,00111,5.RT,5.FS,00000000000:COP1Sa:32,f::MTHC1
301 do_mthc1 (SD_, RT, FS);
305 011111,5.RS,5.RT,5.MSB,5.LSB,000100::32::INS
306 "ins r<RT>, r<RS>, <LSB>, <MSB-LSB+1>"
310 do_ins (SD_, RT, RS, LSB, MSB);
314 011111,00000,5.RT,5.RD,10000,100000::32::SEB
319 do_seb (SD_, RD, RT);
322 011111,00000,5.RT,5.RD,11000,100000::32::SEH
327 do_seh (SD_, RD, RT);
331 000001,5.BASE,11111,16.OFFSET::32::SYNCI
332 "synci <OFFSET>(r<BASE>)"
336 // sync i-cache - nothing to do currently
340 011111,00000,5.RT,5.RD,00000,111011::32::RDHWR
345 do_rdhwr (SD_, RT, RD);
349 011111,00000,5.RT,5.RD,00010,100000::32::WSBH
354 do_wsbh (SD_, RD, RT);