decoder.isa (12104:edd63f9c6184) decoder.isa (12406:86bde4a026b5)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007 MIPS Technologies, Inc.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Korey Sewell
30// Brett Miller
31// Jaidev Patwardhan
32
33////////////////////////////////////////////////////////////////////
34//
35// The actual MIPS32 ISA decoder
36// -----------------------------
37// The following instructions are specified in the MIPS32 ISA
38// Specification. Decoding closely follows the style specified
39// in the MIPS32 ISA specification document starting with Table
40// A-2 (document available @ http://www.mips.com)
41//
42decode OPCODE_HI default Unknown::unknown() {
43 //Table A-2
44 0x0: decode OPCODE_LO {
45 0x0: decode FUNCTION_HI {
46 0x0: decode FUNCTION_LO {
47 0x1: decode MOVCI {
48 format BasicOp {
49 0: movf({{
50 Rd = (getCondCode(FCSR, CC) == 0) ? Rd : Rs;
51 }});
52 1: movt({{
53 Rd = (getCondCode(FCSR, CC) == 1) ? Rd : Rs;
54 }});
55 }
56 }
57
58 format BasicOp {
59 //Table A-3 Note: "Specific encodings of the rd, rs, and
60 //rt fields are used to distinguish SLL, SSNOP, and EHB
61 //functions
62 0x0: decode RS {
63 0x0: decode RT_RD {
64 0x0: decode SA default Nop::nop() {
65 0x1: ssnop({{;}});
66 0x3: ehb({{;}});
67 }
68 default: sll({{ Rd = Rt_uw << SA; }});
69 }
70 }
71
72 0x2: decode RS_SRL {
73 0x0:decode SRL {
74 0: srl({{ Rd = Rt_uw >> SA; }});
75
76 //Hardcoded assuming 32-bit ISA,
77 //probably need parameter here
78 1: rotr({{
79 Rd = (Rt_uw << (32 - SA)) | (Rt_uw >> SA);
80 }});
81 }
82 }
83
84 0x3: decode RS {
85 0x0: sra({{
86 uint32_t temp = Rt >> SA;
87 if ( (Rt & 0x80000000) > 0 ) {
88 uint32_t mask = 0x80000000;
89 for(int i=0; i < SA; i++) {
90 temp |= mask;
91 mask = mask >> 1;
92 }
93 }
94 Rd = temp;
95 }});
96 }
97
98 0x4: sllv({{ Rd = Rt_uw << Rs<4:0>; }});
99
100 0x6: decode SRLV {
101 0: srlv({{ Rd = Rt_uw >> Rs<4:0>; }});
102
103 //Hardcoded assuming 32-bit ISA,
104 //probably need parameter here
105 1: rotrv({{
106 Rd = (Rt_uw << (32 - Rs<4:0>)) |
107 (Rt_uw >> Rs<4:0>);
108 }});
109 }
110
111 0x7: srav({{
112 int shift_amt = Rs<4:0>;
113
114 uint32_t temp = Rt >> shift_amt;
115
116 if ((Rt & 0x80000000) > 0) {
117 uint32_t mask = 0x80000000;
118 for (int i = 0; i < shift_amt; i++) {
119 temp |= mask;
120 mask = mask >> 1;
121 }
122 }
123 Rd = temp;
124 }});
125 }
126 }
127
128 0x1: decode FUNCTION_LO {
129 //Table A-3 Note: "Specific encodings of the hint field are
130 //used to distinguish JR from JR.HB and JALR from JALR.HB"
131 format Jump {
132 0x0: decode HINT {
133 0x1: jr_hb({{
134 Config1Reg config1 = Config1;
135 if (config1.ca == 0) {
136 NNPC = Rs;
137 } else {
138 panic("MIPS16e not supported\n");
139 }
140 }}, IsReturn, ClearHazards);
141 default: jr({{
142 Config1Reg config1 = Config1;
143 if (config1.ca == 0) {
144 NNPC = Rs;
145 } else {
146 panic("MIPS16e not supported\n");
147 }
148 }}, IsReturn);
149 }
150
151 0x1: decode HINT {
152 0x1: jalr_hb({{
153 Rd = NNPC;
154 NNPC = Rs;
155 }}, IsCall, ClearHazards);
156 default: jalr({{
157 Rd = NNPC;
158 NNPC = Rs;
159 }}, IsCall);
160 }
161 }
162
163 format BasicOp {
164 0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
165 0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
166 0x4: decode FullSystemInt {
167 0: syscall_se({{ xc->syscall(R2, &fault); }},
168 IsSerializeAfter, IsNonSpeculative);
169 default: syscall({{ fault = std::make_shared<SystemCallFault>(); }});
170 }
171 0x7: sync({{ ; }}, IsMemBarrier);
172 0x5: break({{fault = std::make_shared<BreakpointFault>();}});
173 }
174
175 }
176
177 0x2: decode FUNCTION_LO {
178 0x0: HiLoRsSelOp::mfhi({{ Rd = HI_RS_SEL; }},
179 IntMultOp, IsIprAccess);
180 0x1: HiLoRdSelOp::mthi({{ HI_RD_SEL = Rs; }});
181 0x2: HiLoRsSelOp::mflo({{ Rd = LO_RS_SEL; }},
182 IntMultOp, IsIprAccess);
183 0x3: HiLoRdSelOp::mtlo({{ LO_RD_SEL = Rs; }});
184 }
185
186 0x3: decode FUNCTION_LO {
187 format HiLoRdSelValOp {
188 0x0: mult({{ val = Rs_sd * Rt_sd; }}, IntMultOp);
189 0x1: multu({{ val = Rs_ud * Rt_ud; }}, IntMultOp);
190 }
191
192 format HiLoOp {
193 0x2: div({{
194 if (Rt_sd != 0) {
195 HI0 = Rs_sd % Rt_sd;
196 LO0 = Rs_sd / Rt_sd;
197 }
198 }}, IntDivOp);
199
200 0x3: divu({{
201 if (Rt_ud != 0) {
202 HI0 = Rs_ud % Rt_ud;
203 LO0 = Rs_ud / Rt_ud;
204 }
205 }}, IntDivOp);
206 }
207 }
208
209 0x4: decode HINT {
210 0x0: decode FUNCTION_LO {
211 format IntOp {
212 0x0: add({{
213 IntReg result;
214 Rd = result = Rs + Rt;
215 if (FullSystem &&
216 findOverflow(32, result, Rs, Rt)) {
217 fault = std::make_shared<IntegerOverflowFault>();
218 }
219 }});
220 0x1: addu({{ Rd_sw = Rs_sw + Rt_sw;}});
221 0x2: sub({{
222 IntReg result;
223 Rd = result = Rs - Rt;
224 if (FullSystem &&
225 findOverflow(32, result, Rs, ~Rt)) {
226 fault = std::make_shared<IntegerOverflowFault>();
227 }
228 }});
229 0x3: subu({{ Rd_sw = Rs_sw - Rt_sw; }});
230 0x4: and({{ Rd = Rs & Rt; }});
231 0x5: or({{ Rd = Rs | Rt; }});
232 0x6: xor({{ Rd = Rs ^ Rt; }});
233 0x7: nor({{ Rd = ~(Rs | Rt); }});
234 }
235 }
236 }
237
238 0x5: decode HINT {
239 0x0: decode FUNCTION_LO {
240 format IntOp{
241 0x2: slt({{ Rd_sw = (Rs_sw < Rt_sw) ? 1 : 0 }});
242 0x3: sltu({{ Rd_uw = (Rs_uw < Rt_uw) ? 1 : 0 }});
243 }
244 }
245 }
246
247 0x6: decode FUNCTION_LO {
248 format Trap {
249 0x0: tge({{ cond = (Rs_sw >= Rt_sw); }});
250 0x1: tgeu({{ cond = (Rs_uw >= Rt_uw); }});
251 0x2: tlt({{ cond = (Rs_sw < Rt_sw); }});
252 0x3: tltu({{ cond = (Rs_uw < Rt_uw); }});
253 0x4: teq({{ cond = (Rs_sw == Rt_sw); }});
254 0x6: tne({{ cond = (Rs_sw != Rt_sw); }});
255 }
256 }
257 }
258
259 0x1: decode REGIMM_HI {
260 0x0: decode REGIMM_LO {
261 format Branch {
262 0x0: bltz({{ cond = (Rs_sw < 0); }});
263 0x1: bgez({{ cond = (Rs_sw >= 0); }});
264 0x2: bltzl({{ cond = (Rs_sw < 0); }}, Likely);
265 0x3: bgezl({{ cond = (Rs_sw >= 0); }}, Likely);
266 }
267 }
268
269 0x1: decode REGIMM_LO {
270 format TrapImm {
271 0x0: tgei( {{ cond = (Rs_sw >= (int16_t)INTIMM); }});
272 0x1: tgeiu({{
273 cond = (Rs_uw >= (uint32_t)(int32_t)(int16_t)INTIMM);
274 }});
275 0x2: tlti( {{ cond = (Rs_sw < (int16_t)INTIMM); }});
276 0x3: tltiu({{
277 cond = (Rs_uw < (uint32_t)(int32_t)(int16_t)INTIMM);
278 }});
279 0x4: teqi( {{ cond = (Rs_sw == (int16_t)INTIMM); }});
280 0x6: tnei( {{ cond = (Rs_sw != (int16_t)INTIMM); }});
281 }
282 }
283
284 0x2: decode REGIMM_LO {
285 format Branch {
286 0x0: bltzal({{ cond = (Rs_sw < 0); }}, Link);
287 0x1: decode RS {
288 0x0: bal ({{ cond = 1; }}, IsCall, Link);
289 default: bgezal({{ cond = (Rs_sw >= 0); }}, Link);
290 }
291 0x2: bltzall({{ cond = (Rs_sw < 0); }}, Link, Likely);
292 0x3: bgezall({{ cond = (Rs_sw >= 0); }}, Link, Likely);
293 }
294 }
295
296 0x3: decode REGIMM_LO {
297 // from Table 5-4 MIPS32 REGIMM Encoding of rt Field
298 // (DSP ASE MANUAL)
299 0x4: DspBranch::bposge32({{ cond = (dspctl<5:0> >= 32); }});
300 format WarnUnimpl {
301 0x7: synci();
302 }
303 }
304 }
305
306 format Jump {
307 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }});
308 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},
309 IsCall, Link);
310 }
311
312 format Branch {
313 0x4: decode RS_RT {
314 0x0: b({{ cond = 1; }});
315 default: beq({{ cond = (Rs_sw == Rt_sw); }});
316 }
317 0x5: bne({{ cond = (Rs_sw != Rt_sw); }});
318 0x6: blez({{ cond = (Rs_sw <= 0); }});
319 0x7: bgtz({{ cond = (Rs_sw > 0); }});
320 }
321 }
322
323 0x1: decode OPCODE_LO {
324 format IntImmOp {
325 0x0: addi({{
326 IntReg result;
327 Rt = result = Rs + imm;
328 if (FullSystem &&
329 findOverflow(32, result, Rs, imm)) {
330 fault = std::make_shared<IntegerOverflowFault>();
331 }
332 }});
333 0x1: addiu({{ Rt_sw = Rs_sw + imm; }});
334 0x2: slti({{ Rt_sw = (Rs_sw < imm) ? 1 : 0 }});
335 0x3: sltiu({{ Rt_uw = (Rs_uw < (uint32_t)sextImm) ? 1 : 0;}});
336 0x4: andi({{ Rt_sw = Rs_sw & zextImm; }});
337 0x5: ori({{ Rt_sw = Rs_sw | zextImm; }});
338 0x6: xori({{ Rt_sw = Rs_sw ^ zextImm; }});
339
340 0x7: decode RS {
341 0x0: lui({{ Rt = imm << 16; }});
342 }
343 }
344 }
345
346 0x2: decode OPCODE_LO {
347 //Table A-11 MIPS32 COP0 Encoding of rs Field
348 0x0: decode RS_MSB {
349 0x0: decode RS {
350 format CP0Control {
351 0x0: mfc0({{
352 Config3Reg config3 = Config3;
353 PageGrainReg pageGrain = PageGrain;
354 Rt = CP0_RD_SEL;
355 /* Hack for PageMask */
356 if (RD == 5) {
357 // PageMask
358 if (config3.sp == 0 || pageGrain.esp == 0)
359 Rt &= 0xFFFFE7FF;
360 }
361 }});
362 0x4: mtc0({{
363 CP0_RD_SEL = Rt;
364 CauseReg cause = Cause;
365 IntCtlReg intCtl = IntCtl;
366 if (RD == 11) {
367 // Compare
368 if (cause.ti == 1) {
369 cause.ti = 0;
370 int offset = 10; // corresponding to cause.ip0
371 offset += intCtl.ipti - 2;
372 replaceBits(cause, offset, offset, 0);
373 }
374 }
375 Cause = cause;
376 }});
377 }
378 format CP0Unimpl {
379 0x1: dmfc0();
380 0x5: dmtc0();
381 default: unknown();
382 }
383 format MT_MFTR {
384 // Decode MIPS MT MFTR instruction into sub-instructions
385 0x8: decode MT_U {
386 0x0: mftc0({{
387 data = xc->readRegOtherThread(RegId(MiscRegClass,
388 (RT << 3 | SEL)));
389 }});
390 0x1: decode SEL {
391 0x0: mftgpr({{
392 data = xc->readRegOtherThread(
393 RegId(IntRegClass, RT));
394 }});
395 0x1: decode RT {
396 0x0: mftlo_dsp0({{
397 data = xc->readRegOtherThread(
398 RegId(IntRegClass, INTREG_DSP_LO0));
399 }});
400 0x1: mfthi_dsp0({{
401 data = xc->readRegOtherThread(
402 RegId(IntRegClass, INTREG_DSP_HI0));
403 }});
404 0x2: mftacx_dsp0({{
405 data = xc->readRegOtherThread(
406 RegId(IntRegClass, INTREG_DSP_ACX0));
407 }});
408 0x4: mftlo_dsp1({{
409 data = xc->readRegOtherThread(
410 RegId(IntRegClass, INTREG_DSP_LO1));
411 }});
412 0x5: mfthi_dsp1({{
413 data = xc->readRegOtherThread(
414 RegId(IntRegClass, INTREG_DSP_HI1));
415 }});
416 0x6: mftacx_dsp1({{
417 data = xc->readRegOtherThread(
418 RegId(IntRegClass, INTREG_DSP_ACX1));
419 }});
420 0x8: mftlo_dsp2({{
421 data = xc->readRegOtherThread(
422 RegId(IntRegClass, INTREG_DSP_LO2));
423 }});
424 0x9: mfthi_dsp2({{
425 data = xc->readRegOtherThread(
426 RegId(IntRegClass, INTREG_DSP_HI2));
427 }});
428 0x10: mftacx_dsp2({{
429 data = xc->readRegOtherThread(
430 RegId(IntRegClass, INTREG_DSP_ACX2));
431 }});
432 0x12: mftlo_dsp3({{
433 data = xc->readRegOtherThread(
434 RegId(IntRegClass, INTREG_DSP_LO3));
435 }});
436 0x13: mfthi_dsp3({{
437 data = xc->readRegOtherThread(
438 RegId(IntRegClass, INTREG_DSP_HI3));
439 }});
440 0x14: mftacx_dsp3({{
441 data = xc->readRegOtherThread(
442 RegId(IntRegClass, INTREG_DSP_ACX3));
443 }});
444 0x16: mftdsp({{
445 data = xc->readRegOtherThread(
446 RegId(IntRegClass, INTREG_DSP_CONTROL));
447 }});
448 default: CP0Unimpl::unknown();
449 }
450 0x2: decode MT_H {
451 0x0: mftc1({{
452 data = xc->readRegOtherThread(
453 RegId(FloatRegClass, RT));
454 }});
455 0x1: mfthc1({{
456 data = xc->readRegOtherThread(
457 RegId(FloatRegClass, RT));
458 }});
459 }
460 0x3: cftc1({{
461 uint32_t fcsr_val = xc->readRegOtherThread(
462 RegId(FloatRegClass, FLOATREG_FCSR));
463 switch (RT) {
464 case 0:
465 data = xc->readRegOtherThread(
466 RegId(MiscRegClass, FLOATREG_FIR));
467 break;
468 case 25:
469 data = (fcsr_val & 0xFE000000 >> 24) |
470 (fcsr_val & 0x00800000 >> 23);
471 break;
472 case 26:
473 data = fcsr_val & 0x0003F07C;
474 break;
475 case 28:
476 data = (fcsr_val & 0x00000F80) |
477 (fcsr_val & 0x01000000 >> 21) |
478 (fcsr_val & 0x00000003);
479 break;
480 case 31:
481 data = fcsr_val;
482 break;
483 default:
484 fatal("FP Control Value (%d) Not Valid");
485 }
486 }});
487 default: CP0Unimpl::unknown();
488 }
489 }
490 }
491
492 format MT_MTTR {
493 // Decode MIPS MT MTTR instruction into sub-instructions
494 0xC: decode MT_U {
495 0x0: mttc0({{ xc->setRegOtherThread(
496 RegId(MiscRegClass, (RD << 3 | SEL)), Rt);
497 }});
498 0x1: decode SEL {
499 0x0: mttgpr({{ xc->setRegOtherThread(
500 RegId(IntRegClass, RD), Rt);
501 }});
502 0x1: decode RT {
503 0x0: mttlo_dsp0({{ xc->setRegOtherThread(
504 RegId(IntRegClass, INTREG_DSP_LO0), Rt);
505 }});
506 0x1: mtthi_dsp0({{ xc->setRegOtherThread(
507 RegId(IntRegClass, INTREG_DSP_HI0), Rt);
508 }});
509 0x2: mttacx_dsp0({{ xc->setRegOtherThread(
510 RegId(IntRegClass, INTREG_DSP_ACX0), Rt);
511 }});
512 0x4: mttlo_dsp1({{ xc->setRegOtherThread(
513 RegId(IntRegClass, INTREG_DSP_LO1), Rt);
514 }});
515 0x5: mtthi_dsp1({{ xc->setRegOtherThread(
516 RegId(IntRegClass, INTREG_DSP_HI1), Rt);
517 }});
518 0x6: mttacx_dsp1({{ xc->setRegOtherThread(
519 RegId(IntRegClass, INTREG_DSP_ACX1), Rt);
520 }});
521 0x8: mttlo_dsp2({{ xc->setRegOtherThread(
522 RegId(IntRegClass, INTREG_DSP_LO2), Rt);
523 }});
524 0x9: mtthi_dsp2({{ xc->setRegOtherThread(
525 RegId(IntRegClass, INTREG_DSP_HI2), Rt);
526 }});
527 0x10: mttacx_dsp2({{ xc->setRegOtherThread(
528 RegId(IntRegClass, INTREG_DSP_ACX2), Rt);
529 }});
530 0x12: mttlo_dsp3({{ xc->setRegOtherThread(
531 RegId(IntRegClass, INTREG_DSP_LO3), Rt);
532 }});
533 0x13: mtthi_dsp3({{ xc->setRegOtherThread(
534 RegId(IntRegClass, INTREG_DSP_HI3), Rt);
535 }});
536 0x14: mttacx_dsp3({{ xc->setRegOtherThread(
537 RegId(IntRegClass, INTREG_DSP_ACX3), Rt);
538 }});
539 0x16: mttdsp({{ xc->setRegOtherThread(
540 RegId(IntRegClass, INTREG_DSP_CONTROL), Rt);
541 }});
542 default: CP0Unimpl::unknown();
543
544 }
545 0x2: mttc1({{
546 uint64_t data = xc->readRegOtherThread(
547 RegId(FloatRegClass, RD));
548 data = insertBits(data, MT_H ? 63 : 31,
549 MT_H ? 32 : 0, Rt);
550 xc->setRegOtherThread(RegId(FloatRegClass, RD),
551 data);
552 }});
553 0x3: cttc1({{
554 uint32_t data;
555 switch (RD) {
556 case 25:
557 data = (Rt_uw<7:1> << 25) | // move 31-25
558 (FCSR & 0x01000000) | // bit 24
559 (FCSR & 0x004FFFFF); // bit 22-0
560 break;
561 case 26:
562 data = (FCSR & 0xFFFC0000) | // move 31-18
563 Rt_uw<17:12> << 12 | // bit 17-12
564 (FCSR & 0x00000F80) << 7 | // bit 11-7
565 Rt_uw<6:2> << 2 | // bit 6-2
566 (FCSR & 0x00000002); // bit 1...0
567 break;
568 case 28:
569 data = (FCSR & 0xFE000000) | // move 31-25
570 Rt_uw<2:2> << 24 | // bit 24
571 (FCSR & 0x00FFF000) << 23 | // bit 23-12
572 Rt_uw<11:7> << 7 | // bit 24
573 (FCSR & 0x000007E) |
574 Rt_uw<1:0>; // bit 22-0
575 break;
576 case 31:
577 data = Rt_uw;
578 break;
579 default:
580 panic("FP Control Value (%d) "
581 "Not Available. Ignoring "
582 "Access to Floating Control "
583 "S""tatus Register", FS);
584 }
585 xc->setRegOtherThread(
586 RegId(FloatRegClass, FLOATREG_FCSR), data);
587 }});
588 default: CP0Unimpl::unknown();
589 }
590 }
591 }
592 0xB: decode RD {
593 format MT_Control {
594 0x0: decode POS {
595 0x0: decode SEL {
596 0x1: decode SC {
597 0x0: dvpe({{
598 MVPControlReg mvpControl = MVPControl;
599 VPEConf0Reg vpeConf0 = VPEConf0;
600 Rt = MVPControl;
601 if (vpeConf0.mvp == 1)
602 mvpControl.evp = 0;
603 MVPControl = mvpControl;
604 }});
605 0x1: evpe({{
606 MVPControlReg mvpControl = MVPControl;
607 VPEConf0Reg vpeConf0 = VPEConf0;
608 Rt = MVPControl;
609 if (vpeConf0.mvp == 1)
610 mvpControl.evp = 1;
611 MVPControl = mvpControl;
612 }});
613 default:CP0Unimpl::unknown();
614 }
615 default:CP0Unimpl::unknown();
616 }
617 default:CP0Unimpl::unknown();
618 }
619 0x1: decode POS {
620 0xF: decode SEL {
621 0x1: decode SC {
622 0x0: dmt({{
623 VPEControlReg vpeControl = VPEControl;
624 Rt = vpeControl;
625 vpeControl.te = 0;
626 VPEControl = vpeControl;
627 }});
628 0x1: emt({{
629 VPEControlReg vpeControl = VPEControl;
630 Rt = vpeControl;
631 vpeControl.te = 1;
632 VPEControl = vpeControl;
633 }});
634 default:CP0Unimpl::unknown();
635 }
636 default:CP0Unimpl::unknown();
637 }
638 default:CP0Unimpl::unknown();
639 }
640 }
641 0xC: decode POS {
642 0x0: decode SC {
643 0x0: CP0Control::di({{
644 StatusReg status = Status;
645 ConfigReg config = Config;
646 // Rev 2.0 or beyond?
647 if (config.ar >= 1) {
648 Rt = status;
649 status.ie = 0;
650 } else {
651 // Enable this else branch once we
652 // actually set values for Config on init
653 fault = std::make_shared<ReservedInstructionFault>();
654 }
655 Status = status;
656 }});
657 0x1: CP0Control::ei({{
658 StatusReg status = Status;
659 ConfigReg config = Config;
660 if (config.ar >= 1) {
661 Rt = status;
662 status.ie = 1;
663 } else {
664 fault = std::make_shared<ReservedInstructionFault>();
665 }
666 }});
667 default:CP0Unimpl::unknown();
668 }
669 }
670 default: CP0Unimpl::unknown();
671 }
672 format CP0Control {
673 0xA: rdpgpr({{
674 ConfigReg config = Config;
675 if (config.ar >= 1) {
676 // Rev 2 of the architecture
677 panic("Shadow Sets Not Fully Implemented.\n");
678 } else {
679 fault = std::make_shared<ReservedInstructionFault>();
680 }
681 }});
682 0xE: wrpgpr({{
683 ConfigReg config = Config;
684 if (config.ar >= 1) {
685 // Rev 2 of the architecture
686 panic("Shadow Sets Not Fully Implemented.\n");
687 } else {
688 fault = std::make_shared<ReservedInstructionFault>();
689 }
690 }});
691 }
692 }
693
694 //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
695 0x1: decode FUNCTION {
696 format CP0Control {
697 0x18: eret({{
698 StatusReg status = Status;
699 ConfigReg config = Config;
700 SRSCtlReg srsCtl = SRSCtl;
701 DPRINTF(MipsPRA,"Restoring PC - %x\n",EPC);
702 if (status.erl == 1) {
703 status.erl = 0;
704 NPC = ErrorEPC;
705 // Need to adjust NNPC, otherwise things break
706 NNPC = ErrorEPC + sizeof(MachInst);
707 } else {
708 NPC = EPC;
709 // Need to adjust NNPC, otherwise things break
710 NNPC = EPC + sizeof(MachInst);
711 status.exl = 0;
712 if (config.ar >=1 &&
713 srsCtl.hss > 0 &&
714 status.bev == 0) {
715 srsCtl.css = srsCtl.pss;
716 //xc->setShadowSet(srsCtl.pss);
717 }
718 }
719 LLFlag = 0;
720 Status = status;
721 SRSCtl = srsCtl;
722 }}, IsReturn, IsSerializing, IsERET);
723
724 0x1F: deret({{
725 DebugReg debug = Debug;
726 if (debug.dm == 1) {
727 debug.dm = 1;
728 debug.iexi = 0;
729 NPC = DEPC;
730 } else {
731 NPC = NPC;
732 // Undefined;
733 }
734 Debug = debug;
735 }}, IsReturn, IsSerializing, IsERET);
736 }
737 format CP0TLB {
738 0x01: tlbr({{
739 MipsISA::PTE *PTEntry =
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007 MIPS Technologies, Inc.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Korey Sewell
30// Brett Miller
31// Jaidev Patwardhan
32
33////////////////////////////////////////////////////////////////////
34//
35// The actual MIPS32 ISA decoder
36// -----------------------------
37// The following instructions are specified in the MIPS32 ISA
38// Specification. Decoding closely follows the style specified
39// in the MIPS32 ISA specification document starting with Table
40// A-2 (document available @ http://www.mips.com)
41//
42decode OPCODE_HI default Unknown::unknown() {
43 //Table A-2
44 0x0: decode OPCODE_LO {
45 0x0: decode FUNCTION_HI {
46 0x0: decode FUNCTION_LO {
47 0x1: decode MOVCI {
48 format BasicOp {
49 0: movf({{
50 Rd = (getCondCode(FCSR, CC) == 0) ? Rd : Rs;
51 }});
52 1: movt({{
53 Rd = (getCondCode(FCSR, CC) == 1) ? Rd : Rs;
54 }});
55 }
56 }
57
58 format BasicOp {
59 //Table A-3 Note: "Specific encodings of the rd, rs, and
60 //rt fields are used to distinguish SLL, SSNOP, and EHB
61 //functions
62 0x0: decode RS {
63 0x0: decode RT_RD {
64 0x0: decode SA default Nop::nop() {
65 0x1: ssnop({{;}});
66 0x3: ehb({{;}});
67 }
68 default: sll({{ Rd = Rt_uw << SA; }});
69 }
70 }
71
72 0x2: decode RS_SRL {
73 0x0:decode SRL {
74 0: srl({{ Rd = Rt_uw >> SA; }});
75
76 //Hardcoded assuming 32-bit ISA,
77 //probably need parameter here
78 1: rotr({{
79 Rd = (Rt_uw << (32 - SA)) | (Rt_uw >> SA);
80 }});
81 }
82 }
83
84 0x3: decode RS {
85 0x0: sra({{
86 uint32_t temp = Rt >> SA;
87 if ( (Rt & 0x80000000) > 0 ) {
88 uint32_t mask = 0x80000000;
89 for(int i=0; i < SA; i++) {
90 temp |= mask;
91 mask = mask >> 1;
92 }
93 }
94 Rd = temp;
95 }});
96 }
97
98 0x4: sllv({{ Rd = Rt_uw << Rs<4:0>; }});
99
100 0x6: decode SRLV {
101 0: srlv({{ Rd = Rt_uw >> Rs<4:0>; }});
102
103 //Hardcoded assuming 32-bit ISA,
104 //probably need parameter here
105 1: rotrv({{
106 Rd = (Rt_uw << (32 - Rs<4:0>)) |
107 (Rt_uw >> Rs<4:0>);
108 }});
109 }
110
111 0x7: srav({{
112 int shift_amt = Rs<4:0>;
113
114 uint32_t temp = Rt >> shift_amt;
115
116 if ((Rt & 0x80000000) > 0) {
117 uint32_t mask = 0x80000000;
118 for (int i = 0; i < shift_amt; i++) {
119 temp |= mask;
120 mask = mask >> 1;
121 }
122 }
123 Rd = temp;
124 }});
125 }
126 }
127
128 0x1: decode FUNCTION_LO {
129 //Table A-3 Note: "Specific encodings of the hint field are
130 //used to distinguish JR from JR.HB and JALR from JALR.HB"
131 format Jump {
132 0x0: decode HINT {
133 0x1: jr_hb({{
134 Config1Reg config1 = Config1;
135 if (config1.ca == 0) {
136 NNPC = Rs;
137 } else {
138 panic("MIPS16e not supported\n");
139 }
140 }}, IsReturn, ClearHazards);
141 default: jr({{
142 Config1Reg config1 = Config1;
143 if (config1.ca == 0) {
144 NNPC = Rs;
145 } else {
146 panic("MIPS16e not supported\n");
147 }
148 }}, IsReturn);
149 }
150
151 0x1: decode HINT {
152 0x1: jalr_hb({{
153 Rd = NNPC;
154 NNPC = Rs;
155 }}, IsCall, ClearHazards);
156 default: jalr({{
157 Rd = NNPC;
158 NNPC = Rs;
159 }}, IsCall);
160 }
161 }
162
163 format BasicOp {
164 0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
165 0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
166 0x4: decode FullSystemInt {
167 0: syscall_se({{ xc->syscall(R2, &fault); }},
168 IsSerializeAfter, IsNonSpeculative);
169 default: syscall({{ fault = std::make_shared<SystemCallFault>(); }});
170 }
171 0x7: sync({{ ; }}, IsMemBarrier);
172 0x5: break({{fault = std::make_shared<BreakpointFault>();}});
173 }
174
175 }
176
177 0x2: decode FUNCTION_LO {
178 0x0: HiLoRsSelOp::mfhi({{ Rd = HI_RS_SEL; }},
179 IntMultOp, IsIprAccess);
180 0x1: HiLoRdSelOp::mthi({{ HI_RD_SEL = Rs; }});
181 0x2: HiLoRsSelOp::mflo({{ Rd = LO_RS_SEL; }},
182 IntMultOp, IsIprAccess);
183 0x3: HiLoRdSelOp::mtlo({{ LO_RD_SEL = Rs; }});
184 }
185
186 0x3: decode FUNCTION_LO {
187 format HiLoRdSelValOp {
188 0x0: mult({{ val = Rs_sd * Rt_sd; }}, IntMultOp);
189 0x1: multu({{ val = Rs_ud * Rt_ud; }}, IntMultOp);
190 }
191
192 format HiLoOp {
193 0x2: div({{
194 if (Rt_sd != 0) {
195 HI0 = Rs_sd % Rt_sd;
196 LO0 = Rs_sd / Rt_sd;
197 }
198 }}, IntDivOp);
199
200 0x3: divu({{
201 if (Rt_ud != 0) {
202 HI0 = Rs_ud % Rt_ud;
203 LO0 = Rs_ud / Rt_ud;
204 }
205 }}, IntDivOp);
206 }
207 }
208
209 0x4: decode HINT {
210 0x0: decode FUNCTION_LO {
211 format IntOp {
212 0x0: add({{
213 IntReg result;
214 Rd = result = Rs + Rt;
215 if (FullSystem &&
216 findOverflow(32, result, Rs, Rt)) {
217 fault = std::make_shared<IntegerOverflowFault>();
218 }
219 }});
220 0x1: addu({{ Rd_sw = Rs_sw + Rt_sw;}});
221 0x2: sub({{
222 IntReg result;
223 Rd = result = Rs - Rt;
224 if (FullSystem &&
225 findOverflow(32, result, Rs, ~Rt)) {
226 fault = std::make_shared<IntegerOverflowFault>();
227 }
228 }});
229 0x3: subu({{ Rd_sw = Rs_sw - Rt_sw; }});
230 0x4: and({{ Rd = Rs & Rt; }});
231 0x5: or({{ Rd = Rs | Rt; }});
232 0x6: xor({{ Rd = Rs ^ Rt; }});
233 0x7: nor({{ Rd = ~(Rs | Rt); }});
234 }
235 }
236 }
237
238 0x5: decode HINT {
239 0x0: decode FUNCTION_LO {
240 format IntOp{
241 0x2: slt({{ Rd_sw = (Rs_sw < Rt_sw) ? 1 : 0 }});
242 0x3: sltu({{ Rd_uw = (Rs_uw < Rt_uw) ? 1 : 0 }});
243 }
244 }
245 }
246
247 0x6: decode FUNCTION_LO {
248 format Trap {
249 0x0: tge({{ cond = (Rs_sw >= Rt_sw); }});
250 0x1: tgeu({{ cond = (Rs_uw >= Rt_uw); }});
251 0x2: tlt({{ cond = (Rs_sw < Rt_sw); }});
252 0x3: tltu({{ cond = (Rs_uw < Rt_uw); }});
253 0x4: teq({{ cond = (Rs_sw == Rt_sw); }});
254 0x6: tne({{ cond = (Rs_sw != Rt_sw); }});
255 }
256 }
257 }
258
259 0x1: decode REGIMM_HI {
260 0x0: decode REGIMM_LO {
261 format Branch {
262 0x0: bltz({{ cond = (Rs_sw < 0); }});
263 0x1: bgez({{ cond = (Rs_sw >= 0); }});
264 0x2: bltzl({{ cond = (Rs_sw < 0); }}, Likely);
265 0x3: bgezl({{ cond = (Rs_sw >= 0); }}, Likely);
266 }
267 }
268
269 0x1: decode REGIMM_LO {
270 format TrapImm {
271 0x0: tgei( {{ cond = (Rs_sw >= (int16_t)INTIMM); }});
272 0x1: tgeiu({{
273 cond = (Rs_uw >= (uint32_t)(int32_t)(int16_t)INTIMM);
274 }});
275 0x2: tlti( {{ cond = (Rs_sw < (int16_t)INTIMM); }});
276 0x3: tltiu({{
277 cond = (Rs_uw < (uint32_t)(int32_t)(int16_t)INTIMM);
278 }});
279 0x4: teqi( {{ cond = (Rs_sw == (int16_t)INTIMM); }});
280 0x6: tnei( {{ cond = (Rs_sw != (int16_t)INTIMM); }});
281 }
282 }
283
284 0x2: decode REGIMM_LO {
285 format Branch {
286 0x0: bltzal({{ cond = (Rs_sw < 0); }}, Link);
287 0x1: decode RS {
288 0x0: bal ({{ cond = 1; }}, IsCall, Link);
289 default: bgezal({{ cond = (Rs_sw >= 0); }}, Link);
290 }
291 0x2: bltzall({{ cond = (Rs_sw < 0); }}, Link, Likely);
292 0x3: bgezall({{ cond = (Rs_sw >= 0); }}, Link, Likely);
293 }
294 }
295
296 0x3: decode REGIMM_LO {
297 // from Table 5-4 MIPS32 REGIMM Encoding of rt Field
298 // (DSP ASE MANUAL)
299 0x4: DspBranch::bposge32({{ cond = (dspctl<5:0> >= 32); }});
300 format WarnUnimpl {
301 0x7: synci();
302 }
303 }
304 }
305
306 format Jump {
307 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }});
308 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},
309 IsCall, Link);
310 }
311
312 format Branch {
313 0x4: decode RS_RT {
314 0x0: b({{ cond = 1; }});
315 default: beq({{ cond = (Rs_sw == Rt_sw); }});
316 }
317 0x5: bne({{ cond = (Rs_sw != Rt_sw); }});
318 0x6: blez({{ cond = (Rs_sw <= 0); }});
319 0x7: bgtz({{ cond = (Rs_sw > 0); }});
320 }
321 }
322
323 0x1: decode OPCODE_LO {
324 format IntImmOp {
325 0x0: addi({{
326 IntReg result;
327 Rt = result = Rs + imm;
328 if (FullSystem &&
329 findOverflow(32, result, Rs, imm)) {
330 fault = std::make_shared<IntegerOverflowFault>();
331 }
332 }});
333 0x1: addiu({{ Rt_sw = Rs_sw + imm; }});
334 0x2: slti({{ Rt_sw = (Rs_sw < imm) ? 1 : 0 }});
335 0x3: sltiu({{ Rt_uw = (Rs_uw < (uint32_t)sextImm) ? 1 : 0;}});
336 0x4: andi({{ Rt_sw = Rs_sw & zextImm; }});
337 0x5: ori({{ Rt_sw = Rs_sw | zextImm; }});
338 0x6: xori({{ Rt_sw = Rs_sw ^ zextImm; }});
339
340 0x7: decode RS {
341 0x0: lui({{ Rt = imm << 16; }});
342 }
343 }
344 }
345
346 0x2: decode OPCODE_LO {
347 //Table A-11 MIPS32 COP0 Encoding of rs Field
348 0x0: decode RS_MSB {
349 0x0: decode RS {
350 format CP0Control {
351 0x0: mfc0({{
352 Config3Reg config3 = Config3;
353 PageGrainReg pageGrain = PageGrain;
354 Rt = CP0_RD_SEL;
355 /* Hack for PageMask */
356 if (RD == 5) {
357 // PageMask
358 if (config3.sp == 0 || pageGrain.esp == 0)
359 Rt &= 0xFFFFE7FF;
360 }
361 }});
362 0x4: mtc0({{
363 CP0_RD_SEL = Rt;
364 CauseReg cause = Cause;
365 IntCtlReg intCtl = IntCtl;
366 if (RD == 11) {
367 // Compare
368 if (cause.ti == 1) {
369 cause.ti = 0;
370 int offset = 10; // corresponding to cause.ip0
371 offset += intCtl.ipti - 2;
372 replaceBits(cause, offset, offset, 0);
373 }
374 }
375 Cause = cause;
376 }});
377 }
378 format CP0Unimpl {
379 0x1: dmfc0();
380 0x5: dmtc0();
381 default: unknown();
382 }
383 format MT_MFTR {
384 // Decode MIPS MT MFTR instruction into sub-instructions
385 0x8: decode MT_U {
386 0x0: mftc0({{
387 data = xc->readRegOtherThread(RegId(MiscRegClass,
388 (RT << 3 | SEL)));
389 }});
390 0x1: decode SEL {
391 0x0: mftgpr({{
392 data = xc->readRegOtherThread(
393 RegId(IntRegClass, RT));
394 }});
395 0x1: decode RT {
396 0x0: mftlo_dsp0({{
397 data = xc->readRegOtherThread(
398 RegId(IntRegClass, INTREG_DSP_LO0));
399 }});
400 0x1: mfthi_dsp0({{
401 data = xc->readRegOtherThread(
402 RegId(IntRegClass, INTREG_DSP_HI0));
403 }});
404 0x2: mftacx_dsp0({{
405 data = xc->readRegOtherThread(
406 RegId(IntRegClass, INTREG_DSP_ACX0));
407 }});
408 0x4: mftlo_dsp1({{
409 data = xc->readRegOtherThread(
410 RegId(IntRegClass, INTREG_DSP_LO1));
411 }});
412 0x5: mfthi_dsp1({{
413 data = xc->readRegOtherThread(
414 RegId(IntRegClass, INTREG_DSP_HI1));
415 }});
416 0x6: mftacx_dsp1({{
417 data = xc->readRegOtherThread(
418 RegId(IntRegClass, INTREG_DSP_ACX1));
419 }});
420 0x8: mftlo_dsp2({{
421 data = xc->readRegOtherThread(
422 RegId(IntRegClass, INTREG_DSP_LO2));
423 }});
424 0x9: mfthi_dsp2({{
425 data = xc->readRegOtherThread(
426 RegId(IntRegClass, INTREG_DSP_HI2));
427 }});
428 0x10: mftacx_dsp2({{
429 data = xc->readRegOtherThread(
430 RegId(IntRegClass, INTREG_DSP_ACX2));
431 }});
432 0x12: mftlo_dsp3({{
433 data = xc->readRegOtherThread(
434 RegId(IntRegClass, INTREG_DSP_LO3));
435 }});
436 0x13: mfthi_dsp3({{
437 data = xc->readRegOtherThread(
438 RegId(IntRegClass, INTREG_DSP_HI3));
439 }});
440 0x14: mftacx_dsp3({{
441 data = xc->readRegOtherThread(
442 RegId(IntRegClass, INTREG_DSP_ACX3));
443 }});
444 0x16: mftdsp({{
445 data = xc->readRegOtherThread(
446 RegId(IntRegClass, INTREG_DSP_CONTROL));
447 }});
448 default: CP0Unimpl::unknown();
449 }
450 0x2: decode MT_H {
451 0x0: mftc1({{
452 data = xc->readRegOtherThread(
453 RegId(FloatRegClass, RT));
454 }});
455 0x1: mfthc1({{
456 data = xc->readRegOtherThread(
457 RegId(FloatRegClass, RT));
458 }});
459 }
460 0x3: cftc1({{
461 uint32_t fcsr_val = xc->readRegOtherThread(
462 RegId(FloatRegClass, FLOATREG_FCSR));
463 switch (RT) {
464 case 0:
465 data = xc->readRegOtherThread(
466 RegId(MiscRegClass, FLOATREG_FIR));
467 break;
468 case 25:
469 data = (fcsr_val & 0xFE000000 >> 24) |
470 (fcsr_val & 0x00800000 >> 23);
471 break;
472 case 26:
473 data = fcsr_val & 0x0003F07C;
474 break;
475 case 28:
476 data = (fcsr_val & 0x00000F80) |
477 (fcsr_val & 0x01000000 >> 21) |
478 (fcsr_val & 0x00000003);
479 break;
480 case 31:
481 data = fcsr_val;
482 break;
483 default:
484 fatal("FP Control Value (%d) Not Valid");
485 }
486 }});
487 default: CP0Unimpl::unknown();
488 }
489 }
490 }
491
492 format MT_MTTR {
493 // Decode MIPS MT MTTR instruction into sub-instructions
494 0xC: decode MT_U {
495 0x0: mttc0({{ xc->setRegOtherThread(
496 RegId(MiscRegClass, (RD << 3 | SEL)), Rt);
497 }});
498 0x1: decode SEL {
499 0x0: mttgpr({{ xc->setRegOtherThread(
500 RegId(IntRegClass, RD), Rt);
501 }});
502 0x1: decode RT {
503 0x0: mttlo_dsp0({{ xc->setRegOtherThread(
504 RegId(IntRegClass, INTREG_DSP_LO0), Rt);
505 }});
506 0x1: mtthi_dsp0({{ xc->setRegOtherThread(
507 RegId(IntRegClass, INTREG_DSP_HI0), Rt);
508 }});
509 0x2: mttacx_dsp0({{ xc->setRegOtherThread(
510 RegId(IntRegClass, INTREG_DSP_ACX0), Rt);
511 }});
512 0x4: mttlo_dsp1({{ xc->setRegOtherThread(
513 RegId(IntRegClass, INTREG_DSP_LO1), Rt);
514 }});
515 0x5: mtthi_dsp1({{ xc->setRegOtherThread(
516 RegId(IntRegClass, INTREG_DSP_HI1), Rt);
517 }});
518 0x6: mttacx_dsp1({{ xc->setRegOtherThread(
519 RegId(IntRegClass, INTREG_DSP_ACX1), Rt);
520 }});
521 0x8: mttlo_dsp2({{ xc->setRegOtherThread(
522 RegId(IntRegClass, INTREG_DSP_LO2), Rt);
523 }});
524 0x9: mtthi_dsp2({{ xc->setRegOtherThread(
525 RegId(IntRegClass, INTREG_DSP_HI2), Rt);
526 }});
527 0x10: mttacx_dsp2({{ xc->setRegOtherThread(
528 RegId(IntRegClass, INTREG_DSP_ACX2), Rt);
529 }});
530 0x12: mttlo_dsp3({{ xc->setRegOtherThread(
531 RegId(IntRegClass, INTREG_DSP_LO3), Rt);
532 }});
533 0x13: mtthi_dsp3({{ xc->setRegOtherThread(
534 RegId(IntRegClass, INTREG_DSP_HI3), Rt);
535 }});
536 0x14: mttacx_dsp3({{ xc->setRegOtherThread(
537 RegId(IntRegClass, INTREG_DSP_ACX3), Rt);
538 }});
539 0x16: mttdsp({{ xc->setRegOtherThread(
540 RegId(IntRegClass, INTREG_DSP_CONTROL), Rt);
541 }});
542 default: CP0Unimpl::unknown();
543
544 }
545 0x2: mttc1({{
546 uint64_t data = xc->readRegOtherThread(
547 RegId(FloatRegClass, RD));
548 data = insertBits(data, MT_H ? 63 : 31,
549 MT_H ? 32 : 0, Rt);
550 xc->setRegOtherThread(RegId(FloatRegClass, RD),
551 data);
552 }});
553 0x3: cttc1({{
554 uint32_t data;
555 switch (RD) {
556 case 25:
557 data = (Rt_uw<7:1> << 25) | // move 31-25
558 (FCSR & 0x01000000) | // bit 24
559 (FCSR & 0x004FFFFF); // bit 22-0
560 break;
561 case 26:
562 data = (FCSR & 0xFFFC0000) | // move 31-18
563 Rt_uw<17:12> << 12 | // bit 17-12
564 (FCSR & 0x00000F80) << 7 | // bit 11-7
565 Rt_uw<6:2> << 2 | // bit 6-2
566 (FCSR & 0x00000002); // bit 1...0
567 break;
568 case 28:
569 data = (FCSR & 0xFE000000) | // move 31-25
570 Rt_uw<2:2> << 24 | // bit 24
571 (FCSR & 0x00FFF000) << 23 | // bit 23-12
572 Rt_uw<11:7> << 7 | // bit 24
573 (FCSR & 0x000007E) |
574 Rt_uw<1:0>; // bit 22-0
575 break;
576 case 31:
577 data = Rt_uw;
578 break;
579 default:
580 panic("FP Control Value (%d) "
581 "Not Available. Ignoring "
582 "Access to Floating Control "
583 "S""tatus Register", FS);
584 }
585 xc->setRegOtherThread(
586 RegId(FloatRegClass, FLOATREG_FCSR), data);
587 }});
588 default: CP0Unimpl::unknown();
589 }
590 }
591 }
592 0xB: decode RD {
593 format MT_Control {
594 0x0: decode POS {
595 0x0: decode SEL {
596 0x1: decode SC {
597 0x0: dvpe({{
598 MVPControlReg mvpControl = MVPControl;
599 VPEConf0Reg vpeConf0 = VPEConf0;
600 Rt = MVPControl;
601 if (vpeConf0.mvp == 1)
602 mvpControl.evp = 0;
603 MVPControl = mvpControl;
604 }});
605 0x1: evpe({{
606 MVPControlReg mvpControl = MVPControl;
607 VPEConf0Reg vpeConf0 = VPEConf0;
608 Rt = MVPControl;
609 if (vpeConf0.mvp == 1)
610 mvpControl.evp = 1;
611 MVPControl = mvpControl;
612 }});
613 default:CP0Unimpl::unknown();
614 }
615 default:CP0Unimpl::unknown();
616 }
617 default:CP0Unimpl::unknown();
618 }
619 0x1: decode POS {
620 0xF: decode SEL {
621 0x1: decode SC {
622 0x0: dmt({{
623 VPEControlReg vpeControl = VPEControl;
624 Rt = vpeControl;
625 vpeControl.te = 0;
626 VPEControl = vpeControl;
627 }});
628 0x1: emt({{
629 VPEControlReg vpeControl = VPEControl;
630 Rt = vpeControl;
631 vpeControl.te = 1;
632 VPEControl = vpeControl;
633 }});
634 default:CP0Unimpl::unknown();
635 }
636 default:CP0Unimpl::unknown();
637 }
638 default:CP0Unimpl::unknown();
639 }
640 }
641 0xC: decode POS {
642 0x0: decode SC {
643 0x0: CP0Control::di({{
644 StatusReg status = Status;
645 ConfigReg config = Config;
646 // Rev 2.0 or beyond?
647 if (config.ar >= 1) {
648 Rt = status;
649 status.ie = 0;
650 } else {
651 // Enable this else branch once we
652 // actually set values for Config on init
653 fault = std::make_shared<ReservedInstructionFault>();
654 }
655 Status = status;
656 }});
657 0x1: CP0Control::ei({{
658 StatusReg status = Status;
659 ConfigReg config = Config;
660 if (config.ar >= 1) {
661 Rt = status;
662 status.ie = 1;
663 } else {
664 fault = std::make_shared<ReservedInstructionFault>();
665 }
666 }});
667 default:CP0Unimpl::unknown();
668 }
669 }
670 default: CP0Unimpl::unknown();
671 }
672 format CP0Control {
673 0xA: rdpgpr({{
674 ConfigReg config = Config;
675 if (config.ar >= 1) {
676 // Rev 2 of the architecture
677 panic("Shadow Sets Not Fully Implemented.\n");
678 } else {
679 fault = std::make_shared<ReservedInstructionFault>();
680 }
681 }});
682 0xE: wrpgpr({{
683 ConfigReg config = Config;
684 if (config.ar >= 1) {
685 // Rev 2 of the architecture
686 panic("Shadow Sets Not Fully Implemented.\n");
687 } else {
688 fault = std::make_shared<ReservedInstructionFault>();
689 }
690 }});
691 }
692 }
693
694 //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
695 0x1: decode FUNCTION {
696 format CP0Control {
697 0x18: eret({{
698 StatusReg status = Status;
699 ConfigReg config = Config;
700 SRSCtlReg srsCtl = SRSCtl;
701 DPRINTF(MipsPRA,"Restoring PC - %x\n",EPC);
702 if (status.erl == 1) {
703 status.erl = 0;
704 NPC = ErrorEPC;
705 // Need to adjust NNPC, otherwise things break
706 NNPC = ErrorEPC + sizeof(MachInst);
707 } else {
708 NPC = EPC;
709 // Need to adjust NNPC, otherwise things break
710 NNPC = EPC + sizeof(MachInst);
711 status.exl = 0;
712 if (config.ar >=1 &&
713 srsCtl.hss > 0 &&
714 status.bev == 0) {
715 srsCtl.css = srsCtl.pss;
716 //xc->setShadowSet(srsCtl.pss);
717 }
718 }
719 LLFlag = 0;
720 Status = status;
721 SRSCtl = srsCtl;
722 }}, IsReturn, IsSerializing, IsERET);
723
724 0x1F: deret({{
725 DebugReg debug = Debug;
726 if (debug.dm == 1) {
727 debug.dm = 1;
728 debug.iexi = 0;
729 NPC = DEPC;
730 } else {
731 NPC = NPC;
732 // Undefined;
733 }
734 Debug = debug;
735 }}, IsReturn, IsSerializing, IsERET);
736 }
737 format CP0TLB {
738 0x01: tlbr({{
739 MipsISA::PTE *PTEntry =
740 xc->tcBase()->getITBPtr()->
740 dynamic_cast<MipsISA::TLB *>(
741 xc->tcBase()->getITBPtr())->
741 getEntry(Index & 0x7FFFFFFF);
742 if (PTEntry == NULL) {
743 fatal("Invalid PTE Entry received on "
744 "a TLBR instruction\n");
745 }
746 /* Setup PageMask */
747 // If 1KB pages are not enabled, a read of PageMask
748 // must return 0b00 in bits 12, 11
749 PageMask = (PTEntry->Mask << 11);
750 /* Setup EntryHi */
751 EntryHi = ((PTEntry->VPN << 11) | (PTEntry->asid));
752 /* Setup Entry Lo0 */
753 EntryLo0 = ((PTEntry->PFN0 << 6) |
754 (PTEntry->C0 << 3) |
755 (PTEntry->D0 << 2) |
756 (PTEntry->V0 << 1) |
757 PTEntry->G);
758 /* Setup Entry Lo1 */
759 EntryLo1 = ((PTEntry->PFN1 << 6) |
760 (PTEntry->C1 << 3) |
761 (PTEntry->D1 << 2) |
762 (PTEntry->V1 << 1) |
763 PTEntry->G);
764 }}); // Need to hook up to TLB
765
766 0x02: tlbwi({{
767 //Create PTE
768 MipsISA::PTE newEntry;
769 //Write PTE
770 newEntry.Mask = (Addr)(PageMask >> 11);
771 newEntry.VPN = (Addr)(EntryHi >> 11);
772 /* PageGrain _ ESP Config3 _ SP */
773 if (bits(PageGrain, 28) == 0 || bits(Config3, 4) ==0) {
774 // If 1KB pages are *NOT* enabled, lowest bits of
775 // the mask are 0b11 for TLB writes
776 newEntry.Mask |= 0x3;
777 // Reset bits 0 and 1 if 1KB pages are not enabled
778 newEntry.VPN &= 0xFFFFFFFC;
779 }
780 newEntry.asid = (uint8_t)(EntryHi & 0xFF);
781
782 newEntry.PFN0 = (Addr)(EntryLo0 >> 6);
783 newEntry.PFN1 = (Addr)(EntryLo1 >> 6);
784 newEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
785 newEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
786 newEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
787 newEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
788 newEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
789 newEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
790 newEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
791 /* Now, compute the AddrShiftAmount and OffsetMask -
792 TLB optimizations */
793 /* Addr Shift Amount for 1KB or larger pages */
794 if ((newEntry.Mask & 0xFFFF) == 3) {
795 newEntry.AddrShiftAmount = 12;
796 } else if ((newEntry.Mask & 0xFFFF) == 0x0000) {
797 newEntry.AddrShiftAmount = 10;
798 } else if ((newEntry.Mask & 0xFFFC) == 0x000C) {
799 newEntry.AddrShiftAmount = 14;
800 } else if ((newEntry.Mask & 0xFFF0) == 0x0030) {
801 newEntry.AddrShiftAmount = 16;
802 } else if ((newEntry.Mask & 0xFFC0) == 0x00C0) {
803 newEntry.AddrShiftAmount = 18;
804 } else if ((newEntry.Mask & 0xFF00) == 0x0300) {
805 newEntry.AddrShiftAmount = 20;
806 } else if ((newEntry.Mask & 0xFC00) == 0x0C00) {
807 newEntry.AddrShiftAmount = 22;
808 } else if ((newEntry.Mask & 0xF000) == 0x3000) {
809 newEntry.AddrShiftAmount = 24;
810 } else if ((newEntry.Mask & 0xC000) == 0xC000) {
811 newEntry.AddrShiftAmount = 26;
812 } else if ((newEntry.Mask & 0x30000) == 0x30000) {
813 newEntry.AddrShiftAmount = 28;
814 } else {
815 fatal("Invalid Mask Pattern Detected!\n");
816 }
817 newEntry.OffsetMask =
818 (1 << newEntry.AddrShiftAmount) - 1;
819
742 getEntry(Index & 0x7FFFFFFF);
743 if (PTEntry == NULL) {
744 fatal("Invalid PTE Entry received on "
745 "a TLBR instruction\n");
746 }
747 /* Setup PageMask */
748 // If 1KB pages are not enabled, a read of PageMask
749 // must return 0b00 in bits 12, 11
750 PageMask = (PTEntry->Mask << 11);
751 /* Setup EntryHi */
752 EntryHi = ((PTEntry->VPN << 11) | (PTEntry->asid));
753 /* Setup Entry Lo0 */
754 EntryLo0 = ((PTEntry->PFN0 << 6) |
755 (PTEntry->C0 << 3) |
756 (PTEntry->D0 << 2) |
757 (PTEntry->V0 << 1) |
758 PTEntry->G);
759 /* Setup Entry Lo1 */
760 EntryLo1 = ((PTEntry->PFN1 << 6) |
761 (PTEntry->C1 << 3) |
762 (PTEntry->D1 << 2) |
763 (PTEntry->V1 << 1) |
764 PTEntry->G);
765 }}); // Need to hook up to TLB
766
767 0x02: tlbwi({{
768 //Create PTE
769 MipsISA::PTE newEntry;
770 //Write PTE
771 newEntry.Mask = (Addr)(PageMask >> 11);
772 newEntry.VPN = (Addr)(EntryHi >> 11);
773 /* PageGrain _ ESP Config3 _ SP */
774 if (bits(PageGrain, 28) == 0 || bits(Config3, 4) ==0) {
775 // If 1KB pages are *NOT* enabled, lowest bits of
776 // the mask are 0b11 for TLB writes
777 newEntry.Mask |= 0x3;
778 // Reset bits 0 and 1 if 1KB pages are not enabled
779 newEntry.VPN &= 0xFFFFFFFC;
780 }
781 newEntry.asid = (uint8_t)(EntryHi & 0xFF);
782
783 newEntry.PFN0 = (Addr)(EntryLo0 >> 6);
784 newEntry.PFN1 = (Addr)(EntryLo1 >> 6);
785 newEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
786 newEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
787 newEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
788 newEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
789 newEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
790 newEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
791 newEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
792 /* Now, compute the AddrShiftAmount and OffsetMask -
793 TLB optimizations */
794 /* Addr Shift Amount for 1KB or larger pages */
795 if ((newEntry.Mask & 0xFFFF) == 3) {
796 newEntry.AddrShiftAmount = 12;
797 } else if ((newEntry.Mask & 0xFFFF) == 0x0000) {
798 newEntry.AddrShiftAmount = 10;
799 } else if ((newEntry.Mask & 0xFFFC) == 0x000C) {
800 newEntry.AddrShiftAmount = 14;
801 } else if ((newEntry.Mask & 0xFFF0) == 0x0030) {
802 newEntry.AddrShiftAmount = 16;
803 } else if ((newEntry.Mask & 0xFFC0) == 0x00C0) {
804 newEntry.AddrShiftAmount = 18;
805 } else if ((newEntry.Mask & 0xFF00) == 0x0300) {
806 newEntry.AddrShiftAmount = 20;
807 } else if ((newEntry.Mask & 0xFC00) == 0x0C00) {
808 newEntry.AddrShiftAmount = 22;
809 } else if ((newEntry.Mask & 0xF000) == 0x3000) {
810 newEntry.AddrShiftAmount = 24;
811 } else if ((newEntry.Mask & 0xC000) == 0xC000) {
812 newEntry.AddrShiftAmount = 26;
813 } else if ((newEntry.Mask & 0x30000) == 0x30000) {
814 newEntry.AddrShiftAmount = 28;
815 } else {
816 fatal("Invalid Mask Pattern Detected!\n");
817 }
818 newEntry.OffsetMask =
819 (1 << newEntry.AddrShiftAmount) - 1;
820
820 MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
821 auto ptr = dynamic_cast<MipsISA::TLB *>(
822 xc->tcBase()->getITBPtr());
821 Config3Reg config3 = Config3;
822 PageGrainReg pageGrain = PageGrain;
823 int SP = 0;
824 if (bits(config3, config3.sp) == 1 &&
825 bits(pageGrain, pageGrain.esp) == 1) {
826 SP = 1;
827 }
823 Config3Reg config3 = Config3;
824 PageGrainReg pageGrain = PageGrain;
825 int SP = 0;
826 if (bits(config3, config3.sp) == 1 &&
827 bits(pageGrain, pageGrain.esp) == 1) {
828 SP = 1;
829 }
828 Ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP);
830 ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP);
829 }});
830 0x06: tlbwr({{
831 //Create PTE
832 MipsISA::PTE newEntry;
833 //Write PTE
834 newEntry.Mask = (Addr)(PageMask >> 11);
835 newEntry.VPN = (Addr)(EntryHi >> 11);
836 /* PageGrain _ ESP Config3 _ SP */
837 if (bits(PageGrain, 28) == 0 ||
838 bits(Config3, 4) == 0) {
839 // If 1KB pages are *NOT* enabled, lowest bits of
840 // the mask are 0b11 for TLB writes
841 newEntry.Mask |= 0x3;
842 // Reset bits 0 and 1 if 1KB pages are not enabled
843 newEntry.VPN &= 0xFFFFFFFC;
844 }
845 newEntry.asid = (uint8_t)(EntryHi & 0xFF);
846
847 newEntry.PFN0 = (Addr)(EntryLo0 >> 6);
848 newEntry.PFN1 = (Addr)(EntryLo1 >> 6);
849 newEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
850 newEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
851 newEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
852 newEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
853 newEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
854 newEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
855 newEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
856 /* Now, compute the AddrShiftAmount and OffsetMask -
857 TLB optimizations */
858 /* Addr Shift Amount for 1KB or larger pages */
859 if ((newEntry.Mask & 0xFFFF) == 3){
860 newEntry.AddrShiftAmount = 12;
861 } else if ((newEntry.Mask & 0xFFFF) == 0x0000) {
862 newEntry.AddrShiftAmount = 10;
863 } else if ((newEntry.Mask & 0xFFFC) == 0x000C) {
864 newEntry.AddrShiftAmount = 14;
865 } else if ((newEntry.Mask & 0xFFF0) == 0x0030) {
866 newEntry.AddrShiftAmount = 16;
867 } else if ((newEntry.Mask & 0xFFC0) == 0x00C0) {
868 newEntry.AddrShiftAmount = 18;
869 } else if ((newEntry.Mask & 0xFF00) == 0x0300) {
870 newEntry.AddrShiftAmount = 20;
871 } else if ((newEntry.Mask & 0xFC00) == 0x0C00) {
872 newEntry.AddrShiftAmount = 22;
873 } else if ((newEntry.Mask & 0xF000) == 0x3000) {
874 newEntry.AddrShiftAmount = 24;
875 } else if ((newEntry.Mask & 0xC000) == 0xC000) {
876 newEntry.AddrShiftAmount = 26;
877 } else if ((newEntry.Mask & 0x30000) == 0x30000) {
878 newEntry.AddrShiftAmount = 28;
879 } else {
880 fatal("Invalid Mask Pattern Detected!\n");
881 }
882 newEntry.OffsetMask =
883 (1 << newEntry.AddrShiftAmount) - 1;
884
831 }});
832 0x06: tlbwr({{
833 //Create PTE
834 MipsISA::PTE newEntry;
835 //Write PTE
836 newEntry.Mask = (Addr)(PageMask >> 11);
837 newEntry.VPN = (Addr)(EntryHi >> 11);
838 /* PageGrain _ ESP Config3 _ SP */
839 if (bits(PageGrain, 28) == 0 ||
840 bits(Config3, 4) == 0) {
841 // If 1KB pages are *NOT* enabled, lowest bits of
842 // the mask are 0b11 for TLB writes
843 newEntry.Mask |= 0x3;
844 // Reset bits 0 and 1 if 1KB pages are not enabled
845 newEntry.VPN &= 0xFFFFFFFC;
846 }
847 newEntry.asid = (uint8_t)(EntryHi & 0xFF);
848
849 newEntry.PFN0 = (Addr)(EntryLo0 >> 6);
850 newEntry.PFN1 = (Addr)(EntryLo1 >> 6);
851 newEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
852 newEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
853 newEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
854 newEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
855 newEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
856 newEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
857 newEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
858 /* Now, compute the AddrShiftAmount and OffsetMask -
859 TLB optimizations */
860 /* Addr Shift Amount for 1KB or larger pages */
861 if ((newEntry.Mask & 0xFFFF) == 3){
862 newEntry.AddrShiftAmount = 12;
863 } else if ((newEntry.Mask & 0xFFFF) == 0x0000) {
864 newEntry.AddrShiftAmount = 10;
865 } else if ((newEntry.Mask & 0xFFFC) == 0x000C) {
866 newEntry.AddrShiftAmount = 14;
867 } else if ((newEntry.Mask & 0xFFF0) == 0x0030) {
868 newEntry.AddrShiftAmount = 16;
869 } else if ((newEntry.Mask & 0xFFC0) == 0x00C0) {
870 newEntry.AddrShiftAmount = 18;
871 } else if ((newEntry.Mask & 0xFF00) == 0x0300) {
872 newEntry.AddrShiftAmount = 20;
873 } else if ((newEntry.Mask & 0xFC00) == 0x0C00) {
874 newEntry.AddrShiftAmount = 22;
875 } else if ((newEntry.Mask & 0xF000) == 0x3000) {
876 newEntry.AddrShiftAmount = 24;
877 } else if ((newEntry.Mask & 0xC000) == 0xC000) {
878 newEntry.AddrShiftAmount = 26;
879 } else if ((newEntry.Mask & 0x30000) == 0x30000) {
880 newEntry.AddrShiftAmount = 28;
881 } else {
882 fatal("Invalid Mask Pattern Detected!\n");
883 }
884 newEntry.OffsetMask =
885 (1 << newEntry.AddrShiftAmount) - 1;
886
885 MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
887 auto ptr = dynamic_cast<MipsISA::TLB *>(
888 xc->tcBase()->getITBPtr());
886 Config3Reg config3 = Config3;
887 PageGrainReg pageGrain = PageGrain;
888 int SP = 0;
889 if (bits(config3, config3.sp) == 1 &&
890 bits(pageGrain, pageGrain.esp) == 1) {
891 SP = 1;
892 }
889 Config3Reg config3 = Config3;
890 PageGrainReg pageGrain = PageGrain;
891 int SP = 0;
892 if (bits(config3, config3.sp) == 1 &&
893 bits(pageGrain, pageGrain.esp) == 1) {
894 SP = 1;
895 }
893 Ptr->insertAt(newEntry, Random, SP);
896 ptr->insertAt(newEntry, Random, SP);
894 }});
895
896 0x08: tlbp({{
897 Config3Reg config3 = Config3;
898 PageGrainReg pageGrain = PageGrain;
899 EntryHiReg entryHi = EntryHi;
900 int tlbIndex;
901 Addr vpn;
902 if (pageGrain.esp == 1 && config3.sp ==1) {
903 vpn = EntryHi >> 11;
904 } else {
905 // Mask off lower 2 bits
906 vpn = ((EntryHi >> 11) & 0xFFFFFFFC);
907 }
897 }});
898
899 0x08: tlbp({{
900 Config3Reg config3 = Config3;
901 PageGrainReg pageGrain = PageGrain;
902 EntryHiReg entryHi = EntryHi;
903 int tlbIndex;
904 Addr vpn;
905 if (pageGrain.esp == 1 && config3.sp ==1) {
906 vpn = EntryHi >> 11;
907 } else {
908 // Mask off lower 2 bits
909 vpn = ((EntryHi >> 11) & 0xFFFFFFFC);
910 }
908 tlbIndex = xc->tcBase()->getITBPtr()->
909 probeEntry(vpn, entryHi.asid);
911 tlbIndex = dynamic_cast<MipsISA::TLB *>(
912 xc->tcBase()->getITBPtr())->
913 probeEntry(vpn, entryHi.asid);
910 // Check TLB for entry matching EntryHi
911 if (tlbIndex != -1) {
912 Index = tlbIndex;
913 } else {
914 // else, set Index = 1 << 31
915 Index = (1 << 31);
916 }
917 }});
918 }
919 format CP0Unimpl {
920 0x20: wait();
921 }
922 default: CP0Unimpl::unknown();
923 }
924 }
925
926 //Table A-13 MIPS32 COP1 Encoding of rs Field
927 0x1: decode RS_MSB {
928 0x0: decode RS_HI {
929 0x0: decode RS_LO {
930 format CP1Control {
931 0x0: mfc1 ({{ Rt_uw = Fs_uw; }});
932
933 0x2: cfc1({{
934 switch (FS) {
935 case 0:
936 Rt = FIR;
937 break;
938 case 25:
939 Rt = (FCSR & 0xFE000000) >> 24 |
940 (FCSR & 0x00800000) >> 23;
941 break;
942 case 26:
943 Rt = (FCSR & 0x0003F07C);
944 break;
945 case 28:
946 Rt = (FCSR & 0x00000F80) |
947 (FCSR & 0x01000000) >> 21 |
948 (FCSR & 0x00000003);
949 break;
950 case 31:
951 Rt = FCSR;
952 break;
953 default:
954 warn("FP Control Value (%d) Not Valid");
955 }
956 }});
957
958 0x3: mfhc1({{ Rt_uw = Fs_ud<63:32>; }});
959
960 0x4: mtc1({{ Fs_uw = Rt_uw; }});
961
962 0x6: ctc1({{
963 switch (FS) {
964 case 25:
965 FCSR = (Rt_uw<7:1> << 25) | // move 31-25
966 (FCSR & 0x01000000) | // bit 24
967 (FCSR & 0x004FFFFF); // bit 22-0
968 break;
969 case 26:
970 FCSR = (FCSR & 0xFFFC0000) | // move 31-18
971 Rt_uw<17:12> << 12 | // bit 17-12
972 (FCSR & 0x00000F80) << 7 | // bit 11-7
973 Rt_uw<6:2> << 2 | // bit 6-2
974 (FCSR & 0x00000002); // bit 1-0
975 break;
976 case 28:
977 FCSR = (FCSR & 0xFE000000) | // move 31-25
978 Rt_uw<2:2> << 24 | // bit 24
979 (FCSR & 0x00FFF000) << 23 | // bit 23-12
980 Rt_uw<11:7> << 7 | // bit 24
981 (FCSR & 0x000007E) |
982 Rt_uw<1:0>; // bit 22-0
983 break;
984 case 31:
985 FCSR = Rt_uw;
986 break;
987
988 default:
989 panic("FP Control Value (%d) "
990 "Not Available. Ignoring Access "
991 "to Floating Control Status "
992 "Register", FS);
993 }
994 }});
995
996 0x7: mthc1({{
997 uint64_t fs_hi = Rt_uw;
998 uint64_t fs_lo = Fs_ud & 0x0FFFFFFFF;
999 Fs_ud = (fs_hi << 32) | fs_lo;
1000 }});
1001
1002 }
1003 format CP1Unimpl {
1004 0x1: dmfc1();
1005 0x5: dmtc1();
1006 }
1007 }
1008
1009 0x1: decode RS_LO {
1010 0x0: decode ND {
1011 format Branch {
1012 0x0: decode TF {
1013 0x0: bc1f({{
1014 cond = getCondCode(FCSR, BRANCH_CC) == 0;
1015 }});
1016 0x1: bc1t({{
1017 cond = getCondCode(FCSR, BRANCH_CC) == 1;
1018 }});
1019 }
1020 0x1: decode TF {
1021 0x0: bc1fl({{
1022 cond = getCondCode(FCSR, BRANCH_CC) == 0;
1023 }}, Likely);
1024 0x1: bc1tl({{
1025 cond = getCondCode(FCSR, BRANCH_CC) == 1;
1026 }}, Likely);
1027 }
1028 }
1029 }
1030 format CP1Unimpl {
1031 0x1: bc1any2();
1032 0x2: bc1any4();
1033 default: unknown();
1034 }
1035 }
1036 }
1037
1038 0x1: decode RS_HI {
1039 0x2: decode RS_LO {
1040 //Table A-14 MIPS32 COP1 Encoding of Function Field When
1041 //rs=S (( single-precision floating point))
1042 0x0: decode FUNCTION_HI {
1043 0x0: decode FUNCTION_LO {
1044 format FloatOp {
1045 0x0: add_s({{ Fd_sf = Fs_sf + Ft_sf; }});
1046 0x1: sub_s({{ Fd_sf = Fs_sf - Ft_sf; }});
1047 0x2: mul_s({{ Fd_sf = Fs_sf * Ft_sf; }});
1048 0x3: div_s({{ Fd_sf = Fs_sf / Ft_sf; }});
1049 0x4: sqrt_s({{ Fd_sf = sqrt(Fs_sf); }});
1050 0x5: abs_s({{ Fd_sf = fabs(Fs_sf); }});
1051 0x7: neg_s({{ Fd_sf = -Fs_sf; }});
1052 }
1053 0x6: BasicOp::mov_s({{ Fd_sf = Fs_sf; }});
1054 }
1055 0x1: decode FUNCTION_LO {
1056 format FloatConvertOp {
1057 0x0: round_l_s({{ val = Fs_sf; }},
1058 ToLong, Round);
1059 0x1: trunc_l_s({{ val = Fs_sf; }},
1060 ToLong, Trunc);
1061 0x2: ceil_l_s({{ val = Fs_sf;}},
1062 ToLong, Ceil);
1063 0x3: floor_l_s({{ val = Fs_sf; }},
1064 ToLong, Floor);
1065 0x4: round_w_s({{ val = Fs_sf; }},
1066 ToWord, Round);
1067 0x5: trunc_w_s({{ val = Fs_sf; }},
1068 ToWord, Trunc);
1069 0x6: ceil_w_s({{ val = Fs_sf; }},
1070 ToWord, Ceil);
1071 0x7: floor_w_s({{ val = Fs_sf; }},
1072 ToWord, Floor);
1073 }
1074 }
1075
1076 0x2: decode FUNCTION_LO {
1077 0x1: decode MOVCF {
1078 format BasicOp {
1079 0x0: movf_s({{
1080 Fd = (getCondCode(FCSR,CC) == 0) ?
1081 Fs : Fd;
1082 }});
1083 0x1: movt_s({{
1084 Fd = (getCondCode(FCSR,CC) == 1) ?
1085 Fs : Fd;
1086 }});
1087 }
1088 }
1089
1090 format BasicOp {
1091 0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }});
1092 0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }});
1093 }
1094
1095 format FloatOp {
1096 0x5: recip_s({{ Fd = 1 / Fs; }});
1097 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs); }});
1098 }
1099 format CP1Unimpl {
1100 default: unknown();
1101 }
1102 }
1103 0x3: CP1Unimpl::unknown();
1104
1105 0x4: decode FUNCTION_LO {
1106 format FloatConvertOp {
1107 0x1: cvt_d_s({{ val = Fs_sf; }}, ToDouble);
1108 0x4: cvt_w_s({{ val = Fs_sf; }}, ToWord);
1109 0x5: cvt_l_s({{ val = Fs_sf; }}, ToLong);
1110 }
1111
1112 0x6: FloatOp::cvt_ps_s({{
1113 Fd_ud = (uint64_t) Fs_uw << 32 |
1114 (uint64_t) Ft_uw;
1115 }});
1116 format CP1Unimpl {
1117 default: unknown();
1118 }
1119 }
1120 0x5: CP1Unimpl::unknown();
1121
1122 0x6: decode FUNCTION_LO {
1123 format FloatCompareOp {
1124 0x0: c_f_s({{ cond = 0; }},
1125 SinglePrecision, UnorderedFalse);
1126 0x1: c_un_s({{ cond = 0; }},
1127 SinglePrecision, UnorderedTrue);
1128 0x2: c_eq_s({{ cond = (Fs_sf == Ft_sf); }},
1129 UnorderedFalse);
1130 0x3: c_ueq_s({{ cond = (Fs_sf == Ft_sf); }},
1131 UnorderedTrue);
1132 0x4: c_olt_s({{ cond = (Fs_sf < Ft_sf); }},
1133 UnorderedFalse);
1134 0x5: c_ult_s({{ cond = (Fs_sf < Ft_sf); }},
1135 UnorderedTrue);
1136 0x6: c_ole_s({{ cond = (Fs_sf <= Ft_sf); }},
1137 UnorderedFalse);
1138 0x7: c_ule_s({{ cond = (Fs_sf <= Ft_sf); }},
1139 UnorderedTrue);
1140 }
1141 }
1142
1143 0x7: decode FUNCTION_LO {
1144 format FloatCompareOp {
1145 0x0: c_sf_s({{ cond = 0; }}, SinglePrecision,
1146 UnorderedFalse, QnanException);
1147 0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision,
1148 UnorderedTrue, QnanException);
1149 0x2: c_seq_s({{ cond = (Fs_sf == Ft_sf); }},
1150 UnorderedFalse, QnanException);
1151 0x3: c_ngl_s({{ cond = (Fs_sf == Ft_sf); }},
1152 UnorderedTrue, QnanException);
1153 0x4: c_lt_s({{ cond = (Fs_sf < Ft_sf); }},
1154 UnorderedFalse, QnanException);
1155 0x5: c_nge_s({{ cond = (Fs_sf < Ft_sf); }},
1156 UnorderedTrue, QnanException);
1157 0x6: c_le_s({{ cond = (Fs_sf <= Ft_sf); }},
1158 UnorderedFalse, QnanException);
1159 0x7: c_ngt_s({{ cond = (Fs_sf <= Ft_sf); }},
1160 UnorderedTrue, QnanException);
1161 }
1162 }
1163 }
1164
1165 //Table A-15 MIPS32 COP1 Encoding of Function Field When
1166 //rs=D
1167 0x1: decode FUNCTION_HI {
1168 0x0: decode FUNCTION_LO {
1169 format FloatOp {
1170 0x0: add_d({{ Fd_df = Fs_df + Ft_df; }});
1171 0x1: sub_d({{ Fd_df = Fs_df - Ft_df; }});
1172 0x2: mul_d({{ Fd_df = Fs_df * Ft_df; }});
1173 0x3: div_d({{ Fd_df = Fs_df / Ft_df; }});
1174 0x4: sqrt_d({{ Fd_df = sqrt(Fs_df); }});
1175 0x5: abs_d({{ Fd_df = fabs(Fs_df); }});
1176 0x7: neg_d({{ Fd_df = -1 * Fs_df; }});
1177 }
1178 0x6: BasicOp::mov_d({{ Fd_df = Fs_df; }});
1179 }
1180
1181 0x1: decode FUNCTION_LO {
1182 format FloatConvertOp {
1183 0x0: round_l_d({{ val = Fs_df; }},
1184 ToLong, Round);
1185 0x1: trunc_l_d({{ val = Fs_df; }},
1186 ToLong, Trunc);
1187 0x2: ceil_l_d({{ val = Fs_df; }},
1188 ToLong, Ceil);
1189 0x3: floor_l_d({{ val = Fs_df; }},
1190 ToLong, Floor);
1191 0x4: round_w_d({{ val = Fs_df; }},
1192 ToWord, Round);
1193 0x5: trunc_w_d({{ val = Fs_df; }},
1194 ToWord, Trunc);
1195 0x6: ceil_w_d({{ val = Fs_df; }},
1196 ToWord, Ceil);
1197 0x7: floor_w_d({{ val = Fs_df; }},
1198 ToWord, Floor);
1199 }
1200 }
1201
1202 0x2: decode FUNCTION_LO {
1203 0x1: decode MOVCF {
1204 format BasicOp {
1205 0x0: movf_d({{
1206 Fd_df = (getCondCode(FCSR,CC) == 0) ?
1207 Fs_df : Fd_df;
1208 }});
1209 0x1: movt_d({{
1210 Fd_df = (getCondCode(FCSR,CC) == 1) ?
1211 Fs_df : Fd_df;
1212 }});
1213 }
1214 }
1215
1216 format BasicOp {
1217 0x2: movz_d({{
1218 Fd_df = (Rt == 0) ? Fs_df : Fd_df;
1219 }});
1220 0x3: movn_d({{
1221 Fd_df = (Rt != 0) ? Fs_df : Fd_df;
1222 }});
1223 }
1224
1225 format FloatOp {
1226 0x5: recip_d({{ Fd_df = 1 / Fs_df; }});
1227 0x6: rsqrt_d({{ Fd_df = 1 / sqrt(Fs_df); }});
1228 }
1229 format CP1Unimpl {
1230 default: unknown();
1231 }
1232
1233 }
1234 0x4: decode FUNCTION_LO {
1235 format FloatConvertOp {
1236 0x0: cvt_s_d({{ val = Fs_df; }}, ToSingle);
1237 0x4: cvt_w_d({{ val = Fs_df; }}, ToWord);
1238 0x5: cvt_l_d({{ val = Fs_df; }}, ToLong);
1239 }
1240 default: CP1Unimpl::unknown();
1241 }
1242
1243 0x6: decode FUNCTION_LO {
1244 format FloatCompareOp {
1245 0x0: c_f_d({{ cond = 0; }},
1246 DoublePrecision, UnorderedFalse);
1247 0x1: c_un_d({{ cond = 0; }},
1248 DoublePrecision, UnorderedTrue);
1249 0x2: c_eq_d({{ cond = (Fs_df == Ft_df); }},
1250 UnorderedFalse);
1251 0x3: c_ueq_d({{ cond = (Fs_df == Ft_df); }},
1252 UnorderedTrue);
1253 0x4: c_olt_d({{ cond = (Fs_df < Ft_df); }},
1254 UnorderedFalse);
1255 0x5: c_ult_d({{ cond = (Fs_df < Ft_df); }},
1256 UnorderedTrue);
1257 0x6: c_ole_d({{ cond = (Fs_df <= Ft_df); }},
1258 UnorderedFalse);
1259 0x7: c_ule_d({{ cond = (Fs_df <= Ft_df); }},
1260 UnorderedTrue);
1261 }
1262 }
1263
1264 0x7: decode FUNCTION_LO {
1265 format FloatCompareOp {
1266 0x0: c_sf_d({{ cond = 0; }}, DoublePrecision,
1267 UnorderedFalse, QnanException);
1268 0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision,
1269 UnorderedTrue, QnanException);
1270 0x2: c_seq_d({{ cond = (Fs_df == Ft_df); }},
1271 UnorderedFalse, QnanException);
1272 0x3: c_ngl_d({{ cond = (Fs_df == Ft_df); }},
1273 UnorderedTrue, QnanException);
1274 0x4: c_lt_d({{ cond = (Fs_df < Ft_df); }},
1275 UnorderedFalse, QnanException);
1276 0x5: c_nge_d({{ cond = (Fs_df < Ft_df); }},
1277 UnorderedTrue, QnanException);
1278 0x6: c_le_d({{ cond = (Fs_df <= Ft_df); }},
1279 UnorderedFalse, QnanException);
1280 0x7: c_ngt_d({{ cond = (Fs_df <= Ft_df); }},
1281 UnorderedTrue, QnanException);
1282 }
1283 }
1284 default: CP1Unimpl::unknown();
1285 }
1286 0x2: CP1Unimpl::unknown();
1287 0x3: CP1Unimpl::unknown();
1288 0x7: CP1Unimpl::unknown();
1289
1290 //Table A-16 MIPS32 COP1 Encoding of Function
1291 //Field When rs=W
1292 0x4: decode FUNCTION {
1293 format FloatConvertOp {
1294 0x20: cvt_s_w({{ val = Fs_sw; }}, ToSingle);
1295 0x21: cvt_d_w({{ val = Fs_sw; }}, ToDouble);
1296 0x26: CP1Unimpl::cvt_ps_w();
1297 }
1298 default: CP1Unimpl::unknown();
1299 }
1300
1301 //Table A-16 MIPS32 COP1 Encoding of Function Field
1302 //When rs=L1
1303 //Note: "1. Format type L is legal only if 64-bit
1304 //floating point operations are enabled."
1305 0x5: decode FUNCTION {
1306 format FloatConvertOp {
1307 0x20: cvt_s_l({{ val = Fs_sd; }}, ToSingle);
1308 0x21: cvt_d_l({{ val = Fs_sd; }}, ToDouble);
1309 0x26: CP1Unimpl::cvt_ps_l();
1310 }
1311 default: CP1Unimpl::unknown();
1312 }
1313
1314 //Table A-17 MIPS64 COP1 Encoding of Function Field
1315 //When rs=PS1
1316 //Note: "1. Format type PS is legal only if 64-bit
1317 //floating point operations are enabled. "
1318 0x6: decode FUNCTION_HI {
1319 0x0: decode FUNCTION_LO {
1320 format Float64Op {
1321 0x0: add_ps({{
1322 Fd1_sf = Fs1_sf + Ft2_sf;
1323 Fd2_sf = Fs2_sf + Ft2_sf;
1324 }});
1325 0x1: sub_ps({{
1326 Fd1_sf = Fs1_sf - Ft2_sf;
1327 Fd2_sf = Fs2_sf - Ft2_sf;
1328 }});
1329 0x2: mul_ps({{
1330 Fd1_sf = Fs1_sf * Ft2_sf;
1331 Fd2_sf = Fs2_sf * Ft2_sf;
1332 }});
1333 0x5: abs_ps({{
1334 Fd1_sf = fabs(Fs1_sf);
1335 Fd2_sf = fabs(Fs2_sf);
1336 }});
1337 0x6: mov_ps({{
1338 Fd1_sf = Fs1_sf;
1339 Fd2_sf = Fs2_sf;
1340 }});
1341 0x7: neg_ps({{
1342 Fd1_sf = -(Fs1_sf);
1343 Fd2_sf = -(Fs2_sf);
1344 }});
1345 default: CP1Unimpl::unknown();
1346 }
1347 }
1348 0x1: CP1Unimpl::unknown();
1349 0x2: decode FUNCTION_LO {
1350 0x1: decode MOVCF {
1351 format Float64Op {
1352 0x0: movf_ps({{
1353 Fd1 = (getCondCode(FCSR, CC) == 0) ?
1354 Fs1 : Fd1;
1355 Fd2 = (getCondCode(FCSR, CC+1) == 0) ?
1356 Fs2 : Fd2;
1357 }});
1358 0x1: movt_ps({{
1359 Fd2 = (getCondCode(FCSR, CC) == 1) ?
1360 Fs1 : Fd1;
1361 Fd2 = (getCondCode(FCSR, CC+1) == 1) ?
1362 Fs2 : Fd2;
1363 }});
1364 }
1365 }
1366
1367 format Float64Op {
1368 0x2: movz_ps({{
1369 Fd1 = (getCondCode(FCSR, CC) == 0) ?
1370 Fs1 : Fd1;
1371 Fd2 = (getCondCode(FCSR, CC) == 0) ?
1372 Fs2 : Fd2;
1373 }});
1374 0x3: movn_ps({{
1375 Fd1 = (getCondCode(FCSR, CC) == 1) ?
1376 Fs1 : Fd1;
1377 Fd2 = (getCondCode(FCSR, CC) == 1) ?
1378 Fs2 : Fd2;
1379 }});
1380 }
1381 default: CP1Unimpl::unknown();
1382 }
1383 0x3: CP1Unimpl::unknown();
1384 0x4: decode FUNCTION_LO {
1385 0x0: FloatOp::cvt_s_pu({{ Fd_sf = Fs2_sf; }});
1386 default: CP1Unimpl::unknown();
1387 }
1388
1389 0x5: decode FUNCTION_LO {
1390 0x0: FloatOp::cvt_s_pl({{ Fd_sf = Fs1_sf; }});
1391 format Float64Op {
1392 0x4: pll({{
1393 Fd_ud = (uint64_t)Fs1_uw << 32 | Ft1_uw;
1394 }});
1395 0x5: plu({{
1396 Fd_ud = (uint64_t)Fs1_uw << 32 | Ft2_uw;
1397 }});
1398 0x6: pul({{
1399 Fd_ud = (uint64_t)Fs2_uw << 32 | Ft1_uw;
1400 }});
1401 0x7: puu({{
1402 Fd_ud = (uint64_t)Fs2_uw << 32 | Ft2_uw;
1403 }});
1404 }
1405 default: CP1Unimpl::unknown();
1406 }
1407
1408 0x6: decode FUNCTION_LO {
1409 format FloatPSCompareOp {
1410 0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1411 UnorderedFalse);
1412 0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1413 UnorderedTrue);
1414 0x2: c_eq_ps({{ cond1 = (Fs1_sf == Ft1_sf); }},
1415 {{ cond2 = (Fs2_sf == Ft2_sf); }},
1416 UnorderedFalse);
1417 0x3: c_ueq_ps({{ cond1 = (Fs1_sf == Ft1_sf); }},
1418 {{ cond2 = (Fs2_sf == Ft2_sf); }},
1419 UnorderedTrue);
1420 0x4: c_olt_ps({{ cond1 = (Fs1_sf < Ft1_sf); }},
1421 {{ cond2 = (Fs2_sf < Ft2_sf); }},
1422 UnorderedFalse);
1423 0x5: c_ult_ps({{ cond1 = (Fs_sf < Ft_sf); }},
1424 {{ cond2 = (Fs2_sf < Ft2_sf); }},
1425 UnorderedTrue);
1426 0x6: c_ole_ps({{ cond1 = (Fs_sf <= Ft_sf); }},
1427 {{ cond2 = (Fs2_sf <= Ft2_sf); }},
1428 UnorderedFalse);
1429 0x7: c_ule_ps({{ cond1 = (Fs1_sf <= Ft1_sf); }},
1430 {{ cond2 = (Fs2_sf <= Ft2_sf); }},
1431 UnorderedTrue);
1432 }
1433 }
1434
1435 0x7: decode FUNCTION_LO {
1436 format FloatPSCompareOp {
1437 0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1438 UnorderedFalse, QnanException);
1439 0x1: c_ngle_ps({{ cond1 = 0; }},
1440 {{ cond2 = 0; }},
1441 UnorderedTrue, QnanException);
1442 0x2: c_seq_ps({{ cond1 = (Fs1_sf == Ft1_sf); }},
1443 {{ cond2 = (Fs2_sf == Ft2_sf); }},
1444 UnorderedFalse, QnanException);
1445 0x3: c_ngl_ps({{ cond1 = (Fs1_sf == Ft1_sf); }},
1446 {{ cond2 = (Fs2_sf == Ft2_sf); }},
1447 UnorderedTrue, QnanException);
1448 0x4: c_lt_ps({{ cond1 = (Fs1_sf < Ft1_sf); }},
1449 {{ cond2 = (Fs2_sf < Ft2_sf); }},
1450 UnorderedFalse, QnanException);
1451 0x5: c_nge_ps({{ cond1 = (Fs1_sf < Ft1_sf); }},
1452 {{ cond2 = (Fs2_sf < Ft2_sf); }},
1453 UnorderedTrue, QnanException);
1454 0x6: c_le_ps({{ cond1 = (Fs1_sf <= Ft1_sf); }},
1455 {{ cond2 = (Fs2_sf <= Ft2_sf); }},
1456 UnorderedFalse, QnanException);
1457 0x7: c_ngt_ps({{ cond1 = (Fs1_sf <= Ft1_sf); }},
1458 {{ cond2 = (Fs2_sf <= Ft2_sf); }},
1459 UnorderedTrue, QnanException);
1460 }
1461 }
1462 }
1463 }
1464 default: CP1Unimpl::unknown();
1465 }
1466 }
1467
1468 //Table A-19 MIPS32 COP2 Encoding of rs Field
1469 0x2: decode RS_MSB {
1470 format CP2Unimpl {
1471 0x0: decode RS_HI {
1472 0x0: decode RS_LO {
1473 0x0: mfc2();
1474 0x2: cfc2();
1475 0x3: mfhc2();
1476 0x4: mtc2();
1477 0x6: ctc2();
1478 0x7: mftc2();
1479 default: unknown();
1480 }
1481
1482 0x1: decode ND {
1483 0x0: decode TF {
1484 0x0: bc2f();
1485 0x1: bc2t();
1486 default: unknown();
1487 }
1488
1489 0x1: decode TF {
1490 0x0: bc2fl();
1491 0x1: bc2tl();
1492 default: unknown();
1493 }
1494 default: unknown();
1495
1496 }
1497 default: unknown();
1498 }
1499 default: unknown();
1500 }
1501 }
1502
1503 //Table A-20 MIPS64 COP1X Encoding of Function Field 1
1504 //Note: "COP1X instructions are legal only if 64-bit floating point
1505 //operations are enabled."
1506 0x3: decode FUNCTION_HI {
1507 0x0: decode FUNCTION_LO {
1508 format LoadIndexedMemory {
1509 0x0: lwxc1({{ Fd_uw = Mem_uw; }});
1510 0x1: ldxc1({{ Fd_ud = Mem_ud; }});
1511 0x5: luxc1({{ Fd_ud = Mem_ud; }},
1512 {{ EA = (Rs + Rt) & ~7; }});
1513 }
1514 }
1515
1516 0x1: decode FUNCTION_LO {
1517 format StoreIndexedMemory {
1518 0x0: swxc1({{ Mem_uw = Fs_uw; }});
1519 0x1: sdxc1({{ Mem_ud = Fs_ud; }});
1520 0x5: suxc1({{ Mem_ud = Fs_ud; }},
1521 {{ EA = (Rs + Rt) & ~7; }});
1522 }
1523 0x7: Prefetch::prefx({{ EA = Rs + Rt; }});
1524 }
1525
1526 0x3: decode FUNCTION_LO {
1527 0x6: Float64Op::alnv_ps({{
1528 if (Rs<2:0> == 0) {
1529 Fd_ud = Fs_ud;
1530 } else if (Rs<2:0> == 4) {
1531 if (GuestByteOrder == BigEndianByteOrder)
1532 Fd_ud = Fs_ud<31:0> << 32 | Ft_ud<63:32>;
1533 else
1534 Fd_ud = Ft_ud<31:0> << 32 | Fs_ud<63:32>;
1535 } else {
1536 Fd_ud = Fd_ud;
1537 }
1538 }});
1539 }
1540
1541 format FloatAccOp {
1542 0x4: decode FUNCTION_LO {
1543 0x0: madd_s({{ Fd_sf = (Fs_sf * Ft_sf) + Fr_sf; }});
1544 0x1: madd_d({{ Fd_df = (Fs_df * Ft_df) + Fr_df; }});
1545 0x6: madd_ps({{
1546 Fd1_sf = (Fs1_df * Ft1_df) + Fr1_df;
1547 Fd2_sf = (Fs2_df * Ft2_df) + Fr2_df;
1548 }});
1549 }
1550
1551 0x5: decode FUNCTION_LO {
1552 0x0: msub_s({{ Fd_sf = (Fs_sf * Ft_sf) - Fr_sf; }});
1553 0x1: msub_d({{ Fd_df = (Fs_df * Ft_df) - Fr_df; }});
1554 0x6: msub_ps({{
1555 Fd1_sf = (Fs1_df * Ft1_df) - Fr1_df;
1556 Fd2_sf = (Fs2_df * Ft2_df) - Fr2_df;
1557 }});
1558 }
1559
1560 0x6: decode FUNCTION_LO {
1561 0x0: nmadd_s({{ Fd_sf = (-1 * Fs_sf * Ft_sf) - Fr_sf; }});
1562 0x1: nmadd_d({{ Fd_df = (-1 * Fs_df * Ft_df) - Fr_df; }});
1563 0x6: nmadd_ps({{
1564 Fd1_sf = -((Fs1_df * Ft1_df) + Fr1_df);
1565 Fd2_sf = -((Fs2_df * Ft2_df) + Fr2_df);
1566 }});
1567 }
1568
1569 0x7: decode FUNCTION_LO {
1570 0x0: nmsub_s({{ Fd_sf = (-1 * Fs_sf * Ft_sf) + Fr_sf; }});
1571 0x1: nmsub_d({{ Fd_df = (-1 * Fs_df * Ft_df) + Fr_df; }});
1572 0x6: nmsub_ps({{
1573 Fd1_sf = -((Fs1_df * Ft1_df) - Fr1_df);
1574 Fd2_sf = -((Fs2_df * Ft2_df) - Fr2_df);
1575 }});
1576 }
1577 }
1578 }
1579
1580 format Branch {
1581 0x4: beql({{ cond = (Rs_sw == Rt_sw); }}, Likely);
1582 0x5: bnel({{ cond = (Rs_sw != Rt_sw); }}, Likely);
1583 0x6: blezl({{ cond = (Rs_sw <= 0); }}, Likely);
1584 0x7: bgtzl({{ cond = (Rs_sw > 0); }}, Likely);
1585 }
1586 }
1587
1588 0x3: decode OPCODE_LO {
1589 //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
1590 0x4: decode FUNCTION_HI {
1591 0x0: decode FUNCTION_LO {
1592 0x2: IntOp::mul({{
1593 int64_t temp1 = Rs_sd * Rt_sd;
1594 Rd_sw = temp1<31:0>;
1595 }}, IntMultOp);
1596
1597 format HiLoRdSelValOp {
1598 0x0: madd({{
1599 val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1600 (Rs_sd * Rt_sd);
1601 }}, IntMultOp);
1602 0x1: maddu({{
1603 val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1604 (Rs_ud * Rt_ud);
1605 }}, IntMultOp);
1606 0x4: msub({{
1607 val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1608 (Rs_sd * Rt_sd);
1609 }}, IntMultOp);
1610 0x5: msubu({{
1611 val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1612 (Rs_ud * Rt_ud);
1613 }}, IntMultOp);
1614 }
1615 }
1616
1617 0x4: decode FUNCTION_LO {
1618 format BasicOp {
1619 0x0: clz({{
1620 int cnt = 32;
1621 for (int idx = 31; idx >= 0; idx--) {
1622 if (Rs<idx:idx> == 1) {
1623 cnt = 31 - idx;
1624 break;
1625 }
1626 }
1627 Rd_uw = cnt;
1628 }});
1629 0x1: clo({{
1630 int cnt = 32;
1631 for (int idx = 31; idx >= 0; idx--) {
1632 if (Rs<idx:idx> == 0) {
1633 cnt = 31 - idx;
1634 break;
1635 }
1636 }
1637 Rd_uw = cnt;
1638 }});
1639 }
1640 }
1641
1642 0x7: decode FUNCTION_LO {
1643 0x7: FailUnimpl::sdbbp();
1644 }
1645 }
1646
1647 //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2
1648 //of the Architecture
1649 0x7: decode FUNCTION_HI {
1650 0x0: decode FUNCTION_LO {
1651 format BasicOp {
1652 0x0: ext({{ Rt_uw = bits(Rs_uw, MSB+LSB, LSB); }});
1653 0x4: ins({{
1654 Rt_uw = bits(Rt_uw, 31, MSB+1) << (MSB+1) |
1655 bits(Rs_uw, MSB-LSB, 0) << LSB |
1656 bits(Rt_uw, LSB-1, 0);
1657 }});
1658 }
1659 }
1660
1661 0x1: decode FUNCTION_LO {
1662 format MT_Control {
1663 0x0: fork({{
1664 forkThread(xc->tcBase(), fault, RD, Rs, Rt);
1665 }}, UserMode);
1666 0x1: yield({{
1667 Rd_sw = yieldThread(xc->tcBase(), fault, Rs_sw,
1668 YQMask);
1669 }}, UserMode);
1670 }
1671
1672 //Table 5-9 MIPS32 LX Encoding of the op Field (DSP ASE MANUAL)
1673 0x2: decode OP_HI {
1674 0x0: decode OP_LO {
1675 format LoadIndexedMemory {
1676 0x0: lwx({{ Rd_sw = Mem_sw; }});
1677 0x4: lhx({{ Rd_sw = Mem_sh; }});
1678 0x6: lbux({{ Rd_uw = Mem_ub; }});
1679 }
1680 }
1681 }
1682 0x4: DspIntOp::insv({{
1683 int pos = dspctl<5:0>;
1684 int size = dspctl<12:7> - 1;
1685 Rt_uw = insertBits(Rt_uw, pos+size,
1686 pos, Rs_uw<size:0>);
1687 }});
1688 }
1689
1690 0x2: decode FUNCTION_LO {
1691
1692 //Table 5-5 MIPS32 ADDU.QB Encoding of the op Field
1693 //(DSP ASE MANUAL)
1694 0x0: decode OP_HI {
1695 0x0: decode OP_LO {
1696 format DspIntOp {
1697 0x0: addu_qb({{
1698 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1699 NOSATURATE, UNSIGNED, &dspctl);
1700 }});
1701 0x1: subu_qb({{
1702 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_QB,
1703 NOSATURATE, UNSIGNED, &dspctl);
1704 }});
1705 0x4: addu_s_qb({{
1706 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1707 SATURATE, UNSIGNED, &dspctl);
1708 }});
1709 0x5: subu_s_qb({{
1710 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_QB,
1711 SATURATE, UNSIGNED, &dspctl);
1712 }});
1713 0x6: muleu_s_ph_qbl({{
1714 Rd_uw = dspMuleu(Rs_uw, Rt_uw,
1715 MODE_L, &dspctl);
1716 }}, IntMultOp);
1717 0x7: muleu_s_ph_qbr({{
1718 Rd_uw = dspMuleu(Rs_uw, Rt_uw,
1719 MODE_R, &dspctl);
1720 }}, IntMultOp);
1721 }
1722 }
1723 0x1: decode OP_LO {
1724 format DspIntOp {
1725 0x0: addu_ph({{
1726 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_PH,
1727 NOSATURATE, UNSIGNED, &dspctl);
1728 }});
1729 0x1: subu_ph({{
1730 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_PH,
1731 NOSATURATE, UNSIGNED, &dspctl);
1732 }});
1733 0x2: addq_ph({{
1734 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_PH,
1735 NOSATURATE, SIGNED, &dspctl);
1736 }});
1737 0x3: subq_ph({{
1738 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_PH,
1739 NOSATURATE, SIGNED, &dspctl);
1740 }});
1741 0x4: addu_s_ph({{
1742 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_PH,
1743 SATURATE, UNSIGNED, &dspctl);
1744 }});
1745 0x5: subu_s_ph({{
1746 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_PH,
1747 SATURATE, UNSIGNED, &dspctl);
1748 }});
1749 0x6: addq_s_ph({{
1750 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_PH,
1751 SATURATE, SIGNED, &dspctl);
1752 }});
1753 0x7: subq_s_ph({{
1754 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_PH,
1755 SATURATE, SIGNED, &dspctl);
1756 }});
1757 }
1758 }
1759 0x2: decode OP_LO {
1760 format DspIntOp {
1761 0x0: addsc({{
1762 int64_t dresult;
1763 dresult = Rs_ud + Rt_ud;
1764 Rd_sw = dresult<31:0>;
1765 dspctl = insertBits(dspctl, 13, 13,
1766 dresult<32:32>);
1767 }});
1768 0x1: addwc({{
1769 int64_t dresult;
1770 dresult = Rs_sd + Rt_sd + dspctl<13:13>;
1771 Rd_sw = dresult<31:0>;
1772 if (dresult<32:32> != dresult<31:31>)
1773 dspctl = insertBits(dspctl, 20, 20, 1);
1774 }});
1775 0x2: modsub({{
1776 Rd_sw = (Rs_sw == 0) ? Rt_sw<23:8> :
1777 Rs_sw - Rt_sw<7:0>;
1778 }});
1779 0x4: raddu_w_qb({{
1780 Rd_uw = Rs_uw<31:24> + Rs_uw<23:16> +
1781 Rs_uw<15:8> + Rs_uw<7:0>;
1782 }});
1783 0x6: addq_s_w({{
1784 Rd_sw = dspAdd(Rs_sw, Rt_sw, SIMD_FMT_W,
1785 SATURATE, SIGNED, &dspctl);
1786 }});
1787 0x7: subq_s_w({{
1788 Rd_sw = dspSub(Rs_sw, Rt_sw, SIMD_FMT_W,
1789 SATURATE, SIGNED, &dspctl);
1790 }});
1791 }
1792 }
1793 0x3: decode OP_LO {
1794 format DspIntOp {
1795 0x4: muleq_s_w_phl({{
1796 Rd_sw = dspMuleq(Rs_sw, Rt_sw,
1797 MODE_L, &dspctl);
1798 }}, IntMultOp);
1799 0x5: muleq_s_w_phr({{
1800 Rd_sw = dspMuleq(Rs_sw, Rt_sw,
1801 MODE_R, &dspctl);
1802 }}, IntMultOp);
1803 0x6: mulq_s_ph({{
1804 Rd_sw = dspMulq(Rs_sw, Rt_sw, SIMD_FMT_PH,
1805 SATURATE, NOROUND, &dspctl);
1806 }}, IntMultOp);
1807 0x7: mulq_rs_ph({{
1808 Rd_sw = dspMulq(Rs_sw, Rt_sw, SIMD_FMT_PH,
1809 SATURATE, ROUND, &dspctl);
1810 }}, IntMultOp);
1811 }
1812 }
1813 }
1814
1815 //Table 5-6 MIPS32 CMPU_EQ_QB Encoding of the op Field
1816 //(DSP ASE MANUAL)
1817 0x1: decode OP_HI {
1818 0x0: decode OP_LO {
1819 format DspIntOp {
1820 0x0: cmpu_eq_qb({{
1821 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_QB,
1822 UNSIGNED, CMP_EQ, &dspctl);
1823 }});
1824 0x1: cmpu_lt_qb({{
1825 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_QB,
1826 UNSIGNED, CMP_LT, &dspctl);
1827 }});
1828 0x2: cmpu_le_qb({{
1829 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_QB,
1830 UNSIGNED, CMP_LE, &dspctl);
1831 }});
1832 0x3: pick_qb({{
1833 Rd_uw = dspPick(Rs_uw, Rt_uw,
1834 SIMD_FMT_QB, &dspctl);
1835 }});
1836 0x4: cmpgu_eq_qb({{
1837 Rd_uw = dspCmpg(Rs_uw, Rt_uw, SIMD_FMT_QB,
1838 UNSIGNED, CMP_EQ );
1839 }});
1840 0x5: cmpgu_lt_qb({{
1841 Rd_uw = dspCmpg(Rs_uw, Rt_uw, SIMD_FMT_QB,
1842 UNSIGNED, CMP_LT);
1843 }});
1844 0x6: cmpgu_le_qb({{
1845 Rd_uw = dspCmpg(Rs_uw, Rt_uw, SIMD_FMT_QB,
1846 UNSIGNED, CMP_LE);
1847 }});
1848 }
1849 }
1850 0x1: decode OP_LO {
1851 format DspIntOp {
1852 0x0: cmp_eq_ph({{
1853 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_PH,
1854 SIGNED, CMP_EQ, &dspctl);
1855 }});
1856 0x1: cmp_lt_ph({{
1857 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_PH,
1858 SIGNED, CMP_LT, &dspctl);
1859 }});
1860 0x2: cmp_le_ph({{
1861 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_PH,
1862 SIGNED, CMP_LE, &dspctl);
1863 }});
1864 0x3: pick_ph({{
1865 Rd_uw = dspPick(Rs_uw, Rt_uw,
1866 SIMD_FMT_PH, &dspctl);
1867 }});
1868 0x4: precrq_qb_ph({{
1869 Rd_uw = Rs_uw<31:24> << 24 |
1870 Rs_uw<15:8> << 16 |
1871 Rt_uw<31:24> << 8 |
1872 Rt_uw<15:8>;
1873 }});
1874 0x5: precr_qb_ph({{
1875 Rd_uw = Rs_uw<23:16> << 24 |
1876 Rs_uw<7:0> << 16 |
1877 Rt_uw<23:16> << 8 |
1878 Rt_uw<7:0>;
1879 }});
1880 0x6: packrl_ph({{
1881 Rd_uw = dspPack(Rs_uw, Rt_uw, SIMD_FMT_PH);
1882 }});
1883 0x7: precrqu_s_qb_ph({{
1884 Rd_uw = dspPrecrqu(Rs_uw, Rt_uw, &dspctl);
1885 }});
1886 }
1887 }
1888 0x2: decode OP_LO {
1889 format DspIntOp {
1890 0x4: precrq_ph_w({{
1891 Rd_uw = Rs_uw<31:16> << 16 | Rt_uw<31:16>;
1892 }});
1893 0x5: precrq_rs_ph_w({{
1894 Rd_uw = dspPrecrq(Rs_uw, Rt_uw,
1895 SIMD_FMT_W, &dspctl);
1896 }});
1897 }
1898 }
1899 0x3: decode OP_LO {
1900 format DspIntOp {
1901 0x0: cmpgdu_eq_qb({{
1902 Rd_uw = dspCmpgd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1903 UNSIGNED, CMP_EQ, &dspctl);
1904 }});
1905 0x1: cmpgdu_lt_qb({{
1906 Rd_uw = dspCmpgd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1907 UNSIGNED, CMP_LT, &dspctl);
1908 }});
1909 0x2: cmpgdu_le_qb({{
1910 Rd_uw = dspCmpgd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1911 UNSIGNED, CMP_LE, &dspctl);
1912 }});
1913 0x6: precr_sra_ph_w({{
1914 Rt_uw = dspPrecrSra(Rt_uw, Rs_uw, RD,
1915 SIMD_FMT_W, NOROUND);
1916 }});
1917 0x7: precr_sra_r_ph_w({{
1918 Rt_uw = dspPrecrSra(Rt_uw, Rs_uw, RD,
1919 SIMD_FMT_W, ROUND);
1920 }});
1921 }
1922 }
1923 }
1924
1925 //Table 5-7 MIPS32 ABSQ_S.PH Encoding of the op Field
1926 //(DSP ASE MANUAL)
1927 0x2: decode OP_HI {
1928 0x0: decode OP_LO {
1929 format DspIntOp {
1930 0x1: absq_s_qb({{
1931 Rd_sw = dspAbs(Rt_sw, SIMD_FMT_QB, &dspctl);
1932 }});
1933 0x2: repl_qb({{
1934 Rd_uw = RS_RT<7:0> << 24 |
1935 RS_RT<7:0> << 16 |
1936 RS_RT<7:0> << 8 |
1937 RS_RT<7:0>;
1938 }});
1939 0x3: replv_qb({{
1940 Rd_sw = Rt_uw<7:0> << 24 |
1941 Rt_uw<7:0> << 16 |
1942 Rt_uw<7:0> << 8 |
1943 Rt_uw<7:0>;
1944 }});
1945 0x4: precequ_ph_qbl({{
1946 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB, UNSIGNED,
1947 SIMD_FMT_PH, SIGNED, MODE_L);
1948 }});
1949 0x5: precequ_ph_qbr({{
1950 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB, UNSIGNED,
1951 SIMD_FMT_PH, SIGNED, MODE_R);
1952 }});
1953 0x6: precequ_ph_qbla({{
1954 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB, UNSIGNED,
1955 SIMD_FMT_PH, SIGNED, MODE_LA);
1956 }});
1957 0x7: precequ_ph_qbra({{
1958 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB, UNSIGNED,
1959 SIMD_FMT_PH, SIGNED, MODE_RA);
1960 }});
1961 }
1962 }
1963 0x1: decode OP_LO {
1964 format DspIntOp {
1965 0x1: absq_s_ph({{
1966 Rd_sw = dspAbs(Rt_sw, SIMD_FMT_PH, &dspctl);
1967 }});
1968 0x2: repl_ph({{
1969 Rd_uw = (sext<10>(RS_RT))<15:0> << 16 |
1970 (sext<10>(RS_RT))<15:0>;
1971 }});
1972 0x3: replv_ph({{
1973 Rd_uw = Rt_uw<15:0> << 16 |
1974 Rt_uw<15:0>;
1975 }});
1976 0x4: preceq_w_phl({{
1977 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_PH, SIGNED,
1978 SIMD_FMT_W, SIGNED, MODE_L);
1979 }});
1980 0x5: preceq_w_phr({{
1981 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_PH, SIGNED,
1982 SIMD_FMT_W, SIGNED, MODE_R);
1983 }});
1984 }
1985 }
1986 0x2: decode OP_LO {
1987 format DspIntOp {
1988 0x1: absq_s_w({{
1989 Rd_sw = dspAbs(Rt_sw, SIMD_FMT_W, &dspctl);
1990 }});
1991 }
1992 }
1993 0x3: decode OP_LO {
1994 0x3: IntOp::bitrev({{
1995 Rd_uw = bitrev( Rt_uw<15:0> );
1996 }});
1997 format DspIntOp {
1998 0x4: preceu_ph_qbl({{
1999 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB,
2000 UNSIGNED, SIMD_FMT_PH,
2001 UNSIGNED, MODE_L);
2002 }});
2003 0x5: preceu_ph_qbr({{
2004 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB,
2005 UNSIGNED, SIMD_FMT_PH,
2006 UNSIGNED, MODE_R );
2007 }});
2008 0x6: preceu_ph_qbla({{
2009 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB,
2010 UNSIGNED, SIMD_FMT_PH,
2011 UNSIGNED, MODE_LA );
2012 }});
2013 0x7: preceu_ph_qbra({{
2014 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB,
2015 UNSIGNED, SIMD_FMT_PH,
2016 UNSIGNED, MODE_RA);
2017 }});
2018 }
2019 }
2020 }
2021
2022 //Table 5-8 MIPS32 SHLL.QB Encoding of the op Field
2023 //(DSP ASE MANUAL)
2024 0x3: decode OP_HI {
2025 0x0: decode OP_LO {
2026 format DspIntOp {
2027 0x0: shll_qb({{
2028 Rd_sw = dspShll(Rt_sw, RS, SIMD_FMT_QB,
2029 NOSATURATE, UNSIGNED, &dspctl);
2030 }});
2031 0x1: shrl_qb({{
2032 Rd_sw = dspShrl(Rt_sw, RS, SIMD_FMT_QB,
2033 UNSIGNED);
2034 }});
2035 0x2: shllv_qb({{
2036 Rd_sw = dspShll(Rt_sw, Rs_sw, SIMD_FMT_QB,
2037 NOSATURATE, UNSIGNED, &dspctl);
2038 }});
2039 0x3: shrlv_qb({{
2040 Rd_sw = dspShrl(Rt_sw, Rs_sw, SIMD_FMT_QB,
2041 UNSIGNED);
2042 }});
2043 0x4: shra_qb({{
2044 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_QB,
2045 NOROUND, SIGNED, &dspctl);
2046 }});
2047 0x5: shra_r_qb({{
2048 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_QB,
2049 ROUND, SIGNED, &dspctl);
2050 }});
2051 0x6: shrav_qb({{
2052 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_QB,
2053 NOROUND, SIGNED, &dspctl);
2054 }});
2055 0x7: shrav_r_qb({{
2056 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_QB,
2057 ROUND, SIGNED, &dspctl);
2058 }});
2059 }
2060 }
2061 0x1: decode OP_LO {
2062 format DspIntOp {
2063 0x0: shll_ph({{
2064 Rd_uw = dspShll(Rt_uw, RS, SIMD_FMT_PH,
2065 NOSATURATE, SIGNED, &dspctl);
2066 }});
2067 0x1: shra_ph({{
2068 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_PH,
2069 NOROUND, SIGNED, &dspctl);
2070 }});
2071 0x2: shllv_ph({{
2072 Rd_sw = dspShll(Rt_sw, Rs_sw, SIMD_FMT_PH,
2073 NOSATURATE, SIGNED, &dspctl);
2074 }});
2075 0x3: shrav_ph({{
2076 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_PH,
2077 NOROUND, SIGNED, &dspctl);
2078 }});
2079 0x4: shll_s_ph({{
2080 Rd_sw = dspShll(Rt_sw, RS, SIMD_FMT_PH,
2081 SATURATE, SIGNED, &dspctl);
2082 }});
2083 0x5: shra_r_ph({{
2084 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_PH,
2085 ROUND, SIGNED, &dspctl);
2086 }});
2087 0x6: shllv_s_ph({{
2088 Rd_sw = dspShll(Rt_sw, Rs_sw, SIMD_FMT_PH,
2089 SATURATE, SIGNED, &dspctl);
2090 }});
2091 0x7: shrav_r_ph({{
2092 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_PH,
2093 ROUND, SIGNED, &dspctl);
2094 }});
2095 }
2096 }
2097 0x2: decode OP_LO {
2098 format DspIntOp {
2099 0x4: shll_s_w({{
2100 Rd_sw = dspShll(Rt_sw, RS, SIMD_FMT_W,
2101 SATURATE, SIGNED, &dspctl);
2102 }});
2103 0x5: shra_r_w({{
2104 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_W,
2105 ROUND, SIGNED, &dspctl);
2106 }});
2107 0x6: shllv_s_w({{
2108 Rd_sw = dspShll(Rt_sw, Rs_sw, SIMD_FMT_W,
2109 SATURATE, SIGNED, &dspctl);
2110 }});
2111 0x7: shrav_r_w({{
2112 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_W,
2113 ROUND, SIGNED, &dspctl);
2114 }});
2115 }
2116 }
2117 0x3: decode OP_LO {
2118 format DspIntOp {
2119 0x1: shrl_ph({{
2120 Rd_sw = dspShrl(Rt_sw, RS, SIMD_FMT_PH,
2121 UNSIGNED);
2122 }});
2123 0x3: shrlv_ph({{
2124 Rd_sw = dspShrl(Rt_sw, Rs_sw, SIMD_FMT_PH,
2125 UNSIGNED);
2126 }});
2127 }
2128 }
2129 }
2130 }
2131
2132 0x3: decode FUNCTION_LO {
2133
2134 //Table 3.12 MIPS32 ADDUH.QB Encoding of the op Field
2135 //(DSP ASE Rev2 Manual)
2136 0x0: decode OP_HI {
2137 0x0: decode OP_LO {
2138 format DspIntOp {
2139 0x0: adduh_qb({{
2140 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_QB,
2141 NOROUND, UNSIGNED);
2142 }});
2143 0x1: subuh_qb({{
2144 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_QB,
2145 NOROUND, UNSIGNED);
2146 }});
2147 0x2: adduh_r_qb({{
2148 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_QB,
2149 ROUND, UNSIGNED);
2150 }});
2151 0x3: subuh_r_qb({{
2152 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_QB,
2153 ROUND, UNSIGNED);
2154 }});
2155 }
2156 }
2157 0x1: decode OP_LO {
2158 format DspIntOp {
2159 0x0: addqh_ph({{
2160 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_PH,
2161 NOROUND, SIGNED);
2162 }});
2163 0x1: subqh_ph({{
2164 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_PH,
2165 NOROUND, SIGNED);
2166 }});
2167 0x2: addqh_r_ph({{
2168 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_PH,
2169 ROUND, SIGNED);
2170 }});
2171 0x3: subqh_r_ph({{
2172 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_PH,
2173 ROUND, SIGNED);
2174 }});
2175 0x4: mul_ph({{
2176 Rd_sw = dspMul(Rs_sw, Rt_sw, SIMD_FMT_PH,
2177 NOSATURATE, &dspctl);
2178 }}, IntMultOp);
2179 0x6: mul_s_ph({{
2180 Rd_sw = dspMul(Rs_sw, Rt_sw, SIMD_FMT_PH,
2181 SATURATE, &dspctl);
2182 }}, IntMultOp);
2183 }
2184 }
2185 0x2: decode OP_LO {
2186 format DspIntOp {
2187 0x0: addqh_w({{
2188 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_W,
2189 NOROUND, SIGNED);
2190 }});
2191 0x1: subqh_w({{
2192 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_W,
2193 NOROUND, SIGNED);
2194 }});
2195 0x2: addqh_r_w({{
2196 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_W,
2197 ROUND, SIGNED);
2198 }});
2199 0x3: subqh_r_w({{
2200 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_W,
2201 ROUND, SIGNED);
2202 }});
2203 0x6: mulq_s_w({{
2204 Rd_sw = dspMulq(Rs_sw, Rt_sw, SIMD_FMT_W,
2205 SATURATE, NOROUND, &dspctl);
2206 }}, IntMultOp);
2207 0x7: mulq_rs_w({{
2208 Rd_sw = dspMulq(Rs_sw, Rt_sw, SIMD_FMT_W,
2209 SATURATE, ROUND, &dspctl);
2210 }}, IntMultOp);
2211 }
2212 }
2213 }
2214 }
2215
2216 //Table A-10 MIPS32 BSHFL Encoding of sa Field
2217 0x4: decode SA {
2218 format BasicOp {
2219 0x02: wsbh({{
2220 Rd_uw = Rt_uw<23:16> << 24 |
2221 Rt_uw<31:24> << 16 |
2222 Rt_uw<7:0> << 8 |
2223 Rt_uw<15:8>;
2224 }});
2225 0x10: seb({{ Rd_sw = Rt_sb; }});
2226 0x18: seh({{ Rd_sw = Rt_sh; }});
2227 }
2228 }
2229
2230 0x6: decode FUNCTION_LO {
2231
2232 //Table 5-10 MIPS32 DPAQ.W.PH Encoding of the op Field
2233 //(DSP ASE MANUAL)
2234 0x0: decode OP_HI {
2235 0x0: decode OP_LO {
2236 format DspHiLoOp {
2237 0x0: dpa_w_ph({{
2238 dspac = dspDpa(dspac, Rs_sw, Rt_sw, ACDST,
2239 SIMD_FMT_PH, SIGNED, MODE_L);
2240 }}, IntMultOp);
2241 0x1: dps_w_ph({{
2242 dspac = dspDps(dspac, Rs_sw, Rt_sw, ACDST,
2243 SIMD_FMT_PH, SIGNED, MODE_L);
2244 }}, IntMultOp);
2245 0x2: mulsa_w_ph({{
2246 dspac = dspMulsa(dspac, Rs_sw, Rt_sw,
2247 ACDST, SIMD_FMT_PH );
2248 }}, IntMultOp);
2249 0x3: dpau_h_qbl({{
2250 dspac = dspDpa(dspac, Rs_sw, Rt_sw, ACDST,
2251 SIMD_FMT_QB, UNSIGNED, MODE_L);
2252 }}, IntMultOp);
2253 0x4: dpaq_s_w_ph({{
2254 dspac = dspDpaq(dspac, Rs_sw, Rt_sw,
2255 ACDST, SIMD_FMT_PH,
2256 SIMD_FMT_W, NOSATURATE,
2257 MODE_L, &dspctl);
2258 }}, IntMultOp);
2259 0x5: dpsq_s_w_ph({{
2260 dspac = dspDpsq(dspac, Rs_sw, Rt_sw,
2261 ACDST, SIMD_FMT_PH,
2262 SIMD_FMT_W, NOSATURATE,
2263 MODE_L, &dspctl);
2264 }}, IntMultOp);
2265 0x6: mulsaq_s_w_ph({{
2266 dspac = dspMulsaq(dspac, Rs_sw, Rt_sw,
2267 ACDST, SIMD_FMT_PH,
2268 &dspctl);
2269 }}, IntMultOp);
2270 0x7: dpau_h_qbr({{
2271 dspac = dspDpa(dspac, Rs_sw, Rt_sw, ACDST,
2272 SIMD_FMT_QB, UNSIGNED, MODE_R);
2273 }}, IntMultOp);
2274 }
2275 }
2276 0x1: decode OP_LO {
2277 format DspHiLoOp {
2278 0x0: dpax_w_ph({{
2279 dspac = dspDpa(dspac, Rs_sw, Rt_sw, ACDST,
2280 SIMD_FMT_PH, SIGNED, MODE_X);
2281 }}, IntMultOp);
2282 0x1: dpsx_w_ph({{
2283 dspac = dspDps(dspac, Rs_sw, Rt_sw, ACDST,
2284 SIMD_FMT_PH, SIGNED, MODE_X);
2285 }}, IntMultOp);
2286 0x3: dpsu_h_qbl({{
2287 dspac = dspDps(dspac, Rs_sw, Rt_sw, ACDST,
2288 SIMD_FMT_QB, UNSIGNED, MODE_L);
2289 }}, IntMultOp);
2290 0x4: dpaq_sa_l_w({{
2291 dspac = dspDpaq(dspac, Rs_sw, Rt_sw,
2292 ACDST, SIMD_FMT_W,
2293 SIMD_FMT_L, SATURATE,
2294 MODE_L, &dspctl);
2295 }}, IntMultOp);
2296 0x5: dpsq_sa_l_w({{
2297 dspac = dspDpsq(dspac, Rs_sw, Rt_sw,
2298 ACDST, SIMD_FMT_W,
2299 SIMD_FMT_L, SATURATE,
2300 MODE_L, &dspctl);
2301 }}, IntMultOp);
2302 0x7: dpsu_h_qbr({{
2303 dspac = dspDps(dspac, Rs_sw, Rt_sw, ACDST,
2304 SIMD_FMT_QB, UNSIGNED, MODE_R);
2305 }}, IntMultOp);
2306 }
2307 }
2308 0x2: decode OP_LO {
2309 format DspHiLoOp {
2310 0x0: maq_sa_w_phl({{
2311 dspac = dspMaq(dspac, Rs_uw, Rt_uw,
2312 ACDST, SIMD_FMT_PH,
2313 MODE_L, SATURATE, &dspctl);
2314 }}, IntMultOp);
2315 0x2: maq_sa_w_phr({{
2316 dspac = dspMaq(dspac, Rs_uw, Rt_uw,
2317 ACDST, SIMD_FMT_PH,
2318 MODE_R, SATURATE, &dspctl);
2319 }}, IntMultOp);
2320 0x4: maq_s_w_phl({{
2321 dspac = dspMaq(dspac, Rs_uw, Rt_uw,
2322 ACDST, SIMD_FMT_PH,
2323 MODE_L, NOSATURATE, &dspctl);
2324 }}, IntMultOp);
2325 0x6: maq_s_w_phr({{
2326 dspac = dspMaq(dspac, Rs_uw, Rt_uw,
2327 ACDST, SIMD_FMT_PH,
2328 MODE_R, NOSATURATE, &dspctl);
2329 }}, IntMultOp);
2330 }
2331 }
2332 0x3: decode OP_LO {
2333 format DspHiLoOp {
2334 0x0: dpaqx_s_w_ph({{
2335 dspac = dspDpaq(dspac, Rs_sw, Rt_sw,
2336 ACDST, SIMD_FMT_PH,
2337 SIMD_FMT_W, NOSATURATE,
2338 MODE_X, &dspctl);
2339 }}, IntMultOp);
2340 0x1: dpsqx_s_w_ph({{
2341 dspac = dspDpsq(dspac, Rs_sw, Rt_sw,
2342 ACDST, SIMD_FMT_PH,
2343 SIMD_FMT_W, NOSATURATE,
2344 MODE_X, &dspctl);
2345 }}, IntMultOp);
2346 0x2: dpaqx_sa_w_ph({{
2347 dspac = dspDpaq(dspac, Rs_sw, Rt_sw,
2348 ACDST, SIMD_FMT_PH,
2349 SIMD_FMT_W, SATURATE,
2350 MODE_X, &dspctl);
2351 }}, IntMultOp);
2352 0x3: dpsqx_sa_w_ph({{
2353 dspac = dspDpsq(dspac, Rs_sw, Rt_sw,
2354 ACDST, SIMD_FMT_PH,
2355 SIMD_FMT_W, SATURATE,
2356 MODE_X, &dspctl);
2357 }}, IntMultOp);
2358 }
2359 }
2360 }
2361
2362 //Table 3.3 MIPS32 APPEND Encoding of the op Field
2363 0x1: decode OP_HI {
2364 0x0: decode OP_LO {
2365 format IntOp {
2366 0x0: append({{
2367 Rt_uw = (Rt_uw << RD) | bits(Rs_uw, RD - 1, 0);
2368 }});
2369 0x1: prepend({{
2370 Rt_uw = (Rt_uw >> RD) |
2371 (bits(Rs_uw, RD - 1, 0) << (32 - RD));
2372 }});
2373 }
2374 }
2375 0x2: decode OP_LO {
2376 format IntOp {
2377 0x0: balign({{
2378 Rt_uw = (Rt_uw << (8 * BP)) |
2379 (Rs_uw >> (8 * (4 - BP)));
2380 }});
2381 }
2382 }
2383 }
2384
2385 }
2386 0x7: decode FUNCTION_LO {
2387
2388 //Table 5-11 MIPS32 EXTR.W Encoding of the op Field
2389 //(DSP ASE MANUAL)
2390 0x0: decode OP_HI {
2391 0x0: decode OP_LO {
2392 format DspHiLoOp {
2393 0x0: extr_w({{
2394 Rt_uw = dspExtr(dspac, SIMD_FMT_W, RS,
2395 NOROUND, NOSATURATE, &dspctl);
2396 }});
2397 0x1: extrv_w({{
2398 Rt_uw = dspExtr(dspac, SIMD_FMT_W, Rs_uw,
2399 NOROUND, NOSATURATE, &dspctl);
2400 }});
2401 0x2: extp({{
2402 Rt_uw = dspExtp(dspac, RS, &dspctl);
2403 }});
2404 0x3: extpv({{
2405 Rt_uw = dspExtp(dspac, Rs_uw, &dspctl);
2406 }});
2407 0x4: extr_r_w({{
2408 Rt_uw = dspExtr(dspac, SIMD_FMT_W, RS,
2409 ROUND, NOSATURATE, &dspctl);
2410 }});
2411 0x5: extrv_r_w({{
2412 Rt_uw = dspExtr(dspac, SIMD_FMT_W, Rs_uw,
2413 ROUND, NOSATURATE, &dspctl);
2414 }});
2415 0x6: extr_rs_w({{
2416 Rt_uw = dspExtr(dspac, SIMD_FMT_W, RS,
2417 ROUND, SATURATE, &dspctl);
2418 }});
2419 0x7: extrv_rs_w({{
2420 Rt_uw = dspExtr(dspac, SIMD_FMT_W, Rs_uw,
2421 ROUND, SATURATE, &dspctl);
2422 }});
2423 }
2424 }
2425 0x1: decode OP_LO {
2426 format DspHiLoOp {
2427 0x2: extpdp({{
2428 Rt_uw = dspExtpd(dspac, RS, &dspctl);
2429 }});
2430 0x3: extpdpv({{
2431 Rt_uw = dspExtpd(dspac, Rs_uw, &dspctl);
2432 }});
2433 0x6: extr_s_h({{
2434 Rt_uw = dspExtr(dspac, SIMD_FMT_PH, RS,
2435 NOROUND, SATURATE, &dspctl);
2436 }});
2437 0x7: extrv_s_h({{
2438 Rt_uw = dspExtr(dspac, SIMD_FMT_PH, Rs_uw,
2439 NOROUND, SATURATE, &dspctl);
2440 }});
2441 }
2442 }
2443 0x2: decode OP_LO {
2444 format DspIntOp {
2445 0x2: rddsp({{
2446 Rd_uw = readDSPControl(&dspctl, RDDSPMASK);
2447 }});
2448 0x3: wrdsp({{
2449 writeDSPControl(&dspctl, Rs_uw, WRDSPMASK);
2450 }});
2451 }
2452 }
2453 0x3: decode OP_LO {
2454 format DspHiLoOp {
2455 0x2: shilo({{
2456 if ((int64_t)sext<6>(HILOSA) < 0) {
2457 dspac = (uint64_t)dspac <<
2458 -sext<6>(HILOSA);
2459 } else {
2460 dspac = (uint64_t)dspac >>
2461 sext<6>(HILOSA);
2462 }
2463 }});
2464 0x3: shilov({{
2465 if ((int64_t)sext<6>(Rs_sw<5:0>) < 0) {
2466 dspac = (uint64_t)dspac <<
2467 -sext<6>(Rs_sw<5:0>);
2468 } else {
2469 dspac = (uint64_t)dspac >>
2470 sext<6>(Rs_sw<5:0>);
2471 }
2472 }});
2473 0x7: mthlip({{
2474 dspac = dspac << 32;
2475 dspac |= Rs_uw;
2476 dspctl = insertBits(dspctl, 5, 0,
2477 dspctl<5:0> + 32);
2478 }});
2479 }
2480 }
2481 }
2482 0x3: decode OP default FailUnimpl::rdhwr() {
2483 0x0: decode FullSystemInt {
2484 0: decode RD {
2485 29: BasicOp::rdhwr_se({{ Rt = TpValue; }});
2486 }
2487 }
2488 }
2489 }
2490 }
2491 }
2492
2493 0x4: decode OPCODE_LO {
2494 format LoadMemory {
2495 0x0: lb({{ Rt_sw = Mem_sb; }});
2496 0x1: lh({{ Rt_sw = Mem_sh; }});
2497 0x3: lw({{ Rt_sw = Mem_sw; }});
2498 0x4: lbu({{ Rt_uw = Mem_ub;}});
2499 0x5: lhu({{ Rt_uw = Mem_uh; }});
2500 }
2501
2502 format LoadUnalignedMemory {
2503 0x2: lwl({{
2504 uint32_t mem_shift = 24 - (8 * byte_offset);
2505 Rt_uw = mem_word << mem_shift | (Rt_uw & mask(mem_shift));
2506 }});
2507 0x6: lwr({{
2508 uint32_t mem_shift = 8 * byte_offset;
2509 Rt_uw = (Rt_uw & (mask(mem_shift) << (32 - mem_shift))) |
2510 (mem_word >> mem_shift);
2511 }});
2512 }
2513 }
2514
2515 0x5: decode OPCODE_LO {
2516 format StoreMemory {
2517 0x0: sb({{ Mem_ub = Rt<7:0>; }});
2518 0x1: sh({{ Mem_uh = Rt<15:0>; }});
2519 0x3: sw({{ Mem_uw = Rt<31:0>; }});
2520 }
2521
2522 format StoreUnalignedMemory {
2523 0x2: swl({{
2524 uint32_t reg_shift = 24 - (8 * byte_offset);
2525 uint32_t mem_shift = 32 - reg_shift;
2526 mem_word = (mem_word & (mask(reg_shift) << mem_shift)) |
2527 (Rt_uw >> reg_shift);
2528 }});
2529 0x6: swr({{
2530 uint32_t reg_shift = 8 * byte_offset;
2531 mem_word = Rt_uw << reg_shift |
2532 (mem_word & (mask(reg_shift)));
2533 }});
2534 }
2535 format CP0Control {
2536 0x7: cache({{
2537 //Addr CacheEA = Rs_uw + OFFSET;
2538 //fault = xc->CacheOp((uint8_t)CACHE_OP,(Addr) CacheEA);
2539 }});
2540 }
2541 }
2542
2543 0x6: decode OPCODE_LO {
2544 format LoadMemory {
2545 0x0: ll({{ Rt_uw = Mem_uw; }}, mem_flags=LLSC);
2546 0x1: lwc1({{ Ft_uw = Mem_uw; }});
2547 0x5: ldc1({{ Ft_ud = Mem_ud; }});
2548 }
2549 0x2: CP2Unimpl::lwc2();
2550 0x6: CP2Unimpl::ldc2();
2551 0x3: Prefetch::pref();
2552 }
2553
2554
2555 0x7: decode OPCODE_LO {
2556 0x0: StoreCond::sc({{ Mem_uw = Rt_uw; }},
2557 {{ uint64_t tmp = write_result;
2558 Rt_uw = (tmp == 0 || tmp == 1) ? tmp : Rt_uw;
2559 }}, mem_flags=LLSC,
2560 inst_flags = IsStoreConditional);
2561 format StoreMemory {
2562 0x1: swc1({{ Mem_uw = Ft_uw; }});
2563 0x5: sdc1({{ Mem_ud = Ft_ud; }});
2564 }
2565 0x2: CP2Unimpl::swc2();
2566 0x6: CP2Unimpl::sdc2();
2567 }
2568}
2569
2570
914 // Check TLB for entry matching EntryHi
915 if (tlbIndex != -1) {
916 Index = tlbIndex;
917 } else {
918 // else, set Index = 1 << 31
919 Index = (1 << 31);
920 }
921 }});
922 }
923 format CP0Unimpl {
924 0x20: wait();
925 }
926 default: CP0Unimpl::unknown();
927 }
928 }
929
930 //Table A-13 MIPS32 COP1 Encoding of rs Field
931 0x1: decode RS_MSB {
932 0x0: decode RS_HI {
933 0x0: decode RS_LO {
934 format CP1Control {
935 0x0: mfc1 ({{ Rt_uw = Fs_uw; }});
936
937 0x2: cfc1({{
938 switch (FS) {
939 case 0:
940 Rt = FIR;
941 break;
942 case 25:
943 Rt = (FCSR & 0xFE000000) >> 24 |
944 (FCSR & 0x00800000) >> 23;
945 break;
946 case 26:
947 Rt = (FCSR & 0x0003F07C);
948 break;
949 case 28:
950 Rt = (FCSR & 0x00000F80) |
951 (FCSR & 0x01000000) >> 21 |
952 (FCSR & 0x00000003);
953 break;
954 case 31:
955 Rt = FCSR;
956 break;
957 default:
958 warn("FP Control Value (%d) Not Valid");
959 }
960 }});
961
962 0x3: mfhc1({{ Rt_uw = Fs_ud<63:32>; }});
963
964 0x4: mtc1({{ Fs_uw = Rt_uw; }});
965
966 0x6: ctc1({{
967 switch (FS) {
968 case 25:
969 FCSR = (Rt_uw<7:1> << 25) | // move 31-25
970 (FCSR & 0x01000000) | // bit 24
971 (FCSR & 0x004FFFFF); // bit 22-0
972 break;
973 case 26:
974 FCSR = (FCSR & 0xFFFC0000) | // move 31-18
975 Rt_uw<17:12> << 12 | // bit 17-12
976 (FCSR & 0x00000F80) << 7 | // bit 11-7
977 Rt_uw<6:2> << 2 | // bit 6-2
978 (FCSR & 0x00000002); // bit 1-0
979 break;
980 case 28:
981 FCSR = (FCSR & 0xFE000000) | // move 31-25
982 Rt_uw<2:2> << 24 | // bit 24
983 (FCSR & 0x00FFF000) << 23 | // bit 23-12
984 Rt_uw<11:7> << 7 | // bit 24
985 (FCSR & 0x000007E) |
986 Rt_uw<1:0>; // bit 22-0
987 break;
988 case 31:
989 FCSR = Rt_uw;
990 break;
991
992 default:
993 panic("FP Control Value (%d) "
994 "Not Available. Ignoring Access "
995 "to Floating Control Status "
996 "Register", FS);
997 }
998 }});
999
1000 0x7: mthc1({{
1001 uint64_t fs_hi = Rt_uw;
1002 uint64_t fs_lo = Fs_ud & 0x0FFFFFFFF;
1003 Fs_ud = (fs_hi << 32) | fs_lo;
1004 }});
1005
1006 }
1007 format CP1Unimpl {
1008 0x1: dmfc1();
1009 0x5: dmtc1();
1010 }
1011 }
1012
1013 0x1: decode RS_LO {
1014 0x0: decode ND {
1015 format Branch {
1016 0x0: decode TF {
1017 0x0: bc1f({{
1018 cond = getCondCode(FCSR, BRANCH_CC) == 0;
1019 }});
1020 0x1: bc1t({{
1021 cond = getCondCode(FCSR, BRANCH_CC) == 1;
1022 }});
1023 }
1024 0x1: decode TF {
1025 0x0: bc1fl({{
1026 cond = getCondCode(FCSR, BRANCH_CC) == 0;
1027 }}, Likely);
1028 0x1: bc1tl({{
1029 cond = getCondCode(FCSR, BRANCH_CC) == 1;
1030 }}, Likely);
1031 }
1032 }
1033 }
1034 format CP1Unimpl {
1035 0x1: bc1any2();
1036 0x2: bc1any4();
1037 default: unknown();
1038 }
1039 }
1040 }
1041
1042 0x1: decode RS_HI {
1043 0x2: decode RS_LO {
1044 //Table A-14 MIPS32 COP1 Encoding of Function Field When
1045 //rs=S (( single-precision floating point))
1046 0x0: decode FUNCTION_HI {
1047 0x0: decode FUNCTION_LO {
1048 format FloatOp {
1049 0x0: add_s({{ Fd_sf = Fs_sf + Ft_sf; }});
1050 0x1: sub_s({{ Fd_sf = Fs_sf - Ft_sf; }});
1051 0x2: mul_s({{ Fd_sf = Fs_sf * Ft_sf; }});
1052 0x3: div_s({{ Fd_sf = Fs_sf / Ft_sf; }});
1053 0x4: sqrt_s({{ Fd_sf = sqrt(Fs_sf); }});
1054 0x5: abs_s({{ Fd_sf = fabs(Fs_sf); }});
1055 0x7: neg_s({{ Fd_sf = -Fs_sf; }});
1056 }
1057 0x6: BasicOp::mov_s({{ Fd_sf = Fs_sf; }});
1058 }
1059 0x1: decode FUNCTION_LO {
1060 format FloatConvertOp {
1061 0x0: round_l_s({{ val = Fs_sf; }},
1062 ToLong, Round);
1063 0x1: trunc_l_s({{ val = Fs_sf; }},
1064 ToLong, Trunc);
1065 0x2: ceil_l_s({{ val = Fs_sf;}},
1066 ToLong, Ceil);
1067 0x3: floor_l_s({{ val = Fs_sf; }},
1068 ToLong, Floor);
1069 0x4: round_w_s({{ val = Fs_sf; }},
1070 ToWord, Round);
1071 0x5: trunc_w_s({{ val = Fs_sf; }},
1072 ToWord, Trunc);
1073 0x6: ceil_w_s({{ val = Fs_sf; }},
1074 ToWord, Ceil);
1075 0x7: floor_w_s({{ val = Fs_sf; }},
1076 ToWord, Floor);
1077 }
1078 }
1079
1080 0x2: decode FUNCTION_LO {
1081 0x1: decode MOVCF {
1082 format BasicOp {
1083 0x0: movf_s({{
1084 Fd = (getCondCode(FCSR,CC) == 0) ?
1085 Fs : Fd;
1086 }});
1087 0x1: movt_s({{
1088 Fd = (getCondCode(FCSR,CC) == 1) ?
1089 Fs : Fd;
1090 }});
1091 }
1092 }
1093
1094 format BasicOp {
1095 0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }});
1096 0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }});
1097 }
1098
1099 format FloatOp {
1100 0x5: recip_s({{ Fd = 1 / Fs; }});
1101 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs); }});
1102 }
1103 format CP1Unimpl {
1104 default: unknown();
1105 }
1106 }
1107 0x3: CP1Unimpl::unknown();
1108
1109 0x4: decode FUNCTION_LO {
1110 format FloatConvertOp {
1111 0x1: cvt_d_s({{ val = Fs_sf; }}, ToDouble);
1112 0x4: cvt_w_s({{ val = Fs_sf; }}, ToWord);
1113 0x5: cvt_l_s({{ val = Fs_sf; }}, ToLong);
1114 }
1115
1116 0x6: FloatOp::cvt_ps_s({{
1117 Fd_ud = (uint64_t) Fs_uw << 32 |
1118 (uint64_t) Ft_uw;
1119 }});
1120 format CP1Unimpl {
1121 default: unknown();
1122 }
1123 }
1124 0x5: CP1Unimpl::unknown();
1125
1126 0x6: decode FUNCTION_LO {
1127 format FloatCompareOp {
1128 0x0: c_f_s({{ cond = 0; }},
1129 SinglePrecision, UnorderedFalse);
1130 0x1: c_un_s({{ cond = 0; }},
1131 SinglePrecision, UnorderedTrue);
1132 0x2: c_eq_s({{ cond = (Fs_sf == Ft_sf); }},
1133 UnorderedFalse);
1134 0x3: c_ueq_s({{ cond = (Fs_sf == Ft_sf); }},
1135 UnorderedTrue);
1136 0x4: c_olt_s({{ cond = (Fs_sf < Ft_sf); }},
1137 UnorderedFalse);
1138 0x5: c_ult_s({{ cond = (Fs_sf < Ft_sf); }},
1139 UnorderedTrue);
1140 0x6: c_ole_s({{ cond = (Fs_sf <= Ft_sf); }},
1141 UnorderedFalse);
1142 0x7: c_ule_s({{ cond = (Fs_sf <= Ft_sf); }},
1143 UnorderedTrue);
1144 }
1145 }
1146
1147 0x7: decode FUNCTION_LO {
1148 format FloatCompareOp {
1149 0x0: c_sf_s({{ cond = 0; }}, SinglePrecision,
1150 UnorderedFalse, QnanException);
1151 0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision,
1152 UnorderedTrue, QnanException);
1153 0x2: c_seq_s({{ cond = (Fs_sf == Ft_sf); }},
1154 UnorderedFalse, QnanException);
1155 0x3: c_ngl_s({{ cond = (Fs_sf == Ft_sf); }},
1156 UnorderedTrue, QnanException);
1157 0x4: c_lt_s({{ cond = (Fs_sf < Ft_sf); }},
1158 UnorderedFalse, QnanException);
1159 0x5: c_nge_s({{ cond = (Fs_sf < Ft_sf); }},
1160 UnorderedTrue, QnanException);
1161 0x6: c_le_s({{ cond = (Fs_sf <= Ft_sf); }},
1162 UnorderedFalse, QnanException);
1163 0x7: c_ngt_s({{ cond = (Fs_sf <= Ft_sf); }},
1164 UnorderedTrue, QnanException);
1165 }
1166 }
1167 }
1168
1169 //Table A-15 MIPS32 COP1 Encoding of Function Field When
1170 //rs=D
1171 0x1: decode FUNCTION_HI {
1172 0x0: decode FUNCTION_LO {
1173 format FloatOp {
1174 0x0: add_d({{ Fd_df = Fs_df + Ft_df; }});
1175 0x1: sub_d({{ Fd_df = Fs_df - Ft_df; }});
1176 0x2: mul_d({{ Fd_df = Fs_df * Ft_df; }});
1177 0x3: div_d({{ Fd_df = Fs_df / Ft_df; }});
1178 0x4: sqrt_d({{ Fd_df = sqrt(Fs_df); }});
1179 0x5: abs_d({{ Fd_df = fabs(Fs_df); }});
1180 0x7: neg_d({{ Fd_df = -1 * Fs_df; }});
1181 }
1182 0x6: BasicOp::mov_d({{ Fd_df = Fs_df; }});
1183 }
1184
1185 0x1: decode FUNCTION_LO {
1186 format FloatConvertOp {
1187 0x0: round_l_d({{ val = Fs_df; }},
1188 ToLong, Round);
1189 0x1: trunc_l_d({{ val = Fs_df; }},
1190 ToLong, Trunc);
1191 0x2: ceil_l_d({{ val = Fs_df; }},
1192 ToLong, Ceil);
1193 0x3: floor_l_d({{ val = Fs_df; }},
1194 ToLong, Floor);
1195 0x4: round_w_d({{ val = Fs_df; }},
1196 ToWord, Round);
1197 0x5: trunc_w_d({{ val = Fs_df; }},
1198 ToWord, Trunc);
1199 0x6: ceil_w_d({{ val = Fs_df; }},
1200 ToWord, Ceil);
1201 0x7: floor_w_d({{ val = Fs_df; }},
1202 ToWord, Floor);
1203 }
1204 }
1205
1206 0x2: decode FUNCTION_LO {
1207 0x1: decode MOVCF {
1208 format BasicOp {
1209 0x0: movf_d({{
1210 Fd_df = (getCondCode(FCSR,CC) == 0) ?
1211 Fs_df : Fd_df;
1212 }});
1213 0x1: movt_d({{
1214 Fd_df = (getCondCode(FCSR,CC) == 1) ?
1215 Fs_df : Fd_df;
1216 }});
1217 }
1218 }
1219
1220 format BasicOp {
1221 0x2: movz_d({{
1222 Fd_df = (Rt == 0) ? Fs_df : Fd_df;
1223 }});
1224 0x3: movn_d({{
1225 Fd_df = (Rt != 0) ? Fs_df : Fd_df;
1226 }});
1227 }
1228
1229 format FloatOp {
1230 0x5: recip_d({{ Fd_df = 1 / Fs_df; }});
1231 0x6: rsqrt_d({{ Fd_df = 1 / sqrt(Fs_df); }});
1232 }
1233 format CP1Unimpl {
1234 default: unknown();
1235 }
1236
1237 }
1238 0x4: decode FUNCTION_LO {
1239 format FloatConvertOp {
1240 0x0: cvt_s_d({{ val = Fs_df; }}, ToSingle);
1241 0x4: cvt_w_d({{ val = Fs_df; }}, ToWord);
1242 0x5: cvt_l_d({{ val = Fs_df; }}, ToLong);
1243 }
1244 default: CP1Unimpl::unknown();
1245 }
1246
1247 0x6: decode FUNCTION_LO {
1248 format FloatCompareOp {
1249 0x0: c_f_d({{ cond = 0; }},
1250 DoublePrecision, UnorderedFalse);
1251 0x1: c_un_d({{ cond = 0; }},
1252 DoublePrecision, UnorderedTrue);
1253 0x2: c_eq_d({{ cond = (Fs_df == Ft_df); }},
1254 UnorderedFalse);
1255 0x3: c_ueq_d({{ cond = (Fs_df == Ft_df); }},
1256 UnorderedTrue);
1257 0x4: c_olt_d({{ cond = (Fs_df < Ft_df); }},
1258 UnorderedFalse);
1259 0x5: c_ult_d({{ cond = (Fs_df < Ft_df); }},
1260 UnorderedTrue);
1261 0x6: c_ole_d({{ cond = (Fs_df <= Ft_df); }},
1262 UnorderedFalse);
1263 0x7: c_ule_d({{ cond = (Fs_df <= Ft_df); }},
1264 UnorderedTrue);
1265 }
1266 }
1267
1268 0x7: decode FUNCTION_LO {
1269 format FloatCompareOp {
1270 0x0: c_sf_d({{ cond = 0; }}, DoublePrecision,
1271 UnorderedFalse, QnanException);
1272 0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision,
1273 UnorderedTrue, QnanException);
1274 0x2: c_seq_d({{ cond = (Fs_df == Ft_df); }},
1275 UnorderedFalse, QnanException);
1276 0x3: c_ngl_d({{ cond = (Fs_df == Ft_df); }},
1277 UnorderedTrue, QnanException);
1278 0x4: c_lt_d({{ cond = (Fs_df < Ft_df); }},
1279 UnorderedFalse, QnanException);
1280 0x5: c_nge_d({{ cond = (Fs_df < Ft_df); }},
1281 UnorderedTrue, QnanException);
1282 0x6: c_le_d({{ cond = (Fs_df <= Ft_df); }},
1283 UnorderedFalse, QnanException);
1284 0x7: c_ngt_d({{ cond = (Fs_df <= Ft_df); }},
1285 UnorderedTrue, QnanException);
1286 }
1287 }
1288 default: CP1Unimpl::unknown();
1289 }
1290 0x2: CP1Unimpl::unknown();
1291 0x3: CP1Unimpl::unknown();
1292 0x7: CP1Unimpl::unknown();
1293
1294 //Table A-16 MIPS32 COP1 Encoding of Function
1295 //Field When rs=W
1296 0x4: decode FUNCTION {
1297 format FloatConvertOp {
1298 0x20: cvt_s_w({{ val = Fs_sw; }}, ToSingle);
1299 0x21: cvt_d_w({{ val = Fs_sw; }}, ToDouble);
1300 0x26: CP1Unimpl::cvt_ps_w();
1301 }
1302 default: CP1Unimpl::unknown();
1303 }
1304
1305 //Table A-16 MIPS32 COP1 Encoding of Function Field
1306 //When rs=L1
1307 //Note: "1. Format type L is legal only if 64-bit
1308 //floating point operations are enabled."
1309 0x5: decode FUNCTION {
1310 format FloatConvertOp {
1311 0x20: cvt_s_l({{ val = Fs_sd; }}, ToSingle);
1312 0x21: cvt_d_l({{ val = Fs_sd; }}, ToDouble);
1313 0x26: CP1Unimpl::cvt_ps_l();
1314 }
1315 default: CP1Unimpl::unknown();
1316 }
1317
1318 //Table A-17 MIPS64 COP1 Encoding of Function Field
1319 //When rs=PS1
1320 //Note: "1. Format type PS is legal only if 64-bit
1321 //floating point operations are enabled. "
1322 0x6: decode FUNCTION_HI {
1323 0x0: decode FUNCTION_LO {
1324 format Float64Op {
1325 0x0: add_ps({{
1326 Fd1_sf = Fs1_sf + Ft2_sf;
1327 Fd2_sf = Fs2_sf + Ft2_sf;
1328 }});
1329 0x1: sub_ps({{
1330 Fd1_sf = Fs1_sf - Ft2_sf;
1331 Fd2_sf = Fs2_sf - Ft2_sf;
1332 }});
1333 0x2: mul_ps({{
1334 Fd1_sf = Fs1_sf * Ft2_sf;
1335 Fd2_sf = Fs2_sf * Ft2_sf;
1336 }});
1337 0x5: abs_ps({{
1338 Fd1_sf = fabs(Fs1_sf);
1339 Fd2_sf = fabs(Fs2_sf);
1340 }});
1341 0x6: mov_ps({{
1342 Fd1_sf = Fs1_sf;
1343 Fd2_sf = Fs2_sf;
1344 }});
1345 0x7: neg_ps({{
1346 Fd1_sf = -(Fs1_sf);
1347 Fd2_sf = -(Fs2_sf);
1348 }});
1349 default: CP1Unimpl::unknown();
1350 }
1351 }
1352 0x1: CP1Unimpl::unknown();
1353 0x2: decode FUNCTION_LO {
1354 0x1: decode MOVCF {
1355 format Float64Op {
1356 0x0: movf_ps({{
1357 Fd1 = (getCondCode(FCSR, CC) == 0) ?
1358 Fs1 : Fd1;
1359 Fd2 = (getCondCode(FCSR, CC+1) == 0) ?
1360 Fs2 : Fd2;
1361 }});
1362 0x1: movt_ps({{
1363 Fd2 = (getCondCode(FCSR, CC) == 1) ?
1364 Fs1 : Fd1;
1365 Fd2 = (getCondCode(FCSR, CC+1) == 1) ?
1366 Fs2 : Fd2;
1367 }});
1368 }
1369 }
1370
1371 format Float64Op {
1372 0x2: movz_ps({{
1373 Fd1 = (getCondCode(FCSR, CC) == 0) ?
1374 Fs1 : Fd1;
1375 Fd2 = (getCondCode(FCSR, CC) == 0) ?
1376 Fs2 : Fd2;
1377 }});
1378 0x3: movn_ps({{
1379 Fd1 = (getCondCode(FCSR, CC) == 1) ?
1380 Fs1 : Fd1;
1381 Fd2 = (getCondCode(FCSR, CC) == 1) ?
1382 Fs2 : Fd2;
1383 }});
1384 }
1385 default: CP1Unimpl::unknown();
1386 }
1387 0x3: CP1Unimpl::unknown();
1388 0x4: decode FUNCTION_LO {
1389 0x0: FloatOp::cvt_s_pu({{ Fd_sf = Fs2_sf; }});
1390 default: CP1Unimpl::unknown();
1391 }
1392
1393 0x5: decode FUNCTION_LO {
1394 0x0: FloatOp::cvt_s_pl({{ Fd_sf = Fs1_sf; }});
1395 format Float64Op {
1396 0x4: pll({{
1397 Fd_ud = (uint64_t)Fs1_uw << 32 | Ft1_uw;
1398 }});
1399 0x5: plu({{
1400 Fd_ud = (uint64_t)Fs1_uw << 32 | Ft2_uw;
1401 }});
1402 0x6: pul({{
1403 Fd_ud = (uint64_t)Fs2_uw << 32 | Ft1_uw;
1404 }});
1405 0x7: puu({{
1406 Fd_ud = (uint64_t)Fs2_uw << 32 | Ft2_uw;
1407 }});
1408 }
1409 default: CP1Unimpl::unknown();
1410 }
1411
1412 0x6: decode FUNCTION_LO {
1413 format FloatPSCompareOp {
1414 0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1415 UnorderedFalse);
1416 0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1417 UnorderedTrue);
1418 0x2: c_eq_ps({{ cond1 = (Fs1_sf == Ft1_sf); }},
1419 {{ cond2 = (Fs2_sf == Ft2_sf); }},
1420 UnorderedFalse);
1421 0x3: c_ueq_ps({{ cond1 = (Fs1_sf == Ft1_sf); }},
1422 {{ cond2 = (Fs2_sf == Ft2_sf); }},
1423 UnorderedTrue);
1424 0x4: c_olt_ps({{ cond1 = (Fs1_sf < Ft1_sf); }},
1425 {{ cond2 = (Fs2_sf < Ft2_sf); }},
1426 UnorderedFalse);
1427 0x5: c_ult_ps({{ cond1 = (Fs_sf < Ft_sf); }},
1428 {{ cond2 = (Fs2_sf < Ft2_sf); }},
1429 UnorderedTrue);
1430 0x6: c_ole_ps({{ cond1 = (Fs_sf <= Ft_sf); }},
1431 {{ cond2 = (Fs2_sf <= Ft2_sf); }},
1432 UnorderedFalse);
1433 0x7: c_ule_ps({{ cond1 = (Fs1_sf <= Ft1_sf); }},
1434 {{ cond2 = (Fs2_sf <= Ft2_sf); }},
1435 UnorderedTrue);
1436 }
1437 }
1438
1439 0x7: decode FUNCTION_LO {
1440 format FloatPSCompareOp {
1441 0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1442 UnorderedFalse, QnanException);
1443 0x1: c_ngle_ps({{ cond1 = 0; }},
1444 {{ cond2 = 0; }},
1445 UnorderedTrue, QnanException);
1446 0x2: c_seq_ps({{ cond1 = (Fs1_sf == Ft1_sf); }},
1447 {{ cond2 = (Fs2_sf == Ft2_sf); }},
1448 UnorderedFalse, QnanException);
1449 0x3: c_ngl_ps({{ cond1 = (Fs1_sf == Ft1_sf); }},
1450 {{ cond2 = (Fs2_sf == Ft2_sf); }},
1451 UnorderedTrue, QnanException);
1452 0x4: c_lt_ps({{ cond1 = (Fs1_sf < Ft1_sf); }},
1453 {{ cond2 = (Fs2_sf < Ft2_sf); }},
1454 UnorderedFalse, QnanException);
1455 0x5: c_nge_ps({{ cond1 = (Fs1_sf < Ft1_sf); }},
1456 {{ cond2 = (Fs2_sf < Ft2_sf); }},
1457 UnorderedTrue, QnanException);
1458 0x6: c_le_ps({{ cond1 = (Fs1_sf <= Ft1_sf); }},
1459 {{ cond2 = (Fs2_sf <= Ft2_sf); }},
1460 UnorderedFalse, QnanException);
1461 0x7: c_ngt_ps({{ cond1 = (Fs1_sf <= Ft1_sf); }},
1462 {{ cond2 = (Fs2_sf <= Ft2_sf); }},
1463 UnorderedTrue, QnanException);
1464 }
1465 }
1466 }
1467 }
1468 default: CP1Unimpl::unknown();
1469 }
1470 }
1471
1472 //Table A-19 MIPS32 COP2 Encoding of rs Field
1473 0x2: decode RS_MSB {
1474 format CP2Unimpl {
1475 0x0: decode RS_HI {
1476 0x0: decode RS_LO {
1477 0x0: mfc2();
1478 0x2: cfc2();
1479 0x3: mfhc2();
1480 0x4: mtc2();
1481 0x6: ctc2();
1482 0x7: mftc2();
1483 default: unknown();
1484 }
1485
1486 0x1: decode ND {
1487 0x0: decode TF {
1488 0x0: bc2f();
1489 0x1: bc2t();
1490 default: unknown();
1491 }
1492
1493 0x1: decode TF {
1494 0x0: bc2fl();
1495 0x1: bc2tl();
1496 default: unknown();
1497 }
1498 default: unknown();
1499
1500 }
1501 default: unknown();
1502 }
1503 default: unknown();
1504 }
1505 }
1506
1507 //Table A-20 MIPS64 COP1X Encoding of Function Field 1
1508 //Note: "COP1X instructions are legal only if 64-bit floating point
1509 //operations are enabled."
1510 0x3: decode FUNCTION_HI {
1511 0x0: decode FUNCTION_LO {
1512 format LoadIndexedMemory {
1513 0x0: lwxc1({{ Fd_uw = Mem_uw; }});
1514 0x1: ldxc1({{ Fd_ud = Mem_ud; }});
1515 0x5: luxc1({{ Fd_ud = Mem_ud; }},
1516 {{ EA = (Rs + Rt) & ~7; }});
1517 }
1518 }
1519
1520 0x1: decode FUNCTION_LO {
1521 format StoreIndexedMemory {
1522 0x0: swxc1({{ Mem_uw = Fs_uw; }});
1523 0x1: sdxc1({{ Mem_ud = Fs_ud; }});
1524 0x5: suxc1({{ Mem_ud = Fs_ud; }},
1525 {{ EA = (Rs + Rt) & ~7; }});
1526 }
1527 0x7: Prefetch::prefx({{ EA = Rs + Rt; }});
1528 }
1529
1530 0x3: decode FUNCTION_LO {
1531 0x6: Float64Op::alnv_ps({{
1532 if (Rs<2:0> == 0) {
1533 Fd_ud = Fs_ud;
1534 } else if (Rs<2:0> == 4) {
1535 if (GuestByteOrder == BigEndianByteOrder)
1536 Fd_ud = Fs_ud<31:0> << 32 | Ft_ud<63:32>;
1537 else
1538 Fd_ud = Ft_ud<31:0> << 32 | Fs_ud<63:32>;
1539 } else {
1540 Fd_ud = Fd_ud;
1541 }
1542 }});
1543 }
1544
1545 format FloatAccOp {
1546 0x4: decode FUNCTION_LO {
1547 0x0: madd_s({{ Fd_sf = (Fs_sf * Ft_sf) + Fr_sf; }});
1548 0x1: madd_d({{ Fd_df = (Fs_df * Ft_df) + Fr_df; }});
1549 0x6: madd_ps({{
1550 Fd1_sf = (Fs1_df * Ft1_df) + Fr1_df;
1551 Fd2_sf = (Fs2_df * Ft2_df) + Fr2_df;
1552 }});
1553 }
1554
1555 0x5: decode FUNCTION_LO {
1556 0x0: msub_s({{ Fd_sf = (Fs_sf * Ft_sf) - Fr_sf; }});
1557 0x1: msub_d({{ Fd_df = (Fs_df * Ft_df) - Fr_df; }});
1558 0x6: msub_ps({{
1559 Fd1_sf = (Fs1_df * Ft1_df) - Fr1_df;
1560 Fd2_sf = (Fs2_df * Ft2_df) - Fr2_df;
1561 }});
1562 }
1563
1564 0x6: decode FUNCTION_LO {
1565 0x0: nmadd_s({{ Fd_sf = (-1 * Fs_sf * Ft_sf) - Fr_sf; }});
1566 0x1: nmadd_d({{ Fd_df = (-1 * Fs_df * Ft_df) - Fr_df; }});
1567 0x6: nmadd_ps({{
1568 Fd1_sf = -((Fs1_df * Ft1_df) + Fr1_df);
1569 Fd2_sf = -((Fs2_df * Ft2_df) + Fr2_df);
1570 }});
1571 }
1572
1573 0x7: decode FUNCTION_LO {
1574 0x0: nmsub_s({{ Fd_sf = (-1 * Fs_sf * Ft_sf) + Fr_sf; }});
1575 0x1: nmsub_d({{ Fd_df = (-1 * Fs_df * Ft_df) + Fr_df; }});
1576 0x6: nmsub_ps({{
1577 Fd1_sf = -((Fs1_df * Ft1_df) - Fr1_df);
1578 Fd2_sf = -((Fs2_df * Ft2_df) - Fr2_df);
1579 }});
1580 }
1581 }
1582 }
1583
1584 format Branch {
1585 0x4: beql({{ cond = (Rs_sw == Rt_sw); }}, Likely);
1586 0x5: bnel({{ cond = (Rs_sw != Rt_sw); }}, Likely);
1587 0x6: blezl({{ cond = (Rs_sw <= 0); }}, Likely);
1588 0x7: bgtzl({{ cond = (Rs_sw > 0); }}, Likely);
1589 }
1590 }
1591
1592 0x3: decode OPCODE_LO {
1593 //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
1594 0x4: decode FUNCTION_HI {
1595 0x0: decode FUNCTION_LO {
1596 0x2: IntOp::mul({{
1597 int64_t temp1 = Rs_sd * Rt_sd;
1598 Rd_sw = temp1<31:0>;
1599 }}, IntMultOp);
1600
1601 format HiLoRdSelValOp {
1602 0x0: madd({{
1603 val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1604 (Rs_sd * Rt_sd);
1605 }}, IntMultOp);
1606 0x1: maddu({{
1607 val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1608 (Rs_ud * Rt_ud);
1609 }}, IntMultOp);
1610 0x4: msub({{
1611 val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1612 (Rs_sd * Rt_sd);
1613 }}, IntMultOp);
1614 0x5: msubu({{
1615 val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1616 (Rs_ud * Rt_ud);
1617 }}, IntMultOp);
1618 }
1619 }
1620
1621 0x4: decode FUNCTION_LO {
1622 format BasicOp {
1623 0x0: clz({{
1624 int cnt = 32;
1625 for (int idx = 31; idx >= 0; idx--) {
1626 if (Rs<idx:idx> == 1) {
1627 cnt = 31 - idx;
1628 break;
1629 }
1630 }
1631 Rd_uw = cnt;
1632 }});
1633 0x1: clo({{
1634 int cnt = 32;
1635 for (int idx = 31; idx >= 0; idx--) {
1636 if (Rs<idx:idx> == 0) {
1637 cnt = 31 - idx;
1638 break;
1639 }
1640 }
1641 Rd_uw = cnt;
1642 }});
1643 }
1644 }
1645
1646 0x7: decode FUNCTION_LO {
1647 0x7: FailUnimpl::sdbbp();
1648 }
1649 }
1650
1651 //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2
1652 //of the Architecture
1653 0x7: decode FUNCTION_HI {
1654 0x0: decode FUNCTION_LO {
1655 format BasicOp {
1656 0x0: ext({{ Rt_uw = bits(Rs_uw, MSB+LSB, LSB); }});
1657 0x4: ins({{
1658 Rt_uw = bits(Rt_uw, 31, MSB+1) << (MSB+1) |
1659 bits(Rs_uw, MSB-LSB, 0) << LSB |
1660 bits(Rt_uw, LSB-1, 0);
1661 }});
1662 }
1663 }
1664
1665 0x1: decode FUNCTION_LO {
1666 format MT_Control {
1667 0x0: fork({{
1668 forkThread(xc->tcBase(), fault, RD, Rs, Rt);
1669 }}, UserMode);
1670 0x1: yield({{
1671 Rd_sw = yieldThread(xc->tcBase(), fault, Rs_sw,
1672 YQMask);
1673 }}, UserMode);
1674 }
1675
1676 //Table 5-9 MIPS32 LX Encoding of the op Field (DSP ASE MANUAL)
1677 0x2: decode OP_HI {
1678 0x0: decode OP_LO {
1679 format LoadIndexedMemory {
1680 0x0: lwx({{ Rd_sw = Mem_sw; }});
1681 0x4: lhx({{ Rd_sw = Mem_sh; }});
1682 0x6: lbux({{ Rd_uw = Mem_ub; }});
1683 }
1684 }
1685 }
1686 0x4: DspIntOp::insv({{
1687 int pos = dspctl<5:0>;
1688 int size = dspctl<12:7> - 1;
1689 Rt_uw = insertBits(Rt_uw, pos+size,
1690 pos, Rs_uw<size:0>);
1691 }});
1692 }
1693
1694 0x2: decode FUNCTION_LO {
1695
1696 //Table 5-5 MIPS32 ADDU.QB Encoding of the op Field
1697 //(DSP ASE MANUAL)
1698 0x0: decode OP_HI {
1699 0x0: decode OP_LO {
1700 format DspIntOp {
1701 0x0: addu_qb({{
1702 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1703 NOSATURATE, UNSIGNED, &dspctl);
1704 }});
1705 0x1: subu_qb({{
1706 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_QB,
1707 NOSATURATE, UNSIGNED, &dspctl);
1708 }});
1709 0x4: addu_s_qb({{
1710 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1711 SATURATE, UNSIGNED, &dspctl);
1712 }});
1713 0x5: subu_s_qb({{
1714 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_QB,
1715 SATURATE, UNSIGNED, &dspctl);
1716 }});
1717 0x6: muleu_s_ph_qbl({{
1718 Rd_uw = dspMuleu(Rs_uw, Rt_uw,
1719 MODE_L, &dspctl);
1720 }}, IntMultOp);
1721 0x7: muleu_s_ph_qbr({{
1722 Rd_uw = dspMuleu(Rs_uw, Rt_uw,
1723 MODE_R, &dspctl);
1724 }}, IntMultOp);
1725 }
1726 }
1727 0x1: decode OP_LO {
1728 format DspIntOp {
1729 0x0: addu_ph({{
1730 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_PH,
1731 NOSATURATE, UNSIGNED, &dspctl);
1732 }});
1733 0x1: subu_ph({{
1734 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_PH,
1735 NOSATURATE, UNSIGNED, &dspctl);
1736 }});
1737 0x2: addq_ph({{
1738 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_PH,
1739 NOSATURATE, SIGNED, &dspctl);
1740 }});
1741 0x3: subq_ph({{
1742 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_PH,
1743 NOSATURATE, SIGNED, &dspctl);
1744 }});
1745 0x4: addu_s_ph({{
1746 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_PH,
1747 SATURATE, UNSIGNED, &dspctl);
1748 }});
1749 0x5: subu_s_ph({{
1750 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_PH,
1751 SATURATE, UNSIGNED, &dspctl);
1752 }});
1753 0x6: addq_s_ph({{
1754 Rd_uw = dspAdd(Rs_uw, Rt_uw, SIMD_FMT_PH,
1755 SATURATE, SIGNED, &dspctl);
1756 }});
1757 0x7: subq_s_ph({{
1758 Rd_uw = dspSub(Rs_uw, Rt_uw, SIMD_FMT_PH,
1759 SATURATE, SIGNED, &dspctl);
1760 }});
1761 }
1762 }
1763 0x2: decode OP_LO {
1764 format DspIntOp {
1765 0x0: addsc({{
1766 int64_t dresult;
1767 dresult = Rs_ud + Rt_ud;
1768 Rd_sw = dresult<31:0>;
1769 dspctl = insertBits(dspctl, 13, 13,
1770 dresult<32:32>);
1771 }});
1772 0x1: addwc({{
1773 int64_t dresult;
1774 dresult = Rs_sd + Rt_sd + dspctl<13:13>;
1775 Rd_sw = dresult<31:0>;
1776 if (dresult<32:32> != dresult<31:31>)
1777 dspctl = insertBits(dspctl, 20, 20, 1);
1778 }});
1779 0x2: modsub({{
1780 Rd_sw = (Rs_sw == 0) ? Rt_sw<23:8> :
1781 Rs_sw - Rt_sw<7:0>;
1782 }});
1783 0x4: raddu_w_qb({{
1784 Rd_uw = Rs_uw<31:24> + Rs_uw<23:16> +
1785 Rs_uw<15:8> + Rs_uw<7:0>;
1786 }});
1787 0x6: addq_s_w({{
1788 Rd_sw = dspAdd(Rs_sw, Rt_sw, SIMD_FMT_W,
1789 SATURATE, SIGNED, &dspctl);
1790 }});
1791 0x7: subq_s_w({{
1792 Rd_sw = dspSub(Rs_sw, Rt_sw, SIMD_FMT_W,
1793 SATURATE, SIGNED, &dspctl);
1794 }});
1795 }
1796 }
1797 0x3: decode OP_LO {
1798 format DspIntOp {
1799 0x4: muleq_s_w_phl({{
1800 Rd_sw = dspMuleq(Rs_sw, Rt_sw,
1801 MODE_L, &dspctl);
1802 }}, IntMultOp);
1803 0x5: muleq_s_w_phr({{
1804 Rd_sw = dspMuleq(Rs_sw, Rt_sw,
1805 MODE_R, &dspctl);
1806 }}, IntMultOp);
1807 0x6: mulq_s_ph({{
1808 Rd_sw = dspMulq(Rs_sw, Rt_sw, SIMD_FMT_PH,
1809 SATURATE, NOROUND, &dspctl);
1810 }}, IntMultOp);
1811 0x7: mulq_rs_ph({{
1812 Rd_sw = dspMulq(Rs_sw, Rt_sw, SIMD_FMT_PH,
1813 SATURATE, ROUND, &dspctl);
1814 }}, IntMultOp);
1815 }
1816 }
1817 }
1818
1819 //Table 5-6 MIPS32 CMPU_EQ_QB Encoding of the op Field
1820 //(DSP ASE MANUAL)
1821 0x1: decode OP_HI {
1822 0x0: decode OP_LO {
1823 format DspIntOp {
1824 0x0: cmpu_eq_qb({{
1825 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_QB,
1826 UNSIGNED, CMP_EQ, &dspctl);
1827 }});
1828 0x1: cmpu_lt_qb({{
1829 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_QB,
1830 UNSIGNED, CMP_LT, &dspctl);
1831 }});
1832 0x2: cmpu_le_qb({{
1833 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_QB,
1834 UNSIGNED, CMP_LE, &dspctl);
1835 }});
1836 0x3: pick_qb({{
1837 Rd_uw = dspPick(Rs_uw, Rt_uw,
1838 SIMD_FMT_QB, &dspctl);
1839 }});
1840 0x4: cmpgu_eq_qb({{
1841 Rd_uw = dspCmpg(Rs_uw, Rt_uw, SIMD_FMT_QB,
1842 UNSIGNED, CMP_EQ );
1843 }});
1844 0x5: cmpgu_lt_qb({{
1845 Rd_uw = dspCmpg(Rs_uw, Rt_uw, SIMD_FMT_QB,
1846 UNSIGNED, CMP_LT);
1847 }});
1848 0x6: cmpgu_le_qb({{
1849 Rd_uw = dspCmpg(Rs_uw, Rt_uw, SIMD_FMT_QB,
1850 UNSIGNED, CMP_LE);
1851 }});
1852 }
1853 }
1854 0x1: decode OP_LO {
1855 format DspIntOp {
1856 0x0: cmp_eq_ph({{
1857 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_PH,
1858 SIGNED, CMP_EQ, &dspctl);
1859 }});
1860 0x1: cmp_lt_ph({{
1861 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_PH,
1862 SIGNED, CMP_LT, &dspctl);
1863 }});
1864 0x2: cmp_le_ph({{
1865 dspCmp(Rs_uw, Rt_uw, SIMD_FMT_PH,
1866 SIGNED, CMP_LE, &dspctl);
1867 }});
1868 0x3: pick_ph({{
1869 Rd_uw = dspPick(Rs_uw, Rt_uw,
1870 SIMD_FMT_PH, &dspctl);
1871 }});
1872 0x4: precrq_qb_ph({{
1873 Rd_uw = Rs_uw<31:24> << 24 |
1874 Rs_uw<15:8> << 16 |
1875 Rt_uw<31:24> << 8 |
1876 Rt_uw<15:8>;
1877 }});
1878 0x5: precr_qb_ph({{
1879 Rd_uw = Rs_uw<23:16> << 24 |
1880 Rs_uw<7:0> << 16 |
1881 Rt_uw<23:16> << 8 |
1882 Rt_uw<7:0>;
1883 }});
1884 0x6: packrl_ph({{
1885 Rd_uw = dspPack(Rs_uw, Rt_uw, SIMD_FMT_PH);
1886 }});
1887 0x7: precrqu_s_qb_ph({{
1888 Rd_uw = dspPrecrqu(Rs_uw, Rt_uw, &dspctl);
1889 }});
1890 }
1891 }
1892 0x2: decode OP_LO {
1893 format DspIntOp {
1894 0x4: precrq_ph_w({{
1895 Rd_uw = Rs_uw<31:16> << 16 | Rt_uw<31:16>;
1896 }});
1897 0x5: precrq_rs_ph_w({{
1898 Rd_uw = dspPrecrq(Rs_uw, Rt_uw,
1899 SIMD_FMT_W, &dspctl);
1900 }});
1901 }
1902 }
1903 0x3: decode OP_LO {
1904 format DspIntOp {
1905 0x0: cmpgdu_eq_qb({{
1906 Rd_uw = dspCmpgd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1907 UNSIGNED, CMP_EQ, &dspctl);
1908 }});
1909 0x1: cmpgdu_lt_qb({{
1910 Rd_uw = dspCmpgd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1911 UNSIGNED, CMP_LT, &dspctl);
1912 }});
1913 0x2: cmpgdu_le_qb({{
1914 Rd_uw = dspCmpgd(Rs_uw, Rt_uw, SIMD_FMT_QB,
1915 UNSIGNED, CMP_LE, &dspctl);
1916 }});
1917 0x6: precr_sra_ph_w({{
1918 Rt_uw = dspPrecrSra(Rt_uw, Rs_uw, RD,
1919 SIMD_FMT_W, NOROUND);
1920 }});
1921 0x7: precr_sra_r_ph_w({{
1922 Rt_uw = dspPrecrSra(Rt_uw, Rs_uw, RD,
1923 SIMD_FMT_W, ROUND);
1924 }});
1925 }
1926 }
1927 }
1928
1929 //Table 5-7 MIPS32 ABSQ_S.PH Encoding of the op Field
1930 //(DSP ASE MANUAL)
1931 0x2: decode OP_HI {
1932 0x0: decode OP_LO {
1933 format DspIntOp {
1934 0x1: absq_s_qb({{
1935 Rd_sw = dspAbs(Rt_sw, SIMD_FMT_QB, &dspctl);
1936 }});
1937 0x2: repl_qb({{
1938 Rd_uw = RS_RT<7:0> << 24 |
1939 RS_RT<7:0> << 16 |
1940 RS_RT<7:0> << 8 |
1941 RS_RT<7:0>;
1942 }});
1943 0x3: replv_qb({{
1944 Rd_sw = Rt_uw<7:0> << 24 |
1945 Rt_uw<7:0> << 16 |
1946 Rt_uw<7:0> << 8 |
1947 Rt_uw<7:0>;
1948 }});
1949 0x4: precequ_ph_qbl({{
1950 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB, UNSIGNED,
1951 SIMD_FMT_PH, SIGNED, MODE_L);
1952 }});
1953 0x5: precequ_ph_qbr({{
1954 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB, UNSIGNED,
1955 SIMD_FMT_PH, SIGNED, MODE_R);
1956 }});
1957 0x6: precequ_ph_qbla({{
1958 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB, UNSIGNED,
1959 SIMD_FMT_PH, SIGNED, MODE_LA);
1960 }});
1961 0x7: precequ_ph_qbra({{
1962 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB, UNSIGNED,
1963 SIMD_FMT_PH, SIGNED, MODE_RA);
1964 }});
1965 }
1966 }
1967 0x1: decode OP_LO {
1968 format DspIntOp {
1969 0x1: absq_s_ph({{
1970 Rd_sw = dspAbs(Rt_sw, SIMD_FMT_PH, &dspctl);
1971 }});
1972 0x2: repl_ph({{
1973 Rd_uw = (sext<10>(RS_RT))<15:0> << 16 |
1974 (sext<10>(RS_RT))<15:0>;
1975 }});
1976 0x3: replv_ph({{
1977 Rd_uw = Rt_uw<15:0> << 16 |
1978 Rt_uw<15:0>;
1979 }});
1980 0x4: preceq_w_phl({{
1981 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_PH, SIGNED,
1982 SIMD_FMT_W, SIGNED, MODE_L);
1983 }});
1984 0x5: preceq_w_phr({{
1985 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_PH, SIGNED,
1986 SIMD_FMT_W, SIGNED, MODE_R);
1987 }});
1988 }
1989 }
1990 0x2: decode OP_LO {
1991 format DspIntOp {
1992 0x1: absq_s_w({{
1993 Rd_sw = dspAbs(Rt_sw, SIMD_FMT_W, &dspctl);
1994 }});
1995 }
1996 }
1997 0x3: decode OP_LO {
1998 0x3: IntOp::bitrev({{
1999 Rd_uw = bitrev( Rt_uw<15:0> );
2000 }});
2001 format DspIntOp {
2002 0x4: preceu_ph_qbl({{
2003 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB,
2004 UNSIGNED, SIMD_FMT_PH,
2005 UNSIGNED, MODE_L);
2006 }});
2007 0x5: preceu_ph_qbr({{
2008 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB,
2009 UNSIGNED, SIMD_FMT_PH,
2010 UNSIGNED, MODE_R );
2011 }});
2012 0x6: preceu_ph_qbla({{
2013 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB,
2014 UNSIGNED, SIMD_FMT_PH,
2015 UNSIGNED, MODE_LA );
2016 }});
2017 0x7: preceu_ph_qbra({{
2018 Rd_uw = dspPrece(Rt_uw, SIMD_FMT_QB,
2019 UNSIGNED, SIMD_FMT_PH,
2020 UNSIGNED, MODE_RA);
2021 }});
2022 }
2023 }
2024 }
2025
2026 //Table 5-8 MIPS32 SHLL.QB Encoding of the op Field
2027 //(DSP ASE MANUAL)
2028 0x3: decode OP_HI {
2029 0x0: decode OP_LO {
2030 format DspIntOp {
2031 0x0: shll_qb({{
2032 Rd_sw = dspShll(Rt_sw, RS, SIMD_FMT_QB,
2033 NOSATURATE, UNSIGNED, &dspctl);
2034 }});
2035 0x1: shrl_qb({{
2036 Rd_sw = dspShrl(Rt_sw, RS, SIMD_FMT_QB,
2037 UNSIGNED);
2038 }});
2039 0x2: shllv_qb({{
2040 Rd_sw = dspShll(Rt_sw, Rs_sw, SIMD_FMT_QB,
2041 NOSATURATE, UNSIGNED, &dspctl);
2042 }});
2043 0x3: shrlv_qb({{
2044 Rd_sw = dspShrl(Rt_sw, Rs_sw, SIMD_FMT_QB,
2045 UNSIGNED);
2046 }});
2047 0x4: shra_qb({{
2048 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_QB,
2049 NOROUND, SIGNED, &dspctl);
2050 }});
2051 0x5: shra_r_qb({{
2052 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_QB,
2053 ROUND, SIGNED, &dspctl);
2054 }});
2055 0x6: shrav_qb({{
2056 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_QB,
2057 NOROUND, SIGNED, &dspctl);
2058 }});
2059 0x7: shrav_r_qb({{
2060 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_QB,
2061 ROUND, SIGNED, &dspctl);
2062 }});
2063 }
2064 }
2065 0x1: decode OP_LO {
2066 format DspIntOp {
2067 0x0: shll_ph({{
2068 Rd_uw = dspShll(Rt_uw, RS, SIMD_FMT_PH,
2069 NOSATURATE, SIGNED, &dspctl);
2070 }});
2071 0x1: shra_ph({{
2072 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_PH,
2073 NOROUND, SIGNED, &dspctl);
2074 }});
2075 0x2: shllv_ph({{
2076 Rd_sw = dspShll(Rt_sw, Rs_sw, SIMD_FMT_PH,
2077 NOSATURATE, SIGNED, &dspctl);
2078 }});
2079 0x3: shrav_ph({{
2080 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_PH,
2081 NOROUND, SIGNED, &dspctl);
2082 }});
2083 0x4: shll_s_ph({{
2084 Rd_sw = dspShll(Rt_sw, RS, SIMD_FMT_PH,
2085 SATURATE, SIGNED, &dspctl);
2086 }});
2087 0x5: shra_r_ph({{
2088 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_PH,
2089 ROUND, SIGNED, &dspctl);
2090 }});
2091 0x6: shllv_s_ph({{
2092 Rd_sw = dspShll(Rt_sw, Rs_sw, SIMD_FMT_PH,
2093 SATURATE, SIGNED, &dspctl);
2094 }});
2095 0x7: shrav_r_ph({{
2096 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_PH,
2097 ROUND, SIGNED, &dspctl);
2098 }});
2099 }
2100 }
2101 0x2: decode OP_LO {
2102 format DspIntOp {
2103 0x4: shll_s_w({{
2104 Rd_sw = dspShll(Rt_sw, RS, SIMD_FMT_W,
2105 SATURATE, SIGNED, &dspctl);
2106 }});
2107 0x5: shra_r_w({{
2108 Rd_sw = dspShra(Rt_sw, RS, SIMD_FMT_W,
2109 ROUND, SIGNED, &dspctl);
2110 }});
2111 0x6: shllv_s_w({{
2112 Rd_sw = dspShll(Rt_sw, Rs_sw, SIMD_FMT_W,
2113 SATURATE, SIGNED, &dspctl);
2114 }});
2115 0x7: shrav_r_w({{
2116 Rd_sw = dspShra(Rt_sw, Rs_sw, SIMD_FMT_W,
2117 ROUND, SIGNED, &dspctl);
2118 }});
2119 }
2120 }
2121 0x3: decode OP_LO {
2122 format DspIntOp {
2123 0x1: shrl_ph({{
2124 Rd_sw = dspShrl(Rt_sw, RS, SIMD_FMT_PH,
2125 UNSIGNED);
2126 }});
2127 0x3: shrlv_ph({{
2128 Rd_sw = dspShrl(Rt_sw, Rs_sw, SIMD_FMT_PH,
2129 UNSIGNED);
2130 }});
2131 }
2132 }
2133 }
2134 }
2135
2136 0x3: decode FUNCTION_LO {
2137
2138 //Table 3.12 MIPS32 ADDUH.QB Encoding of the op Field
2139 //(DSP ASE Rev2 Manual)
2140 0x0: decode OP_HI {
2141 0x0: decode OP_LO {
2142 format DspIntOp {
2143 0x0: adduh_qb({{
2144 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_QB,
2145 NOROUND, UNSIGNED);
2146 }});
2147 0x1: subuh_qb({{
2148 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_QB,
2149 NOROUND, UNSIGNED);
2150 }});
2151 0x2: adduh_r_qb({{
2152 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_QB,
2153 ROUND, UNSIGNED);
2154 }});
2155 0x3: subuh_r_qb({{
2156 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_QB,
2157 ROUND, UNSIGNED);
2158 }});
2159 }
2160 }
2161 0x1: decode OP_LO {
2162 format DspIntOp {
2163 0x0: addqh_ph({{
2164 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_PH,
2165 NOROUND, SIGNED);
2166 }});
2167 0x1: subqh_ph({{
2168 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_PH,
2169 NOROUND, SIGNED);
2170 }});
2171 0x2: addqh_r_ph({{
2172 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_PH,
2173 ROUND, SIGNED);
2174 }});
2175 0x3: subqh_r_ph({{
2176 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_PH,
2177 ROUND, SIGNED);
2178 }});
2179 0x4: mul_ph({{
2180 Rd_sw = dspMul(Rs_sw, Rt_sw, SIMD_FMT_PH,
2181 NOSATURATE, &dspctl);
2182 }}, IntMultOp);
2183 0x6: mul_s_ph({{
2184 Rd_sw = dspMul(Rs_sw, Rt_sw, SIMD_FMT_PH,
2185 SATURATE, &dspctl);
2186 }}, IntMultOp);
2187 }
2188 }
2189 0x2: decode OP_LO {
2190 format DspIntOp {
2191 0x0: addqh_w({{
2192 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_W,
2193 NOROUND, SIGNED);
2194 }});
2195 0x1: subqh_w({{
2196 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_W,
2197 NOROUND, SIGNED);
2198 }});
2199 0x2: addqh_r_w({{
2200 Rd_uw = dspAddh(Rs_sw, Rt_sw, SIMD_FMT_W,
2201 ROUND, SIGNED);
2202 }});
2203 0x3: subqh_r_w({{
2204 Rd_uw = dspSubh(Rs_sw, Rt_sw, SIMD_FMT_W,
2205 ROUND, SIGNED);
2206 }});
2207 0x6: mulq_s_w({{
2208 Rd_sw = dspMulq(Rs_sw, Rt_sw, SIMD_FMT_W,
2209 SATURATE, NOROUND, &dspctl);
2210 }}, IntMultOp);
2211 0x7: mulq_rs_w({{
2212 Rd_sw = dspMulq(Rs_sw, Rt_sw, SIMD_FMT_W,
2213 SATURATE, ROUND, &dspctl);
2214 }}, IntMultOp);
2215 }
2216 }
2217 }
2218 }
2219
2220 //Table A-10 MIPS32 BSHFL Encoding of sa Field
2221 0x4: decode SA {
2222 format BasicOp {
2223 0x02: wsbh({{
2224 Rd_uw = Rt_uw<23:16> << 24 |
2225 Rt_uw<31:24> << 16 |
2226 Rt_uw<7:0> << 8 |
2227 Rt_uw<15:8>;
2228 }});
2229 0x10: seb({{ Rd_sw = Rt_sb; }});
2230 0x18: seh({{ Rd_sw = Rt_sh; }});
2231 }
2232 }
2233
2234 0x6: decode FUNCTION_LO {
2235
2236 //Table 5-10 MIPS32 DPAQ.W.PH Encoding of the op Field
2237 //(DSP ASE MANUAL)
2238 0x0: decode OP_HI {
2239 0x0: decode OP_LO {
2240 format DspHiLoOp {
2241 0x0: dpa_w_ph({{
2242 dspac = dspDpa(dspac, Rs_sw, Rt_sw, ACDST,
2243 SIMD_FMT_PH, SIGNED, MODE_L);
2244 }}, IntMultOp);
2245 0x1: dps_w_ph({{
2246 dspac = dspDps(dspac, Rs_sw, Rt_sw, ACDST,
2247 SIMD_FMT_PH, SIGNED, MODE_L);
2248 }}, IntMultOp);
2249 0x2: mulsa_w_ph({{
2250 dspac = dspMulsa(dspac, Rs_sw, Rt_sw,
2251 ACDST, SIMD_FMT_PH );
2252 }}, IntMultOp);
2253 0x3: dpau_h_qbl({{
2254 dspac = dspDpa(dspac, Rs_sw, Rt_sw, ACDST,
2255 SIMD_FMT_QB, UNSIGNED, MODE_L);
2256 }}, IntMultOp);
2257 0x4: dpaq_s_w_ph({{
2258 dspac = dspDpaq(dspac, Rs_sw, Rt_sw,
2259 ACDST, SIMD_FMT_PH,
2260 SIMD_FMT_W, NOSATURATE,
2261 MODE_L, &dspctl);
2262 }}, IntMultOp);
2263 0x5: dpsq_s_w_ph({{
2264 dspac = dspDpsq(dspac, Rs_sw, Rt_sw,
2265 ACDST, SIMD_FMT_PH,
2266 SIMD_FMT_W, NOSATURATE,
2267 MODE_L, &dspctl);
2268 }}, IntMultOp);
2269 0x6: mulsaq_s_w_ph({{
2270 dspac = dspMulsaq(dspac, Rs_sw, Rt_sw,
2271 ACDST, SIMD_FMT_PH,
2272 &dspctl);
2273 }}, IntMultOp);
2274 0x7: dpau_h_qbr({{
2275 dspac = dspDpa(dspac, Rs_sw, Rt_sw, ACDST,
2276 SIMD_FMT_QB, UNSIGNED, MODE_R);
2277 }}, IntMultOp);
2278 }
2279 }
2280 0x1: decode OP_LO {
2281 format DspHiLoOp {
2282 0x0: dpax_w_ph({{
2283 dspac = dspDpa(dspac, Rs_sw, Rt_sw, ACDST,
2284 SIMD_FMT_PH, SIGNED, MODE_X);
2285 }}, IntMultOp);
2286 0x1: dpsx_w_ph({{
2287 dspac = dspDps(dspac, Rs_sw, Rt_sw, ACDST,
2288 SIMD_FMT_PH, SIGNED, MODE_X);
2289 }}, IntMultOp);
2290 0x3: dpsu_h_qbl({{
2291 dspac = dspDps(dspac, Rs_sw, Rt_sw, ACDST,
2292 SIMD_FMT_QB, UNSIGNED, MODE_L);
2293 }}, IntMultOp);
2294 0x4: dpaq_sa_l_w({{
2295 dspac = dspDpaq(dspac, Rs_sw, Rt_sw,
2296 ACDST, SIMD_FMT_W,
2297 SIMD_FMT_L, SATURATE,
2298 MODE_L, &dspctl);
2299 }}, IntMultOp);
2300 0x5: dpsq_sa_l_w({{
2301 dspac = dspDpsq(dspac, Rs_sw, Rt_sw,
2302 ACDST, SIMD_FMT_W,
2303 SIMD_FMT_L, SATURATE,
2304 MODE_L, &dspctl);
2305 }}, IntMultOp);
2306 0x7: dpsu_h_qbr({{
2307 dspac = dspDps(dspac, Rs_sw, Rt_sw, ACDST,
2308 SIMD_FMT_QB, UNSIGNED, MODE_R);
2309 }}, IntMultOp);
2310 }
2311 }
2312 0x2: decode OP_LO {
2313 format DspHiLoOp {
2314 0x0: maq_sa_w_phl({{
2315 dspac = dspMaq(dspac, Rs_uw, Rt_uw,
2316 ACDST, SIMD_FMT_PH,
2317 MODE_L, SATURATE, &dspctl);
2318 }}, IntMultOp);
2319 0x2: maq_sa_w_phr({{
2320 dspac = dspMaq(dspac, Rs_uw, Rt_uw,
2321 ACDST, SIMD_FMT_PH,
2322 MODE_R, SATURATE, &dspctl);
2323 }}, IntMultOp);
2324 0x4: maq_s_w_phl({{
2325 dspac = dspMaq(dspac, Rs_uw, Rt_uw,
2326 ACDST, SIMD_FMT_PH,
2327 MODE_L, NOSATURATE, &dspctl);
2328 }}, IntMultOp);
2329 0x6: maq_s_w_phr({{
2330 dspac = dspMaq(dspac, Rs_uw, Rt_uw,
2331 ACDST, SIMD_FMT_PH,
2332 MODE_R, NOSATURATE, &dspctl);
2333 }}, IntMultOp);
2334 }
2335 }
2336 0x3: decode OP_LO {
2337 format DspHiLoOp {
2338 0x0: dpaqx_s_w_ph({{
2339 dspac = dspDpaq(dspac, Rs_sw, Rt_sw,
2340 ACDST, SIMD_FMT_PH,
2341 SIMD_FMT_W, NOSATURATE,
2342 MODE_X, &dspctl);
2343 }}, IntMultOp);
2344 0x1: dpsqx_s_w_ph({{
2345 dspac = dspDpsq(dspac, Rs_sw, Rt_sw,
2346 ACDST, SIMD_FMT_PH,
2347 SIMD_FMT_W, NOSATURATE,
2348 MODE_X, &dspctl);
2349 }}, IntMultOp);
2350 0x2: dpaqx_sa_w_ph({{
2351 dspac = dspDpaq(dspac, Rs_sw, Rt_sw,
2352 ACDST, SIMD_FMT_PH,
2353 SIMD_FMT_W, SATURATE,
2354 MODE_X, &dspctl);
2355 }}, IntMultOp);
2356 0x3: dpsqx_sa_w_ph({{
2357 dspac = dspDpsq(dspac, Rs_sw, Rt_sw,
2358 ACDST, SIMD_FMT_PH,
2359 SIMD_FMT_W, SATURATE,
2360 MODE_X, &dspctl);
2361 }}, IntMultOp);
2362 }
2363 }
2364 }
2365
2366 //Table 3.3 MIPS32 APPEND Encoding of the op Field
2367 0x1: decode OP_HI {
2368 0x0: decode OP_LO {
2369 format IntOp {
2370 0x0: append({{
2371 Rt_uw = (Rt_uw << RD) | bits(Rs_uw, RD - 1, 0);
2372 }});
2373 0x1: prepend({{
2374 Rt_uw = (Rt_uw >> RD) |
2375 (bits(Rs_uw, RD - 1, 0) << (32 - RD));
2376 }});
2377 }
2378 }
2379 0x2: decode OP_LO {
2380 format IntOp {
2381 0x0: balign({{
2382 Rt_uw = (Rt_uw << (8 * BP)) |
2383 (Rs_uw >> (8 * (4 - BP)));
2384 }});
2385 }
2386 }
2387 }
2388
2389 }
2390 0x7: decode FUNCTION_LO {
2391
2392 //Table 5-11 MIPS32 EXTR.W Encoding of the op Field
2393 //(DSP ASE MANUAL)
2394 0x0: decode OP_HI {
2395 0x0: decode OP_LO {
2396 format DspHiLoOp {
2397 0x0: extr_w({{
2398 Rt_uw = dspExtr(dspac, SIMD_FMT_W, RS,
2399 NOROUND, NOSATURATE, &dspctl);
2400 }});
2401 0x1: extrv_w({{
2402 Rt_uw = dspExtr(dspac, SIMD_FMT_W, Rs_uw,
2403 NOROUND, NOSATURATE, &dspctl);
2404 }});
2405 0x2: extp({{
2406 Rt_uw = dspExtp(dspac, RS, &dspctl);
2407 }});
2408 0x3: extpv({{
2409 Rt_uw = dspExtp(dspac, Rs_uw, &dspctl);
2410 }});
2411 0x4: extr_r_w({{
2412 Rt_uw = dspExtr(dspac, SIMD_FMT_W, RS,
2413 ROUND, NOSATURATE, &dspctl);
2414 }});
2415 0x5: extrv_r_w({{
2416 Rt_uw = dspExtr(dspac, SIMD_FMT_W, Rs_uw,
2417 ROUND, NOSATURATE, &dspctl);
2418 }});
2419 0x6: extr_rs_w({{
2420 Rt_uw = dspExtr(dspac, SIMD_FMT_W, RS,
2421 ROUND, SATURATE, &dspctl);
2422 }});
2423 0x7: extrv_rs_w({{
2424 Rt_uw = dspExtr(dspac, SIMD_FMT_W, Rs_uw,
2425 ROUND, SATURATE, &dspctl);
2426 }});
2427 }
2428 }
2429 0x1: decode OP_LO {
2430 format DspHiLoOp {
2431 0x2: extpdp({{
2432 Rt_uw = dspExtpd(dspac, RS, &dspctl);
2433 }});
2434 0x3: extpdpv({{
2435 Rt_uw = dspExtpd(dspac, Rs_uw, &dspctl);
2436 }});
2437 0x6: extr_s_h({{
2438 Rt_uw = dspExtr(dspac, SIMD_FMT_PH, RS,
2439 NOROUND, SATURATE, &dspctl);
2440 }});
2441 0x7: extrv_s_h({{
2442 Rt_uw = dspExtr(dspac, SIMD_FMT_PH, Rs_uw,
2443 NOROUND, SATURATE, &dspctl);
2444 }});
2445 }
2446 }
2447 0x2: decode OP_LO {
2448 format DspIntOp {
2449 0x2: rddsp({{
2450 Rd_uw = readDSPControl(&dspctl, RDDSPMASK);
2451 }});
2452 0x3: wrdsp({{
2453 writeDSPControl(&dspctl, Rs_uw, WRDSPMASK);
2454 }});
2455 }
2456 }
2457 0x3: decode OP_LO {
2458 format DspHiLoOp {
2459 0x2: shilo({{
2460 if ((int64_t)sext<6>(HILOSA) < 0) {
2461 dspac = (uint64_t)dspac <<
2462 -sext<6>(HILOSA);
2463 } else {
2464 dspac = (uint64_t)dspac >>
2465 sext<6>(HILOSA);
2466 }
2467 }});
2468 0x3: shilov({{
2469 if ((int64_t)sext<6>(Rs_sw<5:0>) < 0) {
2470 dspac = (uint64_t)dspac <<
2471 -sext<6>(Rs_sw<5:0>);
2472 } else {
2473 dspac = (uint64_t)dspac >>
2474 sext<6>(Rs_sw<5:0>);
2475 }
2476 }});
2477 0x7: mthlip({{
2478 dspac = dspac << 32;
2479 dspac |= Rs_uw;
2480 dspctl = insertBits(dspctl, 5, 0,
2481 dspctl<5:0> + 32);
2482 }});
2483 }
2484 }
2485 }
2486 0x3: decode OP default FailUnimpl::rdhwr() {
2487 0x0: decode FullSystemInt {
2488 0: decode RD {
2489 29: BasicOp::rdhwr_se({{ Rt = TpValue; }});
2490 }
2491 }
2492 }
2493 }
2494 }
2495 }
2496
2497 0x4: decode OPCODE_LO {
2498 format LoadMemory {
2499 0x0: lb({{ Rt_sw = Mem_sb; }});
2500 0x1: lh({{ Rt_sw = Mem_sh; }});
2501 0x3: lw({{ Rt_sw = Mem_sw; }});
2502 0x4: lbu({{ Rt_uw = Mem_ub;}});
2503 0x5: lhu({{ Rt_uw = Mem_uh; }});
2504 }
2505
2506 format LoadUnalignedMemory {
2507 0x2: lwl({{
2508 uint32_t mem_shift = 24 - (8 * byte_offset);
2509 Rt_uw = mem_word << mem_shift | (Rt_uw & mask(mem_shift));
2510 }});
2511 0x6: lwr({{
2512 uint32_t mem_shift = 8 * byte_offset;
2513 Rt_uw = (Rt_uw & (mask(mem_shift) << (32 - mem_shift))) |
2514 (mem_word >> mem_shift);
2515 }});
2516 }
2517 }
2518
2519 0x5: decode OPCODE_LO {
2520 format StoreMemory {
2521 0x0: sb({{ Mem_ub = Rt<7:0>; }});
2522 0x1: sh({{ Mem_uh = Rt<15:0>; }});
2523 0x3: sw({{ Mem_uw = Rt<31:0>; }});
2524 }
2525
2526 format StoreUnalignedMemory {
2527 0x2: swl({{
2528 uint32_t reg_shift = 24 - (8 * byte_offset);
2529 uint32_t mem_shift = 32 - reg_shift;
2530 mem_word = (mem_word & (mask(reg_shift) << mem_shift)) |
2531 (Rt_uw >> reg_shift);
2532 }});
2533 0x6: swr({{
2534 uint32_t reg_shift = 8 * byte_offset;
2535 mem_word = Rt_uw << reg_shift |
2536 (mem_word & (mask(reg_shift)));
2537 }});
2538 }
2539 format CP0Control {
2540 0x7: cache({{
2541 //Addr CacheEA = Rs_uw + OFFSET;
2542 //fault = xc->CacheOp((uint8_t)CACHE_OP,(Addr) CacheEA);
2543 }});
2544 }
2545 }
2546
2547 0x6: decode OPCODE_LO {
2548 format LoadMemory {
2549 0x0: ll({{ Rt_uw = Mem_uw; }}, mem_flags=LLSC);
2550 0x1: lwc1({{ Ft_uw = Mem_uw; }});
2551 0x5: ldc1({{ Ft_ud = Mem_ud; }});
2552 }
2553 0x2: CP2Unimpl::lwc2();
2554 0x6: CP2Unimpl::ldc2();
2555 0x3: Prefetch::pref();
2556 }
2557
2558
2559 0x7: decode OPCODE_LO {
2560 0x0: StoreCond::sc({{ Mem_uw = Rt_uw; }},
2561 {{ uint64_t tmp = write_result;
2562 Rt_uw = (tmp == 0 || tmp == 1) ? tmp : Rt_uw;
2563 }}, mem_flags=LLSC,
2564 inst_flags = IsStoreConditional);
2565 format StoreMemory {
2566 0x1: swc1({{ Mem_uw = Ft_uw; }});
2567 0x5: sdc1({{ Mem_ud = Ft_ud; }});
2568 }
2569 0x2: CP2Unimpl::swc2();
2570 0x6: CP2Unimpl::sdc2();
2571 }
2572}
2573
2574