decoder.isa revision 2022
15081Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
25081Sgblack@eecs.umich.edu//
35081Sgblack@eecs.umich.edu// The actual decoder specification
45081Sgblack@eecs.umich.edu//
55081Sgblack@eecs.umich.edu
65081Sgblack@eecs.umich.edudecode OP default Trap::unknown({{illegal_instruction}}) {
75081Sgblack@eecs.umich.edu
85081Sgblack@eecs.umich.edu        0x0: decode OP2 {
95081Sgblack@eecs.umich.edu                0x0: Trap::illtrap({{illegal_instruction}});  //ILLTRAP
105081Sgblack@eecs.umich.edu                0x1: Branch::bpcc({{
115081Sgblack@eecs.umich.edu                        switch((CC12 << 1) | CC02)
125081Sgblack@eecs.umich.edu                        {
135081Sgblack@eecs.umich.edu                                case 1: case 3:
145081Sgblack@eecs.umich.edu                                        throw illegal_instruction;
155081Sgblack@eecs.umich.edu                                case 0:
165081Sgblack@eecs.umich.edu                                        if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2))
175081Sgblack@eecs.umich.edu                                                ;//branchHere
185081Sgblack@eecs.umich.edu                                break;
195081Sgblack@eecs.umich.edu                                case 2:
205081Sgblack@eecs.umich.edu                                        if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2))
215081Sgblack@eecs.umich.edu                                                ;//branchHere
225081Sgblack@eecs.umich.edu                                break;
235081Sgblack@eecs.umich.edu                        }
245081Sgblack@eecs.umich.edu                }});//BPcc
255081Sgblack@eecs.umich.edu                0x2: Branch::bicc({{
265081Sgblack@eecs.umich.edu                        if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2))
275081Sgblack@eecs.umich.edu                                ;//branchHere
285081Sgblack@eecs.umich.edu                }});//Bicc
295081Sgblack@eecs.umich.edu                0x3: Branch::bpr({{
305081Sgblack@eecs.umich.edu                        switch(RCOND)
315081Sgblack@eecs.umich.edu                        {
325081Sgblack@eecs.umich.edu                                case 0: case 4:
335081Sgblack@eecs.umich.edu                                        throw illegal_instruction;
345081Sgblack@eecs.umich.edu                                case 1:
355081Sgblack@eecs.umich.edu                                        if(Rs1 == 0) ;//branchHere
365081Sgblack@eecs.umich.edu                                break;
375081Sgblack@eecs.umich.edu                                case 2:
385081Sgblack@eecs.umich.edu                                        if(Rs1 <= 0) ;//branchHere
395081Sgblack@eecs.umich.edu                                break;
405081Sgblack@eecs.umich.edu                                case 3:
415081Sgblack@eecs.umich.edu                                        if(Rs1 < 0) ;//branchHere
425081Sgblack@eecs.umich.edu                                break;
435081Sgblack@eecs.umich.edu                                case 5:
445081Sgblack@eecs.umich.edu                                        if(Rs1 != 0) ;//branchHere
455081Sgblack@eecs.umich.edu                                break;
465081Sgblack@eecs.umich.edu                                case 6:
475081Sgblack@eecs.umich.edu                                        if(Rs1 > 0) ;//branchHere
485081Sgblack@eecs.umich.edu                                break;
495081Sgblack@eecs.umich.edu                                case 7:
505081Sgblack@eecs.umich.edu                                        if(Rs1 >= 0) ;//branchHere
515081Sgblack@eecs.umich.edu                                break;
525081Sgblack@eecs.umich.edu                        }
535081Sgblack@eecs.umich.edu                }});    //BPr
545081Sgblack@eecs.umich.edu                0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}});   //SETHI (or NOP if rd == 0 and imm == 0)
555081Sgblack@eecs.umich.edu                0x5: Trap::fbpfcc({{throw fp_disabled;}}); //FBPfcc
565081Sgblack@eecs.umich.edu                0x6: Trap::fbfcc({{throw fp_disabled;}});  //FBfcc
575081Sgblack@eecs.umich.edu        }
585081Sgblack@eecs.umich.edu        0x1: Branch::call({{
595081Sgblack@eecs.umich.edu                //branch here
605081Sgblack@eecs.umich.edu                Rd = xc->pc;
615081Sgblack@eecs.umich.edu        }});
625081Sgblack@eecs.umich.edu        0x2: decode OP3 {
635081Sgblack@eecs.umich.edu                format IntegerOp {
645081Sgblack@eecs.umich.edu                        0x00: add({{
65                                INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
66                                Rd = Rs1.sdw + val2;
67                        }});//ADD
68                        0x01: and({{
69                                UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw);
70                                Rd = Rs1.udw & val2;
71                        }});//AND
72                        0x02: or({{
73                                UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw);
74                                Rd = Rs1.udw | val2;
75                        }});//OR
76                        0x03: xor({{
77                                UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw);
78                                Rd = Rs1.udw ^ val2;
79                        }});//XOR
80                        0x04: sub({{
81                                INT64 val2 = ~((UINT64)(I ? SIMM13.sdw : Rs2.udw))+1;
82                                Rd = Rs1.sdw + val2;
83                        }});//SUB
84                        0x05: andn({{
85                                UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw);
86                                Rd = Rs1.udw & ~val2;
87                        }});//ANDN
88                        0x06: orn({{
89                                UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw);
90                                Rd = Rs1.udw | ~val2;
91                        }});//ORN
92                        0x07: xnor({{
93                                UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw);
94                                Rd = ~(Rs1.udw ^ val2);
95                        }});//XNOR
96                        0x08: addc({{
97                                INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
98                                INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
99                                Rd = Rs1.sdw + val2 + carryin;
100                        }});//ADDC
101                        0x09: mulx({{
102                                INT64 val2 = (I ? SIMM13.sdw : Rs2);
103                                Rd = Rs1 * val2;
104                        }});//MULX
105                        0x0A: umul({{
106                                UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw);
107                                Rd = resTemp = Rs1.udw<31:0> * val2<31:0>;
108                                xc->regs.MiscRegs.yFields.value = resTemp<63:32>;
109                        }});//UMUL
110                        0x0B: smul({{
111                                INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw);
112                                rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>;
113                                xc->regs.MiscRegs.yFields.value = resTemp<63:32>;
114                        }});//SMUL
115                        0x0C: subc({{
116                                INT64 val2 = ~((INT64)(I ? SIMM13.sdw : Rs2.sdw))+1;
117                                INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
118                                Rd.sdw = Rs1.sdw + val2 + carryin;
119                        }});//SUBC
120                        0x0D: udivx({{
121                                UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw);
122                                if(val2 == 0) throw division_by_zero;
123                                Rd.udw = Rs1.udw / val2;
124                        }});//UDIVX
125                        0x0E: udiv({{
126                                UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>);
127                                if(val2 == 0) throw division_by_zero;
128                                resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2;
129                                INT32 overflow = (resTemp<63:32> != 0);
130                                if(overflow) rd.udw = resTemp = 0xFFFFFFFF;
131                                else rd.udw = resTemp;
132                        }});   //UDIV
133                        0x0F: sdiv({{
134                                INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>);
135                                if(val2 == 0) throw division_by_zero;
136                                Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2;
137                                INT32 overflow = (resTemp<63:31> != 0);
138                                INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
139                                if(overflow) rd.udw = resTemp = 0x7FFFFFFF;
140                                else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000;
141                                else rd.udw = resTemp;
142                        }});//SDIV
143                }
144                format IntegerOpCc {
145                        0x10: addcc({{
146                                INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2);
147                                Rd = resTemp = Rs1 + val2;}},
148                                {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
149                                {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
150                                {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
151                                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
152                        );//ADDcc
153                        0x11: andcc({{
154                                INT64 val2 = (I ? SIMM13.sdw : Rs2);
155                                Rd = Rs1 & val2;}}
156                        ,{{0}},{{0}},{{0}},{{0}});//ANDcc
157                        0x12: orcc({{
158                                INT64 val2 = (I ? SIMM13.sdw : Rs2);
159                                Rd = Rs1 | val2;}}
160                        ,{{0}},{{0}},{{0}},{{0}});//ORcc
161                        0x13: xorcc({{
162                                INT64 val2 = (I ? SIMM13.sdw : Rs2);
163                                Rd = Rs1 ^ val2;}}
164                        ,{{0}},{{0}},{{0}},{{0}});//XORcc
165                        0x14: subcc({{
166                                INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2);
167                                Rd = resTemp = Rs1 - val2;}},
168                                {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}},
169                                {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
170                                {{((Rs1 >> 1) + (~val2) >> 1) + ((Rs1 | ~val2) & 0x1))<63:>}},
171                                {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
172                        );//SUBcc
173                        0x15: andncc({{
174                                INT64 val2 = (I ? SIMM13.sdw : Rs2);
175                                Rd = Rs1 & ~val2;}}
176                        ,{{0}},{{0}},{{0}},{{0}});//ANDNcc
177                        0x16: orncc({{
178                                INT64 val2 = (I ? SIMM13.sdw : Rs2);
179                                Rd = Rs1 | ~val2;}}
180                        ,{{0}},{{0}},{{0}},{{0}});//ORNcc
181                        0x17: xnorcc({{
182                                INT64 val2 = (I ? SIMM13.sdw : Rs2);
183                                Rd = ~(Rs1 ^ val2);}}
184                        ,{{0}},{{0}},{{0}},{{0}});//XNORcc
185                        0x18: addccc({{
186                                INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2);
187                                INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
188                                Rd = resTemp = Rs1 + val2 + carryin;}},
189                                {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31 + carryin)}},
190                                {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
191                                {{((Rs1 >> 1) + (val2 >> 1) + ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}},
192                                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
193                        );//ADDCcc
194                        0x1A: umulcc({{
195                                UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2);
196                                Rd = resTemp = Rs1.udw<31:0> * val2<31:0>;
197                                xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}}
198                        ,{{0}},{{0}},{{0}},{{0}});//UMULcc
199                        0x1B: smulcc({{
200                                INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2);
201                                Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>;
202                                xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}}
203                        ,{{0}},{{0}},{{0}},{{0}});//SMULcc
204                        0x1C: subccc({{
205                                INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2);
206                                INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
207                                Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
208                                {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}},
209                                {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
210                                {{((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}},
211                                {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
212                        );//SUBCcc
213                        0x1D: udivxcc({{
214                                UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw);
215                                if(val2 == 0) throw division_by_zero;
216                                Rd.udw = Rs1.udw / val2;}}
217                        ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc
218                        0x1E: udivcc({{
219                                UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>);
220                                if(val2 == 0) throw division_by_zero;
221                                resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2;
222                                INT32 overflow = (resTemp<63:32> != 0);
223                                if(overflow) rd.udw = resTemp = 0xFFFFFFFF;
224                                else rd.udw = resTemp;}},
225                                {{0}},
226                                {{overflow}},
227                                {{0}},
228                                {{0}}
229                        );//UDIVcc
230                        0x1F: sdivcc({{
231                                INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>);
232                                if(val2 == 0) throw division_by_zero;
233                                Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2;
234                                INT32 overflow = (resTemp<63:31> != 0);
235                                INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
236                                if(overflow) rd.udw = resTemp = 0x7FFFFFFF;
237                                else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000;
238                                else rd.udw = resTemp;}},
239                                {{0}},
240                                {{overflow || underflow}},
241                                {{0}},
242                                {{0}}
243                        );//SDIVcc
244                        0x20: taddcc({{
245                                INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2);
246                                Rd = resTemp = Rs1 + val2;
247                                INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
248                                {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
249                                {{overflow}},
250                                {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
251                                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
252                        );//TADDcc
253                        0x21: tsubcc({{
254                                INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2);
255                                Rd = resTemp = Rs1 + val2;
256                                INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
257                                {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
258                                {{overflow}},
259                                {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
260                                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
261                        );//TSUBcc
262                        0x22: taddcctv({{
263                                INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2);
264                                Rd = resTemp = Rs1 + val2;
265                                INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
266                                if(overflow) throw tag_overflow;}},
267                                {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
268                                {{overflow}},
269                                {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
270                                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
271                        );//TADDccTV
272                        0x23: tsubcctv({{
273                                INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2);
274                                Rd = resTemp = Rs1 + val2;
275                                INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
276                                if(overflow) throw tag_overflow;}},
277                                {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
278                                {{overflow}},
279                                {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
280                                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
281                        );//TSUBccTV
282                        0x24: mulscc({{
283                                INT64 resTemp, multiplicand = (I ? SIMM13.sdw : Rs2);
284                                INT32 multiplier = Rs1<31:0>;
285                                INT32 savedLSB = Rs1<0:>;
286                                multiplier = multipler<31:1> |
287                                        ((xc->regs.MiscRegs.ccrFields.iccFields.n
288                                        ^ xc->regs.MiscRegs.ccrFields.iccFields.v) << 32);
289                                if(!xc->regs.MiscRegs.yFields.value<0:>)
290                                        multiplicand = 0;
291                                Rd = resTemp = multiplicand + multiplier;
292                                xc->regs.MiscRegs.yFields.value = xc->regs.MiscRegs.yFields.value<31:1> | (savedLSB << 31);}},
293                                {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}},
294                                {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}},
295                                {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}},
296                                {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}}
297                        );//MULScc
298                }
299                format IntegerOp
300                {
301                        0x25: decode X {
302                                0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}}); //SLL
303                                0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}}); //SLLX
304                        }
305                        0x26: decode X {
306                                0x0: srl({{Rd = Rs1.udw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRL
307                                0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRLX
308                        }
309                        0x27: decode X {
310                                0x0: sra({{Rd = Rs1.sdw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRA
311                                0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRAX
312                        }
313                        0x28: decode RS1 {
314                                0x0: rdy({{Rd = xc->regs.MiscRegs.yFields.value;}}); //RDY
315                                0x2: rdccr({{Rd = xc->regs.MiscRegs.ccr;}}); //RDCCR
316                                0x3: rdasi({{Rd = xc->regs.MiscRegs.asi;}}); //RDASI
317                                0x4: rdtick({{
318                                        if(xc->regs.MiscRegs.pstateFields.priv == 0 &&
319                                                xc->regs.MiscRegs.tickFields.npt == 1)
320                                                throw privileged_action;
321                                        Rd = xc->regs.MiscRegs.tick;
322                                }});//RDTICK
323                                0x5: rdpc({{Rd = xc->regs.pc;}}); //RDPC
324                                0x6: rdfprs({{Rd = xc->regs.MiscRegs.fprs;}}); //RDFPRS
325                                0xF: decode I {
326                                        0x0: Noop::membar({{//Membar isn't needed yet}}); //MEMBAR
327                                        0x1: Noop::stbar({{//Stbar isn/'t needed yet}}); //STBAR
328                                }
329                        }
330
331                        0x2A: decode RS1 {
332                                0x0: rdprtpc({{checkPriv Rd = xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl];}});
333                                0x1: rdprtnpc({{checkPriv Rd = xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl];}});
334                                0x2: rdprtstate({{checkPriv Rd = xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl];}});
335                                0x3: rdprtt({{checkPriv Rd = xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl];}});
336                                0x4: rdprtick({{checkPriv Rd = xc->regs.MiscRegs.tick;}});
337                                0x5: rdprtba({{checkPriv Rd = xc->regs.MiscRegs.tba;}});
338                                0x6: rdprpstate({{checkPriv Rd = xc->regs.MiscRegs.pstate;}});
339                                0x7: rdprtl({{checkPriv Rd = xc->regs.MiscRegs.tl;}});
340                                0x8: rdprpil({{checkPriv Rd = xc->regs.MiscRegs.pil;}});
341                                0x9: rdprcwp({{checkPriv Rd = xc->regs.MiscRegs.cwp;}});
342                                0xA: rdprcansave({{checkPriv Rd = xc->regs.MiscRegs.cansave;}});
343                                0xB: rdprcanrestore({{checkPriv Rd = xc->regs.MiscRegs.canrestore;}});
344                                0xC: rdprcleanwin({{checkPriv Rd = xc->regs.MiscRegs.cleanwin;}});
345                                0xD: rdprotherwin({{checkPriv Rd = xc->regs.MiscRegs.otherwin;}});
346                                0xE: rdprwstate({{checkPriv Rd = xc->regs.MiscRegs.wstate;}});
347                                0xF: rdprfq({{throw illegal_instruction;}}); //The floating point queue isn't implemented right now.
348                        }
349                        0x2B: BasicOperate::flushw({{\\window toilet}}); //FLUSHW
350                        0x2C: movcc({{
351                                ccBank = (CC24 << 2) | (CC14 << 1) | (CC04 << 0);
352                                switch(ccBank)
353                                {
354                                        case 0: case 1: case 2: case 3:
355                                                throw fp_disabled;
356                                        break;
357                                        case 5: case 7:
358                                                throw illegal_instruction;
359                                        break;
360                                        case 4:
361                                                if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND4))
362                                                        Rd = (I ? SIMM11.sdw : RS2);
363                                        break;
364                                        case 6:
365                                                if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND4))
366                                                        Rd = (I ? SIMM11.sdw : RS2);
367                                        break;
368                                }
369                        }});//MOVcc
370                        0x2D: sdivx({{
371                                INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
372                                if(val2 == 0) throw division_by_zero;
373                                Rd.sdw = Rs1.sdw / val2;
374                        }});//SDIVX
375                        0x2E: decode RS1 {
376                                0x0: IntegerOp::popc({{
377                                INT64 count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw);
378                                UINT8 oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}
379                                for(unsigned int x = 0; x < 16; x++)
380                                {
381                                        count += oneBits[val2 & 0xF];
382                                        val2 >> 4;
383                                }
384                                }});//POPC
385                        }
386                        0x2F: movr({{
387                                UINT64 val2 = (I ? SIMM10.sdw : Rs2.sdw);
388                                switch(RCOND)
389                                {
390                                        case 0: case 4:
391                                                throw illegal_instruction;
392                                        break;
393                                        case 1:
394                                                if(Rs1 == 0) Rd = val2;
395                                        break;
396                                        case 2:
397                                                if(Rs1 <= 0) Rd = val2;
398                                        break;
399                                        case 3:
400                                                if(Rs1 = 0) Rd = val2;
401                                        break;
402                                        case 5:
403                                                if(Rs1 != 0) Rd = val2;
404                                        break;
405                                        case 6:
406                                                if(Rs1 > 0) Rd = val2;
407                                        break;
408                                        case 7:
409                                                if(Rs1 >= 0) Rd = val2;
410                                        break;
411                                }
412                        }});//MOVR
413                        0x30: decode RD {
414                                0x0: wry({{
415                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
416                                        xc->regs.MiscRegs.y = Rs1 ^ val2;
417                                }});//WRY
418                                0x2: wrccr({{
419                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
420                                        xc->regs.MiscRegs.ccr = Rs1 ^ val2;
421                                }});//WRCCR
422                                0x3: wrasi({{
423                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
424                                        xc->regs.MiscRegs.asi = Rs1 ^ val2;
425                                }});//WRASI
426                                0x6: wrfprs({{
427                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
428                                        xc->regs.MiscRegs.asi = Rs1 ^ val2;
429                                }});//WRFPRS
430                                0xF: Trap::sir({{software_initiated_reset}}); //SIR
431                        }
432                        0x31: decode FCN {
433                                0x0: BasicOperate::saved({{\\Boogy Boogy}}); //SAVED
434                                0x1: BasicOperate::restored({{\\Boogy Boogy}}); //RESTORED
435                        }
436                        0x32: decode RD {
437                                0x0: wrprtpc({{checkPriv
438                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
439                                        xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
440                                }});
441                                0x1: wrprtnpc({{checkPriv
442                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
443                                        xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
444                                }});
445                                0x2: wrprtstate({{checkPriv
446                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
447                                        xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
448                                }});
449                                0x3: wrprtt({{checkPriv
450                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
451                                        xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
452                                }});
453                                0x4: wrprtick({{checkPriv
454                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
455                                        xc->regs.MiscRegs.tick = Rs1 ^ val2;
456                                }});
457                                0x5: wrprtba({{checkPriv
458                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
459                                        xc->regs.MiscRegs.tba = Rs1 ^ val2;
460                                }});
461                                0x6: wrprpstate({{checkPriv
462                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
463                                        xc->regs.MiscRegs.pstate = Rs1 ^ val2;
464                                }});
465                                0x7: wrprtl({{checkPriv
466                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
467                                        xc->regs.MiscRegs.tl = Rs1 ^ val2;
468                                }});
469                                0x8: wrprpil({{checkPriv
470                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
471                                        xc->regs.MiscRegs.pil = Rs1 ^ val2;
472                                }});
473                                0x9: wrprcwp({{checkPriv
474                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
475                                        xc->regs.MiscRegs.cwp = Rs1 ^ val2;
476                                }});
477                                0xA: wrprcansave({{checkPriv
478                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
479                                        xc->regs.MiscRegs.cansave = Rs1 ^ val2;
480                                }});
481                                0xB: wrprcanrestore({{checkPriv
482                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
483                                        xc->regs.MiscRegs.canrestore = Rs1 ^ val2;
484                                }});
485                                0xC: wrprcleanwin({{checkPriv
486                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
487                                        xc->regs.MiscRegs.cleanwin = Rs1 ^ val2;
488                                }});
489                                0xD: wrprotherwin({{checkPriv
490                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
491                                        xc->regs.MiscRegs.otherwin = Rs1 ^ val2;
492                                }});
493                                0xE: wrprwstate({{checkPriv
494                                        UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw);
495                                        xc->regs.MiscRegs.wstate = Rs1 ^ val2;
496                                }});
497                        }
498
499                        0x34: Trap::fpop1({{Throw fp_disabled;}}); //FPOP1
500                        0x35: Trap::fpop2({{Throw fp_disabled;}}); //FPOP2
501
502
503                        0x38: Branch::jmpl({{//Stuff}}); //JMPL
504                        0x39: Branch::return({{//Other Stuff}}); //RETURN
505                        0x3A: Trap::tcc({{
506                                switch((CC14 << 1) | (CC04 << 0))
507                                {
508                                        case 1: case 3:
509                                                throw illegal_instruction;
510                                        case 0:
511                                                if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, machInst<25:28>))
512                                                        throw trap_instruction;
513                                        break;
514                                        case 2:
515                                                if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, machInst<25:28>))
516                                                        throw trap_instruction;
517                                        break;
518                                }
519                        }}); //Tcc
520                        0x3B: BasicOperate::flush({{//Lala}}); //FLUSH
521                        0x3C: BasicOperate::save({{//leprechauns); //SAVE
522                        0x3D: BasicOperate::restore({{//Eat my short int}}); //RESTORE
523                        0x3E: decode FCN {
524                                0x1: BasicOperate::done({{//Done thing}}); //DONE
525                                0x2: BasicOperate::retry({{//Retry thing}}); //RETRY
526                        }
527                }
528        }
529        0x3: decode OP3 {
530                format Mem {
531                        0x00: lduw({{Rd.uw = Mem.uw;}}); //LDUW
532                        0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB
533                        0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH
534                        0x03: ldd({{
535                                UINT64 val = Mem.udw;
536                                setIntReg(RD & (~1), val<31:0>);
537                                setIntReg(RD | 1, val<63:32>);
538                        }});//LDD
539                        0x04: stw({{Mem.sw = Rd.sw;}}); //STW
540                        0x05: stb({{Mem.sb = Rd.sb;}}); //STB
541                        0x06: sth({{Mem.shw = Rd.shw;}}); //STH
542                        0x07: std({{
543                                Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
544                        }});//STD
545                        0x08: ldsw({{Rd.sw = Mem.sw;}}); //LDSW
546                        0x09: ldsb({{Rd.sb = Mem.sb;}}); //LDSB
547                        0x0A: ldsh({{Rd.shw = Mem.shw;}}); //LDSH
548                        0x0B: ldx({{Rd.udw = Mem.udw;}}); //LDX
549
550                        0x0D: ldstub({{
551                                Rd.ub = Mem.ub;
552                                Mem.ub = 0xFF;
553                        }}); //LDSTUB
554                        0x0E: stx({{Rd.udw = Mem.udw;}}); //STX
555                        0x0F: swap({{
556                                UINT32 temp = Rd.uw;
557                                Rd.uw = Mem.uw;
558                                Mem.uw = temp;
559                        }}); //SWAP
560                        0x10: lduwa({{Rd.uw = Mem.uw;}}); //LDUWA
561                        0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA
562                        0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA
563                        0x13: ldda({{
564                                UINT64 val = Mem.udw;
565                                setIntReg(RD & (~1), val<31:0>);
566                                setIntReg(RD | 1, val<63:32>);
567                        }}); //LDDA
568                        0x14: stwa({{Mem.uw = Rd.uw;}}); //STWA
569                        0x15: stba({{Mem.ub = Rd.ub;}}); //STBA
570                        0x16: stha({{Mem.uhw = Rd.uhw;}}); //STHA
571                        0x17: stda({{
572                                Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
573                        }}); //STDA
574                        0x18: ldswa({{Rd.sw = Mem.sw;}}); //LDSWA
575                        0x19: ldsba({{Rd.sb = Mem.sb;}}); //LDSBA
576                        0x1A: ldsha({{Rd.shw = Mem.shw;}}); //LDSHA
577                        0x1B: ldxa({{Rd.sdw = Mem.sdw;}}); //LDXA
578
579                        0x1D: ldstuba({{
580                                Rd.ub = Mem.ub;
581                                Mem.ub = 0xFF;
582                        }}); //LDSTUBA
583                        0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA
584                        0x1F: swapa({{
585                                UINT32 temp = Rd.uw;
586                                Rd.uw = Mem.uw;
587                                Mem.uw = temp;
588                        }}); //SWAPA
589                        0x20: Trap::ldf({{throw fp_disabled;}}); //LDF
590                        0x21: decode X {
591                                0x0: Trap::ldfsr({{throw fp_disabled;}}); //LDFSR
592                                0x1: Trap::ldxfsr({{throw fp_disabled;}}); //LDXFSR
593                        }
594                        0x22: Trap::ldqf({{throw fp_disabled;}}); //LDQF
595                        0x23: Trap::lddf({{throw fp_disabled;}}); //LDDF
596                        0x24: Trap::stf({{throw fp_disabled;}}); //STF
597                        0x25: decode X {
598                                0x0: Trap::stfsr({{throw fp_disabled;}}); //STFSR
599                                0x1: Trap::stxfsr({{throw fp_disabled;}}); //STXFSR
600                        }
601                        0x26: Trap::stqf({{throw fp_disabled;}}); //STQF
602                        0x27: Trap::stdf({{throw fp_disabled;}}); //STDF
603
604
605
606
607
608                        0x2D: Noop::prefetch({{ }}); //PREFETCH
609
610
611                        0x30: Trap::ldfa({{throw fp_disabled;}}); //LDFA
612
613                        0x32: Trap::ldqfa({{throw fp_disabled;}}); //LDQFA
614                        0x33: Trap::lddfa({{throw fp_disabled;}}); //LDDFA
615                        0x34: Trap::stfa({{throw fp_disabled;}}); //STFA
616                        0x35: Trap::stqfa({{throw fp_disabled;}}); //STQFA
617                        0x36: Trap::stdfa({{throw fp_disabled;}}); //STDFA
618
619
620
621
622
623                        0x3C: Cas::casa(
624                                {{UINT64 val = Mem.uw;
625                                if(Rs2.uw == val)
626                                        Mem.uw = Rd.uw;
627                                Rd.uw = val;
628                        }}); //CASA
629                        0x3D: Noop::prefetcha({{ }}); //PREFETCHA
630                        0x3E: Cas::casxa(
631                                {{UINT64 val = Mem.udw;
632                                if(Rs2 == val)
633                                        Mem.udw = Rd;
634                                Rd = val;
635                        }}); //CASXA
636                }
637        }
638}
639