decoder.isa (8564:f81bcb16fa1b) decoder.isa (8568:83f728db3332)
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 FULL_SYSTEM {
167 0: syscall_se({{ xc->syscall(R2); }},
168 IsSerializeAfter, IsNonSpeculative);
169 default: syscall({{ fault = new SystemCallFault(); }});
170 }
171 0x7: sync({{ ; }}, IsMemBarrier);
172 0x5: break({{fault = new 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 (FULL_SYSTEM &&
216 findOverflow(32, result, Rs, Rt)) {
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 FULL_SYSTEM {
167 0: syscall_se({{ xc->syscall(R2); }},
168 IsSerializeAfter, IsNonSpeculative);
169 default: syscall({{ fault = new SystemCallFault(); }});
170 }
171 0x7: sync({{ ; }}, IsMemBarrier);
172 0x5: break({{fault = new 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 (FULL_SYSTEM &&
216 findOverflow(32, result, Rs, Rt)) {
217 fault = new ArithmeticFault();
217 fault = new 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 (FULL_SYSTEM &&
225 findOverflow(32, result, Rs, ~Rt)) {
218 }
219 }});
220 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
221 0x2: sub({{
222 IntReg result;
223 Rd = result = Rs - Rt;
224 if (FULL_SYSTEM &&
225 findOverflow(32, result, Rs, ~Rt)) {
226 fault = new ArithmeticFault();
226 fault = new 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 (FULL_SYSTEM &&
329 findOverflow(32, result, Rs, imm)) {
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 (FULL_SYSTEM &&
329 findOverflow(32, result, Rs, imm)) {
330 fault = new ArithmeticFault();
330 fault = new 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 Ctrl_Base_DepTag);
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_Base_DepTag);
413 }});
414 0x1: mfthc1({{ data = xc->readRegOtherThread(RT +
415 FP_Base_DepTag);
416 }});
417 }
418 0x3: cftc1({{
419 uint32_t fcsr_val = xc->readRegOtherThread(FLOATREG_FCSR +
420 FP_Base_DepTag);
421 switch (RT) {
422 case 0:
423 data = xc->readRegOtherThread(FLOATREG_FIR +
424 Ctrl_Base_DepTag);
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) + Ctrl_Base_DepTag,
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_Base_DepTag);
500 data = insertBits(data, top_bit,
501 bottom_bit, Rt);
502 xc->setRegOtherThread(RD + FP_Base_DepTag,
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 "Status Register", FS);
536 }
537 xc->setRegOtherThread(FLOATREG_FCSR + FP_Base_DepTag, 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 = new 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 = new 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 = new 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 = new 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 IndexReg index = Index;
780 Ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP);
781 }});
782 0x06: tlbwr({{
783 //Create PTE
784 MipsISA::PTE newEntry;
785 //Write PTE
786 newEntry.Mask = (Addr)(PageMask >> 11);
787 newEntry.VPN = (Addr)(EntryHi >> 11);
788 /* PageGrain _ ESP Config3 _ SP */
789 if (bits(PageGrain, 28) == 0 ||
790 bits(Config3, 4) == 0) {
791 // If 1KB pages are *NOT* enabled, lowest bits of
792 // the mask are 0b11 for TLB writes
793 newEntry.Mask |= 0x3;
794 // Reset bits 0 and 1 if 1KB pages are not enabled
795 newEntry.VPN &= 0xFFFFFFFC;
796 }
797 newEntry.asid = (uint8_t)(EntryHi & 0xFF);
798
799 newEntry.PFN0 = (Addr)(EntryLo0 >> 6);
800 newEntry.PFN1 = (Addr)(EntryLo1 >> 6);
801 newEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
802 newEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
803 newEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
804 newEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
805 newEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
806 newEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
807 newEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
808 /* Now, compute the AddrShiftAmount and OffsetMask -
809 TLB optimizations */
810 /* Addr Shift Amount for 1KB or larger pages */
811 if ((newEntry.Mask & 0xFFFF) == 3){
812 newEntry.AddrShiftAmount = 12;
813 } else if ((newEntry.Mask & 0xFFFF) == 0x0000) {
814 newEntry.AddrShiftAmount = 10;
815 } else if ((newEntry.Mask & 0xFFFC) == 0x000C) {
816 newEntry.AddrShiftAmount = 14;
817 } else if ((newEntry.Mask & 0xFFF0) == 0x0030) {
818 newEntry.AddrShiftAmount = 16;
819 } else if ((newEntry.Mask & 0xFFC0) == 0x00C0) {
820 newEntry.AddrShiftAmount = 18;
821 } else if ((newEntry.Mask & 0xFF00) == 0x0300) {
822 newEntry.AddrShiftAmount = 20;
823 } else if ((newEntry.Mask & 0xFC00) == 0x0C00) {
824 newEntry.AddrShiftAmount = 22;
825 } else if ((newEntry.Mask & 0xF000) == 0x3000) {
826 newEntry.AddrShiftAmount = 24;
827 } else if ((newEntry.Mask & 0xC000) == 0xC000) {
828 newEntry.AddrShiftAmount = 26;
829 } else if ((newEntry.Mask & 0x30000) == 0x30000) {
830 newEntry.AddrShiftAmount = 28;
831 } else {
832 fatal("Invalid Mask Pattern Detected!\n");
833 }
834 newEntry.OffsetMask =
835 (1 << newEntry.AddrShiftAmount) - 1;
836
837 MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
838 Config3Reg config3 = Config3;
839 PageGrainReg pageGrain = PageGrain;
840 int SP = 0;
841 if (bits(config3, config3.sp) == 1 &&
842 bits(pageGrain, pageGrain.esp) == 1) {
843 SP = 1;
844 }
845 IndexReg index = Index;
846 Ptr->insertAt(newEntry, Random, SP);
847 }});
848
849 0x08: tlbp({{
850 Config3Reg config3 = Config3;
851 PageGrainReg pageGrain = PageGrain;
852 EntryHiReg entryHi = EntryHi;
853 int tlbIndex;
854 Addr vpn;
855 if (pageGrain.esp == 1 && config3.sp ==1) {
856 vpn = EntryHi >> 11;
857 } else {
858 // Mask off lower 2 bits
859 vpn = ((EntryHi >> 11) & 0xFFFFFFFC);
860 }
861 tlbIndex = xc->tcBase()->getITBPtr()->
862 probeEntry(vpn, entryHi.asid);
863 // Check TLB for entry matching EntryHi
864 if (tlbIndex != -1) {
865 Index = tlbIndex;
866 } else {
867 // else, set Index = 1 << 31
868 Index = (1 << 31);
869 }
870 }});
871 }
872 format CP0Unimpl {
873 0x20: wait();
874 }
875 default: CP0Unimpl::unknown();
876 }
877 }
878
879 //Table A-13 MIPS32 COP1 Encoding of rs Field
880 0x1: decode RS_MSB {
881 0x0: decode RS_HI {
882 0x0: decode RS_LO {
883 format CP1Control {
884 0x0: mfc1 ({{ Rt.uw = Fs.uw; }});
885
886 0x2: cfc1({{
887 switch (FS) {
888 case 0:
889 Rt = FIR;
890 break;
891 case 25:
892 Rt = (FCSR & 0xFE000000) >> 24 |
893 (FCSR & 0x00800000) >> 23;
894 break;
895 case 26:
896 Rt = (FCSR & 0x0003F07C);
897 break;
898 case 28:
899 Rt = (FCSR & 0x00000F80) |
900 (FCSR & 0x01000000) >> 21 |
901 (FCSR & 0x00000003);
902 break;
903 case 31:
904 Rt = FCSR;
905 break;
906 default:
907 warn("FP Control Value (%d) Not Valid");
908 }
909 }});
910
911 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>; }});
912
913 0x4: mtc1({{ Fs.uw = Rt.uw; }});
914
915 0x6: ctc1({{
916 switch (FS) {
917 case 25:
918 FCSR = (Rt.uw<7:1> << 25) | // move 31-25
919 (FCSR & 0x01000000) | // bit 24
920 (FCSR & 0x004FFFFF); // bit 22-0
921 break;
922 case 26:
923 FCSR = (FCSR & 0xFFFC0000) | // move 31-18
924 Rt.uw<17:12> << 12 | // bit 17-12
925 (FCSR & 0x00000F80) << 7 | // bit 11-7
926 Rt.uw<6:2> << 2 | // bit 6-2
927 (FCSR & 0x00000002); // bit 1-0
928 break;
929 case 28:
930 FCSR = (FCSR & 0xFE000000) | // move 31-25
931 Rt.uw<2:2> << 24 | // bit 24
932 (FCSR & 0x00FFF000) << 23 | // bit 23-12
933 Rt.uw<11:7> << 7 | // bit 24
934 (FCSR & 0x000007E) |
935 Rt.uw<1:0>; // bit 22-0
936 break;
937 case 31:
938 FCSR = Rt.uw;
939 break;
940
941 default:
942 panic("FP Control Value (%d) "
943 "Not Available. Ignoring Access "
944 "to Floating Control Status "
945 "Register", FS);
946 }
947 }});
948
949 0x7: mthc1({{
950 uint64_t fs_hi = Rt.uw;
951 uint64_t fs_lo = Fs.ud & 0x0FFFFFFFF;
952 Fs.ud = (fs_hi << 32) | fs_lo;
953 }});
954
955 }
956 format CP1Unimpl {
957 0x1: dmfc1();
958 0x5: dmtc1();
959 }
960 }
961
962 0x1: decode RS_LO {
963 0x0: decode ND {
964 format Branch {
965 0x0: decode TF {
966 0x0: bc1f({{
967 cond = getCondCode(FCSR, BRANCH_CC) == 0;
968 }});
969 0x1: bc1t({{
970 cond = getCondCode(FCSR, BRANCH_CC) == 1;
971 }});
972 }
973 0x1: decode TF {
974 0x0: bc1fl({{
975 cond = getCondCode(FCSR, BRANCH_CC) == 0;
976 }}, Likely);
977 0x1: bc1tl({{
978 cond = getCondCode(FCSR, BRANCH_CC) == 1;
979 }}, Likely);
980 }
981 }
982 }
983 format CP1Unimpl {
984 0x1: bc1any2();
985 0x2: bc1any4();
986 default: unknown();
987 }
988 }
989 }
990
991 0x1: decode RS_HI {
992 0x2: decode RS_LO {
993 //Table A-14 MIPS32 COP1 Encoding of Function Field When
994 //rs=S (( single-precision floating point))
995 0x0: decode FUNCTION_HI {
996 0x0: decode FUNCTION_LO {
997 format FloatOp {
998 0x0: add_s({{ Fd.sf = Fs.sf + Ft.sf; }});
999 0x1: sub_s({{ Fd.sf = Fs.sf - Ft.sf; }});
1000 0x2: mul_s({{ Fd.sf = Fs.sf * Ft.sf; }});
1001 0x3: div_s({{ Fd.sf = Fs.sf / Ft.sf; }});
1002 0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf); }});
1003 0x5: abs_s({{ Fd.sf = fabs(Fs.sf); }});
1004 0x7: neg_s({{ Fd.sf = -Fs.sf; }});
1005 }
1006 0x6: BasicOp::mov_s({{ Fd.sf = Fs.sf; }});
1007 }
1008 0x1: decode FUNCTION_LO {
1009 format FloatConvertOp {
1010 0x0: round_l_s({{ val = Fs.sf; }},
1011 ToLong, Round);
1012 0x1: trunc_l_s({{ val = Fs.sf; }},
1013 ToLong, Trunc);
1014 0x2: ceil_l_s({{ val = Fs.sf;}},
1015 ToLong, Ceil);
1016 0x3: floor_l_s({{ val = Fs.sf; }},
1017 ToLong, Floor);
1018 0x4: round_w_s({{ val = Fs.sf; }},
1019 ToWord, Round);
1020 0x5: trunc_w_s({{ val = Fs.sf; }},
1021 ToWord, Trunc);
1022 0x6: ceil_w_s({{ val = Fs.sf; }},
1023 ToWord, Ceil);
1024 0x7: floor_w_s({{ val = Fs.sf; }},
1025 ToWord, Floor);
1026 }
1027 }
1028
1029 0x2: decode FUNCTION_LO {
1030 0x1: decode MOVCF {
1031 format BasicOp {
1032 0x0: movf_s({{
1033 Fd = (getCondCode(FCSR,CC) == 0) ?
1034 Fs : Fd;
1035 }});
1036 0x1: movt_s({{
1037 Fd = (getCondCode(FCSR,CC) == 1) ?
1038 Fs : Fd;
1039 }});
1040 }
1041 }
1042
1043 format BasicOp {
1044 0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }});
1045 0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }});
1046 }
1047
1048 format FloatOp {
1049 0x5: recip_s({{ Fd = 1 / Fs; }});
1050 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs); }});
1051 }
1052 format CP1Unimpl {
1053 default: unknown();
1054 }
1055 }
1056 0x3: CP1Unimpl::unknown();
1057
1058 0x4: decode FUNCTION_LO {
1059 format FloatConvertOp {
1060 0x1: cvt_d_s({{ val = Fs.sf; }}, ToDouble);
1061 0x4: cvt_w_s({{ val = Fs.sf; }}, ToWord);
1062 0x5: cvt_l_s({{ val = Fs.sf; }}, ToLong);
1063 }
1064
1065 0x6: FloatOp::cvt_ps_s({{
1066 Fd.ud = (uint64_t) Fs.uw << 32 |
1067 (uint64_t) Ft.uw;
1068 }});
1069 format CP1Unimpl {
1070 default: unknown();
1071 }
1072 }
1073 0x5: CP1Unimpl::unknown();
1074
1075 0x6: decode FUNCTION_LO {
1076 format FloatCompareOp {
1077 0x0: c_f_s({{ cond = 0; }},
1078 SinglePrecision, UnorderedFalse);
1079 0x1: c_un_s({{ cond = 0; }},
1080 SinglePrecision, UnorderedTrue);
1081 0x2: c_eq_s({{ cond = (Fs.sf == Ft.sf); }},
1082 UnorderedFalse);
1083 0x3: c_ueq_s({{ cond = (Fs.sf == Ft.sf); }},
1084 UnorderedTrue);
1085 0x4: c_olt_s({{ cond = (Fs.sf < Ft.sf); }},
1086 UnorderedFalse);
1087 0x5: c_ult_s({{ cond = (Fs.sf < Ft.sf); }},
1088 UnorderedTrue);
1089 0x6: c_ole_s({{ cond = (Fs.sf <= Ft.sf); }},
1090 UnorderedFalse);
1091 0x7: c_ule_s({{ cond = (Fs.sf <= Ft.sf); }},
1092 UnorderedTrue);
1093 }
1094 }
1095
1096 0x7: decode FUNCTION_LO {
1097 format FloatCompareOp {
1098 0x0: c_sf_s({{ cond = 0; }}, SinglePrecision,
1099 UnorderedFalse, QnanException);
1100 0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision,
1101 UnorderedTrue, QnanException);
1102 0x2: c_seq_s({{ cond = (Fs.sf == Ft.sf); }},
1103 UnorderedFalse, QnanException);
1104 0x3: c_ngl_s({{ cond = (Fs.sf == Ft.sf); }},
1105 UnorderedTrue, QnanException);
1106 0x4: c_lt_s({{ cond = (Fs.sf < Ft.sf); }},
1107 UnorderedFalse, QnanException);
1108 0x5: c_nge_s({{ cond = (Fs.sf < Ft.sf); }},
1109 UnorderedTrue, QnanException);
1110 0x6: c_le_s({{ cond = (Fs.sf <= Ft.sf); }},
1111 UnorderedFalse, QnanException);
1112 0x7: c_ngt_s({{ cond = (Fs.sf <= Ft.sf); }},
1113 UnorderedTrue, QnanException);
1114 }
1115 }
1116 }
1117
1118 //Table A-15 MIPS32 COP1 Encoding of Function Field When
1119 //rs=D
1120 0x1: decode FUNCTION_HI {
1121 0x0: decode FUNCTION_LO {
1122 format FloatOp {
1123 0x0: add_d({{ Fd.df = Fs.df + Ft.df; }});
1124 0x1: sub_d({{ Fd.df = Fs.df - Ft.df; }});
1125 0x2: mul_d({{ Fd.df = Fs.df * Ft.df; }});
1126 0x3: div_d({{ Fd.df = Fs.df / Ft.df; }});
1127 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df); }});
1128 0x5: abs_d({{ Fd.df = fabs(Fs.df); }});
1129 0x7: neg_d({{ Fd.df = -1 * Fs.df; }});
1130 }
1131 0x6: BasicOp::mov_d({{ Fd.df = Fs.df; }});
1132 }
1133
1134 0x1: decode FUNCTION_LO {
1135 format FloatConvertOp {
1136 0x0: round_l_d({{ val = Fs.df; }},
1137 ToLong, Round);
1138 0x1: trunc_l_d({{ val = Fs.df; }},
1139 ToLong, Trunc);
1140 0x2: ceil_l_d({{ val = Fs.df; }},
1141 ToLong, Ceil);
1142 0x3: floor_l_d({{ val = Fs.df; }},
1143 ToLong, Floor);
1144 0x4: round_w_d({{ val = Fs.df; }},
1145 ToWord, Round);
1146 0x5: trunc_w_d({{ val = Fs.df; }},
1147 ToWord, Trunc);
1148 0x6: ceil_w_d({{ val = Fs.df; }},
1149 ToWord, Ceil);
1150 0x7: floor_w_d({{ val = Fs.df; }},
1151 ToWord, Floor);
1152 }
1153 }
1154
1155 0x2: decode FUNCTION_LO {
1156 0x1: decode MOVCF {
1157 format BasicOp {
1158 0x0: movf_d({{
1159 Fd.df = (getCondCode(FCSR,CC) == 0) ?
1160 Fs.df : Fd.df;
1161 }});
1162 0x1: movt_d({{
1163 Fd.df = (getCondCode(FCSR,CC) == 1) ?
1164 Fs.df : Fd.df;
1165 }});
1166 }
1167 }
1168
1169 format BasicOp {
1170 0x2: movz_d({{
1171 Fd.df = (Rt == 0) ? Fs.df : Fd.df;
1172 }});
1173 0x3: movn_d({{
1174 Fd.df = (Rt != 0) ? Fs.df : Fd.df;
1175 }});
1176 }
1177
1178 format FloatOp {
1179 0x5: recip_d({{ Fd.df = 1 / Fs.df; }});
1180 0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df); }});
1181 }
1182 format CP1Unimpl {
1183 default: unknown();
1184 }
1185
1186 }
1187 0x4: decode FUNCTION_LO {
1188 format FloatConvertOp {
1189 0x0: cvt_s_d({{ val = Fs.df; }}, ToSingle);
1190 0x4: cvt_w_d({{ val = Fs.df; }}, ToWord);
1191 0x5: cvt_l_d({{ val = Fs.df; }}, ToLong);
1192 }
1193 default: CP1Unimpl::unknown();
1194 }
1195
1196 0x6: decode FUNCTION_LO {
1197 format FloatCompareOp {
1198 0x0: c_f_d({{ cond = 0; }},
1199 DoublePrecision, UnorderedFalse);
1200 0x1: c_un_d({{ cond = 0; }},
1201 DoublePrecision, UnorderedTrue);
1202 0x2: c_eq_d({{ cond = (Fs.df == Ft.df); }},
1203 UnorderedFalse);
1204 0x3: c_ueq_d({{ cond = (Fs.df == Ft.df); }},
1205 UnorderedTrue);
1206 0x4: c_olt_d({{ cond = (Fs.df < Ft.df); }},
1207 UnorderedFalse);
1208 0x5: c_ult_d({{ cond = (Fs.df < Ft.df); }},
1209 UnorderedTrue);
1210 0x6: c_ole_d({{ cond = (Fs.df <= Ft.df); }},
1211 UnorderedFalse);
1212 0x7: c_ule_d({{ cond = (Fs.df <= Ft.df); }},
1213 UnorderedTrue);
1214 }
1215 }
1216
1217 0x7: decode FUNCTION_LO {
1218 format FloatCompareOp {
1219 0x0: c_sf_d({{ cond = 0; }}, DoublePrecision,
1220 UnorderedFalse, QnanException);
1221 0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision,
1222 UnorderedTrue, QnanException);
1223 0x2: c_seq_d({{ cond = (Fs.df == Ft.df); }},
1224 UnorderedFalse, QnanException);
1225 0x3: c_ngl_d({{ cond = (Fs.df == Ft.df); }},
1226 UnorderedTrue, QnanException);
1227 0x4: c_lt_d({{ cond = (Fs.df < Ft.df); }},
1228 UnorderedFalse, QnanException);
1229 0x5: c_nge_d({{ cond = (Fs.df < Ft.df); }},
1230 UnorderedTrue, QnanException);
1231 0x6: c_le_d({{ cond = (Fs.df <= Ft.df); }},
1232 UnorderedFalse, QnanException);
1233 0x7: c_ngt_d({{ cond = (Fs.df <= Ft.df); }},
1234 UnorderedTrue, QnanException);
1235 }
1236 }
1237 default: CP1Unimpl::unknown();
1238 }
1239 0x2: CP1Unimpl::unknown();
1240 0x3: CP1Unimpl::unknown();
1241 0x7: CP1Unimpl::unknown();
1242
1243 //Table A-16 MIPS32 COP1 Encoding of Function
1244 //Field When rs=W
1245 0x4: decode FUNCTION {
1246 format FloatConvertOp {
1247 0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle);
1248 0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble);
1249 0x26: CP1Unimpl::cvt_ps_w();
1250 }
1251 default: CP1Unimpl::unknown();
1252 }
1253
1254 //Table A-16 MIPS32 COP1 Encoding of Function Field
1255 //When rs=L1
1256 //Note: "1. Format type L is legal only if 64-bit
1257 //floating point operations are enabled."
1258 0x5: decode FUNCTION_HI {
1259 format FloatConvertOp {
1260 0x20: cvt_s_l({{ val = Fs.ud; }}, ToSingle);
1261 0x21: cvt_d_l({{ val = Fs.ud; }}, ToDouble);
1262 0x26: CP1Unimpl::cvt_ps_l();
1263 }
1264 default: CP1Unimpl::unknown();
1265 }
1266
1267 //Table A-17 MIPS64 COP1 Encoding of Function Field
1268 //When rs=PS1
1269 //Note: "1. Format type PS is legal only if 64-bit
1270 //floating point operations are enabled. "
1271 0x6: decode FUNCTION_HI {
1272 0x0: decode FUNCTION_LO {
1273 format Float64Op {
1274 0x0: add_ps({{
1275 Fd1.sf = Fs1.sf + Ft2.sf;
1276 Fd2.sf = Fs2.sf + Ft2.sf;
1277 }});
1278 0x1: sub_ps({{
1279 Fd1.sf = Fs1.sf - Ft2.sf;
1280 Fd2.sf = Fs2.sf - Ft2.sf;
1281 }});
1282 0x2: mul_ps({{
1283 Fd1.sf = Fs1.sf * Ft2.sf;
1284 Fd2.sf = Fs2.sf * Ft2.sf;
1285 }});
1286 0x5: abs_ps({{
1287 Fd1.sf = fabs(Fs1.sf);
1288 Fd2.sf = fabs(Fs2.sf);
1289 }});
1290 0x6: mov_ps({{
1291 Fd1.sf = Fs1.sf;
1292 Fd2.sf = Fs2.sf;
1293 }});
1294 0x7: neg_ps({{
1295 Fd1.sf = -(Fs1.sf);
1296 Fd2.sf = -(Fs2.sf);
1297 }});
1298 default: CP1Unimpl::unknown();
1299 }
1300 }
1301 0x1: CP1Unimpl::unknown();
1302 0x2: decode FUNCTION_LO {
1303 0x1: decode MOVCF {
1304 format Float64Op {
1305 0x0: movf_ps({{
1306 Fd1 = (getCondCode(FCSR, CC) == 0) ?
1307 Fs1 : Fd1;
1308 Fd2 = (getCondCode(FCSR, CC+1) == 0) ?
1309 Fs2 : Fd2;
1310 }});
1311 0x1: movt_ps({{
1312 Fd2 = (getCondCode(FCSR, CC) == 1) ?
1313 Fs1 : Fd1;
1314 Fd2 = (getCondCode(FCSR, CC+1) == 1) ?
1315 Fs2 : Fd2;
1316 }});
1317 }
1318 }
1319
1320 format Float64Op {
1321 0x2: movz_ps({{
1322 Fd1 = (getCondCode(FCSR, CC) == 0) ?
1323 Fs1 : Fd1;
1324 Fd2 = (getCondCode(FCSR, CC) == 0) ?
1325 Fs2 : Fd2;
1326 }});
1327 0x3: movn_ps({{
1328 Fd1 = (getCondCode(FCSR, CC) == 1) ?
1329 Fs1 : Fd1;
1330 Fd2 = (getCondCode(FCSR, CC) == 1) ?
1331 Fs2 : Fd2;
1332 }});
1333 }
1334 default: CP1Unimpl::unknown();
1335 }
1336 0x3: CP1Unimpl::unknown();
1337 0x4: decode FUNCTION_LO {
1338 0x0: FloatOp::cvt_s_pu({{ Fd.sf = Fs2.sf; }});
1339 default: CP1Unimpl::unknown();
1340 }
1341
1342 0x5: decode FUNCTION_LO {
1343 0x0: FloatOp::cvt_s_pl({{ Fd.sf = Fs1.sf; }});
1344 format Float64Op {
1345 0x4: pll({{
1346 Fd.ud = (uint64_t)Fs1.uw << 32 | Ft1.uw;
1347 }});
1348 0x5: plu({{
1349 Fd.ud = (uint64_t)Fs1.uw << 32 | Ft2.uw;
1350 }});
1351 0x6: pul({{
1352 Fd.ud = (uint64_t)Fs2.uw << 32 | Ft1.uw;
1353 }});
1354 0x7: puu({{
1355 Fd.ud = (uint64_t)Fs2.uw << 32 | Ft2.uw;
1356 }});
1357 }
1358 default: CP1Unimpl::unknown();
1359 }
1360
1361 0x6: decode FUNCTION_LO {
1362 format FloatPSCompareOp {
1363 0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1364 UnorderedFalse);
1365 0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1366 UnorderedTrue);
1367 0x2: c_eq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1368 {{ cond2 = (Fs2.sf == Ft2.sf); }},
1369 UnorderedFalse);
1370 0x3: c_ueq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1371 {{ cond2 = (Fs2.sf == Ft2.sf); }},
1372 UnorderedTrue);
1373 0x4: c_olt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
1374 {{ cond2 = (Fs2.sf < Ft2.sf); }},
1375 UnorderedFalse);
1376 0x5: c_ult_ps({{ cond1 = (Fs.sf < Ft.sf); }},
1377 {{ cond2 = (Fs2.sf < Ft2.sf); }},
1378 UnorderedTrue);
1379 0x6: c_ole_ps({{ cond1 = (Fs.sf <= Ft.sf); }},
1380 {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1381 UnorderedFalse);
1382 0x7: c_ule_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
1383 {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1384 UnorderedTrue);
1385 }
1386 }
1387
1388 0x7: decode FUNCTION_LO {
1389 format FloatPSCompareOp {
1390 0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1391 UnorderedFalse, QnanException);
1392 0x1: c_ngle_ps({{ cond1 = 0; }},
1393 {{ cond2 = 0; }},
1394 UnorderedTrue, QnanException);
1395 0x2: c_seq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1396 {{ cond2 = (Fs2.sf == Ft2.sf); }},
1397 UnorderedFalse, QnanException);
1398 0x3: c_ngl_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1399 {{ cond2 = (Fs2.sf == Ft2.sf); }},
1400 UnorderedTrue, QnanException);
1401 0x4: c_lt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
1402 {{ cond2 = (Fs2.sf < Ft2.sf); }},
1403 UnorderedFalse, QnanException);
1404 0x5: c_nge_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
1405 {{ cond2 = (Fs2.sf < Ft2.sf); }},
1406 UnorderedTrue, QnanException);
1407 0x6: c_le_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
1408 {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1409 UnorderedFalse, QnanException);
1410 0x7: c_ngt_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
1411 {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1412 UnorderedTrue, QnanException);
1413 }
1414 }
1415 }
1416 }
1417 default: CP1Unimpl::unknown();
1418 }
1419 }
1420
1421 //Table A-19 MIPS32 COP2 Encoding of rs Field
1422 0x2: decode RS_MSB {
1423 format CP2Unimpl {
1424 0x0: decode RS_HI {
1425 0x0: decode RS_LO {
1426 0x0: mfc2();
1427 0x2: cfc2();
1428 0x3: mfhc2();
1429 0x4: mtc2();
1430 0x6: ctc2();
1431 0x7: mftc2();
1432 default: unknown();
1433 }
1434
1435 0x1: decode ND {
1436 0x0: decode TF {
1437 0x0: bc2f();
1438 0x1: bc2t();
1439 default: unknown();
1440 }
1441
1442 0x1: decode TF {
1443 0x0: bc2fl();
1444 0x1: bc2tl();
1445 default: unknown();
1446 }
1447 default: unknown();
1448
1449 }
1450 default: unknown();
1451 }
1452 default: unknown();
1453 }
1454 }
1455
1456 //Table A-20 MIPS64 COP1X Encoding of Function Field 1
1457 //Note: "COP1X instructions are legal only if 64-bit floating point
1458 //operations are enabled."
1459 0x3: decode FUNCTION_HI {
1460 0x0: decode FUNCTION_LO {
1461 format LoadIndexedMemory {
1462 0x0: lwxc1({{ Fd.uw = Mem.uw; }});
1463 0x1: ldxc1({{ Fd.ud = Mem.ud; }});
1464 0x5: luxc1({{ Fd.ud = Mem.ud; }},
1465 {{ EA = (Rs + Rt) & ~7; }});
1466 }
1467 }
1468
1469 0x1: decode FUNCTION_LO {
1470 format StoreIndexedMemory {
1471 0x0: swxc1({{ Mem.uw = Fs.uw; }});
1472 0x1: sdxc1({{ Mem.ud = Fs.ud; }});
1473 0x5: suxc1({{ Mem.ud = Fs.ud; }},
1474 {{ EA = (Rs + Rt) & ~7; }});
1475 }
1476 0x7: Prefetch::prefx({{ EA = Rs + Rt; }});
1477 }
1478
1479 0x3: decode FUNCTION_LO {
1480 0x6: Float64Op::alnv_ps({{
1481 if (Rs<2:0> == 0) {
1482 Fd.ud = Fs.ud;
1483 } else if (Rs<2:0> == 4) {
1484 if (GuestByteOrder == BigEndianByteOrder)
1485 Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<63:32>;
1486 else
1487 Fd.ud = Ft.ud<31:0> << 32 | Fs.ud<63:32>;
1488 } else {
1489 Fd.ud = Fd.ud;
1490 }
1491 }});
1492 }
1493
1494 format FloatAccOp {
1495 0x4: decode FUNCTION_LO {
1496 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }});
1497 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }});
1498 0x6: madd_ps({{
1499 Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df;
1500 Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df;
1501 }});
1502 }
1503
1504 0x5: decode FUNCTION_LO {
1505 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }});
1506 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }});
1507 0x6: msub_ps({{
1508 Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df;
1509 Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df;
1510 }});
1511 }
1512
1513 0x6: decode FUNCTION_LO {
1514 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
1515 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }});
1516 0x6: nmadd_ps({{
1517 Fd1.sf = -((Fs1.df * Ft1.df) + Fr1.df);
1518 Fd2.sf = -((Fs2.df * Ft2.df) + Fr2.df);
1519 }});
1520 }
1521
1522 0x7: decode FUNCTION_LO {
1523 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) + Fr.sf; }});
1524 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }});
1525 0x6: nmsub_ps({{
1526 Fd1.sf = -((Fs1.df * Ft1.df) - Fr1.df);
1527 Fd2.sf = -((Fs2.df * Ft2.df) - Fr2.df);
1528 }});
1529 }
1530 }
1531 }
1532
1533 format Branch {
1534 0x4: beql({{ cond = (Rs.sw == Rt.sw); }}, Likely);
1535 0x5: bnel({{ cond = (Rs.sw != Rt.sw); }}, Likely);
1536 0x6: blezl({{ cond = (Rs.sw <= 0); }}, Likely);
1537 0x7: bgtzl({{ cond = (Rs.sw > 0); }}, Likely);
1538 }
1539 }
1540
1541 0x3: decode OPCODE_LO {
1542 //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
1543 0x4: decode FUNCTION_HI {
1544 0x0: decode FUNCTION_LO {
1545 0x2: IntOp::mul({{
1546 int64_t temp1 = Rs.sd * Rt.sd;
1547 Rd.sw = temp1<31:0>;
1548 }}, IntMultOp);
1549
1550 format HiLoRdSelValOp {
1551 0x0: madd({{
1552 val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1553 (Rs.sd * Rt.sd);
1554 }}, IntMultOp);
1555 0x1: maddu({{
1556 val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1557 (Rs.ud * Rt.ud);
1558 }}, IntMultOp);
1559 0x4: msub({{
1560 val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1561 (Rs.sd * Rt.sd);
1562 }}, IntMultOp);
1563 0x5: msubu({{
1564 val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1565 (Rs.ud * Rt.ud);
1566 }}, IntMultOp);
1567 }
1568 }
1569
1570 0x4: decode FUNCTION_LO {
1571 format BasicOp {
1572 0x0: clz({{
1573 int cnt = 32;
1574 for (int idx = 31; idx >= 0; idx--) {
1575 if (Rs<idx:idx> == 1) {
1576 cnt = 31 - idx;
1577 break;
1578 }
1579 }
1580 Rd.uw = cnt;
1581 }});
1582 0x1: clo({{
1583 int cnt = 32;
1584 for (int idx = 31; idx >= 0; idx--) {
1585 if (Rs<idx:idx> == 0) {
1586 cnt = 31 - idx;
1587 break;
1588 }
1589 }
1590 Rd.uw = cnt;
1591 }});
1592 }
1593 }
1594
1595 0x7: decode FUNCTION_LO {
1596 0x7: FailUnimpl::sdbbp();
1597 }
1598 }
1599
1600 //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2
1601 //of the Architecture
1602 0x7: decode FUNCTION_HI {
1603 0x0: decode FUNCTION_LO {
1604 format BasicOp {
1605 0x0: ext({{ Rt.uw = bits(Rs.uw, MSB+LSB, LSB); }});
1606 0x4: ins({{
1607 Rt.uw = bits(Rt.uw, 31, MSB+1) << (MSB+1) |
1608 bits(Rs.uw, MSB-LSB, 0) << LSB |
1609 bits(Rt.uw, LSB-1, 0);
1610 }});
1611 }
1612 }
1613
1614 0x1: decode FUNCTION_LO {
1615 format MT_Control {
1616 0x0: fork({{
1617 forkThread(xc->tcBase(), fault, RD, Rs, Rt);
1618 }}, UserMode);
1619 0x1: yield({{
1620 Rd.sw = yieldThread(xc->tcBase(), fault, Rs.sw,
1621 YQMask);
1622 }}, UserMode);
1623 }
1624
1625 //Table 5-9 MIPS32 LX Encoding of the op Field (DSP ASE MANUAL)
1626 0x2: decode OP_HI {
1627 0x0: decode OP_LO {
1628 format LoadIndexedMemory {
1629 0x0: lwx({{ Rd.sw = Mem.sw; }});
1630 0x4: lhx({{ Rd.sw = Mem.sh; }});
1631 0x6: lbux({{ Rd.uw = Mem.ub; }});
1632 }
1633 }
1634 }
1635 0x4: DspIntOp::insv({{
1636 int pos = dspctl<5:0>;
1637 int size = dspctl<12:7> - 1;
1638 Rt.uw = insertBits(Rt.uw, pos+size,
1639 pos, Rs.uw<size:0>);
1640 }});
1641 }
1642
1643 0x2: decode FUNCTION_LO {
1644
1645 //Table 5-5 MIPS32 ADDU.QB Encoding of the op Field
1646 //(DSP ASE MANUAL)
1647 0x0: decode OP_HI {
1648 0x0: decode OP_LO {
1649 format DspIntOp {
1650 0x0: addu_qb({{
1651 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1652 NOSATURATE, UNSIGNED, &dspctl);
1653 }});
1654 0x1: subu_qb({{
1655 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_QB,
1656 NOSATURATE, UNSIGNED, &dspctl);
1657 }});
1658 0x4: addu_s_qb({{
1659 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1660 SATURATE, UNSIGNED, &dspctl);
1661 }});
1662 0x5: subu_s_qb({{
1663 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_QB,
1664 SATURATE, UNSIGNED, &dspctl);
1665 }});
1666 0x6: muleu_s_ph_qbl({{
1667 Rd.uw = dspMuleu(Rs.uw, Rt.uw,
1668 MODE_L, &dspctl);
1669 }}, IntMultOp);
1670 0x7: muleu_s_ph_qbr({{
1671 Rd.uw = dspMuleu(Rs.uw, Rt.uw,
1672 MODE_R, &dspctl);
1673 }}, IntMultOp);
1674 }
1675 }
1676 0x1: decode OP_LO {
1677 format DspIntOp {
1678 0x0: addu_ph({{
1679 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1680 NOSATURATE, UNSIGNED, &dspctl);
1681 }});
1682 0x1: subu_ph({{
1683 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1684 NOSATURATE, UNSIGNED, &dspctl);
1685 }});
1686 0x2: addq_ph({{
1687 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1688 NOSATURATE, SIGNED, &dspctl);
1689 }});
1690 0x3: subq_ph({{
1691 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1692 NOSATURATE, SIGNED, &dspctl);
1693 }});
1694 0x4: addu_s_ph({{
1695 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1696 SATURATE, UNSIGNED, &dspctl);
1697 }});
1698 0x5: subu_s_ph({{
1699 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1700 SATURATE, UNSIGNED, &dspctl);
1701 }});
1702 0x6: addq_s_ph({{
1703 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1704 SATURATE, SIGNED, &dspctl);
1705 }});
1706 0x7: subq_s_ph({{
1707 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1708 SATURATE, SIGNED, &dspctl);
1709 }});
1710 }
1711 }
1712 0x2: decode OP_LO {
1713 format DspIntOp {
1714 0x0: addsc({{
1715 int64_t dresult;
1716 dresult = Rs.ud + Rt.ud;
1717 Rd.sw = dresult<31:0>;
1718 dspctl = insertBits(dspctl, 13, 13,
1719 dresult<32:32>);
1720 }});
1721 0x1: addwc({{
1722 int64_t dresult;
1723 dresult = Rs.sd + Rt.sd + dspctl<13:13>;
1724 Rd.sw = dresult<31:0>;
1725 if (dresult<32:32> != dresult<31:31>)
1726 dspctl = insertBits(dspctl, 20, 20, 1);
1727 }});
1728 0x2: modsub({{
1729 Rd.sw = (Rs.sw == 0) ? Rt.sw<23:8> :
1730 Rs.sw - Rt.sw<7:0>;
1731 }});
1732 0x4: raddu_w_qb({{
1733 Rd.uw = Rs.uw<31:24> + Rs.uw<23:16> +
1734 Rs.uw<15:8> + Rs.uw<7:0>;
1735 }});
1736 0x6: addq_s_w({{
1737 Rd.sw = dspAdd(Rs.sw, Rt.sw, SIMD_FMT_W,
1738 SATURATE, SIGNED, &dspctl);
1739 }});
1740 0x7: subq_s_w({{
1741 Rd.sw = dspSub(Rs.sw, Rt.sw, SIMD_FMT_W,
1742 SATURATE, SIGNED, &dspctl);
1743 }});
1744 }
1745 }
1746 0x3: decode OP_LO {
1747 format DspIntOp {
1748 0x4: muleq_s_w_phl({{
1749 Rd.sw = dspMuleq(Rs.sw, Rt.sw,
1750 MODE_L, &dspctl);
1751 }}, IntMultOp);
1752 0x5: muleq_s_w_phr({{
1753 Rd.sw = dspMuleq(Rs.sw, Rt.sw,
1754 MODE_R, &dspctl);
1755 }}, IntMultOp);
1756 0x6: mulq_s_ph({{
1757 Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_PH,
1758 SATURATE, NOROUND, &dspctl);
1759 }}, IntMultOp);
1760 0x7: mulq_rs_ph({{
1761 Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_PH,
1762 SATURATE, ROUND, &dspctl);
1763 }}, IntMultOp);
1764 }
1765 }
1766 }
1767
1768 //Table 5-6 MIPS32 CMPU_EQ_QB Encoding of the op Field
1769 //(DSP ASE MANUAL)
1770 0x1: decode OP_HI {
1771 0x0: decode OP_LO {
1772 format DspIntOp {
1773 0x0: cmpu_eq_qb({{
1774 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_QB,
1775 UNSIGNED, CMP_EQ, &dspctl);
1776 }});
1777 0x1: cmpu_lt_qb({{
1778 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_QB,
1779 UNSIGNED, CMP_LT, &dspctl);
1780 }});
1781 0x2: cmpu_le_qb({{
1782 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_QB,
1783 UNSIGNED, CMP_LE, &dspctl);
1784 }});
1785 0x3: pick_qb({{
1786 Rd.uw = dspPick(Rs.uw, Rt.uw,
1787 SIMD_FMT_QB, &dspctl);
1788 }});
1789 0x4: cmpgu_eq_qb({{
1790 Rd.uw = dspCmpg(Rs.uw, Rt.uw, SIMD_FMT_QB,
1791 UNSIGNED, CMP_EQ );
1792 }});
1793 0x5: cmpgu_lt_qb({{
1794 Rd.uw = dspCmpg(Rs.uw, Rt.uw, SIMD_FMT_QB,
1795 UNSIGNED, CMP_LT);
1796 }});
1797 0x6: cmpgu_le_qb({{
1798 Rd.uw = dspCmpg(Rs.uw, Rt.uw, SIMD_FMT_QB,
1799 UNSIGNED, CMP_LE);
1800 }});
1801 }
1802 }
1803 0x1: decode OP_LO {
1804 format DspIntOp {
1805 0x0: cmp_eq_ph({{
1806 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_PH,
1807 SIGNED, CMP_EQ, &dspctl);
1808 }});
1809 0x1: cmp_lt_ph({{
1810 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_PH,
1811 SIGNED, CMP_LT, &dspctl);
1812 }});
1813 0x2: cmp_le_ph({{
1814 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_PH,
1815 SIGNED, CMP_LE, &dspctl);
1816 }});
1817 0x3: pick_ph({{
1818 Rd.uw = dspPick(Rs.uw, Rt.uw,
1819 SIMD_FMT_PH, &dspctl);
1820 }});
1821 0x4: precrq_qb_ph({{
1822 Rd.uw = Rs.uw<31:24> << 24 |
1823 Rs.uw<15:8> << 16 |
1824 Rt.uw<31:24> << 8 |
1825 Rt.uw<15:8>;
1826 }});
1827 0x5: precr_qb_ph({{
1828 Rd.uw = Rs.uw<23:16> << 24 |
1829 Rs.uw<7:0> << 16 |
1830 Rt.uw<23:16> << 8 |
1831 Rt.uw<7:0>;
1832 }});
1833 0x6: packrl_ph({{
1834 Rd.uw = dspPack(Rs.uw, Rt.uw, SIMD_FMT_PH);
1835 }});
1836 0x7: precrqu_s_qb_ph({{
1837 Rd.uw = dspPrecrqu(Rs.uw, Rt.uw, &dspctl);
1838 }});
1839 }
1840 }
1841 0x2: decode OP_LO {
1842 format DspIntOp {
1843 0x4: precrq_ph_w({{
1844 Rd.uw = Rs.uw<31:16> << 16 | Rt.uw<31:16>;
1845 }});
1846 0x5: precrq_rs_ph_w({{
1847 Rd.uw = dspPrecrq(Rs.uw, Rt.uw,
1848 SIMD_FMT_W, &dspctl);
1849 }});
1850 }
1851 }
1852 0x3: decode OP_LO {
1853 format DspIntOp {
1854 0x0: cmpgdu_eq_qb({{
1855 Rd.uw = dspCmpgd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1856 UNSIGNED, CMP_EQ, &dspctl);
1857 }});
1858 0x1: cmpgdu_lt_qb({{
1859 Rd.uw = dspCmpgd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1860 UNSIGNED, CMP_LT, &dspctl);
1861 }});
1862 0x2: cmpgdu_le_qb({{
1863 Rd.uw = dspCmpgd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1864 UNSIGNED, CMP_LE, &dspctl);
1865 }});
1866 0x6: precr_sra_ph_w({{
1867 Rt.uw = dspPrecrSra(Rt.uw, Rs.uw, RD,
1868 SIMD_FMT_W, NOROUND);
1869 }});
1870 0x7: precr_sra_r_ph_w({{
1871 Rt.uw = dspPrecrSra(Rt.uw, Rs.uw, RD,
1872 SIMD_FMT_W, ROUND);
1873 }});
1874 }
1875 }
1876 }
1877
1878 //Table 5-7 MIPS32 ABSQ_S.PH Encoding of the op Field
1879 //(DSP ASE MANUAL)
1880 0x2: decode OP_HI {
1881 0x0: decode OP_LO {
1882 format DspIntOp {
1883 0x1: absq_s_qb({{
1884 Rd.sw = dspAbs(Rt.sw, SIMD_FMT_QB, &dspctl);
1885 }});
1886 0x2: repl_qb({{
1887 Rd.uw = RS_RT<7:0> << 24 |
1888 RS_RT<7:0> << 16 |
1889 RS_RT<7:0> << 8 |
1890 RS_RT<7:0>;
1891 }});
1892 0x3: replv_qb({{
1893 Rd.sw = Rt.uw<7:0> << 24 |
1894 Rt.uw<7:0> << 16 |
1895 Rt.uw<7:0> << 8 |
1896 Rt.uw<7:0>;
1897 }});
1898 0x4: precequ_ph_qbl({{
1899 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1900 SIMD_FMT_PH, SIGNED, MODE_L);
1901 }});
1902 0x5: precequ_ph_qbr({{
1903 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1904 SIMD_FMT_PH, SIGNED, MODE_R);
1905 }});
1906 0x6: precequ_ph_qbla({{
1907 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1908 SIMD_FMT_PH, SIGNED, MODE_LA);
1909 }});
1910 0x7: precequ_ph_qbra({{
1911 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1912 SIMD_FMT_PH, SIGNED, MODE_RA);
1913 }});
1914 }
1915 }
1916 0x1: decode OP_LO {
1917 format DspIntOp {
1918 0x1: absq_s_ph({{
1919 Rd.sw = dspAbs(Rt.sw, SIMD_FMT_PH, &dspctl);
1920 }});
1921 0x2: repl_ph({{
1922 Rd.uw = (sext<10>(RS_RT))<15:0> << 16 |
1923 (sext<10>(RS_RT))<15:0>;
1924 }});
1925 0x3: replv_ph({{
1926 Rd.uw = Rt.uw<15:0> << 16 |
1927 Rt.uw<15:0>;
1928 }});
1929 0x4: preceq_w_phl({{
1930 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_PH, SIGNED,
1931 SIMD_FMT_W, SIGNED, MODE_L);
1932 }});
1933 0x5: preceq_w_phr({{
1934 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_PH, SIGNED,
1935 SIMD_FMT_W, SIGNED, MODE_R);
1936 }});
1937 }
1938 }
1939 0x2: decode OP_LO {
1940 format DspIntOp {
1941 0x1: absq_s_w({{
1942 Rd.sw = dspAbs(Rt.sw, SIMD_FMT_W, &dspctl);
1943 }});
1944 }
1945 }
1946 0x3: decode OP_LO {
1947 0x3: IntOp::bitrev({{
1948 Rd.uw = bitrev( Rt.uw<15:0> );
1949 }});
1950 format DspIntOp {
1951 0x4: preceu_ph_qbl({{
1952 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1953 UNSIGNED, SIMD_FMT_PH,
1954 UNSIGNED, MODE_L);
1955 }});
1956 0x5: preceu_ph_qbr({{
1957 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1958 UNSIGNED, SIMD_FMT_PH,
1959 UNSIGNED, MODE_R );
1960 }});
1961 0x6: preceu_ph_qbla({{
1962 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1963 UNSIGNED, SIMD_FMT_PH,
1964 UNSIGNED, MODE_LA );
1965 }});
1966 0x7: preceu_ph_qbra({{
1967 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1968 UNSIGNED, SIMD_FMT_PH,
1969 UNSIGNED, MODE_RA);
1970 }});
1971 }
1972 }
1973 }
1974
1975 //Table 5-8 MIPS32 SHLL.QB Encoding of the op Field
1976 //(DSP ASE MANUAL)
1977 0x3: decode OP_HI {
1978 0x0: decode OP_LO {
1979 format DspIntOp {
1980 0x0: shll_qb({{
1981 Rd.sw = dspShll(Rt.sw, RS, SIMD_FMT_QB,
1982 NOSATURATE, UNSIGNED, &dspctl);
1983 }});
1984 0x1: shrl_qb({{
1985 Rd.sw = dspShrl(Rt.sw, RS, SIMD_FMT_QB,
1986 UNSIGNED);
1987 }});
1988 0x2: shllv_qb({{
1989 Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_QB,
1990 NOSATURATE, UNSIGNED, &dspctl);
1991 }});
1992 0x3: shrlv_qb({{
1993 Rd.sw = dspShrl(Rt.sw, Rs.sw, SIMD_FMT_QB,
1994 UNSIGNED);
1995 }});
1996 0x4: shra_qb({{
1997 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_QB,
1998 NOROUND, SIGNED, &dspctl);
1999 }});
2000 0x5: shra_r_qb({{
2001 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_QB,
2002 ROUND, SIGNED, &dspctl);
2003 }});
2004 0x6: shrav_qb({{
2005 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_QB,
2006 NOROUND, SIGNED, &dspctl);
2007 }});
2008 0x7: shrav_r_qb({{
2009 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_QB,
2010 ROUND, SIGNED, &dspctl);
2011 }});
2012 }
2013 }
2014 0x1: decode OP_LO {
2015 format DspIntOp {
2016 0x0: shll_ph({{
2017 Rd.uw = dspShll(Rt.uw, RS, SIMD_FMT_PH,
2018 NOSATURATE, SIGNED, &dspctl);
2019 }});
2020 0x1: shra_ph({{
2021 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_PH,
2022 NOROUND, SIGNED, &dspctl);
2023 }});
2024 0x2: shllv_ph({{
2025 Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_PH,
2026 NOSATURATE, SIGNED, &dspctl);
2027 }});
2028 0x3: shrav_ph({{
2029 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_PH,
2030 NOROUND, SIGNED, &dspctl);
2031 }});
2032 0x4: shll_s_ph({{
2033 Rd.sw = dspShll(Rt.sw, RS, SIMD_FMT_PH,
2034 SATURATE, SIGNED, &dspctl);
2035 }});
2036 0x5: shra_r_ph({{
2037 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_PH,
2038 ROUND, SIGNED, &dspctl);
2039 }});
2040 0x6: shllv_s_ph({{
2041 Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_PH,
2042 SATURATE, SIGNED, &dspctl);
2043 }});
2044 0x7: shrav_r_ph({{
2045 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_PH,
2046 ROUND, SIGNED, &dspctl);
2047 }});
2048 }
2049 }
2050 0x2: decode OP_LO {
2051 format DspIntOp {
2052 0x4: shll_s_w({{
2053 Rd.sw = dspShll(Rt.sw, RS, SIMD_FMT_W,
2054 SATURATE, SIGNED, &dspctl);
2055 }});
2056 0x5: shra_r_w({{
2057 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_W,
2058 ROUND, SIGNED, &dspctl);
2059 }});
2060 0x6: shllv_s_w({{
2061 Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_W,
2062 SATURATE, SIGNED, &dspctl);
2063 }});
2064 0x7: shrav_r_w({{
2065 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_W,
2066 ROUND, SIGNED, &dspctl);
2067 }});
2068 }
2069 }
2070 0x3: decode OP_LO {
2071 format DspIntOp {
2072 0x1: shrl_ph({{
2073 Rd.sw = dspShrl(Rt.sw, RS, SIMD_FMT_PH,
2074 UNSIGNED);
2075 }});
2076 0x3: shrlv_ph({{
2077 Rd.sw = dspShrl(Rt.sw, Rs.sw, SIMD_FMT_PH,
2078 UNSIGNED);
2079 }});
2080 }
2081 }
2082 }
2083 }
2084
2085 0x3: decode FUNCTION_LO {
2086
2087 //Table 3.12 MIPS32 ADDUH.QB Encoding of the op Field
2088 //(DSP ASE Rev2 Manual)
2089 0x0: decode OP_HI {
2090 0x0: decode OP_LO {
2091 format DspIntOp {
2092 0x0: adduh_qb({{
2093 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2094 NOROUND, UNSIGNED);
2095 }});
2096 0x1: subuh_qb({{
2097 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2098 NOROUND, UNSIGNED);
2099 }});
2100 0x2: adduh_r_qb({{
2101 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2102 ROUND, UNSIGNED);
2103 }});
2104 0x3: subuh_r_qb({{
2105 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2106 ROUND, UNSIGNED);
2107 }});
2108 }
2109 }
2110 0x1: decode OP_LO {
2111 format DspIntOp {
2112 0x0: addqh_ph({{
2113 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2114 NOROUND, SIGNED);
2115 }});
2116 0x1: subqh_ph({{
2117 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2118 NOROUND, SIGNED);
2119 }});
2120 0x2: addqh_r_ph({{
2121 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2122 ROUND, SIGNED);
2123 }});
2124 0x3: subqh_r_ph({{
2125 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2126 ROUND, SIGNED);
2127 }});
2128 0x4: mul_ph({{
2129 Rd.sw = dspMul(Rs.sw, Rt.sw, SIMD_FMT_PH,
2130 NOSATURATE, &dspctl);
2131 }}, IntMultOp);
2132 0x6: mul_s_ph({{
2133 Rd.sw = dspMul(Rs.sw, Rt.sw, SIMD_FMT_PH,
2134 SATURATE, &dspctl);
2135 }}, IntMultOp);
2136 }
2137 }
2138 0x2: decode OP_LO {
2139 format DspIntOp {
2140 0x0: addqh_w({{
2141 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_W,
2142 NOROUND, SIGNED);
2143 }});
2144 0x1: subqh_w({{
2145 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_W,
2146 NOROUND, SIGNED);
2147 }});
2148 0x2: addqh_r_w({{
2149 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_W,
2150 ROUND, SIGNED);
2151 }});
2152 0x3: subqh_r_w({{
2153 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_W,
2154 ROUND, SIGNED);
2155 }});
2156 0x6: mulq_s_w({{
2157 Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_W,
2158 SATURATE, NOROUND, &dspctl);
2159 }}, IntMultOp);
2160 0x7: mulq_rs_w({{
2161 Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_W,
2162 SATURATE, ROUND, &dspctl);
2163 }}, IntMultOp);
2164 }
2165 }
2166 }
2167 }
2168
2169 //Table A-10 MIPS32 BSHFL Encoding of sa Field
2170 0x4: decode SA {
2171 format BasicOp {
2172 0x02: wsbh({{
2173 Rd.uw = Rt.uw<23:16> << 24 |
2174 Rt.uw<31:24> << 16 |
2175 Rt.uw<7:0> << 8 |
2176 Rt.uw<15:8>;
2177 }});
2178 0x10: seb({{ Rd.sw = Rt.sb; }});
2179 0x18: seh({{ Rd.sw = Rt.sh; }});
2180 }
2181 }
2182
2183 0x6: decode FUNCTION_LO {
2184
2185 //Table 5-10 MIPS32 DPAQ.W.PH Encoding of the op Field
2186 //(DSP ASE MANUAL)
2187 0x0: decode OP_HI {
2188 0x0: decode OP_LO {
2189 format DspHiLoOp {
2190 0x0: dpa_w_ph({{
2191 dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2192 SIMD_FMT_PH, SIGNED, MODE_L);
2193 }}, IntMultOp);
2194 0x1: dps_w_ph({{
2195 dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2196 SIMD_FMT_PH, SIGNED, MODE_L);
2197 }}, IntMultOp);
2198 0x2: mulsa_w_ph({{
2199 dspac = dspMulsa(dspac, Rs.sw, Rt.sw,
2200 ACDST, SIMD_FMT_PH );
2201 }}, IntMultOp);
2202 0x3: dpau_h_qbl({{
2203 dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2204 SIMD_FMT_QB, UNSIGNED, MODE_L);
2205 }}, IntMultOp);
2206 0x4: dpaq_s_w_ph({{
2207 dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2208 ACDST, SIMD_FMT_PH,
2209 SIMD_FMT_W, NOSATURATE,
2210 MODE_L, &dspctl);
2211 }}, IntMultOp);
2212 0x5: dpsq_s_w_ph({{
2213 dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2214 ACDST, SIMD_FMT_PH,
2215 SIMD_FMT_W, NOSATURATE,
2216 MODE_L, &dspctl);
2217 }}, IntMultOp);
2218 0x6: mulsaq_s_w_ph({{
2219 dspac = dspMulsaq(dspac, Rs.sw, Rt.sw,
2220 ACDST, SIMD_FMT_PH,
2221 &dspctl);
2222 }}, IntMultOp);
2223 0x7: dpau_h_qbr({{
2224 dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2225 SIMD_FMT_QB, UNSIGNED, MODE_R);
2226 }}, IntMultOp);
2227 }
2228 }
2229 0x1: decode OP_LO {
2230 format DspHiLoOp {
2231 0x0: dpax_w_ph({{
2232 dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2233 SIMD_FMT_PH, SIGNED, MODE_X);
2234 }}, IntMultOp);
2235 0x1: dpsx_w_ph({{
2236 dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2237 SIMD_FMT_PH, SIGNED, MODE_X);
2238 }}, IntMultOp);
2239 0x3: dpsu_h_qbl({{
2240 dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2241 SIMD_FMT_QB, UNSIGNED, MODE_L);
2242 }}, IntMultOp);
2243 0x4: dpaq_sa_l_w({{
2244 dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2245 ACDST, SIMD_FMT_W,
2246 SIMD_FMT_L, SATURATE,
2247 MODE_L, &dspctl);
2248 }}, IntMultOp);
2249 0x5: dpsq_sa_l_w({{
2250 dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2251 ACDST, SIMD_FMT_W,
2252 SIMD_FMT_L, SATURATE,
2253 MODE_L, &dspctl);
2254 }}, IntMultOp);
2255 0x7: dpsu_h_qbr({{
2256 dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2257 SIMD_FMT_QB, UNSIGNED, MODE_R);
2258 }}, IntMultOp);
2259 }
2260 }
2261 0x2: decode OP_LO {
2262 format DspHiLoOp {
2263 0x0: maq_sa_w_phl({{
2264 dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2265 ACDST, SIMD_FMT_PH,
2266 MODE_L, SATURATE, &dspctl);
2267 }}, IntMultOp);
2268 0x2: maq_sa_w_phr({{
2269 dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2270 ACDST, SIMD_FMT_PH,
2271 MODE_R, SATURATE, &dspctl);
2272 }}, IntMultOp);
2273 0x4: maq_s_w_phl({{
2274 dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2275 ACDST, SIMD_FMT_PH,
2276 MODE_L, NOSATURATE, &dspctl);
2277 }}, IntMultOp);
2278 0x6: maq_s_w_phr({{
2279 dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2280 ACDST, SIMD_FMT_PH,
2281 MODE_R, NOSATURATE, &dspctl);
2282 }}, IntMultOp);
2283 }
2284 }
2285 0x3: decode OP_LO {
2286 format DspHiLoOp {
2287 0x0: dpaqx_s_w_ph({{
2288 dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2289 ACDST, SIMD_FMT_PH,
2290 SIMD_FMT_W, NOSATURATE,
2291 MODE_X, &dspctl);
2292 }}, IntMultOp);
2293 0x1: dpsqx_s_w_ph({{
2294 dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2295 ACDST, SIMD_FMT_PH,
2296 SIMD_FMT_W, NOSATURATE,
2297 MODE_X, &dspctl);
2298 }}, IntMultOp);
2299 0x2: dpaqx_sa_w_ph({{
2300 dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2301 ACDST, SIMD_FMT_PH,
2302 SIMD_FMT_W, SATURATE,
2303 MODE_X, &dspctl);
2304 }}, IntMultOp);
2305 0x3: dpsqx_sa_w_ph({{
2306 dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2307 ACDST, SIMD_FMT_PH,
2308 SIMD_FMT_W, SATURATE,
2309 MODE_X, &dspctl);
2310 }}, IntMultOp);
2311 }
2312 }
2313 }
2314
2315 //Table 3.3 MIPS32 APPEND Encoding of the op Field
2316 0x1: decode OP_HI {
2317 0x0: decode OP_LO {
2318 format IntOp {
2319 0x0: append({{
2320 Rt.uw = (Rt.uw << RD) | bits(Rs.uw, RD - 1, 0);
2321 }});
2322 0x1: prepend({{
2323 Rt.uw = (Rt.uw >> RD) |
2324 (bits(Rs.uw, RD - 1, 0) << (32 - RD));
2325 }});
2326 }
2327 }
2328 0x2: decode OP_LO {
2329 format IntOp {
2330 0x0: balign({{
2331 Rt.uw = (Rt.uw << (8 * BP)) |
2332 (Rs.uw >> (8 * (4 - BP)));
2333 }});
2334 }
2335 }
2336 }
2337
2338 }
2339 0x7: decode FUNCTION_LO {
2340
2341 //Table 5-11 MIPS32 EXTR.W Encoding of the op Field
2342 //(DSP ASE MANUAL)
2343 0x0: decode OP_HI {
2344 0x0: decode OP_LO {
2345 format DspHiLoOp {
2346 0x0: extr_w({{
2347 Rt.uw = dspExtr(dspac, SIMD_FMT_W, RS,
2348 NOROUND, NOSATURATE, &dspctl);
2349 }});
2350 0x1: extrv_w({{
2351 Rt.uw = dspExtr(dspac, SIMD_FMT_W, Rs.uw,
2352 NOROUND, NOSATURATE, &dspctl);
2353 }});
2354 0x2: extp({{
2355 Rt.uw = dspExtp(dspac, RS, &dspctl);
2356 }});
2357 0x3: extpv({{
2358 Rt.uw = dspExtp(dspac, Rs.uw, &dspctl);
2359 }});
2360 0x4: extr_r_w({{
2361 Rt.uw = dspExtr(dspac, SIMD_FMT_W, RS,
2362 ROUND, NOSATURATE, &dspctl);
2363 }});
2364 0x5: extrv_r_w({{
2365 Rt.uw = dspExtr(dspac, SIMD_FMT_W, Rs.uw,
2366 ROUND, NOSATURATE, &dspctl);
2367 }});
2368 0x6: extr_rs_w({{
2369 Rt.uw = dspExtr(dspac, SIMD_FMT_W, RS,
2370 ROUND, SATURATE, &dspctl);
2371 }});
2372 0x7: extrv_rs_w({{
2373 Rt.uw = dspExtr(dspac, SIMD_FMT_W, Rs.uw,
2374 ROUND, SATURATE, &dspctl);
2375 }});
2376 }
2377 }
2378 0x1: decode OP_LO {
2379 format DspHiLoOp {
2380 0x2: extpdp({{
2381 Rt.uw = dspExtpd(dspac, RS, &dspctl);
2382 }});
2383 0x3: extpdpv({{
2384 Rt.uw = dspExtpd(dspac, Rs.uw, &dspctl);
2385 }});
2386 0x6: extr_s_h({{
2387 Rt.uw = dspExtr(dspac, SIMD_FMT_PH, RS,
2388 NOROUND, SATURATE, &dspctl);
2389 }});
2390 0x7: extrv_s_h({{
2391 Rt.uw = dspExtr(dspac, SIMD_FMT_PH, Rs.uw,
2392 NOROUND, SATURATE, &dspctl);
2393 }});
2394 }
2395 }
2396 0x2: decode OP_LO {
2397 format DspIntOp {
2398 0x2: rddsp({{
2399 Rd.uw = readDSPControl(&dspctl, RDDSPMASK);
2400 }});
2401 0x3: wrdsp({{
2402 writeDSPControl(&dspctl, Rs.uw, WRDSPMASK);
2403 }});
2404 }
2405 }
2406 0x3: decode OP_LO {
2407 format DspHiLoOp {
2408 0x2: shilo({{
2409 if (sext<6>(HILOSA) < 0) {
2410 dspac = (uint64_t)dspac <<
2411 -sext<6>(HILOSA);
2412 } else {
2413 dspac = (uint64_t)dspac >>
2414 sext<6>(HILOSA);
2415 }
2416 }});
2417 0x3: shilov({{
2418 if (sext<6>(Rs.sw<5:0>) < 0) {
2419 dspac = (uint64_t)dspac <<
2420 -sext<6>(Rs.sw<5:0>);
2421 } else {
2422 dspac = (uint64_t)dspac >>
2423 sext<6>(Rs.sw<5:0>);
2424 }
2425 }});
2426 0x7: mthlip({{
2427 dspac = dspac << 32;
2428 dspac |= Rs.uw;
2429 dspctl = insertBits(dspctl, 5, 0,
2430 dspctl<5:0> + 32);
2431 }});
2432 }
2433 }
2434 }
2435 0x3: decode OP default FailUnimpl::rdhwr() {
2436 0x0: decode FULL_SYSTEM {
2437 0: decode RD {
2438 29: BasicOp::rdhwr_se({{ Rt = TpValue; }});
2439 }
2440 }
2441 }
2442 }
2443 }
2444 }
2445
2446 0x4: decode OPCODE_LO {
2447 format LoadMemory {
2448 0x0: lb({{ Rt.sw = Mem.sb; }});
2449 0x1: lh({{ Rt.sw = Mem.sh; }});
2450 0x3: lw({{ Rt.sw = Mem.sw; }});
2451 0x4: lbu({{ Rt.uw = Mem.ub;}});
2452 0x5: lhu({{ Rt.uw = Mem.uh; }});
2453 }
2454
2455 format LoadUnalignedMemory {
2456 0x2: lwl({{
2457 uint32_t mem_shift = 24 - (8 * byte_offset);
2458 Rt.uw = mem_word << mem_shift | (Rt.uw & mask(mem_shift));
2459 }});
2460 0x6: lwr({{
2461 uint32_t mem_shift = 8 * byte_offset;
2462 Rt.uw = (Rt.uw & (mask(mem_shift) << (32 - mem_shift))) |
2463 (mem_word >> mem_shift);
2464 }});
2465 }
2466 }
2467
2468 0x5: decode OPCODE_LO {
2469 format StoreMemory {
2470 0x0: sb({{ Mem.ub = Rt<7:0>; }});
2471 0x1: sh({{ Mem.uh = Rt<15:0>; }});
2472 0x3: sw({{ Mem.uw = Rt<31:0>; }});
2473 }
2474
2475 format StoreUnalignedMemory {
2476 0x2: swl({{
2477 uint32_t reg_shift = 24 - (8 * byte_offset);
2478 uint32_t mem_shift = 32 - reg_shift;
2479 mem_word = (mem_word & (mask(reg_shift) << mem_shift)) |
2480 (Rt.uw >> reg_shift);
2481 }});
2482 0x6: swr({{
2483 uint32_t reg_shift = 8 * byte_offset;
2484 mem_word = Rt.uw << reg_shift |
2485 (mem_word & (mask(reg_shift)));
2486 }});
2487 }
2488 format CP0Control {
2489 0x7: cache({{
2490 //Addr CacheEA = Rs.uw + OFFSET;
2491 //fault = xc->CacheOp((uint8_t)CACHE_OP,(Addr) CacheEA);
2492 }});
2493 }
2494 }
2495
2496 0x6: decode OPCODE_LO {
2497 format LoadMemory {
2498 0x0: ll({{ Rt.uw = Mem.uw; }}, mem_flags=LLSC);
2499 0x1: lwc1({{ Ft.uw = Mem.uw; }});
2500 0x5: ldc1({{ Ft.ud = Mem.ud; }});
2501 }
2502 0x2: CP2Unimpl::lwc2();
2503 0x6: CP2Unimpl::ldc2();
2504 0x3: Prefetch::pref();
2505 }
2506
2507
2508 0x7: decode OPCODE_LO {
2509 0x0: StoreCond::sc({{ Mem.uw = Rt.uw; }},
2510 {{ uint64_t tmp = write_result;
2511 Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw;
2512 }}, mem_flags=LLSC,
2513 inst_flags = IsStoreConditional);
2514 format StoreMemory {
2515 0x1: swc1({{ Mem.uw = Ft.uw; }});
2516 0x5: sdc1({{ Mem.ud = Ft.ud; }});
2517 }
2518 0x2: CP2Unimpl::swc2();
2519 0x6: CP2Unimpl::sdc2();
2520 }
2521}
2522
2523
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 Ctrl_Base_DepTag);
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_Base_DepTag);
413 }});
414 0x1: mfthc1({{ data = xc->readRegOtherThread(RT +
415 FP_Base_DepTag);
416 }});
417 }
418 0x3: cftc1({{
419 uint32_t fcsr_val = xc->readRegOtherThread(FLOATREG_FCSR +
420 FP_Base_DepTag);
421 switch (RT) {
422 case 0:
423 data = xc->readRegOtherThread(FLOATREG_FIR +
424 Ctrl_Base_DepTag);
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) + Ctrl_Base_DepTag,
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_Base_DepTag);
500 data = insertBits(data, top_bit,
501 bottom_bit, Rt);
502 xc->setRegOtherThread(RD + FP_Base_DepTag,
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 "Status Register", FS);
536 }
537 xc->setRegOtherThread(FLOATREG_FCSR + FP_Base_DepTag, 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 = new 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 = new 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 = new 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 = new 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 IndexReg index = Index;
780 Ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP);
781 }});
782 0x06: tlbwr({{
783 //Create PTE
784 MipsISA::PTE newEntry;
785 //Write PTE
786 newEntry.Mask = (Addr)(PageMask >> 11);
787 newEntry.VPN = (Addr)(EntryHi >> 11);
788 /* PageGrain _ ESP Config3 _ SP */
789 if (bits(PageGrain, 28) == 0 ||
790 bits(Config3, 4) == 0) {
791 // If 1KB pages are *NOT* enabled, lowest bits of
792 // the mask are 0b11 for TLB writes
793 newEntry.Mask |= 0x3;
794 // Reset bits 0 and 1 if 1KB pages are not enabled
795 newEntry.VPN &= 0xFFFFFFFC;
796 }
797 newEntry.asid = (uint8_t)(EntryHi & 0xFF);
798
799 newEntry.PFN0 = (Addr)(EntryLo0 >> 6);
800 newEntry.PFN1 = (Addr)(EntryLo1 >> 6);
801 newEntry.D0 = (bool)((EntryLo0 >> 2) & 1);
802 newEntry.D1 = (bool)((EntryLo1 >> 2) & 1);
803 newEntry.V1 = (bool)((EntryLo1 >> 1) & 1);
804 newEntry.V0 = (bool)((EntryLo0 >> 1) & 1);
805 newEntry.G = (bool)((EntryLo0 & EntryLo1) & 1);
806 newEntry.C0 = (uint8_t)((EntryLo0 >> 3) & 0x7);
807 newEntry.C1 = (uint8_t)((EntryLo1 >> 3) & 0x7);
808 /* Now, compute the AddrShiftAmount and OffsetMask -
809 TLB optimizations */
810 /* Addr Shift Amount for 1KB or larger pages */
811 if ((newEntry.Mask & 0xFFFF) == 3){
812 newEntry.AddrShiftAmount = 12;
813 } else if ((newEntry.Mask & 0xFFFF) == 0x0000) {
814 newEntry.AddrShiftAmount = 10;
815 } else if ((newEntry.Mask & 0xFFFC) == 0x000C) {
816 newEntry.AddrShiftAmount = 14;
817 } else if ((newEntry.Mask & 0xFFF0) == 0x0030) {
818 newEntry.AddrShiftAmount = 16;
819 } else if ((newEntry.Mask & 0xFFC0) == 0x00C0) {
820 newEntry.AddrShiftAmount = 18;
821 } else if ((newEntry.Mask & 0xFF00) == 0x0300) {
822 newEntry.AddrShiftAmount = 20;
823 } else if ((newEntry.Mask & 0xFC00) == 0x0C00) {
824 newEntry.AddrShiftAmount = 22;
825 } else if ((newEntry.Mask & 0xF000) == 0x3000) {
826 newEntry.AddrShiftAmount = 24;
827 } else if ((newEntry.Mask & 0xC000) == 0xC000) {
828 newEntry.AddrShiftAmount = 26;
829 } else if ((newEntry.Mask & 0x30000) == 0x30000) {
830 newEntry.AddrShiftAmount = 28;
831 } else {
832 fatal("Invalid Mask Pattern Detected!\n");
833 }
834 newEntry.OffsetMask =
835 (1 << newEntry.AddrShiftAmount) - 1;
836
837 MipsISA::TLB *Ptr = xc->tcBase()->getITBPtr();
838 Config3Reg config3 = Config3;
839 PageGrainReg pageGrain = PageGrain;
840 int SP = 0;
841 if (bits(config3, config3.sp) == 1 &&
842 bits(pageGrain, pageGrain.esp) == 1) {
843 SP = 1;
844 }
845 IndexReg index = Index;
846 Ptr->insertAt(newEntry, Random, SP);
847 }});
848
849 0x08: tlbp({{
850 Config3Reg config3 = Config3;
851 PageGrainReg pageGrain = PageGrain;
852 EntryHiReg entryHi = EntryHi;
853 int tlbIndex;
854 Addr vpn;
855 if (pageGrain.esp == 1 && config3.sp ==1) {
856 vpn = EntryHi >> 11;
857 } else {
858 // Mask off lower 2 bits
859 vpn = ((EntryHi >> 11) & 0xFFFFFFFC);
860 }
861 tlbIndex = xc->tcBase()->getITBPtr()->
862 probeEntry(vpn, entryHi.asid);
863 // Check TLB for entry matching EntryHi
864 if (tlbIndex != -1) {
865 Index = tlbIndex;
866 } else {
867 // else, set Index = 1 << 31
868 Index = (1 << 31);
869 }
870 }});
871 }
872 format CP0Unimpl {
873 0x20: wait();
874 }
875 default: CP0Unimpl::unknown();
876 }
877 }
878
879 //Table A-13 MIPS32 COP1 Encoding of rs Field
880 0x1: decode RS_MSB {
881 0x0: decode RS_HI {
882 0x0: decode RS_LO {
883 format CP1Control {
884 0x0: mfc1 ({{ Rt.uw = Fs.uw; }});
885
886 0x2: cfc1({{
887 switch (FS) {
888 case 0:
889 Rt = FIR;
890 break;
891 case 25:
892 Rt = (FCSR & 0xFE000000) >> 24 |
893 (FCSR & 0x00800000) >> 23;
894 break;
895 case 26:
896 Rt = (FCSR & 0x0003F07C);
897 break;
898 case 28:
899 Rt = (FCSR & 0x00000F80) |
900 (FCSR & 0x01000000) >> 21 |
901 (FCSR & 0x00000003);
902 break;
903 case 31:
904 Rt = FCSR;
905 break;
906 default:
907 warn("FP Control Value (%d) Not Valid");
908 }
909 }});
910
911 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>; }});
912
913 0x4: mtc1({{ Fs.uw = Rt.uw; }});
914
915 0x6: ctc1({{
916 switch (FS) {
917 case 25:
918 FCSR = (Rt.uw<7:1> << 25) | // move 31-25
919 (FCSR & 0x01000000) | // bit 24
920 (FCSR & 0x004FFFFF); // bit 22-0
921 break;
922 case 26:
923 FCSR = (FCSR & 0xFFFC0000) | // move 31-18
924 Rt.uw<17:12> << 12 | // bit 17-12
925 (FCSR & 0x00000F80) << 7 | // bit 11-7
926 Rt.uw<6:2> << 2 | // bit 6-2
927 (FCSR & 0x00000002); // bit 1-0
928 break;
929 case 28:
930 FCSR = (FCSR & 0xFE000000) | // move 31-25
931 Rt.uw<2:2> << 24 | // bit 24
932 (FCSR & 0x00FFF000) << 23 | // bit 23-12
933 Rt.uw<11:7> << 7 | // bit 24
934 (FCSR & 0x000007E) |
935 Rt.uw<1:0>; // bit 22-0
936 break;
937 case 31:
938 FCSR = Rt.uw;
939 break;
940
941 default:
942 panic("FP Control Value (%d) "
943 "Not Available. Ignoring Access "
944 "to Floating Control Status "
945 "Register", FS);
946 }
947 }});
948
949 0x7: mthc1({{
950 uint64_t fs_hi = Rt.uw;
951 uint64_t fs_lo = Fs.ud & 0x0FFFFFFFF;
952 Fs.ud = (fs_hi << 32) | fs_lo;
953 }});
954
955 }
956 format CP1Unimpl {
957 0x1: dmfc1();
958 0x5: dmtc1();
959 }
960 }
961
962 0x1: decode RS_LO {
963 0x0: decode ND {
964 format Branch {
965 0x0: decode TF {
966 0x0: bc1f({{
967 cond = getCondCode(FCSR, BRANCH_CC) == 0;
968 }});
969 0x1: bc1t({{
970 cond = getCondCode(FCSR, BRANCH_CC) == 1;
971 }});
972 }
973 0x1: decode TF {
974 0x0: bc1fl({{
975 cond = getCondCode(FCSR, BRANCH_CC) == 0;
976 }}, Likely);
977 0x1: bc1tl({{
978 cond = getCondCode(FCSR, BRANCH_CC) == 1;
979 }}, Likely);
980 }
981 }
982 }
983 format CP1Unimpl {
984 0x1: bc1any2();
985 0x2: bc1any4();
986 default: unknown();
987 }
988 }
989 }
990
991 0x1: decode RS_HI {
992 0x2: decode RS_LO {
993 //Table A-14 MIPS32 COP1 Encoding of Function Field When
994 //rs=S (( single-precision floating point))
995 0x0: decode FUNCTION_HI {
996 0x0: decode FUNCTION_LO {
997 format FloatOp {
998 0x0: add_s({{ Fd.sf = Fs.sf + Ft.sf; }});
999 0x1: sub_s({{ Fd.sf = Fs.sf - Ft.sf; }});
1000 0x2: mul_s({{ Fd.sf = Fs.sf * Ft.sf; }});
1001 0x3: div_s({{ Fd.sf = Fs.sf / Ft.sf; }});
1002 0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf); }});
1003 0x5: abs_s({{ Fd.sf = fabs(Fs.sf); }});
1004 0x7: neg_s({{ Fd.sf = -Fs.sf; }});
1005 }
1006 0x6: BasicOp::mov_s({{ Fd.sf = Fs.sf; }});
1007 }
1008 0x1: decode FUNCTION_LO {
1009 format FloatConvertOp {
1010 0x0: round_l_s({{ val = Fs.sf; }},
1011 ToLong, Round);
1012 0x1: trunc_l_s({{ val = Fs.sf; }},
1013 ToLong, Trunc);
1014 0x2: ceil_l_s({{ val = Fs.sf;}},
1015 ToLong, Ceil);
1016 0x3: floor_l_s({{ val = Fs.sf; }},
1017 ToLong, Floor);
1018 0x4: round_w_s({{ val = Fs.sf; }},
1019 ToWord, Round);
1020 0x5: trunc_w_s({{ val = Fs.sf; }},
1021 ToWord, Trunc);
1022 0x6: ceil_w_s({{ val = Fs.sf; }},
1023 ToWord, Ceil);
1024 0x7: floor_w_s({{ val = Fs.sf; }},
1025 ToWord, Floor);
1026 }
1027 }
1028
1029 0x2: decode FUNCTION_LO {
1030 0x1: decode MOVCF {
1031 format BasicOp {
1032 0x0: movf_s({{
1033 Fd = (getCondCode(FCSR,CC) == 0) ?
1034 Fs : Fd;
1035 }});
1036 0x1: movt_s({{
1037 Fd = (getCondCode(FCSR,CC) == 1) ?
1038 Fs : Fd;
1039 }});
1040 }
1041 }
1042
1043 format BasicOp {
1044 0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }});
1045 0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }});
1046 }
1047
1048 format FloatOp {
1049 0x5: recip_s({{ Fd = 1 / Fs; }});
1050 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs); }});
1051 }
1052 format CP1Unimpl {
1053 default: unknown();
1054 }
1055 }
1056 0x3: CP1Unimpl::unknown();
1057
1058 0x4: decode FUNCTION_LO {
1059 format FloatConvertOp {
1060 0x1: cvt_d_s({{ val = Fs.sf; }}, ToDouble);
1061 0x4: cvt_w_s({{ val = Fs.sf; }}, ToWord);
1062 0x5: cvt_l_s({{ val = Fs.sf; }}, ToLong);
1063 }
1064
1065 0x6: FloatOp::cvt_ps_s({{
1066 Fd.ud = (uint64_t) Fs.uw << 32 |
1067 (uint64_t) Ft.uw;
1068 }});
1069 format CP1Unimpl {
1070 default: unknown();
1071 }
1072 }
1073 0x5: CP1Unimpl::unknown();
1074
1075 0x6: decode FUNCTION_LO {
1076 format FloatCompareOp {
1077 0x0: c_f_s({{ cond = 0; }},
1078 SinglePrecision, UnorderedFalse);
1079 0x1: c_un_s({{ cond = 0; }},
1080 SinglePrecision, UnorderedTrue);
1081 0x2: c_eq_s({{ cond = (Fs.sf == Ft.sf); }},
1082 UnorderedFalse);
1083 0x3: c_ueq_s({{ cond = (Fs.sf == Ft.sf); }},
1084 UnorderedTrue);
1085 0x4: c_olt_s({{ cond = (Fs.sf < Ft.sf); }},
1086 UnorderedFalse);
1087 0x5: c_ult_s({{ cond = (Fs.sf < Ft.sf); }},
1088 UnorderedTrue);
1089 0x6: c_ole_s({{ cond = (Fs.sf <= Ft.sf); }},
1090 UnorderedFalse);
1091 0x7: c_ule_s({{ cond = (Fs.sf <= Ft.sf); }},
1092 UnorderedTrue);
1093 }
1094 }
1095
1096 0x7: decode FUNCTION_LO {
1097 format FloatCompareOp {
1098 0x0: c_sf_s({{ cond = 0; }}, SinglePrecision,
1099 UnorderedFalse, QnanException);
1100 0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision,
1101 UnorderedTrue, QnanException);
1102 0x2: c_seq_s({{ cond = (Fs.sf == Ft.sf); }},
1103 UnorderedFalse, QnanException);
1104 0x3: c_ngl_s({{ cond = (Fs.sf == Ft.sf); }},
1105 UnorderedTrue, QnanException);
1106 0x4: c_lt_s({{ cond = (Fs.sf < Ft.sf); }},
1107 UnorderedFalse, QnanException);
1108 0x5: c_nge_s({{ cond = (Fs.sf < Ft.sf); }},
1109 UnorderedTrue, QnanException);
1110 0x6: c_le_s({{ cond = (Fs.sf <= Ft.sf); }},
1111 UnorderedFalse, QnanException);
1112 0x7: c_ngt_s({{ cond = (Fs.sf <= Ft.sf); }},
1113 UnorderedTrue, QnanException);
1114 }
1115 }
1116 }
1117
1118 //Table A-15 MIPS32 COP1 Encoding of Function Field When
1119 //rs=D
1120 0x1: decode FUNCTION_HI {
1121 0x0: decode FUNCTION_LO {
1122 format FloatOp {
1123 0x0: add_d({{ Fd.df = Fs.df + Ft.df; }});
1124 0x1: sub_d({{ Fd.df = Fs.df - Ft.df; }});
1125 0x2: mul_d({{ Fd.df = Fs.df * Ft.df; }});
1126 0x3: div_d({{ Fd.df = Fs.df / Ft.df; }});
1127 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df); }});
1128 0x5: abs_d({{ Fd.df = fabs(Fs.df); }});
1129 0x7: neg_d({{ Fd.df = -1 * Fs.df; }});
1130 }
1131 0x6: BasicOp::mov_d({{ Fd.df = Fs.df; }});
1132 }
1133
1134 0x1: decode FUNCTION_LO {
1135 format FloatConvertOp {
1136 0x0: round_l_d({{ val = Fs.df; }},
1137 ToLong, Round);
1138 0x1: trunc_l_d({{ val = Fs.df; }},
1139 ToLong, Trunc);
1140 0x2: ceil_l_d({{ val = Fs.df; }},
1141 ToLong, Ceil);
1142 0x3: floor_l_d({{ val = Fs.df; }},
1143 ToLong, Floor);
1144 0x4: round_w_d({{ val = Fs.df; }},
1145 ToWord, Round);
1146 0x5: trunc_w_d({{ val = Fs.df; }},
1147 ToWord, Trunc);
1148 0x6: ceil_w_d({{ val = Fs.df; }},
1149 ToWord, Ceil);
1150 0x7: floor_w_d({{ val = Fs.df; }},
1151 ToWord, Floor);
1152 }
1153 }
1154
1155 0x2: decode FUNCTION_LO {
1156 0x1: decode MOVCF {
1157 format BasicOp {
1158 0x0: movf_d({{
1159 Fd.df = (getCondCode(FCSR,CC) == 0) ?
1160 Fs.df : Fd.df;
1161 }});
1162 0x1: movt_d({{
1163 Fd.df = (getCondCode(FCSR,CC) == 1) ?
1164 Fs.df : Fd.df;
1165 }});
1166 }
1167 }
1168
1169 format BasicOp {
1170 0x2: movz_d({{
1171 Fd.df = (Rt == 0) ? Fs.df : Fd.df;
1172 }});
1173 0x3: movn_d({{
1174 Fd.df = (Rt != 0) ? Fs.df : Fd.df;
1175 }});
1176 }
1177
1178 format FloatOp {
1179 0x5: recip_d({{ Fd.df = 1 / Fs.df; }});
1180 0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df); }});
1181 }
1182 format CP1Unimpl {
1183 default: unknown();
1184 }
1185
1186 }
1187 0x4: decode FUNCTION_LO {
1188 format FloatConvertOp {
1189 0x0: cvt_s_d({{ val = Fs.df; }}, ToSingle);
1190 0x4: cvt_w_d({{ val = Fs.df; }}, ToWord);
1191 0x5: cvt_l_d({{ val = Fs.df; }}, ToLong);
1192 }
1193 default: CP1Unimpl::unknown();
1194 }
1195
1196 0x6: decode FUNCTION_LO {
1197 format FloatCompareOp {
1198 0x0: c_f_d({{ cond = 0; }},
1199 DoublePrecision, UnorderedFalse);
1200 0x1: c_un_d({{ cond = 0; }},
1201 DoublePrecision, UnorderedTrue);
1202 0x2: c_eq_d({{ cond = (Fs.df == Ft.df); }},
1203 UnorderedFalse);
1204 0x3: c_ueq_d({{ cond = (Fs.df == Ft.df); }},
1205 UnorderedTrue);
1206 0x4: c_olt_d({{ cond = (Fs.df < Ft.df); }},
1207 UnorderedFalse);
1208 0x5: c_ult_d({{ cond = (Fs.df < Ft.df); }},
1209 UnorderedTrue);
1210 0x6: c_ole_d({{ cond = (Fs.df <= Ft.df); }},
1211 UnorderedFalse);
1212 0x7: c_ule_d({{ cond = (Fs.df <= Ft.df); }},
1213 UnorderedTrue);
1214 }
1215 }
1216
1217 0x7: decode FUNCTION_LO {
1218 format FloatCompareOp {
1219 0x0: c_sf_d({{ cond = 0; }}, DoublePrecision,
1220 UnorderedFalse, QnanException);
1221 0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision,
1222 UnorderedTrue, QnanException);
1223 0x2: c_seq_d({{ cond = (Fs.df == Ft.df); }},
1224 UnorderedFalse, QnanException);
1225 0x3: c_ngl_d({{ cond = (Fs.df == Ft.df); }},
1226 UnorderedTrue, QnanException);
1227 0x4: c_lt_d({{ cond = (Fs.df < Ft.df); }},
1228 UnorderedFalse, QnanException);
1229 0x5: c_nge_d({{ cond = (Fs.df < Ft.df); }},
1230 UnorderedTrue, QnanException);
1231 0x6: c_le_d({{ cond = (Fs.df <= Ft.df); }},
1232 UnorderedFalse, QnanException);
1233 0x7: c_ngt_d({{ cond = (Fs.df <= Ft.df); }},
1234 UnorderedTrue, QnanException);
1235 }
1236 }
1237 default: CP1Unimpl::unknown();
1238 }
1239 0x2: CP1Unimpl::unknown();
1240 0x3: CP1Unimpl::unknown();
1241 0x7: CP1Unimpl::unknown();
1242
1243 //Table A-16 MIPS32 COP1 Encoding of Function
1244 //Field When rs=W
1245 0x4: decode FUNCTION {
1246 format FloatConvertOp {
1247 0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle);
1248 0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble);
1249 0x26: CP1Unimpl::cvt_ps_w();
1250 }
1251 default: CP1Unimpl::unknown();
1252 }
1253
1254 //Table A-16 MIPS32 COP1 Encoding of Function Field
1255 //When rs=L1
1256 //Note: "1. Format type L is legal only if 64-bit
1257 //floating point operations are enabled."
1258 0x5: decode FUNCTION_HI {
1259 format FloatConvertOp {
1260 0x20: cvt_s_l({{ val = Fs.ud; }}, ToSingle);
1261 0x21: cvt_d_l({{ val = Fs.ud; }}, ToDouble);
1262 0x26: CP1Unimpl::cvt_ps_l();
1263 }
1264 default: CP1Unimpl::unknown();
1265 }
1266
1267 //Table A-17 MIPS64 COP1 Encoding of Function Field
1268 //When rs=PS1
1269 //Note: "1. Format type PS is legal only if 64-bit
1270 //floating point operations are enabled. "
1271 0x6: decode FUNCTION_HI {
1272 0x0: decode FUNCTION_LO {
1273 format Float64Op {
1274 0x0: add_ps({{
1275 Fd1.sf = Fs1.sf + Ft2.sf;
1276 Fd2.sf = Fs2.sf + Ft2.sf;
1277 }});
1278 0x1: sub_ps({{
1279 Fd1.sf = Fs1.sf - Ft2.sf;
1280 Fd2.sf = Fs2.sf - Ft2.sf;
1281 }});
1282 0x2: mul_ps({{
1283 Fd1.sf = Fs1.sf * Ft2.sf;
1284 Fd2.sf = Fs2.sf * Ft2.sf;
1285 }});
1286 0x5: abs_ps({{
1287 Fd1.sf = fabs(Fs1.sf);
1288 Fd2.sf = fabs(Fs2.sf);
1289 }});
1290 0x6: mov_ps({{
1291 Fd1.sf = Fs1.sf;
1292 Fd2.sf = Fs2.sf;
1293 }});
1294 0x7: neg_ps({{
1295 Fd1.sf = -(Fs1.sf);
1296 Fd2.sf = -(Fs2.sf);
1297 }});
1298 default: CP1Unimpl::unknown();
1299 }
1300 }
1301 0x1: CP1Unimpl::unknown();
1302 0x2: decode FUNCTION_LO {
1303 0x1: decode MOVCF {
1304 format Float64Op {
1305 0x0: movf_ps({{
1306 Fd1 = (getCondCode(FCSR, CC) == 0) ?
1307 Fs1 : Fd1;
1308 Fd2 = (getCondCode(FCSR, CC+1) == 0) ?
1309 Fs2 : Fd2;
1310 }});
1311 0x1: movt_ps({{
1312 Fd2 = (getCondCode(FCSR, CC) == 1) ?
1313 Fs1 : Fd1;
1314 Fd2 = (getCondCode(FCSR, CC+1) == 1) ?
1315 Fs2 : Fd2;
1316 }});
1317 }
1318 }
1319
1320 format Float64Op {
1321 0x2: movz_ps({{
1322 Fd1 = (getCondCode(FCSR, CC) == 0) ?
1323 Fs1 : Fd1;
1324 Fd2 = (getCondCode(FCSR, CC) == 0) ?
1325 Fs2 : Fd2;
1326 }});
1327 0x3: movn_ps({{
1328 Fd1 = (getCondCode(FCSR, CC) == 1) ?
1329 Fs1 : Fd1;
1330 Fd2 = (getCondCode(FCSR, CC) == 1) ?
1331 Fs2 : Fd2;
1332 }});
1333 }
1334 default: CP1Unimpl::unknown();
1335 }
1336 0x3: CP1Unimpl::unknown();
1337 0x4: decode FUNCTION_LO {
1338 0x0: FloatOp::cvt_s_pu({{ Fd.sf = Fs2.sf; }});
1339 default: CP1Unimpl::unknown();
1340 }
1341
1342 0x5: decode FUNCTION_LO {
1343 0x0: FloatOp::cvt_s_pl({{ Fd.sf = Fs1.sf; }});
1344 format Float64Op {
1345 0x4: pll({{
1346 Fd.ud = (uint64_t)Fs1.uw << 32 | Ft1.uw;
1347 }});
1348 0x5: plu({{
1349 Fd.ud = (uint64_t)Fs1.uw << 32 | Ft2.uw;
1350 }});
1351 0x6: pul({{
1352 Fd.ud = (uint64_t)Fs2.uw << 32 | Ft1.uw;
1353 }});
1354 0x7: puu({{
1355 Fd.ud = (uint64_t)Fs2.uw << 32 | Ft2.uw;
1356 }});
1357 }
1358 default: CP1Unimpl::unknown();
1359 }
1360
1361 0x6: decode FUNCTION_LO {
1362 format FloatPSCompareOp {
1363 0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1364 UnorderedFalse);
1365 0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1366 UnorderedTrue);
1367 0x2: c_eq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1368 {{ cond2 = (Fs2.sf == Ft2.sf); }},
1369 UnorderedFalse);
1370 0x3: c_ueq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1371 {{ cond2 = (Fs2.sf == Ft2.sf); }},
1372 UnorderedTrue);
1373 0x4: c_olt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
1374 {{ cond2 = (Fs2.sf < Ft2.sf); }},
1375 UnorderedFalse);
1376 0x5: c_ult_ps({{ cond1 = (Fs.sf < Ft.sf); }},
1377 {{ cond2 = (Fs2.sf < Ft2.sf); }},
1378 UnorderedTrue);
1379 0x6: c_ole_ps({{ cond1 = (Fs.sf <= Ft.sf); }},
1380 {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1381 UnorderedFalse);
1382 0x7: c_ule_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
1383 {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1384 UnorderedTrue);
1385 }
1386 }
1387
1388 0x7: decode FUNCTION_LO {
1389 format FloatPSCompareOp {
1390 0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
1391 UnorderedFalse, QnanException);
1392 0x1: c_ngle_ps({{ cond1 = 0; }},
1393 {{ cond2 = 0; }},
1394 UnorderedTrue, QnanException);
1395 0x2: c_seq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1396 {{ cond2 = (Fs2.sf == Ft2.sf); }},
1397 UnorderedFalse, QnanException);
1398 0x3: c_ngl_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
1399 {{ cond2 = (Fs2.sf == Ft2.sf); }},
1400 UnorderedTrue, QnanException);
1401 0x4: c_lt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
1402 {{ cond2 = (Fs2.sf < Ft2.sf); }},
1403 UnorderedFalse, QnanException);
1404 0x5: c_nge_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
1405 {{ cond2 = (Fs2.sf < Ft2.sf); }},
1406 UnorderedTrue, QnanException);
1407 0x6: c_le_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
1408 {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1409 UnorderedFalse, QnanException);
1410 0x7: c_ngt_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
1411 {{ cond2 = (Fs2.sf <= Ft2.sf); }},
1412 UnorderedTrue, QnanException);
1413 }
1414 }
1415 }
1416 }
1417 default: CP1Unimpl::unknown();
1418 }
1419 }
1420
1421 //Table A-19 MIPS32 COP2 Encoding of rs Field
1422 0x2: decode RS_MSB {
1423 format CP2Unimpl {
1424 0x0: decode RS_HI {
1425 0x0: decode RS_LO {
1426 0x0: mfc2();
1427 0x2: cfc2();
1428 0x3: mfhc2();
1429 0x4: mtc2();
1430 0x6: ctc2();
1431 0x7: mftc2();
1432 default: unknown();
1433 }
1434
1435 0x1: decode ND {
1436 0x0: decode TF {
1437 0x0: bc2f();
1438 0x1: bc2t();
1439 default: unknown();
1440 }
1441
1442 0x1: decode TF {
1443 0x0: bc2fl();
1444 0x1: bc2tl();
1445 default: unknown();
1446 }
1447 default: unknown();
1448
1449 }
1450 default: unknown();
1451 }
1452 default: unknown();
1453 }
1454 }
1455
1456 //Table A-20 MIPS64 COP1X Encoding of Function Field 1
1457 //Note: "COP1X instructions are legal only if 64-bit floating point
1458 //operations are enabled."
1459 0x3: decode FUNCTION_HI {
1460 0x0: decode FUNCTION_LO {
1461 format LoadIndexedMemory {
1462 0x0: lwxc1({{ Fd.uw = Mem.uw; }});
1463 0x1: ldxc1({{ Fd.ud = Mem.ud; }});
1464 0x5: luxc1({{ Fd.ud = Mem.ud; }},
1465 {{ EA = (Rs + Rt) & ~7; }});
1466 }
1467 }
1468
1469 0x1: decode FUNCTION_LO {
1470 format StoreIndexedMemory {
1471 0x0: swxc1({{ Mem.uw = Fs.uw; }});
1472 0x1: sdxc1({{ Mem.ud = Fs.ud; }});
1473 0x5: suxc1({{ Mem.ud = Fs.ud; }},
1474 {{ EA = (Rs + Rt) & ~7; }});
1475 }
1476 0x7: Prefetch::prefx({{ EA = Rs + Rt; }});
1477 }
1478
1479 0x3: decode FUNCTION_LO {
1480 0x6: Float64Op::alnv_ps({{
1481 if (Rs<2:0> == 0) {
1482 Fd.ud = Fs.ud;
1483 } else if (Rs<2:0> == 4) {
1484 if (GuestByteOrder == BigEndianByteOrder)
1485 Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<63:32>;
1486 else
1487 Fd.ud = Ft.ud<31:0> << 32 | Fs.ud<63:32>;
1488 } else {
1489 Fd.ud = Fd.ud;
1490 }
1491 }});
1492 }
1493
1494 format FloatAccOp {
1495 0x4: decode FUNCTION_LO {
1496 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }});
1497 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }});
1498 0x6: madd_ps({{
1499 Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df;
1500 Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df;
1501 }});
1502 }
1503
1504 0x5: decode FUNCTION_LO {
1505 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }});
1506 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }});
1507 0x6: msub_ps({{
1508 Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df;
1509 Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df;
1510 }});
1511 }
1512
1513 0x6: decode FUNCTION_LO {
1514 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
1515 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }});
1516 0x6: nmadd_ps({{
1517 Fd1.sf = -((Fs1.df * Ft1.df) + Fr1.df);
1518 Fd2.sf = -((Fs2.df * Ft2.df) + Fr2.df);
1519 }});
1520 }
1521
1522 0x7: decode FUNCTION_LO {
1523 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) + Fr.sf; }});
1524 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }});
1525 0x6: nmsub_ps({{
1526 Fd1.sf = -((Fs1.df * Ft1.df) - Fr1.df);
1527 Fd2.sf = -((Fs2.df * Ft2.df) - Fr2.df);
1528 }});
1529 }
1530 }
1531 }
1532
1533 format Branch {
1534 0x4: beql({{ cond = (Rs.sw == Rt.sw); }}, Likely);
1535 0x5: bnel({{ cond = (Rs.sw != Rt.sw); }}, Likely);
1536 0x6: blezl({{ cond = (Rs.sw <= 0); }}, Likely);
1537 0x7: bgtzl({{ cond = (Rs.sw > 0); }}, Likely);
1538 }
1539 }
1540
1541 0x3: decode OPCODE_LO {
1542 //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
1543 0x4: decode FUNCTION_HI {
1544 0x0: decode FUNCTION_LO {
1545 0x2: IntOp::mul({{
1546 int64_t temp1 = Rs.sd * Rt.sd;
1547 Rd.sw = temp1<31:0>;
1548 }}, IntMultOp);
1549
1550 format HiLoRdSelValOp {
1551 0x0: madd({{
1552 val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1553 (Rs.sd * Rt.sd);
1554 }}, IntMultOp);
1555 0x1: maddu({{
1556 val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) +
1557 (Rs.ud * Rt.ud);
1558 }}, IntMultOp);
1559 0x4: msub({{
1560 val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1561 (Rs.sd * Rt.sd);
1562 }}, IntMultOp);
1563 0x5: msubu({{
1564 val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) -
1565 (Rs.ud * Rt.ud);
1566 }}, IntMultOp);
1567 }
1568 }
1569
1570 0x4: decode FUNCTION_LO {
1571 format BasicOp {
1572 0x0: clz({{
1573 int cnt = 32;
1574 for (int idx = 31; idx >= 0; idx--) {
1575 if (Rs<idx:idx> == 1) {
1576 cnt = 31 - idx;
1577 break;
1578 }
1579 }
1580 Rd.uw = cnt;
1581 }});
1582 0x1: clo({{
1583 int cnt = 32;
1584 for (int idx = 31; idx >= 0; idx--) {
1585 if (Rs<idx:idx> == 0) {
1586 cnt = 31 - idx;
1587 break;
1588 }
1589 }
1590 Rd.uw = cnt;
1591 }});
1592 }
1593 }
1594
1595 0x7: decode FUNCTION_LO {
1596 0x7: FailUnimpl::sdbbp();
1597 }
1598 }
1599
1600 //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2
1601 //of the Architecture
1602 0x7: decode FUNCTION_HI {
1603 0x0: decode FUNCTION_LO {
1604 format BasicOp {
1605 0x0: ext({{ Rt.uw = bits(Rs.uw, MSB+LSB, LSB); }});
1606 0x4: ins({{
1607 Rt.uw = bits(Rt.uw, 31, MSB+1) << (MSB+1) |
1608 bits(Rs.uw, MSB-LSB, 0) << LSB |
1609 bits(Rt.uw, LSB-1, 0);
1610 }});
1611 }
1612 }
1613
1614 0x1: decode FUNCTION_LO {
1615 format MT_Control {
1616 0x0: fork({{
1617 forkThread(xc->tcBase(), fault, RD, Rs, Rt);
1618 }}, UserMode);
1619 0x1: yield({{
1620 Rd.sw = yieldThread(xc->tcBase(), fault, Rs.sw,
1621 YQMask);
1622 }}, UserMode);
1623 }
1624
1625 //Table 5-9 MIPS32 LX Encoding of the op Field (DSP ASE MANUAL)
1626 0x2: decode OP_HI {
1627 0x0: decode OP_LO {
1628 format LoadIndexedMemory {
1629 0x0: lwx({{ Rd.sw = Mem.sw; }});
1630 0x4: lhx({{ Rd.sw = Mem.sh; }});
1631 0x6: lbux({{ Rd.uw = Mem.ub; }});
1632 }
1633 }
1634 }
1635 0x4: DspIntOp::insv({{
1636 int pos = dspctl<5:0>;
1637 int size = dspctl<12:7> - 1;
1638 Rt.uw = insertBits(Rt.uw, pos+size,
1639 pos, Rs.uw<size:0>);
1640 }});
1641 }
1642
1643 0x2: decode FUNCTION_LO {
1644
1645 //Table 5-5 MIPS32 ADDU.QB Encoding of the op Field
1646 //(DSP ASE MANUAL)
1647 0x0: decode OP_HI {
1648 0x0: decode OP_LO {
1649 format DspIntOp {
1650 0x0: addu_qb({{
1651 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1652 NOSATURATE, UNSIGNED, &dspctl);
1653 }});
1654 0x1: subu_qb({{
1655 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_QB,
1656 NOSATURATE, UNSIGNED, &dspctl);
1657 }});
1658 0x4: addu_s_qb({{
1659 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1660 SATURATE, UNSIGNED, &dspctl);
1661 }});
1662 0x5: subu_s_qb({{
1663 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_QB,
1664 SATURATE, UNSIGNED, &dspctl);
1665 }});
1666 0x6: muleu_s_ph_qbl({{
1667 Rd.uw = dspMuleu(Rs.uw, Rt.uw,
1668 MODE_L, &dspctl);
1669 }}, IntMultOp);
1670 0x7: muleu_s_ph_qbr({{
1671 Rd.uw = dspMuleu(Rs.uw, Rt.uw,
1672 MODE_R, &dspctl);
1673 }}, IntMultOp);
1674 }
1675 }
1676 0x1: decode OP_LO {
1677 format DspIntOp {
1678 0x0: addu_ph({{
1679 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1680 NOSATURATE, UNSIGNED, &dspctl);
1681 }});
1682 0x1: subu_ph({{
1683 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1684 NOSATURATE, UNSIGNED, &dspctl);
1685 }});
1686 0x2: addq_ph({{
1687 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1688 NOSATURATE, SIGNED, &dspctl);
1689 }});
1690 0x3: subq_ph({{
1691 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1692 NOSATURATE, SIGNED, &dspctl);
1693 }});
1694 0x4: addu_s_ph({{
1695 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1696 SATURATE, UNSIGNED, &dspctl);
1697 }});
1698 0x5: subu_s_ph({{
1699 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1700 SATURATE, UNSIGNED, &dspctl);
1701 }});
1702 0x6: addq_s_ph({{
1703 Rd.uw = dspAdd(Rs.uw, Rt.uw, SIMD_FMT_PH,
1704 SATURATE, SIGNED, &dspctl);
1705 }});
1706 0x7: subq_s_ph({{
1707 Rd.uw = dspSub(Rs.uw, Rt.uw, SIMD_FMT_PH,
1708 SATURATE, SIGNED, &dspctl);
1709 }});
1710 }
1711 }
1712 0x2: decode OP_LO {
1713 format DspIntOp {
1714 0x0: addsc({{
1715 int64_t dresult;
1716 dresult = Rs.ud + Rt.ud;
1717 Rd.sw = dresult<31:0>;
1718 dspctl = insertBits(dspctl, 13, 13,
1719 dresult<32:32>);
1720 }});
1721 0x1: addwc({{
1722 int64_t dresult;
1723 dresult = Rs.sd + Rt.sd + dspctl<13:13>;
1724 Rd.sw = dresult<31:0>;
1725 if (dresult<32:32> != dresult<31:31>)
1726 dspctl = insertBits(dspctl, 20, 20, 1);
1727 }});
1728 0x2: modsub({{
1729 Rd.sw = (Rs.sw == 0) ? Rt.sw<23:8> :
1730 Rs.sw - Rt.sw<7:0>;
1731 }});
1732 0x4: raddu_w_qb({{
1733 Rd.uw = Rs.uw<31:24> + Rs.uw<23:16> +
1734 Rs.uw<15:8> + Rs.uw<7:0>;
1735 }});
1736 0x6: addq_s_w({{
1737 Rd.sw = dspAdd(Rs.sw, Rt.sw, SIMD_FMT_W,
1738 SATURATE, SIGNED, &dspctl);
1739 }});
1740 0x7: subq_s_w({{
1741 Rd.sw = dspSub(Rs.sw, Rt.sw, SIMD_FMT_W,
1742 SATURATE, SIGNED, &dspctl);
1743 }});
1744 }
1745 }
1746 0x3: decode OP_LO {
1747 format DspIntOp {
1748 0x4: muleq_s_w_phl({{
1749 Rd.sw = dspMuleq(Rs.sw, Rt.sw,
1750 MODE_L, &dspctl);
1751 }}, IntMultOp);
1752 0x5: muleq_s_w_phr({{
1753 Rd.sw = dspMuleq(Rs.sw, Rt.sw,
1754 MODE_R, &dspctl);
1755 }}, IntMultOp);
1756 0x6: mulq_s_ph({{
1757 Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_PH,
1758 SATURATE, NOROUND, &dspctl);
1759 }}, IntMultOp);
1760 0x7: mulq_rs_ph({{
1761 Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_PH,
1762 SATURATE, ROUND, &dspctl);
1763 }}, IntMultOp);
1764 }
1765 }
1766 }
1767
1768 //Table 5-6 MIPS32 CMPU_EQ_QB Encoding of the op Field
1769 //(DSP ASE MANUAL)
1770 0x1: decode OP_HI {
1771 0x0: decode OP_LO {
1772 format DspIntOp {
1773 0x0: cmpu_eq_qb({{
1774 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_QB,
1775 UNSIGNED, CMP_EQ, &dspctl);
1776 }});
1777 0x1: cmpu_lt_qb({{
1778 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_QB,
1779 UNSIGNED, CMP_LT, &dspctl);
1780 }});
1781 0x2: cmpu_le_qb({{
1782 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_QB,
1783 UNSIGNED, CMP_LE, &dspctl);
1784 }});
1785 0x3: pick_qb({{
1786 Rd.uw = dspPick(Rs.uw, Rt.uw,
1787 SIMD_FMT_QB, &dspctl);
1788 }});
1789 0x4: cmpgu_eq_qb({{
1790 Rd.uw = dspCmpg(Rs.uw, Rt.uw, SIMD_FMT_QB,
1791 UNSIGNED, CMP_EQ );
1792 }});
1793 0x5: cmpgu_lt_qb({{
1794 Rd.uw = dspCmpg(Rs.uw, Rt.uw, SIMD_FMT_QB,
1795 UNSIGNED, CMP_LT);
1796 }});
1797 0x6: cmpgu_le_qb({{
1798 Rd.uw = dspCmpg(Rs.uw, Rt.uw, SIMD_FMT_QB,
1799 UNSIGNED, CMP_LE);
1800 }});
1801 }
1802 }
1803 0x1: decode OP_LO {
1804 format DspIntOp {
1805 0x0: cmp_eq_ph({{
1806 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_PH,
1807 SIGNED, CMP_EQ, &dspctl);
1808 }});
1809 0x1: cmp_lt_ph({{
1810 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_PH,
1811 SIGNED, CMP_LT, &dspctl);
1812 }});
1813 0x2: cmp_le_ph({{
1814 dspCmp(Rs.uw, Rt.uw, SIMD_FMT_PH,
1815 SIGNED, CMP_LE, &dspctl);
1816 }});
1817 0x3: pick_ph({{
1818 Rd.uw = dspPick(Rs.uw, Rt.uw,
1819 SIMD_FMT_PH, &dspctl);
1820 }});
1821 0x4: precrq_qb_ph({{
1822 Rd.uw = Rs.uw<31:24> << 24 |
1823 Rs.uw<15:8> << 16 |
1824 Rt.uw<31:24> << 8 |
1825 Rt.uw<15:8>;
1826 }});
1827 0x5: precr_qb_ph({{
1828 Rd.uw = Rs.uw<23:16> << 24 |
1829 Rs.uw<7:0> << 16 |
1830 Rt.uw<23:16> << 8 |
1831 Rt.uw<7:0>;
1832 }});
1833 0x6: packrl_ph({{
1834 Rd.uw = dspPack(Rs.uw, Rt.uw, SIMD_FMT_PH);
1835 }});
1836 0x7: precrqu_s_qb_ph({{
1837 Rd.uw = dspPrecrqu(Rs.uw, Rt.uw, &dspctl);
1838 }});
1839 }
1840 }
1841 0x2: decode OP_LO {
1842 format DspIntOp {
1843 0x4: precrq_ph_w({{
1844 Rd.uw = Rs.uw<31:16> << 16 | Rt.uw<31:16>;
1845 }});
1846 0x5: precrq_rs_ph_w({{
1847 Rd.uw = dspPrecrq(Rs.uw, Rt.uw,
1848 SIMD_FMT_W, &dspctl);
1849 }});
1850 }
1851 }
1852 0x3: decode OP_LO {
1853 format DspIntOp {
1854 0x0: cmpgdu_eq_qb({{
1855 Rd.uw = dspCmpgd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1856 UNSIGNED, CMP_EQ, &dspctl);
1857 }});
1858 0x1: cmpgdu_lt_qb({{
1859 Rd.uw = dspCmpgd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1860 UNSIGNED, CMP_LT, &dspctl);
1861 }});
1862 0x2: cmpgdu_le_qb({{
1863 Rd.uw = dspCmpgd(Rs.uw, Rt.uw, SIMD_FMT_QB,
1864 UNSIGNED, CMP_LE, &dspctl);
1865 }});
1866 0x6: precr_sra_ph_w({{
1867 Rt.uw = dspPrecrSra(Rt.uw, Rs.uw, RD,
1868 SIMD_FMT_W, NOROUND);
1869 }});
1870 0x7: precr_sra_r_ph_w({{
1871 Rt.uw = dspPrecrSra(Rt.uw, Rs.uw, RD,
1872 SIMD_FMT_W, ROUND);
1873 }});
1874 }
1875 }
1876 }
1877
1878 //Table 5-7 MIPS32 ABSQ_S.PH Encoding of the op Field
1879 //(DSP ASE MANUAL)
1880 0x2: decode OP_HI {
1881 0x0: decode OP_LO {
1882 format DspIntOp {
1883 0x1: absq_s_qb({{
1884 Rd.sw = dspAbs(Rt.sw, SIMD_FMT_QB, &dspctl);
1885 }});
1886 0x2: repl_qb({{
1887 Rd.uw = RS_RT<7:0> << 24 |
1888 RS_RT<7:0> << 16 |
1889 RS_RT<7:0> << 8 |
1890 RS_RT<7:0>;
1891 }});
1892 0x3: replv_qb({{
1893 Rd.sw = Rt.uw<7:0> << 24 |
1894 Rt.uw<7:0> << 16 |
1895 Rt.uw<7:0> << 8 |
1896 Rt.uw<7:0>;
1897 }});
1898 0x4: precequ_ph_qbl({{
1899 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1900 SIMD_FMT_PH, SIGNED, MODE_L);
1901 }});
1902 0x5: precequ_ph_qbr({{
1903 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1904 SIMD_FMT_PH, SIGNED, MODE_R);
1905 }});
1906 0x6: precequ_ph_qbla({{
1907 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1908 SIMD_FMT_PH, SIGNED, MODE_LA);
1909 }});
1910 0x7: precequ_ph_qbra({{
1911 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB, UNSIGNED,
1912 SIMD_FMT_PH, SIGNED, MODE_RA);
1913 }});
1914 }
1915 }
1916 0x1: decode OP_LO {
1917 format DspIntOp {
1918 0x1: absq_s_ph({{
1919 Rd.sw = dspAbs(Rt.sw, SIMD_FMT_PH, &dspctl);
1920 }});
1921 0x2: repl_ph({{
1922 Rd.uw = (sext<10>(RS_RT))<15:0> << 16 |
1923 (sext<10>(RS_RT))<15:0>;
1924 }});
1925 0x3: replv_ph({{
1926 Rd.uw = Rt.uw<15:0> << 16 |
1927 Rt.uw<15:0>;
1928 }});
1929 0x4: preceq_w_phl({{
1930 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_PH, SIGNED,
1931 SIMD_FMT_W, SIGNED, MODE_L);
1932 }});
1933 0x5: preceq_w_phr({{
1934 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_PH, SIGNED,
1935 SIMD_FMT_W, SIGNED, MODE_R);
1936 }});
1937 }
1938 }
1939 0x2: decode OP_LO {
1940 format DspIntOp {
1941 0x1: absq_s_w({{
1942 Rd.sw = dspAbs(Rt.sw, SIMD_FMT_W, &dspctl);
1943 }});
1944 }
1945 }
1946 0x3: decode OP_LO {
1947 0x3: IntOp::bitrev({{
1948 Rd.uw = bitrev( Rt.uw<15:0> );
1949 }});
1950 format DspIntOp {
1951 0x4: preceu_ph_qbl({{
1952 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1953 UNSIGNED, SIMD_FMT_PH,
1954 UNSIGNED, MODE_L);
1955 }});
1956 0x5: preceu_ph_qbr({{
1957 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1958 UNSIGNED, SIMD_FMT_PH,
1959 UNSIGNED, MODE_R );
1960 }});
1961 0x6: preceu_ph_qbla({{
1962 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1963 UNSIGNED, SIMD_FMT_PH,
1964 UNSIGNED, MODE_LA );
1965 }});
1966 0x7: preceu_ph_qbra({{
1967 Rd.uw = dspPrece(Rt.uw, SIMD_FMT_QB,
1968 UNSIGNED, SIMD_FMT_PH,
1969 UNSIGNED, MODE_RA);
1970 }});
1971 }
1972 }
1973 }
1974
1975 //Table 5-8 MIPS32 SHLL.QB Encoding of the op Field
1976 //(DSP ASE MANUAL)
1977 0x3: decode OP_HI {
1978 0x0: decode OP_LO {
1979 format DspIntOp {
1980 0x0: shll_qb({{
1981 Rd.sw = dspShll(Rt.sw, RS, SIMD_FMT_QB,
1982 NOSATURATE, UNSIGNED, &dspctl);
1983 }});
1984 0x1: shrl_qb({{
1985 Rd.sw = dspShrl(Rt.sw, RS, SIMD_FMT_QB,
1986 UNSIGNED);
1987 }});
1988 0x2: shllv_qb({{
1989 Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_QB,
1990 NOSATURATE, UNSIGNED, &dspctl);
1991 }});
1992 0x3: shrlv_qb({{
1993 Rd.sw = dspShrl(Rt.sw, Rs.sw, SIMD_FMT_QB,
1994 UNSIGNED);
1995 }});
1996 0x4: shra_qb({{
1997 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_QB,
1998 NOROUND, SIGNED, &dspctl);
1999 }});
2000 0x5: shra_r_qb({{
2001 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_QB,
2002 ROUND, SIGNED, &dspctl);
2003 }});
2004 0x6: shrav_qb({{
2005 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_QB,
2006 NOROUND, SIGNED, &dspctl);
2007 }});
2008 0x7: shrav_r_qb({{
2009 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_QB,
2010 ROUND, SIGNED, &dspctl);
2011 }});
2012 }
2013 }
2014 0x1: decode OP_LO {
2015 format DspIntOp {
2016 0x0: shll_ph({{
2017 Rd.uw = dspShll(Rt.uw, RS, SIMD_FMT_PH,
2018 NOSATURATE, SIGNED, &dspctl);
2019 }});
2020 0x1: shra_ph({{
2021 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_PH,
2022 NOROUND, SIGNED, &dspctl);
2023 }});
2024 0x2: shllv_ph({{
2025 Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_PH,
2026 NOSATURATE, SIGNED, &dspctl);
2027 }});
2028 0x3: shrav_ph({{
2029 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_PH,
2030 NOROUND, SIGNED, &dspctl);
2031 }});
2032 0x4: shll_s_ph({{
2033 Rd.sw = dspShll(Rt.sw, RS, SIMD_FMT_PH,
2034 SATURATE, SIGNED, &dspctl);
2035 }});
2036 0x5: shra_r_ph({{
2037 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_PH,
2038 ROUND, SIGNED, &dspctl);
2039 }});
2040 0x6: shllv_s_ph({{
2041 Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_PH,
2042 SATURATE, SIGNED, &dspctl);
2043 }});
2044 0x7: shrav_r_ph({{
2045 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_PH,
2046 ROUND, SIGNED, &dspctl);
2047 }});
2048 }
2049 }
2050 0x2: decode OP_LO {
2051 format DspIntOp {
2052 0x4: shll_s_w({{
2053 Rd.sw = dspShll(Rt.sw, RS, SIMD_FMT_W,
2054 SATURATE, SIGNED, &dspctl);
2055 }});
2056 0x5: shra_r_w({{
2057 Rd.sw = dspShra(Rt.sw, RS, SIMD_FMT_W,
2058 ROUND, SIGNED, &dspctl);
2059 }});
2060 0x6: shllv_s_w({{
2061 Rd.sw = dspShll(Rt.sw, Rs.sw, SIMD_FMT_W,
2062 SATURATE, SIGNED, &dspctl);
2063 }});
2064 0x7: shrav_r_w({{
2065 Rd.sw = dspShra(Rt.sw, Rs.sw, SIMD_FMT_W,
2066 ROUND, SIGNED, &dspctl);
2067 }});
2068 }
2069 }
2070 0x3: decode OP_LO {
2071 format DspIntOp {
2072 0x1: shrl_ph({{
2073 Rd.sw = dspShrl(Rt.sw, RS, SIMD_FMT_PH,
2074 UNSIGNED);
2075 }});
2076 0x3: shrlv_ph({{
2077 Rd.sw = dspShrl(Rt.sw, Rs.sw, SIMD_FMT_PH,
2078 UNSIGNED);
2079 }});
2080 }
2081 }
2082 }
2083 }
2084
2085 0x3: decode FUNCTION_LO {
2086
2087 //Table 3.12 MIPS32 ADDUH.QB Encoding of the op Field
2088 //(DSP ASE Rev2 Manual)
2089 0x0: decode OP_HI {
2090 0x0: decode OP_LO {
2091 format DspIntOp {
2092 0x0: adduh_qb({{
2093 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2094 NOROUND, UNSIGNED);
2095 }});
2096 0x1: subuh_qb({{
2097 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2098 NOROUND, UNSIGNED);
2099 }});
2100 0x2: adduh_r_qb({{
2101 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2102 ROUND, UNSIGNED);
2103 }});
2104 0x3: subuh_r_qb({{
2105 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_QB,
2106 ROUND, UNSIGNED);
2107 }});
2108 }
2109 }
2110 0x1: decode OP_LO {
2111 format DspIntOp {
2112 0x0: addqh_ph({{
2113 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2114 NOROUND, SIGNED);
2115 }});
2116 0x1: subqh_ph({{
2117 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2118 NOROUND, SIGNED);
2119 }});
2120 0x2: addqh_r_ph({{
2121 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2122 ROUND, SIGNED);
2123 }});
2124 0x3: subqh_r_ph({{
2125 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_PH,
2126 ROUND, SIGNED);
2127 }});
2128 0x4: mul_ph({{
2129 Rd.sw = dspMul(Rs.sw, Rt.sw, SIMD_FMT_PH,
2130 NOSATURATE, &dspctl);
2131 }}, IntMultOp);
2132 0x6: mul_s_ph({{
2133 Rd.sw = dspMul(Rs.sw, Rt.sw, SIMD_FMT_PH,
2134 SATURATE, &dspctl);
2135 }}, IntMultOp);
2136 }
2137 }
2138 0x2: decode OP_LO {
2139 format DspIntOp {
2140 0x0: addqh_w({{
2141 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_W,
2142 NOROUND, SIGNED);
2143 }});
2144 0x1: subqh_w({{
2145 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_W,
2146 NOROUND, SIGNED);
2147 }});
2148 0x2: addqh_r_w({{
2149 Rd.uw = dspAddh(Rs.sw, Rt.sw, SIMD_FMT_W,
2150 ROUND, SIGNED);
2151 }});
2152 0x3: subqh_r_w({{
2153 Rd.uw = dspSubh(Rs.sw, Rt.sw, SIMD_FMT_W,
2154 ROUND, SIGNED);
2155 }});
2156 0x6: mulq_s_w({{
2157 Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_W,
2158 SATURATE, NOROUND, &dspctl);
2159 }}, IntMultOp);
2160 0x7: mulq_rs_w({{
2161 Rd.sw = dspMulq(Rs.sw, Rt.sw, SIMD_FMT_W,
2162 SATURATE, ROUND, &dspctl);
2163 }}, IntMultOp);
2164 }
2165 }
2166 }
2167 }
2168
2169 //Table A-10 MIPS32 BSHFL Encoding of sa Field
2170 0x4: decode SA {
2171 format BasicOp {
2172 0x02: wsbh({{
2173 Rd.uw = Rt.uw<23:16> << 24 |
2174 Rt.uw<31:24> << 16 |
2175 Rt.uw<7:0> << 8 |
2176 Rt.uw<15:8>;
2177 }});
2178 0x10: seb({{ Rd.sw = Rt.sb; }});
2179 0x18: seh({{ Rd.sw = Rt.sh; }});
2180 }
2181 }
2182
2183 0x6: decode FUNCTION_LO {
2184
2185 //Table 5-10 MIPS32 DPAQ.W.PH Encoding of the op Field
2186 //(DSP ASE MANUAL)
2187 0x0: decode OP_HI {
2188 0x0: decode OP_LO {
2189 format DspHiLoOp {
2190 0x0: dpa_w_ph({{
2191 dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2192 SIMD_FMT_PH, SIGNED, MODE_L);
2193 }}, IntMultOp);
2194 0x1: dps_w_ph({{
2195 dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2196 SIMD_FMT_PH, SIGNED, MODE_L);
2197 }}, IntMultOp);
2198 0x2: mulsa_w_ph({{
2199 dspac = dspMulsa(dspac, Rs.sw, Rt.sw,
2200 ACDST, SIMD_FMT_PH );
2201 }}, IntMultOp);
2202 0x3: dpau_h_qbl({{
2203 dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2204 SIMD_FMT_QB, UNSIGNED, MODE_L);
2205 }}, IntMultOp);
2206 0x4: dpaq_s_w_ph({{
2207 dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2208 ACDST, SIMD_FMT_PH,
2209 SIMD_FMT_W, NOSATURATE,
2210 MODE_L, &dspctl);
2211 }}, IntMultOp);
2212 0x5: dpsq_s_w_ph({{
2213 dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2214 ACDST, SIMD_FMT_PH,
2215 SIMD_FMT_W, NOSATURATE,
2216 MODE_L, &dspctl);
2217 }}, IntMultOp);
2218 0x6: mulsaq_s_w_ph({{
2219 dspac = dspMulsaq(dspac, Rs.sw, Rt.sw,
2220 ACDST, SIMD_FMT_PH,
2221 &dspctl);
2222 }}, IntMultOp);
2223 0x7: dpau_h_qbr({{
2224 dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2225 SIMD_FMT_QB, UNSIGNED, MODE_R);
2226 }}, IntMultOp);
2227 }
2228 }
2229 0x1: decode OP_LO {
2230 format DspHiLoOp {
2231 0x0: dpax_w_ph({{
2232 dspac = dspDpa(dspac, Rs.sw, Rt.sw, ACDST,
2233 SIMD_FMT_PH, SIGNED, MODE_X);
2234 }}, IntMultOp);
2235 0x1: dpsx_w_ph({{
2236 dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2237 SIMD_FMT_PH, SIGNED, MODE_X);
2238 }}, IntMultOp);
2239 0x3: dpsu_h_qbl({{
2240 dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2241 SIMD_FMT_QB, UNSIGNED, MODE_L);
2242 }}, IntMultOp);
2243 0x4: dpaq_sa_l_w({{
2244 dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2245 ACDST, SIMD_FMT_W,
2246 SIMD_FMT_L, SATURATE,
2247 MODE_L, &dspctl);
2248 }}, IntMultOp);
2249 0x5: dpsq_sa_l_w({{
2250 dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2251 ACDST, SIMD_FMT_W,
2252 SIMD_FMT_L, SATURATE,
2253 MODE_L, &dspctl);
2254 }}, IntMultOp);
2255 0x7: dpsu_h_qbr({{
2256 dspac = dspDps(dspac, Rs.sw, Rt.sw, ACDST,
2257 SIMD_FMT_QB, UNSIGNED, MODE_R);
2258 }}, IntMultOp);
2259 }
2260 }
2261 0x2: decode OP_LO {
2262 format DspHiLoOp {
2263 0x0: maq_sa_w_phl({{
2264 dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2265 ACDST, SIMD_FMT_PH,
2266 MODE_L, SATURATE, &dspctl);
2267 }}, IntMultOp);
2268 0x2: maq_sa_w_phr({{
2269 dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2270 ACDST, SIMD_FMT_PH,
2271 MODE_R, SATURATE, &dspctl);
2272 }}, IntMultOp);
2273 0x4: maq_s_w_phl({{
2274 dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2275 ACDST, SIMD_FMT_PH,
2276 MODE_L, NOSATURATE, &dspctl);
2277 }}, IntMultOp);
2278 0x6: maq_s_w_phr({{
2279 dspac = dspMaq(dspac, Rs.uw, Rt.uw,
2280 ACDST, SIMD_FMT_PH,
2281 MODE_R, NOSATURATE, &dspctl);
2282 }}, IntMultOp);
2283 }
2284 }
2285 0x3: decode OP_LO {
2286 format DspHiLoOp {
2287 0x0: dpaqx_s_w_ph({{
2288 dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2289 ACDST, SIMD_FMT_PH,
2290 SIMD_FMT_W, NOSATURATE,
2291 MODE_X, &dspctl);
2292 }}, IntMultOp);
2293 0x1: dpsqx_s_w_ph({{
2294 dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2295 ACDST, SIMD_FMT_PH,
2296 SIMD_FMT_W, NOSATURATE,
2297 MODE_X, &dspctl);
2298 }}, IntMultOp);
2299 0x2: dpaqx_sa_w_ph({{
2300 dspac = dspDpaq(dspac, Rs.sw, Rt.sw,
2301 ACDST, SIMD_FMT_PH,
2302 SIMD_FMT_W, SATURATE,
2303 MODE_X, &dspctl);
2304 }}, IntMultOp);
2305 0x3: dpsqx_sa_w_ph({{
2306 dspac = dspDpsq(dspac, Rs.sw, Rt.sw,
2307 ACDST, SIMD_FMT_PH,
2308 SIMD_FMT_W, SATURATE,
2309 MODE_X, &dspctl);
2310 }}, IntMultOp);
2311 }
2312 }
2313 }
2314
2315 //Table 3.3 MIPS32 APPEND Encoding of the op Field
2316 0x1: decode OP_HI {
2317 0x0: decode OP_LO {
2318 format IntOp {
2319 0x0: append({{
2320 Rt.uw = (Rt.uw << RD) | bits(Rs.uw, RD - 1, 0);
2321 }});
2322 0x1: prepend({{
2323 Rt.uw = (Rt.uw >> RD) |
2324 (bits(Rs.uw, RD - 1, 0) << (32 - RD));
2325 }});
2326 }
2327 }
2328 0x2: decode OP_LO {
2329 format IntOp {
2330 0x0: balign({{
2331 Rt.uw = (Rt.uw << (8 * BP)) |
2332 (Rs.uw >> (8 * (4 - BP)));
2333 }});
2334 }
2335 }
2336 }
2337
2338 }
2339 0x7: decode FUNCTION_LO {
2340
2341 //Table 5-11 MIPS32 EXTR.W Encoding of the op Field
2342 //(DSP ASE MANUAL)
2343 0x0: decode OP_HI {
2344 0x0: decode OP_LO {
2345 format DspHiLoOp {
2346 0x0: extr_w({{
2347 Rt.uw = dspExtr(dspac, SIMD_FMT_W, RS,
2348 NOROUND, NOSATURATE, &dspctl);
2349 }});
2350 0x1: extrv_w({{
2351 Rt.uw = dspExtr(dspac, SIMD_FMT_W, Rs.uw,
2352 NOROUND, NOSATURATE, &dspctl);
2353 }});
2354 0x2: extp({{
2355 Rt.uw = dspExtp(dspac, RS, &dspctl);
2356 }});
2357 0x3: extpv({{
2358 Rt.uw = dspExtp(dspac, Rs.uw, &dspctl);
2359 }});
2360 0x4: extr_r_w({{
2361 Rt.uw = dspExtr(dspac, SIMD_FMT_W, RS,
2362 ROUND, NOSATURATE, &dspctl);
2363 }});
2364 0x5: extrv_r_w({{
2365 Rt.uw = dspExtr(dspac, SIMD_FMT_W, Rs.uw,
2366 ROUND, NOSATURATE, &dspctl);
2367 }});
2368 0x6: extr_rs_w({{
2369 Rt.uw = dspExtr(dspac, SIMD_FMT_W, RS,
2370 ROUND, SATURATE, &dspctl);
2371 }});
2372 0x7: extrv_rs_w({{
2373 Rt.uw = dspExtr(dspac, SIMD_FMT_W, Rs.uw,
2374 ROUND, SATURATE, &dspctl);
2375 }});
2376 }
2377 }
2378 0x1: decode OP_LO {
2379 format DspHiLoOp {
2380 0x2: extpdp({{
2381 Rt.uw = dspExtpd(dspac, RS, &dspctl);
2382 }});
2383 0x3: extpdpv({{
2384 Rt.uw = dspExtpd(dspac, Rs.uw, &dspctl);
2385 }});
2386 0x6: extr_s_h({{
2387 Rt.uw = dspExtr(dspac, SIMD_FMT_PH, RS,
2388 NOROUND, SATURATE, &dspctl);
2389 }});
2390 0x7: extrv_s_h({{
2391 Rt.uw = dspExtr(dspac, SIMD_FMT_PH, Rs.uw,
2392 NOROUND, SATURATE, &dspctl);
2393 }});
2394 }
2395 }
2396 0x2: decode OP_LO {
2397 format DspIntOp {
2398 0x2: rddsp({{
2399 Rd.uw = readDSPControl(&dspctl, RDDSPMASK);
2400 }});
2401 0x3: wrdsp({{
2402 writeDSPControl(&dspctl, Rs.uw, WRDSPMASK);
2403 }});
2404 }
2405 }
2406 0x3: decode OP_LO {
2407 format DspHiLoOp {
2408 0x2: shilo({{
2409 if (sext<6>(HILOSA) < 0) {
2410 dspac = (uint64_t)dspac <<
2411 -sext<6>(HILOSA);
2412 } else {
2413 dspac = (uint64_t)dspac >>
2414 sext<6>(HILOSA);
2415 }
2416 }});
2417 0x3: shilov({{
2418 if (sext<6>(Rs.sw<5:0>) < 0) {
2419 dspac = (uint64_t)dspac <<
2420 -sext<6>(Rs.sw<5:0>);
2421 } else {
2422 dspac = (uint64_t)dspac >>
2423 sext<6>(Rs.sw<5:0>);
2424 }
2425 }});
2426 0x7: mthlip({{
2427 dspac = dspac << 32;
2428 dspac |= Rs.uw;
2429 dspctl = insertBits(dspctl, 5, 0,
2430 dspctl<5:0> + 32);
2431 }});
2432 }
2433 }
2434 }
2435 0x3: decode OP default FailUnimpl::rdhwr() {
2436 0x0: decode FULL_SYSTEM {
2437 0: decode RD {
2438 29: BasicOp::rdhwr_se({{ Rt = TpValue; }});
2439 }
2440 }
2441 }
2442 }
2443 }
2444 }
2445
2446 0x4: decode OPCODE_LO {
2447 format LoadMemory {
2448 0x0: lb({{ Rt.sw = Mem.sb; }});
2449 0x1: lh({{ Rt.sw = Mem.sh; }});
2450 0x3: lw({{ Rt.sw = Mem.sw; }});
2451 0x4: lbu({{ Rt.uw = Mem.ub;}});
2452 0x5: lhu({{ Rt.uw = Mem.uh; }});
2453 }
2454
2455 format LoadUnalignedMemory {
2456 0x2: lwl({{
2457 uint32_t mem_shift = 24 - (8 * byte_offset);
2458 Rt.uw = mem_word << mem_shift | (Rt.uw & mask(mem_shift));
2459 }});
2460 0x6: lwr({{
2461 uint32_t mem_shift = 8 * byte_offset;
2462 Rt.uw = (Rt.uw & (mask(mem_shift) << (32 - mem_shift))) |
2463 (mem_word >> mem_shift);
2464 }});
2465 }
2466 }
2467
2468 0x5: decode OPCODE_LO {
2469 format StoreMemory {
2470 0x0: sb({{ Mem.ub = Rt<7:0>; }});
2471 0x1: sh({{ Mem.uh = Rt<15:0>; }});
2472 0x3: sw({{ Mem.uw = Rt<31:0>; }});
2473 }
2474
2475 format StoreUnalignedMemory {
2476 0x2: swl({{
2477 uint32_t reg_shift = 24 - (8 * byte_offset);
2478 uint32_t mem_shift = 32 - reg_shift;
2479 mem_word = (mem_word & (mask(reg_shift) << mem_shift)) |
2480 (Rt.uw >> reg_shift);
2481 }});
2482 0x6: swr({{
2483 uint32_t reg_shift = 8 * byte_offset;
2484 mem_word = Rt.uw << reg_shift |
2485 (mem_word & (mask(reg_shift)));
2486 }});
2487 }
2488 format CP0Control {
2489 0x7: cache({{
2490 //Addr CacheEA = Rs.uw + OFFSET;
2491 //fault = xc->CacheOp((uint8_t)CACHE_OP,(Addr) CacheEA);
2492 }});
2493 }
2494 }
2495
2496 0x6: decode OPCODE_LO {
2497 format LoadMemory {
2498 0x0: ll({{ Rt.uw = Mem.uw; }}, mem_flags=LLSC);
2499 0x1: lwc1({{ Ft.uw = Mem.uw; }});
2500 0x5: ldc1({{ Ft.ud = Mem.ud; }});
2501 }
2502 0x2: CP2Unimpl::lwc2();
2503 0x6: CP2Unimpl::ldc2();
2504 0x3: Prefetch::pref();
2505 }
2506
2507
2508 0x7: decode OPCODE_LO {
2509 0x0: StoreCond::sc({{ Mem.uw = Rt.uw; }},
2510 {{ uint64_t tmp = write_result;
2511 Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw;
2512 }}, mem_flags=LLSC,
2513 inst_flags = IsStoreConditional);
2514 format StoreMemory {
2515 0x1: swc1({{ Mem.uw = Ft.uw; }});
2516 0x5: sdc1({{ Mem.ud = Ft.ud; }});
2517 }
2518 0x2: CP2Unimpl::swc2();
2519 0x6: CP2Unimpl::sdc2();
2520 }
2521}
2522
2523