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