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