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