Deleted Added
sdiff udiff text old ( 7790:9df469679ac7 ) new ( 7837:bd474b97535c )
full compact
1// Copyright (c) 2006-2007 The Regents of The University of Michigan
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met: redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer;
8// redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution;
11// neither the name of the copyright holders nor the names of its
12// contributors may be used to endorse or promote products derived from
13// this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26//
27// Authors: Ali Saidi
28// Gabe Black
29// Steve Reinhardt
30
31////////////////////////////////////////////////////////////////////
32//
33// The actual decoder specification
34//
35
36decode OP default Unknown::unknown()
37{
38 0x0: decode OP2
39 {
40 // Throw an illegal instruction acception
41 0x0: Trap::illtrap({{fault = new IllegalInstruction;}});
42 format BranchN
43 {
44 // bpcc
45 0x1: decode COND2
46 {
47 // Branch Always
48 0x8: bpa(19, annul_code={{
49 NPC = PC + disp;
50 NNPC = PC + disp + 4;
51 }});
52 // Branch Never
53 0x0: bpn(19, {{;}},
54 annul_code={{
55 NNPC = NPC + 8;
56 NPC = NPC + 4;
57 }});
58 default: decode BPCC
59 {
60 0x0: bpcci(19, test={{passesCondition(Ccr<3:0>, COND2)}});
61 0x2: bpccx(19, test={{passesCondition(Ccr<7:4>, COND2)}});
62 }
63 }
64 // bicc
65 0x2: decode COND2
66 {
67 // Branch Always
68 0x8: ba(22, annul_code={{
69 NPC = PC + disp;
70 NNPC = PC + disp + 4;
71 }});
72 // Branch Never
73 0x0: bn(22, {{;}},
74 annul_code={{
75 NNPC = NPC + 8;
76 NPC = NPC + 4;
77 }});
78 default: bicc(22, test={{passesCondition(Ccr<3:0>, COND2)}});
79 }
80 }
81 0x3: decode RCOND2
82 {
83 format BranchSplit
84 {
85 0x1: bpreq(test={{Rs1.sdw == 0}});
86 0x2: bprle(test={{Rs1.sdw <= 0}});
87 0x3: bprl(test={{Rs1.sdw < 0}});
88 0x5: bprne(test={{Rs1.sdw != 0}});
89 0x6: bprg(test={{Rs1.sdw > 0}});
90 0x7: bprge(test={{Rs1.sdw >= 0}});
91 }
92 }
93 // SETHI (or NOP if rd == 0 and imm == 0)
94 0x4: SetHi::sethi({{Rd.udw = imm;}});
95 // fbpfcc
96 0x5: decode COND2 {
97 format BranchN {
98 // Branch Always
99 0x8: fbpa(22, annul_code={{
100 NPC = PC + disp;
101 NNPC = PC + disp + 4;
102 }});
103 // Branch Never
104 0x0: fbpn(22, {{;}},
105 annul_code={{
106 NNPC = NPC + 8;
107 NPC = NPC + 4;
108 }});
109 default: decode BPCC {
110 0x0: fbpfcc0(19, test=
111 {{passesFpCondition(Fsr<11:10>, COND2)}});
112 0x1: fbpfcc1(19, test=
113 {{passesFpCondition(Fsr<33:32>, COND2)}});
114 0x2: fbpfcc2(19, test=
115 {{passesFpCondition(Fsr<35:34>, COND2)}});
116 0x3: fbpfcc3(19, test=
117 {{passesFpCondition(Fsr<37:36>, COND2)}});
118 }
119 }
120 }
121 // fbfcc
122 0x6: decode COND2 {
123 format BranchN {
124 // Branch Always
125 0x8: fba(22, annul_code={{
126 NPC = PC + disp;
127 NNPC = PC + disp + 4;
128 }});
129 // Branch Never
130 0x0: fbn(22, {{;}},
131 annul_code={{
132 NNPC = NPC + 8;
133 NPC = NPC + 4;
134 }});
135 default: fbfcc(22, test=
136 {{passesFpCondition(Fsr<11:10>, COND2)}});
137 }
138 }
139 }
140 0x1: BranchN::call(30, {{
141 if (Pstate<3:>)
142 R15 = (PC)<31:0>;
143 else
144 R15 = PC;
145 NNPC = R15 + disp;
146 }});
147 0x2: decode OP3 {
148 format IntOp {
149 0x00: add({{Rd = Rs1.sdw + Rs2_or_imm13;}});
150 0x01: and({{Rd = Rs1.sdw & Rs2_or_imm13;}});
151 0x02: or({{Rd = Rs1.sdw | Rs2_or_imm13;}});
152 0x03: xor({{Rd = Rs1.sdw ^ Rs2_or_imm13;}});
153 0x04: sub({{Rd = Rs1.sdw - Rs2_or_imm13;}});
154 0x05: andn({{Rd = Rs1.sdw & ~Rs2_or_imm13;}});
155 0x06: orn({{Rd = Rs1.sdw | ~Rs2_or_imm13;}});
156 0x07: xnor({{Rd = ~(Rs1.sdw ^ Rs2_or_imm13);}});
157 0x08: addc({{Rd = Rs1.sdw + Rs2_or_imm13 + Ccr<0:0>;}});
158 0x09: mulx({{Rd = Rs1.sdw * Rs2_or_imm13;}});
159 0x0A: umul({{
160 Rd = Rs1.udw<31:0> * Rs2_or_imm13<31:0>;
161 Y = Rd<63:32>;
162 }});
163 0x0B: smul({{
164 Rd.sdw = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>);
165 Y = Rd.sdw<63:32>;
166 }});
167 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}});
168 0x0D: udivx({{
169 if (Rs2_or_imm13 == 0)
170 fault = new DivisionByZero;
171 else
172 Rd.udw = Rs1.udw / Rs2_or_imm13;
173 }});
174 0x0E: udiv({{
175 if (Rs2_or_imm13 == 0) {
176 fault = new DivisionByZero;
177 } else {
178 Rd.udw = ((Y << 32) | Rs1.udw<31:0>) / Rs2_or_imm13;
179 if (Rd.udw >> 32 != 0)
180 Rd.udw = 0xFFFFFFFF;
181 }
182 }});
183 0x0F: sdiv({{
184 if (Rs2_or_imm13.sdw == 0) {
185 fault = new DivisionByZero;
186 } else {
187 Rd.udw = ((int64_t)((Y << 32) |
188 Rs1.sdw<31:0>)) / Rs2_or_imm13.sdw;
189 if ((int64_t)Rd.udw >=
190 std::numeric_limits<int32_t>::max()) {
191 Rd.udw = 0x7FFFFFFF;
192 } else if ((int64_t)Rd.udw <=
193 std::numeric_limits<int32_t>::min()) {
194 Rd.udw = ULL(0xFFFFFFFF80000000);
195 }
196 }
197 }});
198 }
199 format IntOpCc {
200 0x10: addcc({{
201 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
202 Rd = res = op1 + op2;
203 }});
204 0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}});
205 0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}});
206 0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}});
207 0x14: subcc({{
208 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
209 Rd = res = op1 - op2;
210 }}, sub=True);
211 0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}});
212 0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}});
213 0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}});
214 0x18: addccc({{
215 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
216 Rd = res = op1 + op2 + Ccr<0:>;
217 }});
218 0x1A: IntOpCcRes::umulcc({{
219 uint64_t resTemp;
220 Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>;
221 Y = resTemp<63:32>;}});
222 0x1B: IntOpCcRes::smulcc({{
223 int64_t resTemp;
224 Rd = resTemp = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>);
225 Y = resTemp<63:32>;}});
226 0x1C: subccc({{
227 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
228 Rd = res = op1 - op2 - Ccr<0:>;
229 }}, sub=True);
230 0x1D: IntOpCcRes::udivxcc({{
231 if (Rs2_or_imm13.udw == 0)
232 fault = new DivisionByZero;
233 else
234 Rd = Rs1.udw / Rs2_or_imm13.udw;}});
235 0x1E: IntOpCcRes::udivcc({{
236 uint64_t resTemp;
237 uint32_t val2 = Rs2_or_imm13.udw;
238 int32_t overflow = 0;
239 if (val2 == 0) {
240 fault = new DivisionByZero;
241 } else {
242 resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2;
243 overflow = (resTemp<63:32> != 0);
244 if (overflow)
245 Rd = resTemp = 0xFFFFFFFF;
246 else
247 Rd = resTemp;
248 }
249 }}, iv={{overflow}});
250 0x1F: IntOpCcRes::sdivcc({{
251 int64_t val2 = Rs2_or_imm13.sdw<31:0>;
252 bool overflow = false, underflow = false;
253 if (val2 == 0) {
254 fault = new DivisionByZero;
255 } else {
256 Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2;
257 overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max());
258 underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min());
259 if (overflow)
260 Rd = 0x7FFFFFFF;
261 else if (underflow)
262 Rd = ULL(0xFFFFFFFF80000000);
263 }
264 }}, iv={{overflow || underflow}});
265 0x20: taddcc({{
266 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
267 Rd = res = Rs1 + op2;
268 }}, iv={{
269 (op1 & mask(2)) || (op2 & mask(2)) ||
270 findOverflow(32, res, op1, op2)
271 }});
272 0x21: tsubcc({{
273 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
274 Rd = res = Rs1 - op2;
275 }}, iv={{
276 (op1 & mask(2)) || (op2 & mask(2)) ||
277 findOverflow(32, res, op1, ~op2)
278 }}, sub=True);
279 0x22: taddcctv({{
280 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
281 Rd = res = op1 + op2;
282 bool overflow = (op1 & mask(2)) || (op2 & mask(2)) ||
283 findOverflow(32, res, op1, op2);
284 if (overflow)
285 fault = new TagOverflow;
286 }}, iv={{overflow}});
287 0x23: tsubcctv({{
288 int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
289 Rd = res = op1 - op2;
290 bool overflow = (op1 & mask(2)) || (op2 & mask(2)) ||
291 findOverflow(32, res, op1, ~op2);
292 if (overflow)
293 fault = new TagOverflow;
294 }}, iv={{overflow}}, sub=True);
295 0x24: mulscc({{
296 int32_t savedLSB = Rs1<0:>;
297
298 // Step 1
299 int64_t multiplicand = Rs2_or_imm13;
300 // Step 2
301 int32_t partialP = Rs1<31:1> |
302 ((Ccr<3:3> ^ Ccr<1:1>) << 31);
303 // Step 3
304 int32_t added = Y<0:> ? multiplicand : 0;
305 int64_t res, op1 = partialP, op2 = added;
306 Rd = res = partialP + added;
307 // Steps 4 & 5
308 Y = Y<31:1> | (savedLSB << 31);
309 }});
310 }
311 format IntOp
312 {
313 0x25: decode X {
314 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}});
315 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}});
316 }
317 0x26: decode X {
318 0x0: srl({{Rd = Rs1.uw >> (I ? SHCNT32 : Rs2<4:0>);}});
319 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}});
320 }
321 0x27: decode X {
322 0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}});
323 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});
324 }
325 0x28: decode RS1 {
326 0x00: NoPriv::rdy({{Rd = Y<31:0>;}});
327 // 1 should cause an illegal instruction exception
328 0x02: NoPriv::rdccr({{Rd = Ccr;}});
329 0x03: NoPriv::rdasi({{Rd = Asi;}});
330 0x04: Priv::rdtick({{Rd = Tick;}}, {{Tick<63:>}});
331 0x05: NoPriv::rdpc({{
332 if (Pstate<3:>)
333 Rd = (PC)<31:0>;
334 else
335 Rd = PC;
336 }});
337 0x06: NoPriv::rdfprs({{
338 // Wait for all fpops to finish.
339 Rd = Fprs;
340 }});
341 // 7-14 should cause an illegal instruction exception
342 0x0F: decode I {
343 0x0: Nop::stbar({{/*stuff*/}}, IsWriteBarrier, MemWriteOp);
344 0x1: Nop::membar({{/*stuff*/}}, IsMemBarrier, MemReadOp);
345 }
346 0x10: Priv::rdpcr({{Rd = Pcr;}});
347 0x11: Priv::rdpic({{Rd = Pic;}}, {{Pcr<0:>}});
348 // 0x12 should cause an illegal instruction exception
349 0x13: NoPriv::rdgsr({{
350 fault = checkFpEnableFault(xc);
351 if (fault)
352 return fault;
353 Rd = Gsr;
354 }});
355 // 0x14-0x15 should cause an illegal instruction exception
356 0x16: Priv::rdsoftint({{Rd = Softint;}});
357 0x17: Priv::rdtick_cmpr({{Rd = TickCmpr;}});
358 0x18: Priv::rdstick({{Rd = Stick}}, {{Stick<63:>}});
359 0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}});
360 0x1A: Priv::rdstrand_sts_reg({{
361 if (Pstate<2:> && !Hpstate<2:>)
362 Rd = StrandStsReg<0:>;
363 else
364 Rd = StrandStsReg;
365 }});
366 // 0x1A is supposed to be reserved, but it reads the strand
367 // status register.
368 // 0x1B-0x1F should cause an illegal instruction exception
369 }
370 0x29: decode RS1 {
371 0x00: HPriv::rdhprhpstate({{Rd = Hpstate;}});
372 0x01: HPriv::rdhprhtstate({{Rd = Htstate;}}, checkTl=true);
373 // 0x02 should cause an illegal instruction exception
374 0x03: HPriv::rdhprhintp({{Rd = Hintp;}});
375 // 0x04 should cause an illegal instruction exception
376 0x05: HPriv::rdhprhtba({{Rd = Htba;}});
377 0x06: HPriv::rdhprhver({{Rd = Hver;}});
378 // 0x07-0x1E should cause an illegal instruction exception
379 0x1F: HPriv::rdhprhstick_cmpr({{Rd = HstickCmpr;}});
380 }
381 0x2A: decode RS1 {
382 0x00: Priv::rdprtpc({{Rd = Tpc;}}, checkTl=true);
383 0x01: Priv::rdprtnpc({{Rd = Tnpc;}}, checkTl=true);
384 0x02: Priv::rdprtstate({{Rd = Tstate;}}, checkTl=true);
385 0x03: Priv::rdprtt({{Rd = Tt;}}, checkTl=true);
386 0x04: Priv::rdprtick({{Rd = Tick;}});
387 0x05: Priv::rdprtba({{Rd = Tba;}});
388 0x06: Priv::rdprpstate({{Rd = Pstate;}});
389 0x07: Priv::rdprtl({{Rd = Tl;}});
390 0x08: Priv::rdprpil({{Rd = Pil;}});
391 0x09: Priv::rdprcwp({{Rd = Cwp;}});
392 0x0A: Priv::rdprcansave({{Rd = Cansave;}});
393 0x0B: Priv::rdprcanrestore({{Rd = Canrestore;}});
394 0x0C: Priv::rdprcleanwin({{Rd = Cleanwin;}});
395 0x0D: Priv::rdprotherwin({{Rd = Otherwin;}});
396 0x0E: Priv::rdprwstate({{Rd = Wstate;}});
397 // 0x0F should cause an illegal instruction exception
398 0x10: Priv::rdprgl({{Rd = Gl;}});
399 // 0x11-0x1F should cause an illegal instruction exception
400 }
401 0x2B: BasicOperate::flushw({{
402 if (NWindows - 2 - Cansave != 0) {
403 if (Otherwin)
404 fault = new SpillNOther(4*Wstate<5:3>);
405 else
406 fault = new SpillNNormal(4*Wstate<2:0>);
407 }
408 }});
409 0x2C: decode MOVCC3
410 {
411 0x0: decode CC
412 {
413 0x0: movccfcc0({{
414 if (passesCondition(Fsr<11:10>, COND4))
415 Rd = Rs2_or_imm11;
416 else
417 Rd = Rd;
418 }});
419 0x1: movccfcc1({{
420 if (passesCondition(Fsr<33:32>, COND4))
421 Rd = Rs2_or_imm11;
422 else
423 Rd = Rd;
424 }});
425 0x2: movccfcc2({{
426 if (passesCondition(Fsr<35:34>, COND4))
427 Rd = Rs2_or_imm11;
428 else
429 Rd = Rd;
430 }});
431 0x3: movccfcc3({{
432 if (passesCondition(Fsr<37:36>, COND4))
433 Rd = Rs2_or_imm11;
434 else
435 Rd = Rd;
436 }});
437 }
438 0x1: decode CC
439 {
440 0x0: movcci({{
441 if (passesCondition(Ccr<3:0>, COND4))
442 Rd = Rs2_or_imm11;
443 else
444 Rd = Rd;
445 }});
446 0x2: movccx({{
447 if (passesCondition(Ccr<7:4>, COND4))
448 Rd = Rs2_or_imm11;
449 else
450 Rd = Rd;
451 }});
452 }
453 }
454 0x2D: sdivx({{
455 if (Rs2_or_imm13.sdw == 0)
456 fault = new DivisionByZero;
457 else
458 Rd.sdw = Rs1.sdw / Rs2_or_imm13.sdw;
459 }});
460 0x2E: Trap::popc({{fault = new IllegalInstruction;}});
461 0x2F: decode RCOND3
462 {
463 0x1: movreq({{Rd = (Rs1.sdw == 0) ? Rs2_or_imm10 : Rd;}});
464 0x2: movrle({{Rd = (Rs1.sdw <= 0) ? Rs2_or_imm10 : Rd;}});
465 0x3: movrl({{Rd = (Rs1.sdw < 0) ? Rs2_or_imm10 : Rd;}});
466 0x5: movrne({{Rd = (Rs1.sdw != 0) ? Rs2_or_imm10 : Rd;}});
467 0x6: movrg({{Rd = (Rs1.sdw > 0) ? Rs2_or_imm10 : Rd;}});
468 0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}});
469 }
470 0x30: decode RD {
471 0x00: NoPriv::wry({{Y = (Rs1 ^ Rs2_or_imm13)<31:0>;}});
472 // 0x01 should cause an illegal instruction exception
473 0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}});
474 0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}}, false,
475 IsSquashAfter);
476 // 0x04-0x05 should cause an illegal instruction exception
477 0x06: NoPriv::wrfprs({{Fprs = Rs1 ^ Rs2_or_imm13;}});
478 // 0x07-0x0E should cause an illegal instruction exception
479 0x0F: Trap::softreset({{fault = new SoftwareInitiatedReset;}});
480 0x10: Priv::wrpcr({{Pcr = Rs1 ^ Rs2_or_imm13;}});
481 0x11: Priv::wrpic({{Pic = Rs1 ^ Rs2_or_imm13;}}, {{Pcr<0:>}});
482 // 0x12 should cause an illegal instruction exception
483 0x13: NoPriv::wrgsr({{
484 if (Fprs<2:> == 0 || Pstate<4:> == 0)
485 return new FpDisabled;
486 Gsr = Rs1 ^ Rs2_or_imm13;
487 }});
488 0x14: Priv::wrsoftint_set({{SoftintSet = Rs1 ^ Rs2_or_imm13;}});
489 0x15: Priv::wrsoftint_clr({{SoftintClr = Rs1 ^ Rs2_or_imm13;}});
490 0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}});
491 0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}});
492 0x18: NoPriv::wrstick({{
493 if (!Hpstate<2:>)
494 return new IllegalInstruction;
495 Stick = Rs1 ^ Rs2_or_imm13;
496 }});
497 0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
498 0x1A: Priv::wrstrand_sts_reg({{
499 StrandStsReg = Rs1 ^ Rs2_or_imm13;
500 }});
501 // 0x1A is supposed to be reserved, but it writes the strand
502 // status register.
503 // 0x1B-0x1F should cause an illegal instruction exception
504 }
505 0x31: decode FCN {
506 0x0: Priv::saved({{
507 assert(Cansave < NWindows - 2);
508 assert(Otherwin || Canrestore);
509 Cansave = Cansave + 1;
510 if (Otherwin == 0)
511 Canrestore = Canrestore - 1;
512 else
513 Otherwin = Otherwin - 1;
514 }});
515 0x1: Priv::restored({{
516 assert(Cansave || Otherwin);
517 assert(Canrestore < NWindows - 2);
518 Canrestore = Canrestore + 1;
519 if (Otherwin == 0)
520 Cansave = Cansave - 1;
521 else
522 Otherwin = Otherwin - 1;
523
524 if (Cleanwin < NWindows - 1)
525 Cleanwin = Cleanwin + 1;
526 }});
527 }
528 0x32: decode RD {
529 0x00: Priv::wrprtpc(
530 {{Tpc = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
531 0x01: Priv::wrprtnpc(
532 {{Tnpc = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
533 0x02: Priv::wrprtstate(
534 {{Tstate = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
535 0x03: Priv::wrprtt(
536 {{Tt = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
537 0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}});
538 0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}});
539 0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}});
540 0x07: Priv::wrprtl({{
541 if (Pstate<2:> && !Hpstate<2:>)
542 Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPTL);
543 else
544 Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxTL);
545 }});
546 0x08: Priv::wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}});
547 0x09: Priv::wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}});
548 0x0A: Priv::wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}});
549 0x0B: Priv::wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}});
550 0x0C: Priv::wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}});
551 0x0D: Priv::wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}});
552 0x0E: Priv::wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}});
553 // 0x0F should cause an illegal instruction exception
554 0x10: Priv::wrprgl({{
555 if (Pstate<2:> && !Hpstate<2:>)
556 Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPGL);
557 else
558 Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxGL);
559 }});
560 // 0x11-0x1F should cause an illegal instruction exception
561 }
562 0x33: decode RD {
563 0x00: HPriv::wrhprhpstate({{Hpstate = Rs1 ^ Rs2_or_imm13;}});
564 0x01: HPriv::wrhprhtstate(
565 {{Htstate = Rs1 ^ Rs2_or_imm13;}}, checkTl=true);
566 // 0x02 should cause an illegal instruction exception
567 0x03: HPriv::wrhprhintp({{Hintp = Rs1 ^ Rs2_or_imm13;}});
568 // 0x04 should cause an illegal instruction exception
569 0x05: HPriv::wrhprhtba({{Htba = Rs1 ^ Rs2_or_imm13;}});
570 // 0x06-0x01D should cause an illegal instruction exception
571 0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}});
572 }
573 0x34: decode OPF{
574 format FpBasic{
575 0x01: fmovs({{Frds.uw = Frs2s.uw;}});
576 0x02: fmovd({{Frd.udw = Frs2.udw;}});
577 0x03: FpUnimpl::fmovq();
578 0x05: fnegs({{Frds.uw = Frs2s.uw ^ (1UL << 31);}});
579 0x06: fnegd({{Frd.udw = Frs2.udw ^ (1ULL << 63);}});
580 0x07: FpUnimpl::fnegq();
581 0x09: fabss({{Frds.uw = ((1UL << 31) - 1) & Frs2s.uw;}});
582 0x0A: fabsd({{Frd.udw = ((1ULL << 63) - 1) & Frs2.udw;}});
583 0x0B: FpUnimpl::fabsq();
584 0x29: fsqrts({{Frds.sf = std::sqrt(Frs2s.sf);}});
585 0x2A: fsqrtd({{Frd.df = std::sqrt(Frs2.df);}});
586 0x2B: FpUnimpl::fsqrtq();
587 0x41: fadds({{Frds.sf = Frs1s.sf + Frs2s.sf;}});
588 0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}});
589 0x43: FpUnimpl::faddq();
590 0x45: fsubs({{Frds.sf = Frs1s.sf - Frs2s.sf;}});
591 0x46: fsubd({{Frd.df = Frs1.df - Frs2.df; }});
592 0x47: FpUnimpl::fsubq();
593 0x49: fmuls({{Frds.sf = Frs1s.sf * Frs2s.sf;}});
594 0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}});
595 0x4B: FpUnimpl::fmulq();
596 0x4D: fdivs({{Frds.sf = Frs1s.sf / Frs2s.sf;}});
597 0x4E: fdivd({{Frd.df = Frs1.df / Frs2.df;}});
598 0x4F: FpUnimpl::fdivq();
599 0x69: fsmuld({{Frd.df = Frs1s.sf * Frs2s.sf;}});
600 0x6E: FpUnimpl::fdmulq();
601 0x81: fstox({{Frd.sdw = static_cast<int64_t>(Frs2s.sf);}});
602 0x82: fdtox({{Frd.sdw = static_cast<int64_t>(Frs2.df);}});
603 0x83: FpUnimpl::fqtox();
604 0x84: fxtos({{Frds.sf = static_cast<float>(Frs2.sdw);}});
605 0x88: fxtod({{Frd.df = static_cast<double>(Frs2.sdw);}});
606 0x8C: FpUnimpl::fxtoq();
607 0xC4: fitos({{Frds.sf = static_cast<float>(Frs2s.sw);}});
608 0xC6: fdtos({{Frds.sf = Frs2.df;}});
609 0xC7: FpUnimpl::fqtos();
610 0xC8: fitod({{Frd.df = static_cast<double>(Frs2s.sw);}});
611 0xC9: fstod({{Frd.df = Frs2s.sf;}});
612 0xCB: FpUnimpl::fqtod();
613 0xCC: FpUnimpl::fitoq();
614 0xCD: FpUnimpl::fstoq();
615 0xCE: FpUnimpl::fdtoq();
616 0xD1: fstoi({{
617 Frds.sw = static_cast<int32_t>(Frs2s.sf);
618 float t = Frds.sw;
619 if (t != Frs2s.sf)
620 Fsr = insertBits(Fsr, 4,0, 0x01);
621 }});
622 0xD2: fdtoi({{
623 Frds.sw = static_cast<int32_t>(Frs2.df);
624 double t = Frds.sw;
625 if (t != Frs2.df)
626 Fsr = insertBits(Fsr, 4,0, 0x01);
627 }});
628 0xD3: FpUnimpl::fqtoi();
629 default: FailUnimpl::fpop1();
630 }
631 }
632 0x35: decode OPF{
633 format FpBasic{
634 0x01: fmovs_fcc0({{
635 if (passesFpCondition(Fsr<11:10>, COND4))
636 Frds = Frs2s;
637 else
638 Frds = Frds;
639 }});
640 0x02: fmovd_fcc0({{
641 if (passesFpCondition(Fsr<11:10>, COND4))
642 Frd = Frs2;
643 else
644 Frd = Frd;
645 }});
646 0x03: FpUnimpl::fmovq_fcc0();
647 0x25: fmovrsz({{
648 if (Rs1 == 0)
649 Frds = Frs2s;
650 else
651 Frds = Frds;
652 }});
653 0x26: fmovrdz({{
654 if (Rs1 == 0)
655 Frd = Frs2;
656 else
657 Frd = Frd;
658 }});
659 0x27: FpUnimpl::fmovrqz();
660 0x41: fmovs_fcc1({{
661 if (passesFpCondition(Fsr<33:32>, COND4))
662 Frds = Frs2s;
663 else
664 Frds = Frds;
665 }});
666 0x42: fmovd_fcc1({{
667 if (passesFpCondition(Fsr<33:32>, COND4))
668 Frd = Frs2;
669 else
670 Frd = Frd;
671 }});
672 0x43: FpUnimpl::fmovq_fcc1();
673 0x45: fmovrslez({{
674 if (Rs1 <= 0)
675 Frds = Frs2s;
676 else
677 Frds = Frds;
678 }});
679 0x46: fmovrdlez({{
680 if (Rs1 <= 0)
681 Frd = Frs2;
682 else
683 Frd = Frd;
684 }});
685 0x47: FpUnimpl::fmovrqlez();
686 0x51: fcmps({{
687 uint8_t fcc;
688 if (isnan(Frs1s) || isnan(Frs2s))
689 fcc = 3;
690 else if (Frs1s < Frs2s)
691 fcc = 1;
692 else if (Frs1s > Frs2s)
693 fcc = 2;
694 else
695 fcc = 0;
696 uint8_t firstbit = 10;
697 if (FCMPCC)
698 firstbit = FCMPCC * 2 + 30;
699 Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc);
700 }});
701 0x52: fcmpd({{
702 uint8_t fcc;
703 if (isnan(Frs1) || isnan(Frs2))
704 fcc = 3;
705 else if (Frs1 < Frs2)
706 fcc = 1;
707 else if (Frs1 > Frs2)
708 fcc = 2;
709 else
710 fcc = 0;
711 uint8_t firstbit = 10;
712 if (FCMPCC)
713 firstbit = FCMPCC * 2 + 30;
714 Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc);
715 }});
716 0x53: FpUnimpl::fcmpq();
717 0x55: fcmpes({{
718 uint8_t fcc = 0;
719 if (isnan(Frs1s) || isnan(Frs2s))
720 fault = new FpExceptionIEEE754;
721 if (Frs1s < Frs2s)
722 fcc = 1;
723 else if (Frs1s > Frs2s)
724 fcc = 2;
725 uint8_t firstbit = 10;
726 if (FCMPCC)
727 firstbit = FCMPCC * 2 + 30;
728 Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc);
729 }});
730 0x56: fcmped({{
731 uint8_t fcc = 0;
732 if (isnan(Frs1) || isnan(Frs2))
733 fault = new FpExceptionIEEE754;
734 if (Frs1 < Frs2)
735 fcc = 1;
736 else if (Frs1 > Frs2)
737 fcc = 2;
738 uint8_t firstbit = 10;
739 if (FCMPCC)
740 firstbit = FCMPCC * 2 + 30;
741 Fsr = insertBits(Fsr, firstbit +1, firstbit, fcc);
742 }});
743 0x57: FpUnimpl::fcmpeq();
744 0x65: fmovrslz({{
745 if (Rs1 < 0)
746 Frds = Frs2s;
747 else
748 Frds = Frds;
749 }});
750 0x66: fmovrdlz({{
751 if (Rs1 < 0)
752 Frd = Frs2;
753 else
754 Frd = Frd;
755 }});
756 0x67: FpUnimpl::fmovrqlz();
757 0x81: fmovs_fcc2({{
758 if (passesFpCondition(Fsr<35:34>, COND4))
759 Frds = Frs2s;
760 else
761 Frds = Frds;
762 }});
763 0x82: fmovd_fcc2({{
764 if (passesFpCondition(Fsr<35:34>, COND4))
765 Frd = Frs2;
766 else
767 Frd = Frd;
768 }});
769 0x83: FpUnimpl::fmovq_fcc2();
770 0xA5: fmovrsnz({{
771 if (Rs1 != 0)
772 Frds = Frs2s;
773 else
774 Frds = Frds;
775 }});
776 0xA6: fmovrdnz({{
777 if (Rs1 != 0)
778 Frd = Frs2;
779 else
780 Frd = Frd;
781 }});
782 0xA7: FpUnimpl::fmovrqnz();
783 0xC1: fmovs_fcc3({{
784 if (passesFpCondition(Fsr<37:36>, COND4))
785 Frds = Frs2s;
786 else
787 Frds = Frds;
788 }});
789 0xC2: fmovd_fcc3({{
790 if (passesFpCondition(Fsr<37:36>, COND4))
791 Frd = Frs2;
792 else
793 Frd = Frd;
794 }});
795 0xC3: FpUnimpl::fmovq_fcc3();
796 0xC5: fmovrsgz({{
797 if (Rs1 > 0)
798 Frds = Frs2s;
799 else
800 Frds = Frds;
801 }});
802 0xC6: fmovrdgz({{
803 if (Rs1 > 0)
804 Frd = Frs2;
805 else
806 Frd = Frd;
807 }});
808 0xC7: FpUnimpl::fmovrqgz();
809 0xE5: fmovrsgez({{
810 if (Rs1 >= 0)
811 Frds = Frs2s;
812 else
813 Frds = Frds;
814 }});
815 0xE6: fmovrdgez({{
816 if (Rs1 >= 0)
817 Frd = Frs2;
818 else
819 Frd = Frd;
820 }});
821 0xE7: FpUnimpl::fmovrqgez();
822 0x101: fmovs_icc({{
823 if (passesCondition(Ccr<3:0>, COND4))
824 Frds = Frs2s;
825 else
826 Frds = Frds;
827 }});
828 0x102: fmovd_icc({{
829 if (passesCondition(Ccr<3:0>, COND4))
830 Frd = Frs2;
831 else
832 Frd = Frd;
833 }});
834 0x103: FpUnimpl::fmovq_icc();
835 0x181: fmovs_xcc({{
836 if (passesCondition(Ccr<7:4>, COND4))
837 Frds = Frs2s;
838 else
839 Frds = Frds;
840 }});
841 0x182: fmovd_xcc({{
842 if (passesCondition(Ccr<7:4>, COND4))
843 Frd = Frs2;
844 else
845 Frd = Frd;
846 }});
847 0x183: FpUnimpl::fmovq_xcc();
848 default: FailUnimpl::fpop2();
849 }
850 }
851 // This used to be just impdep1, but now it's a whole bunch
852 // of instructions
853 0x36: decode OPF{
854 0x00: FailUnimpl::edge8();
855 0x01: FailUnimpl::edge8n();
856 0x02: FailUnimpl::edge8l();
857 0x03: FailUnimpl::edge8ln();
858 0x04: FailUnimpl::edge16();
859 0x05: FailUnimpl::edge16n();
860 0x06: FailUnimpl::edge16l();
861 0x07: FailUnimpl::edge16ln();
862 0x08: FailUnimpl::edge32();
863 0x09: FailUnimpl::edge32n();
864 0x0A: FailUnimpl::edge32l();
865 0x0B: FailUnimpl::edge32ln();
866 0x10: FailUnimpl::array8();
867 0x12: FailUnimpl::array16();
868 0x14: FailUnimpl::array32();
869 0x18: BasicOperate::alignaddr({{
870 uint64_t sum = Rs1 + Rs2;
871 Rd = sum & ~7;
872 Gsr = (Gsr & ~7) | (sum & 7);
873 }});
874 0x19: FailUnimpl::bmask();
875 0x1A: BasicOperate::alignaddresslittle({{
876 uint64_t sum = Rs1 + Rs2;
877 Rd = sum & ~7;
878 Gsr = (Gsr & ~7) | ((~sum + 1) & 7);
879 }});
880 0x20: FailUnimpl::fcmple16();
881 0x22: FailUnimpl::fcmpne16();
882 0x24: FailUnimpl::fcmple32();
883 0x26: FailUnimpl::fcmpne32();
884 0x28: FailUnimpl::fcmpgt16();
885 0x2A: FailUnimpl::fcmpeq16();
886 0x2C: FailUnimpl::fcmpgt32();
887 0x2E: FailUnimpl::fcmpeq32();
888 0x31: FailUnimpl::fmul8x16();
889 0x33: FailUnimpl::fmul8x16au();
890 0x35: FailUnimpl::fmul8x16al();
891 0x36: FailUnimpl::fmul8sux16();
892 0x37: FailUnimpl::fmul8ulx16();
893 0x38: FailUnimpl::fmuld8sux16();
894 0x39: FailUnimpl::fmuld8ulx16();
895 0x3A: Trap::fpack32({{fault = new IllegalInstruction;}});
896 0x3B: Trap::fpack16({{fault = new IllegalInstruction;}});
897 0x3D: Trap::fpackfix({{fault = new IllegalInstruction;}});
898 0x3E: Trap::pdist({{fault = new IllegalInstruction;}});
899 0x48: BasicOperate::faligndata({{
900 uint64_t msbX = Frs1.udw;
901 uint64_t lsbX = Frs2.udw;
902 // Some special cases need to be split out, first
903 // because they're the most likely to be used, and
904 // second because otherwise, we end up shifting by
905 // greater than the width of the type being shifted,
906 // namely 64, which produces undefined results
907 // according to the C standard.
908 switch (Gsr<2:0>) {
909 case 0:
910 Frd.udw = msbX;
911 break;
912 case 8:
913 Frd.udw = lsbX;
914 break;
915 default:
916 uint64_t msbShift = Gsr<2:0> * 8;
917 uint64_t lsbShift = (8 - Gsr<2:0>) * 8;
918 uint64_t msbMask = ((uint64_t)(-1)) >> msbShift;
919 uint64_t lsbMask = ((uint64_t)(-1)) << lsbShift;
920 Frd.udw = ((msbX & msbMask) << msbShift) |
921 ((lsbX & lsbMask) >> lsbShift);
922 }
923 }});
924 0x4B: Trap::fpmerge({{fault = new IllegalInstruction;}});
925 0x4C: FailUnimpl::bshuffle();
926 0x4D: FailUnimpl::fexpand();
927 0x50: FailUnimpl::fpadd16();
928 0x51: FailUnimpl::fpadd16s();
929 0x52: FailUnimpl::fpadd32();
930 0x53: FailUnimpl::fpadd32s();
931 0x54: FailUnimpl::fpsub16();
932 0x55: FailUnimpl::fpsub16s();
933 0x56: FailUnimpl::fpsub32();
934 0x57: FailUnimpl::fpsub32s();
935 0x60: FpBasic::fzero({{Frd.df = 0;}});
936 0x61: FpBasic::fzeros({{Frds.sf = 0;}});
937 0x62: FailUnimpl::fnor();
938 0x63: FailUnimpl::fnors();
939 0x64: FailUnimpl::fandnot2();
940 0x65: FailUnimpl::fandnot2s();
941 0x66: FpBasic::fnot2({{
942 Frd.df = (double)(~((uint64_t)Frs2.df));
943 }});
944 0x67: FpBasic::fnot2s({{
945 Frds.sf = (float)(~((uint32_t)Frs2s.sf));
946 }});
947 0x68: FailUnimpl::fandnot1();
948 0x69: FailUnimpl::fandnot1s();
949 0x6A: FpBasic::fnot1({{
950 Frd.df = (double)(~((uint64_t)Frs1.df));
951 }});
952 0x6B: FpBasic::fnot1s({{
953 Frds.sf = (float)(~((uint32_t)Frs1s.sf));
954 }});
955 0x6C: FailUnimpl::fxor();
956 0x6D: FailUnimpl::fxors();
957 0x6E: FailUnimpl::fnand();
958 0x6F: FailUnimpl::fnands();
959 0x70: FailUnimpl::fand();
960 0x71: FailUnimpl::fands();
961 0x72: FailUnimpl::fxnor();
962 0x73: FailUnimpl::fxnors();
963 0x74: FpBasic::fsrc1({{Frd.udw = Frs1.udw;}});
964 0x75: FpBasic::fsrc1s({{Frds.uw = Frs1s.uw;}});
965 0x76: FailUnimpl::fornot2();
966 0x77: FailUnimpl::fornot2s();
967 0x78: FpBasic::fsrc2({{Frd.udw = Frs2.udw;}});
968 0x79: FpBasic::fsrc2s({{Frds.uw = Frs2s.uw;}});
969 0x7A: FailUnimpl::fornot1();
970 0x7B: FailUnimpl::fornot1s();
971 0x7C: FailUnimpl::for();
972 0x7D: FailUnimpl::fors();
973 0x7E: FpBasic::fone({{Frd.udw = std::numeric_limits<uint64_t>::max();}});
974 0x7F: FpBasic::fones({{Frds.uw = std::numeric_limits<uint32_t>::max();}});
975 0x80: Trap::shutdown({{fault = new IllegalInstruction;}});
976 0x81: FailUnimpl::siam();
977 }
978 // M5 special opcodes use the reserved IMPDEP2A opcode space
979 0x37: decode M5FUNC {
980#if FULL_SYSTEM
981 format BasicOperate {
982 // we have 7 bits of space here to play with...
983 0x21: m5exit({{
984 PseudoInst::m5exit(xc->tcBase(), O0);
985 }}, No_OpClass, IsNonSpeculative);
986 0x50: m5readfile({{
987 O0 = PseudoInst::readfile(xc->tcBase(), O0, O1, O2);
988 }}, IsNonSpeculative);
989 0x51: m5break({{
990 PseudoInst::debugbreak(xc->tcBase());
991 }}, IsNonSpeculative);
992 0x54: m5panic({{
993 panic("M5 panic instruction called at pc = %#x.", PC);
994 }}, No_OpClass, IsNonSpeculative);
995 }
996#endif
997 default: Trap::impdep2({{fault = new IllegalInstruction;}});
998 }
999 0x38: Branch::jmpl({{
1000 Addr target = Rs1 + Rs2_or_imm13;
1001 if (target & 0x3) {
1002 fault = new MemAddressNotAligned;
1003 } else {
1004 if (Pstate<3:>)
1005 Rd = (PC)<31:0>;
1006 else
1007 Rd = PC;
1008 NNPC = target;
1009 }
1010 }});
1011 0x39: Branch::return({{
1012 Addr target = Rs1 + Rs2_or_imm13;
1013 if (fault == NoFault) {
1014 // Check for fills which are higher priority than alignment
1015 // faults.
1016 if (Canrestore == 0) {
1017 if (Otherwin)
1018 fault = new FillNOther(4*Wstate<5:3>);
1019 else
1020 fault = new FillNNormal(4*Wstate<2:0>);
1021 } else if (target & 0x3) { // Check for alignment faults
1022 fault = new MemAddressNotAligned;
1023 } else {
1024 NNPC = target;
1025 Cwp = (Cwp - 1 + NWindows) % NWindows;
1026 Cansave = Cansave + 1;
1027 Canrestore = Canrestore - 1;
1028 }
1029 }
1030 }});
1031 0x3A: decode CC
1032 {
1033 0x0: Trap::tcci({{
1034 if (passesCondition(Ccr<3:0>, COND2)) {
1035 int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2);
1036 DPRINTF(Sparc, "The trap number is %d\n", lTrapNum);
1037 fault = new TrapInstruction(lTrapNum);
1038 }
1039 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
1040 0x2: Trap::tccx({{
1041 if (passesCondition(Ccr<7:4>, COND2)) {
1042 int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2);
1043 DPRINTF(Sparc, "The trap number is %d\n", lTrapNum);
1044 fault = new TrapInstruction(lTrapNum);
1045 }
1046 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
1047 }
1048 0x3B: Nop::flush({{/*Instruction memory flush*/}}, IsWriteBarrier,
1049 MemWriteOp);
1050 0x3C: save({{
1051 if (Cansave == 0) {
1052 if (Otherwin)
1053 fault = new SpillNOther(4*Wstate<5:3>);
1054 else
1055 fault = new SpillNNormal(4*Wstate<2:0>);
1056 } else if (Cleanwin - Canrestore == 0) {
1057 fault = new CleanWindow;
1058 } else {
1059 Cwp = (Cwp + 1) % NWindows;
1060 Rd_next = Rs1 + Rs2_or_imm13;
1061 Cansave = Cansave - 1;
1062 Canrestore = Canrestore + 1;
1063 }
1064 }});
1065 0x3D: restore({{
1066 if (Canrestore == 0) {
1067 if (Otherwin)
1068 fault = new FillNOther(4*Wstate<5:3>);
1069 else
1070 fault = new FillNNormal(4*Wstate<2:0>);
1071 } else {
1072 Cwp = (Cwp - 1 + NWindows) % NWindows;
1073 Rd_prev = Rs1 + Rs2_or_imm13;
1074 Cansave = Cansave + 1;
1075 Canrestore = Canrestore - 1;
1076 }
1077 }});
1078 0x3E: decode FCN {
1079 0x0: Priv::done({{
1080 Cwp = Tstate<4:0>;
1081 Pstate = Tstate<20:8>;
1082 Asi = Tstate<31:24>;
1083 Ccr = Tstate<39:32>;
1084 Gl = Tstate<42:40>;
1085 Hpstate = Htstate;
1086 NPC = Tnpc;
1087 NNPC = Tnpc + 4;
1088 Tl = Tl - 1;
1089 }}, checkTl=true);
1090 0x1: Priv::retry({{
1091 Cwp = Tstate<4:0>;
1092 Pstate = Tstate<20:8>;
1093 Asi = Tstate<31:24>;
1094 Ccr = Tstate<39:32>;
1095 Gl = Tstate<42:40>;
1096 Hpstate = Htstate;
1097 NPC = Tpc;
1098 NNPC = Tnpc;
1099 Tl = Tl - 1;
1100 }}, checkTl=true);
1101 }
1102 }
1103 }
1104 0x3: decode OP3 {
1105 format Load {
1106 0x00: lduw({{Rd = Mem.uw;}});
1107 0x01: ldub({{Rd = Mem.ub;}});
1108 0x02: lduh({{Rd = Mem.uhw;}});
1109 0x03: ldtw({{
1110 RdLow = (Mem.tuw).a;
1111 RdHigh = (Mem.tuw).b;
1112 }});
1113 }
1114 format Store {
1115 0x04: stw({{Mem.uw = Rd.sw;}});
1116 0x05: stb({{Mem.ub = Rd.sb;}});
1117 0x06: sth({{Mem.uhw = Rd.shw;}});
1118 0x07: sttw({{
1119 // This temporary needs to be here so that the parser
1120 // will correctly identify this instruction as a store.
1121 // It's probably either the parenthesis or referencing
1122 // the member variable that throws confuses it.
1123 Twin32_t temp;
1124 temp.a = RdLow<31:0>;
1125 temp.b = RdHigh<31:0>;
1126 Mem.tuw = temp;
1127 }});
1128 }
1129 format Load {
1130 0x08: ldsw({{Rd = (int32_t)Mem.sw;}});
1131 0x09: ldsb({{Rd = (int8_t)Mem.sb;}});
1132 0x0A: ldsh({{Rd = (int16_t)Mem.shw;}});
1133 0x0B: ldx({{Rd = (int64_t)Mem.sdw;}});
1134 }
1135 0x0D: Swap::ldstub({{Mem.ub = 0xFF;}},
1136 {{
1137 uint8_t tmp = mem_data;
1138 Rd.ub = tmp;
1139 }}, MEM_SWAP);
1140 0x0E: Store::stx({{Mem.udw = Rd}});
1141 0x0F: Swap::swap({{Mem.uw = Rd.uw}},
1142 {{
1143 uint32_t tmp = mem_data;
1144 Rd.uw = tmp;
1145 }}, MEM_SWAP);
1146 format LoadAlt {
1147 0x10: lduwa({{Rd = Mem.uw;}});
1148 0x11: lduba({{Rd = Mem.ub;}});
1149 0x12: lduha({{Rd = Mem.uhw;}});
1150 0x13: decode EXT_ASI {
1151 // ASI_LDTD_AIUP
1152 0x22: TwinLoad::ldtx_aiup(
1153 {{RdLow.udw = (Mem.tudw).a;
1154 RdHigh.udw = (Mem.tudw).b;}});
1155 // ASI_LDTD_AIUS
1156 0x23: TwinLoad::ldtx_aius(
1157 {{RdLow.udw = (Mem.tudw).a;
1158 RdHigh.udw = (Mem.tudw).b;}});
1159 // ASI_QUAD_LDD
1160 0x24: TwinLoad::ldtx_quad_ldd(
1161 {{RdLow.udw = (Mem.tudw).a;
1162 RdHigh.udw = (Mem.tudw).b;}});
1163 // ASI_LDTX_REAL
1164 0x26: TwinLoad::ldtx_real(
1165 {{RdLow.udw = (Mem.tudw).a;
1166 RdHigh.udw = (Mem.tudw).b;}});
1167 // ASI_LDTX_N
1168 0x27: TwinLoad::ldtx_n(
1169 {{RdLow.udw = (Mem.tudw).a;
1170 RdHigh.udw = (Mem.tudw).b;}});
1171 // ASI_LDTX_AIUP_L
1172 0x2A: TwinLoad::ldtx_aiup_l(
1173 {{RdLow.udw = (Mem.tudw).a;
1174 RdHigh.udw = (Mem.tudw).b;}});
1175 // ASI_LDTX_AIUS_L
1176 0x2B: TwinLoad::ldtx_aius_l(
1177 {{RdLow.udw = (Mem.tudw).a;
1178 RdHigh.udw = (Mem.tudw).b;}});
1179 // ASI_LDTX_L
1180 0x2C: TwinLoad::ldtx_l(
1181 {{RdLow.udw = (Mem.tudw).a;
1182 RdHigh.udw = (Mem.tudw).b;}});
1183 // ASI_LDTX_REAL_L
1184 0x2E: TwinLoad::ldtx_real_l(
1185 {{RdLow.udw = (Mem.tudw).a;
1186 RdHigh.udw = (Mem.tudw).b;}});
1187 // ASI_LDTX_N_L
1188 0x2F: TwinLoad::ldtx_n_l(
1189 {{RdLow.udw = (Mem.tudw).a;
1190 RdHigh.udw = (Mem.tudw).b;}});
1191 // ASI_LDTX_P
1192 0xE2: TwinLoad::ldtx_p(
1193 {{RdLow.udw = (Mem.tudw).a;
1194 RdHigh.udw = (Mem.tudw).b;}});
1195 // ASI_LDTX_S
1196 0xE3: TwinLoad::ldtx_s(
1197 {{RdLow.udw = (Mem.tudw).a;
1198 RdHigh.udw = (Mem.tudw).b;}});
1199 // ASI_LDTX_PL
1200 0xEA: TwinLoad::ldtx_pl(
1201 {{RdLow.udw = (Mem.tudw).a;
1202 RdHigh.udw = (Mem.tudw).b;}});
1203 // ASI_LDTX_SL
1204 0xEB: TwinLoad::ldtx_sl(
1205 {{RdLow.udw = (Mem.tudw).a;
1206 RdHigh.udw = (Mem.tudw).b;}});
1207 default: ldtwa({{
1208 RdLow = (Mem.tuw).a;
1209 RdHigh = (Mem.tuw).b;}});
1210 }
1211 }
1212 format StoreAlt {
1213 0x14: stwa({{Mem.uw = Rd;}});
1214 0x15: stba({{Mem.ub = Rd;}});
1215 0x16: stha({{Mem.uhw = Rd;}});
1216 0x17: sttwa({{
1217 // This temporary needs to be here so that the parser
1218 // will correctly identify this instruction as a store.
1219 // It's probably either the parenthesis or referencing
1220 // the member variable that throws confuses it.
1221 Twin32_t temp;
1222 temp.a = RdLow<31:0>;
1223 temp.b = RdHigh<31:0>;
1224 Mem.tuw = temp;
1225 }});
1226 }
1227 format LoadAlt {
1228 0x18: ldswa({{Rd = (int32_t)Mem.sw;}});
1229 0x19: ldsba({{Rd = (int8_t)Mem.sb;}});
1230 0x1A: ldsha({{Rd = (int16_t)Mem.shw;}});
1231 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}});
1232 }
1233 0x1D: SwapAlt::ldstuba({{Mem.ub = 0xFF;}},
1234 {{
1235 uint8_t tmp = mem_data;
1236 Rd.ub = tmp;
1237 }}, MEM_SWAP);
1238 0x1E: StoreAlt::stxa({{Mem.udw = Rd}});
1239 0x1F: SwapAlt::swapa({{Mem.uw = Rd.uw}},
1240 {{
1241 uint32_t tmp = mem_data;
1242 Rd.uw = tmp;
1243 }}, MEM_SWAP);
1244
1245 format Trap {
1246 0x20: Load::ldf({{Frds.uw = Mem.uw;}});
1247 0x21: decode RD {
1248 0x0: Load::ldfsr({{fault = checkFpEnableFault(xc);
1249 if (fault)
1250 return fault;
1251 Fsr = Mem.uw | Fsr<63:32>;}});
1252 0x1: Load::ldxfsr({{fault = checkFpEnableFault(xc);
1253 if (fault)
1254 return fault;
1255 Fsr = Mem.udw;}});
1256 default: FailUnimpl::ldfsrOther();
1257 }
1258 0x22: ldqf({{fault = new FpDisabled;}});
1259 0x23: Load::lddf({{Frd.udw = Mem.udw;}});
1260 0x24: Store::stf({{Mem.uw = Frds.uw;}});
1261 0x25: decode RD {
1262 0x0: StoreFsr::stfsr({{fault = checkFpEnableFault(xc);
1263 if (fault)
1264 return fault;
1265 Mem.uw = Fsr<31:0>;}});
1266 0x1: StoreFsr::stxfsr({{fault = checkFpEnableFault(xc);
1267 if (fault)
1268 return fault;
1269 Mem.udw = Fsr;}});
1270 default: FailUnimpl::stfsrOther();
1271 }
1272 0x26: stqf({{fault = new FpDisabled;}});
1273 0x27: Store::stdf({{Mem.udw = Frd.udw;}});
1274 0x2D: Nop::prefetch({{ }});
1275 0x30: LoadAlt::ldfa({{Frds.uw = Mem.uw;}});
1276 0x32: ldqfa({{fault = new FpDisabled;}});
1277 format LoadAlt {
1278 0x33: decode EXT_ASI {
1279 // ASI_NUCLEUS
1280 0x04: FailUnimpl::lddfa_n();
1281 // ASI_NUCLEUS_LITTLE
1282 0x0C: FailUnimpl::lddfa_nl();
1283 // ASI_AS_IF_USER_PRIMARY
1284 0x10: FailUnimpl::lddfa_aiup();
1285 // ASI_AS_IF_USER_PRIMARY_LITTLE
1286 0x18: FailUnimpl::lddfa_aiupl();
1287 // ASI_AS_IF_USER_SECONDARY
1288 0x11: FailUnimpl::lddfa_aius();
1289 // ASI_AS_IF_USER_SECONDARY_LITTLE
1290 0x19: FailUnimpl::lddfa_aiusl();
1291 // ASI_REAL
1292 0x14: FailUnimpl::lddfa_real();
1293 // ASI_REAL_LITTLE
1294 0x1C: FailUnimpl::lddfa_real_l();
1295 // ASI_REAL_IO
1296 0x15: FailUnimpl::lddfa_real_io();
1297 // ASI_REAL_IO_LITTLE
1298 0x1D: FailUnimpl::lddfa_real_io_l();
1299 // ASI_PRIMARY
1300 0x80: FailUnimpl::lddfa_p();
1301 // ASI_PRIMARY_LITTLE
1302 0x88: FailUnimpl::lddfa_pl();
1303 // ASI_SECONDARY
1304 0x81: FailUnimpl::lddfa_s();
1305 // ASI_SECONDARY_LITTLE
1306 0x89: FailUnimpl::lddfa_sl();
1307 // ASI_PRIMARY_NO_FAULT
1308 0x82: FailUnimpl::lddfa_pnf();
1309 // ASI_PRIMARY_NO_FAULT_LITTLE
1310 0x8A: FailUnimpl::lddfa_pnfl();
1311 // ASI_SECONDARY_NO_FAULT
1312 0x83: FailUnimpl::lddfa_snf();
1313 // ASI_SECONDARY_NO_FAULT_LITTLE
1314 0x8B: FailUnimpl::lddfa_snfl();
1315
1316 format BlockLoad {
1317 // LDBLOCKF
1318 // ASI_BLOCK_AS_IF_USER_PRIMARY
1319 0x16: FailUnimpl::ldblockf_aiup();
1320 // ASI_BLOCK_AS_IF_USER_SECONDARY
1321 0x17: FailUnimpl::ldblockf_aius();
1322 // ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE
1323 0x1E: FailUnimpl::ldblockf_aiupl();
1324 // ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE
1325 0x1F: FailUnimpl::ldblockf_aiusl();
1326 // ASI_BLOCK_PRIMARY
1327 0xF0: ldblockf_p({{Frd_N.udw = Mem.udw;}});
1328 // ASI_BLOCK_SECONDARY
1329 0xF1: FailUnimpl::ldblockf_s();
1330 // ASI_BLOCK_PRIMARY_LITTLE
1331 0xF8: FailUnimpl::ldblockf_pl();
1332 // ASI_BLOCK_SECONDARY_LITTLE
1333 0xF9: FailUnimpl::ldblockf_sl();
1334 }
1335
1336 // LDSHORTF
1337 // ASI_FL8_PRIMARY
1338 0xD0: FailUnimpl::ldshortf_8p();
1339 // ASI_FL8_SECONDARY
1340 0xD1: FailUnimpl::ldshortf_8s();
1341 // ASI_FL8_PRIMARY_LITTLE
1342 0xD8: FailUnimpl::ldshortf_8pl();
1343 // ASI_FL8_SECONDARY_LITTLE
1344 0xD9: FailUnimpl::ldshortf_8sl();
1345 // ASI_FL16_PRIMARY
1346 0xD2: FailUnimpl::ldshortf_16p();
1347 // ASI_FL16_SECONDARY
1348 0xD3: FailUnimpl::ldshortf_16s();
1349 // ASI_FL16_PRIMARY_LITTLE
1350 0xDA: FailUnimpl::ldshortf_16pl();
1351 // ASI_FL16_SECONDARY_LITTLE
1352 0xDB: FailUnimpl::ldshortf_16sl();
1353 // Not an ASI which is legal with lddfa
1354 default: Trap::lddfa_bad_asi(
1355 {{fault = new DataAccessException;}});
1356 }
1357 }
1358 0x34: Store::stfa({{Mem.uw = Frds.uw;}});
1359 0x36: stqfa({{fault = new FpDisabled;}});
1360 format StoreAlt {
1361 0x37: decode EXT_ASI {
1362 // ASI_NUCLEUS
1363 0x04: FailUnimpl::stdfa_n();
1364 // ASI_NUCLEUS_LITTLE
1365 0x0C: FailUnimpl::stdfa_nl();
1366 // ASI_AS_IF_USER_PRIMARY
1367 0x10: FailUnimpl::stdfa_aiup();
1368 // ASI_AS_IF_USER_PRIMARY_LITTLE
1369 0x18: FailUnimpl::stdfa_aiupl();
1370 // ASI_AS_IF_USER_SECONDARY
1371 0x11: FailUnimpl::stdfa_aius();
1372 // ASI_AS_IF_USER_SECONDARY_LITTLE
1373 0x19: FailUnimpl::stdfa_aiusl();
1374 // ASI_REAL
1375 0x14: FailUnimpl::stdfa_real();
1376 // ASI_REAL_LITTLE
1377 0x1C: FailUnimpl::stdfa_real_l();
1378 // ASI_REAL_IO
1379 0x15: FailUnimpl::stdfa_real_io();
1380 // ASI_REAL_IO_LITTLE
1381 0x1D: FailUnimpl::stdfa_real_io_l();
1382 // ASI_PRIMARY
1383 0x80: FailUnimpl::stdfa_p();
1384 // ASI_PRIMARY_LITTLE
1385 0x88: FailUnimpl::stdfa_pl();
1386 // ASI_SECONDARY
1387 0x81: FailUnimpl::stdfa_s();
1388 // ASI_SECONDARY_LITTLE
1389 0x89: FailUnimpl::stdfa_sl();
1390 // ASI_PRIMARY_NO_FAULT
1391 0x82: FailUnimpl::stdfa_pnf();
1392 // ASI_PRIMARY_NO_FAULT_LITTLE
1393 0x8A: FailUnimpl::stdfa_pnfl();
1394 // ASI_SECONDARY_NO_FAULT
1395 0x83: FailUnimpl::stdfa_snf();
1396 // ASI_SECONDARY_NO_FAULT_LITTLE
1397 0x8B: FailUnimpl::stdfa_snfl();
1398
1399 format BlockStore {
1400 // STBLOCKF
1401 // ASI_BLOCK_AS_IF_USER_PRIMARY
1402 0x16: FailUnimpl::stblockf_aiup();
1403 // ASI_BLOCK_AS_IF_USER_SECONDARY
1404 0x17: FailUnimpl::stblockf_aius();
1405 // ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE
1406 0x1E: FailUnimpl::stblockf_aiupl();
1407 // ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE
1408 0x1F: FailUnimpl::stblockf_aiusl();
1409 // ASI_BLOCK_PRIMARY
1410 0xF0: stblockf_p({{Mem.udw = Frd_N.udw;}});
1411 // ASI_BLOCK_SECONDARY
1412 0xF1: FailUnimpl::stblockf_s();
1413 // ASI_BLOCK_PRIMARY_LITTLE
1414 0xF8: FailUnimpl::stblockf_pl();
1415 // ASI_BLOCK_SECONDARY_LITTLE
1416 0xF9: FailUnimpl::stblockf_sl();
1417 }
1418
1419 // STSHORTF
1420 // ASI_FL8_PRIMARY
1421 0xD0: FailUnimpl::stshortf_8p();
1422 // ASI_FL8_SECONDARY
1423 0xD1: FailUnimpl::stshortf_8s();
1424 // ASI_FL8_PRIMARY_LITTLE
1425 0xD8: FailUnimpl::stshortf_8pl();
1426 // ASI_FL8_SECONDARY_LITTLE
1427 0xD9: FailUnimpl::stshortf_8sl();
1428 // ASI_FL16_PRIMARY
1429 0xD2: FailUnimpl::stshortf_16p();
1430 // ASI_FL16_SECONDARY
1431 0xD3: FailUnimpl::stshortf_16s();
1432 // ASI_FL16_PRIMARY_LITTLE
1433 0xDA: FailUnimpl::stshortf_16pl();
1434 // ASI_FL16_SECONDARY_LITTLE
1435 0xDB: FailUnimpl::stshortf_16sl();
1436 // Not an ASI which is legal with lddfa
1437 default: Trap::stdfa_bad_asi(
1438 {{fault = new DataAccessException;}});
1439 }
1440 }
1441 0x3C: CasAlt::casa({{
1442 mem_data = htog(Rs2.uw);
1443 Mem.uw = Rd.uw;}},
1444 {{
1445 uint32_t tmp = mem_data;
1446 Rd.uw = tmp;
1447 }}, MEM_SWAP_COND);
1448 0x3D: Nop::prefetcha({{ }});
1449 0x3E: CasAlt::casxa({{mem_data = gtoh(Rs2);
1450 Mem.udw = Rd.udw; }},
1451 {{ Rd.udw = mem_data; }}, MEM_SWAP_COND);
1452 }
1453 }
1454}